PageSourceSearch

https://www.provinciegroningen.nl/typo3temp/assets/compressed/merg…2b314b07fac5bb514ff4f4d5142fe.js?1787570895

js provinciegroningen.nl collected 2026-10-02 04:26:07 UTC 70,983 bytes, 1,374 lines download raw bytes

1
2!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var i=" ";return 1===e.nodeType&&(i+e.className+i).replace(/[\n\t]/g,i).indexOf(i+t+i)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var i=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(i,"")},interpolateString:function(e,t){var i=/{{([a-z][a-z0-9\-_]*)}}/gi;return e.replace(i,function(e){return t(arguments[1])||""})},getCookie:function(e){var t="; "+document.cookie,i=t.split("; "+e+"=");return 2!=i.length?void 0:i.pop().split(";").shift()},setCookie:function(e,t,i,n,o){var s=new Date;s.setDate(s.getDate()+(i||365));var r=[e+"="+t,"expires="+s.toUTCString(),"path="+(o||"/")];n&&r.push("domain="+n),document.cookie=r.join(";")},deepExtend:function(e,t){for(var i in t)t.hasOwnProperty(i)&&(i in e&&this.isPlainObject(e[i])&&this.isPlainObject(t[i])?this.deepExtend(e[i],t[i]):e[i]=t[i]);return e},throttle:function(e,t){var i=!1;return function(){i||(e.apply(this,arguments),i=!0,setTimeout(function(){i=!1},t))}},hash:function(e){var t,i,n,o=0;if(0===e.length)return o;for(t=0,n=e.length;t<n;++t)i=e.charCodeAt(t),o=(o<<5)-o+i,o|=0;return o},normaliseHex:function(e){return"#"==e[0]&&(e=e.substr(1)),3==e.length&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),e},getContrast:function(e){e=this.normaliseHex(e);var t=parseInt(e.substr(0,2),16),i=parseInt(e.substr(2,2),16),n=parseInt(e.substr(4,2),16),o=(299*t+587*i+114*n)/1e3;return o>=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),i=38,n=(t>>16)+i,o=(t>>8&255)+i,s=(255&t)+i,r=(16777216+65536*(n<255?n<1?0:n:255)+256*(o<255?o<1?0:o:255)+(s<255?s<1?0:s:255)).toString(16).slice(1);return"#"+r},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object}};
2e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var i in t)if(t.hasOwnProperty(i)&&"undefined"!=typeof e.style[i+"ransition"])return t[i];return""}(),e.hasTransition=!!e.transitionEnd;var i=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){function n(){this.initialise.apply(this,arguments)}function o(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function s(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function r(){var t=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return t(e.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return t(e.status.allow),!0;var i=Object.keys(e.status),n=this.getStatus(),o=i.indexOf(n)>=0;return o&&t(n),o}function a(){var e=this.options.position.split("-"),t=[];return e.forEach(function(e){t.push("cc-"+e)}),t}function c(){var e=this.options,i="top"==e.position||"bottom"==e.position?"banner":"floating";t.isMobile()&&(i="floating");var n=["cc-"+i,"cc-type-"+e.type,"cc-theme-"+e.theme];e["static"]&&n.push("cc-static"),n.push.apply(n,a.call(this));p.call(this,this.options.palette);return this.customStyleSelector&&n.push(this.customStyleSelector),n}function l(){var e={},i=this.options;i.showLink||(i.elements.link="",i.elements.messagelink=i.elements.message),Object.keys(i.elements).forEach(function(n){e[n]=t.interpolateString(i.elements[n],function(e){var t=i.content[e];return e&&"string"==typeof t&&t.length?t:""})});var n=i.compliance[i.type];n||(n=i.compliance.info),e.compliance=t.interpolateString(n,function(t){return e[t]});var o=i.layouts[i.layout];return o||(o=i.layouts.basic),t.interpolateString(o,function(t){return e[t]})}function u(i){var n=this.options,o=document.createElement("div"),s=n.container&&1===n.container.nodeType?n.container:document.body;o.innerHTML=i;var r=o.children[0];return r.style.display="none",t.hasClass(r,"cc-window")&&e.hasTransition&&t.addClass(r,"cc-invisible"),this.onButtonClick=h.bind(this),r.addEventListener("click",this.onButtonClick),n.autoAttach&&(s.firstChild?s.insertBefore(r,s.firstChild):s.appendChild(r)),r}function h(n){var o=n.target;if(t.hasClass(o,"cc-btn")){var s=o.className.match(new RegExp("\\bcc-("+i.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(o,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0)),t.hasClass(o,"cc-revoke")&&this.revokeChoice()}function p(e){var i=t.hash(JSON.stringify(e)),n="cc-color-override-"+i,o=t.isPlainObject(e);return this.customStyleSelector=o?n:null,o&&d(i,e,"."+n),o}function d(i,n,o){if(e.customStyles[i])return void++e.customStyles[i].references;var s={},r=n.popup,a=n.button,c=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[o+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[o+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[o+" .cc-link,"+o+" .cc-link:active,"+o+" .cc-link:visited"]=["color: "+r.link],a&&(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[o+" .cc-btn"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background],"transparent"!=a.background&&(s[o+" .cc-btn:hover, "+o+" .cc-btn:focus"]=["background-color: "+v(a.background)]),c?(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background]):s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var l=document.createElement("style");document.head.appendChild(l),e.customStyles[i]={references:1,element:l.sheet};var u=-1;for(var h in s)s.hasOwnProperty(h)&&l.sheet.insertRule(h+"{"+s[h].join(";")+"}",++u)}function v(e){return e=t.normaliseHex(e),"000000"==e?"#222":t.getLuminance(e)}function f(i){if(t.isPlainObject(i)){var n=t.hash(JSON.stringify(i)),o=e.customStyles[n];if(o&&!--o.references){var s=o.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}function m(e,t){for(var i=0,n=e.length;i<n;++i){var o=e[i];if(o instanceof RegExp&&o.test(t)||"string"==typeof o&&o.length&&o===t)return!0}return!1}function b(){var t=this.setStatus.bind(this),i=this.options.dismissOnTimeout;"number"==typeof i&&i>
2=0&&(this.dismissTimeout=window.setTimeout(function(){t(e.status.dismiss)},Math.floor(i)));var n=this.options.dismissOnScroll;if("number"==typeof n&&n>=0){var o=function(i){window.pageYOffset>Math.floor(n)&&(t(e.status.dismiss),window.removeEventListener("scroll",o),this.onWindowScroll=null)};this.onWindowScroll=o,window.addEventListener("scroll",o)}}function y(){if("info"!=this.options.type&&(this.options.revokable=!0),t.isMobile()&&(this.options.animateRevokable=!1),this.options.revokable){var e=a.call(this);this.options.animateRevokable&&e.push("cc-animate"),this.customStyleSelector&&e.push(this.customStyleSelector);var i=this.options.revokeBtn.replace("{{classes}}",e.join(" "));this.revokeBtn=u.call(this,i);var n=this.revokeBtn;if(this.options.animateRevokable){var o=t.throttle(function(e){var i=!1,o=20,s=window.innerHeight-20;t.hasClass(n,"cc-top")&&e.clientY<o&&(i=!0),t.hasClass(n,"cc-bottom")&&e.clientY>s&&(i=!0),i?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")},200);this.onMouseMove=o,window.addEventListener("mousemove",o)}}}var g={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"http://cookie
2sandyou.com",close:"&#x274c;"},elements:{header:'<span class="cc-header">{{header}}</span>&nbsp;',message:'<span id="cookieconsent:desc" class="cc-message">{{message}}</span>',messagelink:'<span id="cookieconsent:desc" class="cc-message">{{message}} <a role=button tabindex="0" class="cc-link" href="{{href}}" target="_blank">{{link}}</a></span>',dismiss:'<a aria-label="dismiss cookie message" role=button tabindex="0" class="cc-btn cc-dismiss">{{dismiss}}</a>',allow:'<a aria-label="allow cookies" role=button tabindex="0"  class="cc-btn cc-allow">{{allow}}</a>',deny:'<a aria-label="deny cookies" role=button tabindex="0" class="cc-btn cc-deny">{{deny}}</a>',link:'<a role=button tabindex="0" class="cc-link" href="{{href}}" target="_blank">{{link}}</a>',close:'<span aria-label="dismiss cookie message" role=button tabindex="0" class="cc-close">{{close}}</span>'},window:'<div role="dialog" aria-live="polite" aria-label="cookieconsent" aria-describedby="cookieconsent:desc" class="cc-window {{classes}}"><!--googleoff: all-->{{children}}<!--googleon: all--></div>',revokeBtn:'<div class="cc-revoke {{classes}}">Cookie Policy</div>',compliance:{info:'<div class="cc-compliance">{{dismiss}}</div>',"opt-in":'<div class="cc-compliance cc-highlight">{{dismiss}}{{allow}}</div>',"opt-out":'<div class="cc-compliance cc-highlight">{{deny}}{{dismiss}}</div>'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block","static":!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};return n.prototype.initialise=function(e){this.options&&this.destroy(),t.deepExtend(this.options={},g),t.isPlainObject(e)&&t.deepExtend(this.options,e),r.call(this)&&(this.options.enabled=!1),m(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),m(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var i=this.options.window.replace("{{classes}}",c.call(this).join(" ")).replace("{{children}}",l.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(i=n),this.options["static"]){var o=u.call(this,'<div class="cc-grower">'+i+"</div>");o.style.display="",this.element=o.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=u.call(this,i);b.call(this),y.call(this),this.options.autoOpen&&this.autoOpen()},n.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,f(this.options.palette),this.options=null},n.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},n.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},n.prototype.fadeIn=function(){var i=this.element;if(e.hasTransition&&i&&(this.afterTransition&&s.call(this,i),t.hasClass(i,"cc-invisible"))){if(i.style.display="",this.options["static"]){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}var r=20;this.openingTimeout=setTimeout(o.bind(this,i),r)}},n.prototype.fadeOut=function(){var i=this.element;e.hasTransition&&i&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),o.bind(this,i)),t.hasClass(i,"cc-invisible")||(this.options["static"]&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,i),i.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(i,"cc-invisible")))},n.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},n.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},n.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},n.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0}
2,n.prototype.hasConsented=function(t){var i=this.getStatus();return i==e.status.allow||i==e.status.dismiss},n.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled&&this.open()},n.prototype.setStatus=function(i){var n=this.options.cookie,o=t.getCookie(n.name),s=Object.keys(e.status).indexOf(o)>=0;Object.keys(e.status).indexOf(i)>=0?(t.setCookie(n.name,i,n.expiryDays,n.domain,n.path),this.options.onStatusChange.call(this,i,s)):this.clearStatus()},n.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},n.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},n}(),e.Location=function(){function e(e){t.deepExtend(this.options={},s),t.isPlainObject(e)&&t.deepExtend(this.options,e),this.currentServiceIndex=-1}function i(e,t,i){var n,o=document.createElement("script");o.type="text/"+(e.type||"javascript"),o.src=e.src||e,o.async=!1,o.onreadystatechange=o.onload=function(){var e=o.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),o.onreadystatechange=o.onload=null)},document.body.appendChild(o),n=setTimeout(function(){t.done=!0,t(),o.onreadystatechange=o.onload=null},i)}function n(e,t,i,n,o){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(o))for(var r=0,a=o.length;r<a;++r){var c=o[r].split(":",2);s.setRequestHeader(c[0].replace(/^\s+|\s+$/g,""),c[1].replace(/^\s+|\s+$/g,""))}"function"==typeof t&&(s.onreadystatechange=function(){s.readyState>3&&t(s)}),s.send(n)}function o(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}var s={timeout:5e3,services:["freegeoip","ipinfo","maxmind"],serviceDefinitions:{freegeoip:function(){return{url:"//freegeoip.net/json/?callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return i.error?o(i):{code:i.country_code}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var i=JSON.parse(t);return i.error?o(i):{code:i.country}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return"ERROR"==i.statusCode?o({error:i.statusMessage}):{code:i.countryCode}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){return window.geoip2?void geoip2.country(function(t){try{e({code:t.country.iso_code})}catch(i){e(o(i))}},function(t){e(o(t))}):void e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};return e.prototype.getNextService=function(){var e;do e=this.getServiceByIdx(++this.currentServiceIndex);while(this.currentServiceIndex<this.options.services.length&&!e);return e},e.prototype.getServiceByIdx=function(e){var i=this.options.services[e];if("function"==typeof i){var n=i();return n.name&&t.deepExtend(n,this.options.serviceDefinitions[n.name](n)),n}return"string"==typeof i?this.options.serviceDefinitions[i]():t.isPlainObject(i)?this.options.serviceDefinitions[i.name](i):null},e.prototype.locate=function(e,t){var i=this.getNextService();return i?(this.callbackComplete=e,this.callbackError=t,void this.runService(i,this.runNextServiceOnError.bind(this))):void t(new Error("No services to run"))},e.prototype.setupUrl=function(e){var t=this.getCurrentServiceOpts();return e.url.replace(/\{(.*?)\}/g,function(i,n){if("callback"===n){var o="callback"+Date.now();return window[o]=function(t){e.__JSONP_DATA=JSON.stringify(t)},o}if(n in t.interpolateUrl)return t.interpolateUrl[n]})},e.prototype.runService=function(e,t){var o=this;if(e&&e.url&&e.callback){var s=e.isScript?i:n,r=this.setupUrl(e);s(r,function(i){var n=i?i.responseText:"";e.__JSONP_DATA&&(n=e.__JSONP_DATA,delete e.__JSONP_DATA),o.runServiceCallback.call(o,t,e,n)},this.options.timeout,e.data,e.headers)}},e.prototype.runServiceCallback=function(e,t,i){var n=this,o=function(t){s||n.onServiceResult.call(n,e,t)},s=t.callback(o,i);s&&this.onServiceResult.call(this,e,s)},e.prototype.onServiceResult=function(e,t){t instanceof Error||t&&t.error?e.call(this,t,null):e.call(this,null,t)},e.prototype.runNextServiceOnError=function(e,t){if(e){this.logError(e);var i=this.getNextService();i?this.runService(i,this.runNextServiceOnError.bind(this)):this.completeService.call(this,this.callbackError,new Error("All services failed"))}else this.completeService.call(this,this.callbackComplete,t)},e.prototype.getCurrentServiceOpts=function(){var e=this.options.services[this.currentServiceIndex];return"string"==typeof e?{name:e}
2:"function"==typeof e?e():t.isPlainObject(e)?e:{}},e.prototype.completeService=function(e,t){this.currentServiceIndex=-1,e&&e(t)},e.prototype.logError=function(e){var t=this.currentServiceIndex,i=this.getServiceByIdx(t);console.error("The service["+t+"] ("+i.url+") responded with the following error",e)},e}(),e.Law=function(){function e(e){this.initialise.apply(this,arguments)}var i={regionalLaw:!0,hasLaw:["AT","BE","BG","HR","CZ","CY","DK","EE","FI","FR","DE","EL","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","SK","SI","ES","SE","GB","UK"],revokable:["HR","CY","DK","EE","FR","DE","LV","LT","NL","PT","ES"],explicitAction:["HR","IT","ES"]};return e.prototype.initialise=function(e){t.deepExtend(this.options={},i),t.isPlainObject(e)&&t.deepExtend(this.options,e)},e.prototype.get=function(e){var t=this.options;return{hasLaw:t.hasLaw.indexOf(e)>=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},e.prototype.applyLaw=function(e,t){var i=this.get(t);return i.hasLaw||(e.enabled=!1),this.options.regionalLaw&&(i.revokable&&(e.revokable=!0),i.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},e}(),e.initialise=function(t,i,n){var o=new e.Law(t.law);i||(i=function(){}),n||(n=function(){}),e.getCountryCode(t,function(n){delete t.law,delete t.location,n.code&&(t=o.applyLaw(t,n.code)),i(new e.Popup(t))},function(i){delete t.law,delete t.location,n(i,new e.Popup(t))})},e.getCountryCode=function(t,i,n){if(t.law&&t.law.countryCode)return void i({code:t.law.countryCode});if(t.location){var o=new e.Location(t.location);return void o.locate(function(e){i(e||{})},n)}i({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{});
3
4// Cookie Consent by Insites. Based on version 3.0.3
5// @see https://cookieconsent.insites.com/
6window.addEventListener('load', function () {
7    window.cookieconsent.initialise({
8        palette: {
9            popup: {
10                background: '#eeeeee',
11            },
12            button: {
13                background: '#162d56',
14            }
15        },
16        position: 'top',
17        static: true,
18        content: {
19            message: 'De provincie Groningen gebruikt cookies op haar website.',
20            dismiss: 'Verberg deze melding',
21            link: 'Welke cookies plaatsen we?',
22            href: '/cookies',
23        },
24        elements: {
25            dismiss: '<a tabindex="0" class="cc-btn cc-dismiss">{{dismiss}}</a>',
26        },
27        onPopupOpen: function () {
28            jQuery(jQuery(this)[0].element).parent().attr('lang', 'nl');
29        },
30    });
31
32    // Make all links clickable when tabbing through a page. This helps with the WCAG guidelines
33    // Select all links on the page and, if they don't have a href, give them an href that does nothing
34    // This function is placed here because it needs to take the 'verberg deze melding' link in account which is created above
35    jQuery('a').each(function () {
36        if (!jQuery(this).attr('href')) {
37            jQuery(this).attr({
38                href: '#',
39                onClick: 'return false;'
40            });
41        }
42    });
43});
44
45/**
46 * @name MarkerClusterer for Google Maps v3
47 * @version version 1.0.1
48 * @author Luke Mahe
49 * @fileoverview
50 * The library creates and manages per-zoom-level clusters for large amounts of
51 * markers.
52 * <br/>
53 * This is a v3 implementation of the
54 * <a href="http://gmaps-utility-library-dev.googlecode.com/svn/tags/markerclusterer/"
55 * >v2 MarkerClusterer</a>.
56 */
57
58/**
59 * Licensed under the Apache License, Version 2.0 (the "License");
60 * you may not use this file except in compliance with the License.
61 * You may obtain a copy of the License at
62 *
63 *     http://www.apache.org/licenses/LICENSE-2.0
64 *
65 * Unless required by applicable law or agreed to in writing, software
66 * distributed under the License is distributed on an "AS IS" BASIS,
67 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68 * See the License for the specific language governing permissions and
69 * limitations under the License.
70 */
71
72
73/**
74 * A Marker Clusterer that clusters markers.
75 *
76 * @param {google.maps.Map} map The Google map to attach to.
77 * @param {Array.<google.maps.Marker>=} opt_markers Optional markers to add to
78 *   the cluster.
79 * @param {Object=} opt_options support the following options:
80 *     'gridSize': (number) The grid size of a cluster in pixels.
81 *     'maxZoom': (number) The maximum zoom level that a marker can be part of a
82 *                cluster.
83 *     'zoomOnClick': (boolean) Whether the default behaviour of clicking on a
84 *                    cluster is to zoom into it.
85 *     'averageCenter': (boolean) Whether the center of each cluster should be
86 *                      the average of all markers in the cluster.
87 *     'minimumClusterSize': (number) The minimum number of markers to be in a
88 *                           cluster before the markers are hidden and a count
89 *                           is shown.
90 *     'styles': (object) An object that has style properties:
91 *       'url': (string) The image url.
92 *       'height': (number) The image height.
93 *       'width': (number) The image width.
94 *       'anchor': (Array) The anchor position of the label text.
95 *       'textColor': (string) The text color.
96 *       'textSize': (number) The text size.
97 *       'backgroundPosition': (string) The position of the backgound x, y.
98 * @constructor
99 * @extends google.maps.OverlayView
100 */
101function MarkerClusterer(map, opt_markers, opt_options) {
102  // MarkerClusterer implements google.maps.OverlayView interface. We use the
103  // extend function to extend MarkerClusterer with google.maps.OverlayView
104  // because it might not always be available when the code is defined so we
105  // look for it at the last possible moment. If it doesn't exist now then
106  // there is no point going ahead :)
107  this.extend(MarkerClusterer, google.maps.OverlayView);
108  this.map_ = map;
109
110  /**
111   * @type {Array.<google.maps.Marker>}
112   * @private
113   */
114  this.markers_ = [];
115
116  /**
117   *  @type {Array.<Cluster>}
118   */
119  this.clusters_ = [];
120
121  this.sizes = [53, 56, 66, 78, 90];
122
123  /**
124   * @private
125   */
126  this.styles_ = [];
127
128  /**
129   * @type {boolean}
130   * @private
131   */
132  this.ready_ = false;
133
134  var options = opt_options || {};
135
136  /**
137   * @type {number}
138   * @private
139   */
140  this.gridSize_ = options['gridSize'] || 60;
141
142  /**
143   * @private
144   */
145  this.minClusterSize_ = options['minimumClusterSize'] || 2;
146
147
148  /**
149   * @type {?number}
150   * @private
151   */
152  this.maxZoom_ = options['maxZoom'] || null;
153
154  this.styles_ = options['styles'] || [];
155
156  /**
157   * @type {string}
158   * @private
159   */
160  this.imagePath_ = options['imagePath'] ||
161    this.MARKER_CLUSTER_IMAGE_PATH_;
162
163  /**
164   * @type {string}
165   * @private
166   */
167  this.imageExtension_ = options['imageExtension'] ||
168    this.MARKER_CLUSTER_IMAGE_EXTENSION_;
169
170  /**
171   * @type {boolean}
172   * @private
173   */
174  this.zoomOnClick_ = true;
175
176  if (options['zoomOnClick'] != undefined) {
177    this.zoomOnClick_ = options['zoomOnClick'];
178  }
179
180  /**
181   * @type {boolean}
182   * @private
183   */
184  this.averageCenter_ = false;
185
186  if (options['averageCenter'] != undefined) {
187    this.averageCenter_ = options['averageCenter'];
188  }
189
190  this.setupStyles_();
191
192  this.setMap(map);
193
194  /**
195   * @type {number}
196   * @private
197   */
198  this.prevZoom_ = this.map_.getZoom();
199
200  // Add the map event listeners
201  var that = this;
202  google.maps.event.addListener(this.map_, 'zoom_changed', function() {
203    // Determines map type and prevent illegal zoom levels
204    var zoom = that.map_.getZoom();
205    var minZoom = that.map_.minZoom || 0;
206    var maxZoom = Math.min(that.map_.maxZoom || 100,
207      that.map_.mapTypes[that.map_.getMapTypeId()].maxZoom);
208    zoom = Math.min(Math.max(zoom,minZoom),maxZoom);
209
210    if (that.prevZoom_ != zoom) {
211      that.prevZoom_ = zoom;
212      that.resetViewport();
213    }
214  });
215
216  google.maps.event.addListener(this.map_, 'idle', function() {
217    that.redraw();
218  });
219
220  // Finally, add the markers
221  if (opt_markers && (opt_markers.length || Object.keys(opt_markers).length)) {
222    this.addMarkers(opt_markers, false);
223  }
224}
225
226
227/**
228 * The marker cluster image path.
229 *
230 * @type {string}
231 * @private
232 */
233MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_PATH_ = '../images/m';
234
235
236/**
237 * The marker cluster image path.
238 *
239 * @type {string}
240 * @private
241 */
242MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_EXTENSION_ = 'png';
243
244
245/**
246 * Extends a objects prototype by anothers.
247 *
248 * @param {Object} obj1 The object to be extended.
249 * @param {Object} obj2 The object to extend with.
250 * @return {Object} The new extended object.
251 * @ignore
252 */
253MarkerClusterer.prototype.extend = function(obj1, obj2) {
254  return (function(object) {
255    for (var property in object.prototype) {
256      this.prototype[property] = object.prototype[property];
257    }
258    return this;
259  }).apply(obj1, [obj2]);
260};
261
262
263/**
264 * Implementaion of the interface method.
265 * @ignore
266 */
267MarkerClusterer.prototype.onAdd = function() {
268  this.setReady_(true);
269};
270
271/**
272 * Implementaion of the interface method.
273 * @ignore
274 */
275MarkerClusterer.prototype.draw = function() {};
276
277/**
278 * Sets up the styles object.
279 *
280 * @private
281 */
282MarkerClusterer.prototype.setupStyles_ = function() {
283  if (this.styles_.length) {
284    return;
285  }
286
287  for (var i = 0, size; size = this.sizes[i]; i++) {
288    this.styles_.push({
289      url: this.imagePath_ + (i + 1) + '.' + this.imageExtension_,
290      height: size,
291      width: size
292    });
293  }
294};
295
296/**
297 *  Fit the map to the bounds of the markers in the clusterer.
298 */
299MarkerClusterer.prototype.fitMapToMarkers = function() {
300  var markers = this.getMarkers();
301  var bounds = new google.maps.LatLngBounds();
302  for (var i = 0, marker; marker = markers[i]; i++) {
303    bounds.extend(marker.getPosition());
304  }
305
306  this.map_.fitBounds(bounds);
307};
308
309
310/**
311 *  Sets the styles.
312 *
313 *  @param {Object} styles The style to set.
314 */
315MarkerClusterer.prototype.setStyles = function(styles) {
316  this.styles_ = styles;
317};
318
319
320/**
321 *  Gets the styles.
322 *
323 *  @return {Object} The styles object.
324 */
325MarkerClusterer.prototype.getStyles = function() {
326  return this.styles_;
327};
328
329
330/**
331 * Whether zoom on click is set.
332 *
333 * @return {boolean} True if zoomOnClick_ is set.
334 */
335MarkerClusterer.prototype.isZoomOnClick = function() {
336  return this.zoomOnClick_;
337};
338
339/**
340 * Whether average center is set.
341 *
342 * @return {boolean} True if averageCenter_ is set.
343 */
344MarkerClusterer.prototype.isAverageCenter = function() {
345  return this.averageCenter_;
346};
347
348
349/**
350 *  Returns the array of markers in the clusterer.
351 *
352 *  @return {Array.<google.maps.Marker>} The markers.
353 */
354MarkerClusterer.prototype.getMarkers = function() {
355  return this.markers_;
356};
357
358
359/**
360 *  Returns the number of markers in the clusterer
361 *
362 *  @return {Number} The number of markers.
363 */
364MarkerClusterer.prototype.getTotalMarkers = function() {
365  return this.markers_.length;
366};
367
368
369/**
370 *  Sets the max zoom for the clusterer.
371 *
372 *  @param {number} maxZoom The max zoom level.
373 */
374MarkerClusterer.prototype.setMaxZoom = function(maxZoom) {
375  this.maxZoom_ = maxZoom;
376};
377
378
379/**
380 *  Gets the max zoom for the clusterer.
381 *
382 *  @return {number} The max zoom level.
383 */
384MarkerClusterer.prototype.getMaxZoom = function() {
385  return this.maxZoom_;
386};
387
388
389/**
390 *  The function for calculating the cluster icon image.
391 *
392 *  @param {Array.<google.maps.Marker>} markers The markers in the clusterer.
393 *  @param {number} numStyles The number of styles available.
394 *  @return {Object} A object properties: 'text' (string) and 'index' (number).
395 *  @private
396 */
397MarkerClusterer.prototype.calculator_ = function(markers, numStyles) {
398  var index = 0;
399  var count = markers.length;
400  var dv = count;
401  while (dv !== 0) {
402    dv = parseInt(dv / 10, 10);
403    index++;
404  }
405
406  index = Math.min(index, numStyles);
407  return {
408    text: count,
409    index: index
410  };
411};
412
413
414/**
415 * Set the calculator function.
416 *
417 * @param {function(Array, number)} calculator The function to set as the
418 *     calculator. The function should return a object properties:
419 *     'text' (string) and 'index' (number).
420 *
421 */
422MarkerClusterer.prototype.setCalculator = function(calculator) {
423  this.calculator_ = calculator;
424};
425
426
427/**
428 * Get the calculator function.
429 *
430 * @return {function(Array, number)} the calculator function.
431 */
432MarkerClusterer.prototype.getCalculator = function() {
433  return this.calculator_;
434};
435
436
437/**
438 * Add an array of markers to the clusterer.
439 *
440 * @param {Array.<google.maps.Marker>} markers The markers to add.
441 * @param {boolean=}
441 opt_nodraw Whether to redraw the clusters.
442 */
443MarkerClusterer.prototype.addMarkers = function(markers, opt_nodraw) {
444  if (markers.length) {
445    for (var i = 0, marker; marker = markers[i]; i++) {
446      this.pushMarkerTo_(marker);
447    }
448  } else if (Object.keys(markers).length) {
449    for (var marker in markers) {
450      this.pushMarkerTo_(markers[marker]);
451    }
452  }
453  if (!opt_nodraw) {
454    this.redraw();
455  }
456};
457
458
459/**
460 * Pushes a marker to the clusterer.
461 *
462 * @param {google.maps.Marker} marker The marker to add.
463 * @private
464 */
465MarkerClusterer.prototype.pushMarkerTo_ = function(marker) {
466  marker.isAdded = false;
467  if (marker['draggable']) {
468    // If the marker is draggable add a listener so we update the clusters on
469    // the drag end.
470    var that = this;
471    google.maps.event.addListener(marker, 'dragend', function() {
472      marker.isAdded = false;
473      that.repaint();
474    });
475  }
476  this.markers_.push(marker);
477};
478
479
480/**
481 * Adds a marker to the clusterer and redraws if needed.
482 *
483 * @param {google.maps.Marker} marker The marker to add.
484 * @param {boolean=} opt_nodraw Whether to redraw the clusters.
485 */
486MarkerClusterer.prototype.addMarker = function(marker, opt_nodraw) {
487  this.pushMarkerTo_(marker);
488  if (!opt_nodraw) {
489    this.redraw();
490  }
491};
492
493
494/**
495 * Removes a marker and returns true if removed, false if not
496 *
497 * @param {google.maps.Marker} marker The marker to remove
498 * @return {boolean} Whether the marker was removed or not
499 * @private
500 */
501MarkerClusterer.prototype.removeMarker_ = function(marker) {
502  var index = -1;
503  if (this.markers_.indexOf) {
504    index = this.markers_.indexOf(marker);
505  } else {
506    for (var i = 0, m; m = this.markers_[i]; i++) {
507      if (m == marker) {
508        index = i;
509        break;
510      }
511    }
512  }
513
514  if (index == -1) {
515    // Marker is not in our list of markers.
516    return false;
517  }
518
519  marker.setMap(null);
520
521  this.markers_.splice(index, 1);
522
523  return true;
524};
525
526
527/**
528 * Remove a marker from the cluster.
529 *
530 * @param {google.maps.Marker} marker The marker to remove.
531 * @param {boolean=} opt_nodraw Optional boolean to force no redraw.
532 * @return {boolean} True if the marker was removed.
533 */
534MarkerClusterer.prototype.removeMarker = function(marker, opt_nodraw) {
535  var removed = this.removeMarker_(marker);
536
537  if (!opt_nodraw && removed) {
538    this.resetViewport();
539    this.redraw();
540    return true;
541  } else {
542    return false;
543  }
544};
545
546
547/**
548 * Removes an array of markers from the cluster.
549 *
550 * @param {Array.<google.maps.Marker>} markers The markers to remove.
551 * @param {boolean=} opt_nodraw Optional boolean to force no redraw.
552 */
553MarkerClusterer.prototype.removeMarkers = function(markers, opt_nodraw) {
554  var removed = false;
555
556  for (var i = 0, marker; marker = markers[i]; i++) {
557    var r = this.removeMarker_(marker);
558    removed = removed || r;
559  }
560
561  if (!opt_nodraw && removed) {
562    this.resetViewport();
563    this.redraw();
564    return true;
565  }
566};
567
568
569/**
570 * Sets the clusterer's ready state.
571 *
572 * @param {boolean} ready The state.
573 * @private
574 */
575MarkerClusterer.prototype.setReady_ = function(ready) {
576  if (!this.ready_) {
577    this.ready_ = ready;
578    this.createClusters_();
579  }
580};
581
582
583/**
584 * Returns the number of clusters in the clusterer.
585 *
586 * @return {number} The number of clusters.
587 */
588MarkerClusterer.prototype.getTotalClusters = function() {
589  return this.clusters_.length;
590};
591
592
593/**
594 * Returns the google map that the clusterer is associated with.
595 *
596 * @return {google.maps.Map} The map.
597 */
598MarkerClusterer.prototype.getMap = function() {
599  return this.map_;
600};
601
602
603/**
604 * Sets the google map that the clusterer is associated with.
605 *
606 * @param {google.maps.Map} map The map.
607 */
608MarkerClusterer.prototype.setMap = function(map) {
609  this.map_ = map;
610};
611
612
613/**
614 * Returns the size of the grid.
615 *
616 * @return {number} The grid size.
617 */
618MarkerClusterer.prototype.getGridSize = function() {
619  return this.gridSize_;
620};
621
622
623/**
624 * Sets the size of the grid.
625 *
626 * @param {number} size The grid size.
627 */
628MarkerClusterer.prototype.setGridSize = function(size) {
629  this.gridSize_ = size;
630};
631
632
633/**
634 * Returns the min cluster size.
635 *
636 * @return {number} The grid size.
637 */
638MarkerClusterer.prototype.getMinClusterSize = function() {
639  return this.minClusterSize_;
640};
641
642/**
643 * Sets the min cluster size.
644 *
645 * @param {number} size The grid size.
646 */
647MarkerClusterer.prototype.setMinClusterSize = function(size) {
648  this.minClusterSize_ = size;
649};
650
651
652/**
653 * Extends a bounds object by the grid size.
654 *
655 * @param {google.maps.LatLngBounds} bounds The bounds to extend.
656 * @return {google.maps.LatLngBounds}
656 The extended bounds.
657 */
658MarkerClusterer.prototype.getExtendedBounds = function(bounds) {
659  var projection = this.getProjection();
660
661  // Turn the bounds into latlng.
662  var tr = new google.maps.LatLng(bounds.getNorthEast().lat(),
663    bounds.getNorthEast().lng());
664  var bl = new google.maps.LatLng(bounds.getSouthWest().lat(),
665    bounds.getSouthWest().lng());
666
667  // Convert the points to pixels and the extend out by the grid size.
668  var trPix = projection.fromLatLngToDivPixel(tr);
669  trPix.x += this.gridSize_;
670  trPix.y -= this.gridSize_;
671
672  var blPix = projection.fromLatLngToDivPixel(bl);
673  blPix.x -= this.gridSize_;
674  blPix.y += this.gridSize_;
675
676  // Convert the pixel points back to LatLng
677  var ne = projection.fromDivPixelToLatLng(trPix);
678  var sw = projection.fromDivPixelToLatLng(blPix);
679
680  // Extend the bounds to contain the new bounds.
681  bounds.extend(ne);
682  bounds.extend(sw);
683
684  return bounds;
685};
686
687
688/**
689 * Determins if a marker is contained in a bounds.
690 *
691 * @param {google.maps.Marker} marker The marker to check.
692 * @param {google.maps.LatLngBounds} bounds The bounds to check against.
693 * @return {boolean} True if the marker is in the bounds.
694 * @private
695 */
696MarkerClusterer.prototype.isMarkerInBounds_ = function(marker, bounds) {
697  return bounds.contains(marker.getPosition());
698};
699
700
701/**
702 * Clears all clusters and markers from the clusterer.
703 */
704MarkerClusterer.prototype.clearMarkers = function() {
705  this.resetViewport(true);
706
707  // Set the markers a empty array.
708  this.markers_ = [];
709};
710
711
712/**
713 * Clears all existing clusters and recreates them.
714 * @param {boolean} opt_hide To also hide the marker.
715 */
716MarkerClusterer.prototype.resetViewport = function(opt_hide) {
717  // Remove all the clusters
718  for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {
719    cluster.remove();
720  }
721
722  // Reset the markers to not be added and to be invisible.
723  for (var i = 0, marker; marker = this.markers_[i]; i++) {
724    marker.isAdded = false;
725    if (opt_hide) {
726      marker.setMap(null);
727    }
728  }
729
730  this.clusters_ = [];
731};
732
733/**
734 *
735 */
736MarkerClusterer.prototype.repaint = function() {
737  var oldClusters = this.clusters_.slice();
738  this.clusters_.length = 0;
739  this.resetViewport();
740  this.redraw();
741
742  // Remove the old clusters.
743  // Do it in a timeout so the other clusters have been drawn first.
744  window.setTimeout(function() {
745    for (var i = 0, cluster; cluster = oldClusters[i]; i++) {
746      cluster.remove();
747    }
748  }, 0);
749};
750
751
752/**
753 * Redraws the clusters.
754 */
755MarkerClusterer.prototype.redraw = function() {
756  this.createClusters_();
757};
758
759
760/**
761 * Calculates the distance between two latlng locations in km.
762 * @see http://www.movable-type.co.uk/scripts/latlong.html
763 *
764 * @param {google.maps.LatLng} p1 The first lat lng point.
765 * @param {google.maps.LatLng} p2 The second lat lng point.
766 * @return {number} The distance between the two points in km.
767 * @private
768 */
769MarkerClusterer.prototype.distanceBetweenPoints_ = function(p1, p2) {
770  if (!p1 || !p2) {
771    return 0;
772  }
773
774  var R = 6371; // Radius of the Earth in km
775  var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
776  var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
777  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
778    Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) *
779    Math.sin(dLon / 2) * Math.sin(dLon / 2);
780  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
781  var d = R * c;
782  return d;
783};
784
785
786/**
787 * Add a marker to a cluster, or creates a new cluster.
788 *
789 * @param {google.maps.Marker} marker The marker to add.
790 * @private
791 */
792MarkerClusterer.prototype.addToClosestCluster_ = function(marker) {
793  var distance = 40000; // Some large number
794  var clusterToAddTo = null;
795  var pos = marker.getPosition();
796  for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {
797    var center = cluster.getCenter();
798    if (center) {
799      var d = this.distanceBetweenPoints_(center, marker.getPosition());
800      if (d < distance) {
801        distance = d;
802        clusterToAddTo = cluster;
803      }
804    }
805  }
806
807  if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {
808    clusterToAddTo.addMarker(marker);
809  } else {
810    var cluster = new Cluster(this);
811    cluster.addMarker(marker);
812    this.clusters_.push(cluster);
813  }
814};
815
816
817/**
818 * Creates the clusters.
819 *
820 * @private
821 */
822MarkerClusterer.prototype.createClusters_ = function() {
823  if (!this.ready_) {
824    return;
825  }
826
827  // Get our current map view bounds.
828  // Create a new bounds object so we don't affect the map.
829  var mapBounds = new google.maps.LatLngBounds(this.map_.getBounds().getSouthWest(),
830    this.map_.getBounds().getNorthEast());
831  var bounds = this.getExtendedBounds(mapBounds);
832
833  for (var i = 0, marker; marker = this.markers_[i]; i++) {
834    if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) {
835      this.addToClosestCluster_(marker);
836    }
837  }
838};
839
840
841/**
842 * A cluster that contains markers.
843 *
844 * @param {MarkerClusterer} markerClusterer The markerclusterer that this
845 *     cluster is associated with.
846 * @constructor
847 * @ignore
848 */
849function Cluster(markerClusterer) {
850  this.markerClusterer_ = markerClusterer;
851  this.map_ = markerClusterer.getMap();
852  this.gridSize_ = markerClusterer.getGridSize();
853  this.minClusterSize_ = markerClusterer.getMinClusterSize();
854  this.averageCenter_ = markerClusterer.isAverageCenter();
855  this.center_ = null;
856  this.markers_ = [];
857  this.bounds_ = null;
858  this.clusterIcon_ = new ClusterIcon(this, markerClusterer.getStyles(),
859    markerClusterer.getGridSize());
860}
861
862/**
863 * Determins if a marker is already added to the cluster.
864 *
865 * @param {google.maps.Marker} marker The marker to check.
866 * @return {boolean} True if the marker is already added.
867 */
868Cluster.prototype.isMarkerAlreadyAdded = function(marker) {
869  if (this.markers_.indexOf) {
870    return this.markers_.indexOf(marker) != -1;
871  } else {
872    for (var i = 0, m; m = this.markers_[i]; i++) {
873      if (m == marker) {
874        return true;
875      }
876    }
877  }
878  return false;
879};
880
881
882/**
883 * Add a marker the cluster.
884 *
885 * @param {google.maps.Marker} marker The marker to add.
886 * @return {boolean} True if the marker was added.
887 */
888Cluster.prototype.addMarker = function(marker) {
889  if (this.isMarkerAlreadyAdded(marker)) {
890    return false;
891  }
892
893  if (!this.center_) {
894    this.center_ = marker.getPosition();
895    this.calculateBounds_();
896  } else {
897    if (this.averageCenter_) {
898      var l = this.markers_.length + 1;
899      var lat = (this.center_.lat() * (l-1) + marker.getPosition().lat()) / l;
900      var lng = (this.center_.lng() * (l-1) + marker.getPosition().lng()) / l;
901      this.center_ = new google.maps.LatLng(lat, lng);
902      this.calculateBounds_();
903    }
904  }
905
906  marker.isAdded = true;
907  this.markers_.push(marker);
908
909  var len = this.markers_.length;
910  if (len < this.minClusterSize_ && marker.getMap() != this.map_) {
911    // Min cluster size not reached so show the marker.
912    marker.setMap(this.map_);
913  }
914
915  if (len == this.minClusterSize_) {
916    // Hide the markers that were showing.
917    for (var i = 0; i < len; i++) {
918      this.markers_[i].setMap(null);
919    }
920  }
921
922  if (len >= this.minClusterSize_) {
923    marker.setMap(null);
924  }
925
926  this.updateIcon();
927  return true;
928};
929
930
931/**
932 * Returns the marker clusterer that the cluster is associated with.
933 *
934 * @return {MarkerClusterer} The associated marker clusterer.
935 */
936Cluster.prototype.getMarkerClusterer = function() {
937  return this.markerClusterer_;
938};
939
940
941/**
942 * Returns the bounds of the cluster.
943 *
944 * @return {google.maps.LatLngBounds} the cluster bounds.
945 */
946Cluster.prototype.getBounds = function() {
947  var bounds = new google.maps.LatLngBounds(this.center_, this.center_);
948  var markers = this.getMarkers();
949  for (var i = 0, marker; marker = markers[i]; i++) {
950    bounds.extend(marker.getPosition());
951  }
952  return bounds;
953};
954
955
956/**
957 * Removes the cluster
958 */
959Cluster.prototype.remove = function() {
960  this.clusterIcon_.remove();
961  this.markers_.length = 0;
962  delete this.markers_;
963};
964
965
966/**
967 * Returns the center of the cluster.
968 *
969 * @return {number} The cluster center.
970 */
971Cluster.prototype.getSize = function() {
972  return this.markers_.length;
973};
974
975
976/**
977 * Returns the center of the cluster.
978 *
979 * @return {Array.<google.maps.Marker>} The cluster center.
980 */
981Cluster.prototype.getMarkers = function() {
982  return this.markers_;
983};
984
985
986/**
987 * Returns the center of the cluster.
988 *
989 * @return {google.maps.LatLng} The cluster center.
990 */
991Cluster.prototype.getCenter = function() {
992  return this.center_;
993};
994
995
996/**
997 * Calculated the extended bounds of the cluster with the grid.
998 *
999 * @private
1000 */
1001Cluster.prototype.calculateBounds_ = function() {
1002  var bounds = new google.maps.LatLngBounds(this.center_, this.center_);
1003  this.bounds_ = this.markerClusterer_.getExtendedBounds(bounds);
1004};
1005
1006
1007/**
1008 * Determines if a marker lies in the clusters bounds.
1009 *
1010 * @param {google.maps.Marker} marker The marker to check.
1011 * @return {boolean} True if the marker lies in the bounds.
1012 */
1013Cluster.prototype.isMarkerInClusterBounds = function(marker) {
1014  return this.bounds_.contains(marker.getPosition());
1015};
1016
1017
1018/**
1019 * Returns the map that the cluster is associated with.
1020 *
1021 * @return {google.maps.Map} The map.
1022 */
1023Cluster.prototype.getMap = function() {
1024  return this.map_;
1025};
1026
1027
1028/**
1029 * Updates the cluster icon
1030 */
1031Cluster.prototype.updateIcon = function() {
1032  var zoom = this.map_.getZoom();
1033  var mz = this.markerClusterer_.getMaxZoom();
1034
1035  if (mz && zoom > mz) {
1036    // The zoom is greater than our max zoom so show all the markers in cluster.
1037    for (var i = 0, marker; marker = this.markers_[i]; i++) {
1038      marker.setMap(this.map_);
1039    }
1040    return;
1041  }
1042
1043  if (this.markers_.length < this.minClusterSize_) {
1044    // Min cluster size not yet reached.
1045    this.clusterIcon_.hide();
1046    return;
1047  }
1048
1049  var numStyles = this.markerClusterer_.getStyles().length;
1050  var sums = this.markerClusterer_.getCalculator()(this.markers_, numStyles);
1051  this.clusterIcon_.setCenter(this.center_);
1052  this.clusterIcon_.setSums(sums);
1053  this.clusterIcon_.show();
1054};
1055
1056
1057/**
1058 * A cluster icon
1059 *
1060 * @param {Cluster} cluster The cluster to be associated with.
1061 * @param {Object} styles An object that has style properties:
1062 *     'url': (string) The image url.
1063 *     'height': (number) The image height.
1064 *     'width': (number) The image width.
1065 *     'anchor': (Array) The anchor position of the label text.
1066 *     'textColor': (string) The text color.
1067 *     'textSize': (number) The text size.
1068 *     'backgroundPosition: (string) The background postition x, y.
1069 * @param {number=} opt_padding Optional padding to apply to the cluster icon.
1070 * @constructor
1071 * @extends google.maps.OverlayView
1072 * @ignore
1073 */
1074function ClusterIcon(cluster, styles, opt_padding) {
1075  cluster.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView);
1076
1077  this.styles_ = styles;
1078  this.padding_ = opt_padding || 0;
1079  this.cluster_ = cluster;
1080  this.center_ = null;
1081  this.map_ = cluster.getMap();
1082  this.div_ = null;
1083  this.sums_ = null;
1084  this.visible_ = false;
1085
1086  this.setMap(this.map_);
1087}
1088
1089
1090/**
1091 * Triggers the clusterclick event and zoom's if the option is set.
1092 */
1093ClusterIcon.prototype.triggerClusterClick = function() {
1094  var markerClusterer = this.cluster_.getMarkerClusterer();
1095
1096  // Trigger the clusterclick event.
1097  google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);
1098
1099  if (markerClusterer.isZoomOnClick()) {
1100    // Zoom into the cluster.
1101    this.map_.fitBounds(this.cluster_.getBounds());
1102  }
1103};
1104
1105
1106/**
1107 * Adding the cluster icon to the dom.
1108 * @ignore
1109 */
1110ClusterIcon.prototype.onAdd = function() {
1111  this.div_ = document.createElement('DIV');
1112  if (this.visible_) {
1113    var pos = this.getPosFromLatLng_(this.center_);
1114    this.div_.style.cssText = this.createCss(pos);
1115    this.div_.innerHTML = this.sums_.text;
1116  }
1117
1118  var panes = this.getPanes();
1119  panes.overlayMouseTarget.appendChild(this.div_);
1120
1121  var that = this;
1122  google.maps.event.addDomListener(this.div_, 'click', function() {
1123    that.triggerClusterClick();
1124  });
1125};
1126
1127
1128/**
1129 * Returns the position to place the div dending on the latlng.
1130 *
1131 * @param {google.maps.LatLng} latlng The position in latlng.
1132 * @return {google.maps.Point} The position in pixels.
1133 * @private
1134 */
1135ClusterIcon.prototype.getPosFromLatLng_ = function(latlng) {
1136  var pos = this.getProjection().fromLatLngToDivPixel(latlng);
1137  pos.x -= parseInt(this.width_ / 2, 10);
1138  pos.y -= parseInt(this.height_ / 2, 10);
1139  return pos;
1140};
1141
1142
1143/**
1144 * Draw the icon.
1145 * @ignore
1146 */
1147ClusterIcon.prototype.draw = function() {
1148  if (this.visible_) {
1149    var pos = this.getPosFromLatLng_(this.center_);
1150    this.div_.style.top = pos.y + 'px';
1151    this.div_.style.left = pos.x + 'px';
1152  }
1153};
1154
1155
1156/**
1157 * Hide the icon.
1158 */
1159ClusterIcon.prototype.hide = function() {
1160  if (this.div_) {
1161    this.div_.style.display = 'none';
1162  }
1163  this.visible_ = false;
1164};
1165
1166
1167/**
1168 * Position and show the icon.
1169 */
1170ClusterIcon.prototype.show = function() {
1171  if (this.div_) {
1172    var pos = this.getPosFromLatLng_(this.center_);
1173    this.div_.style.cssText = this.createCss(pos);
1174    this.div_.style.display = '';
1175  }
1176  this.visible_ = true;
1177};
1178
1179
1180/**
1181 * Remove the icon from the map
1182 */
1183ClusterIcon.prototype.remove = function() {
1184  this.setMap(null);
1185};
1186
1187
1188/**
1189 * Implementation of the onRemove interface.
1190 * @ignore
1191 */
1192ClusterIcon.prototype.onRemove = function() {
1193  if (this.div_ && this.div_.parentNode) {
1194    this.hide();
1195    this.div_.parentNode.removeChild(this.div_);
1196    this.div_ = null;
1197  }
1198};
1199
1200
1201/**
1202 * Set the sums of the icon.
1203 *
1204 * @param {Object} sums The sums containing:
1205 *   'text': (string) The text to display in the icon.
1206 *   'index': (number) The style index of the icon.
1207 */
1208ClusterIcon.prototype.setSums = function(sums) {
1209  this.sums_ = sums;
1210  this.text_ = sums.text;
1211  this.index_ = sums.index;
1212  if (this.div_) {
1213    this.div_.innerHTML = sums.text;
1214  }
1215
1216  this.useStyle();
1217};
1218
1219
1220/**
1221 * Sets the icon to the the styles.
1222 */
1223ClusterIcon.prototype.useStyle = function() {
1224  var index = Math.max(0, this.sums_.index - 1);
1225  index = Math.min(this.styles_.length - 1, index);
1226  var style = this.styles_[index];
1227  this.url_ = style['url'];
1228  this.height_ = style['height'];
1229  this.width_ = style['width'];
1230  this.textColor_ = style['textColor'];
1231  this.anchor_ = style['anchor'];
1232  this.textSize_ = style['textSize'];
1233  this.backgroundPosition_ = style['backgroundPosition'];
1234};
1235
1236
1237/**
1238 * Sets the center of the icon.
1239 *
1240 * @param {google.maps.LatLng} center The latlng to set as the center.
1241 */
1242ClusterIcon.prototype.setCenter = function(center) {
1243  this.center_ = center;
1244};
1245
1246
1247/**
1248 * Create the css text based on the position of the icon.
1249 *
1250 * @param {google.maps.Point} pos The position.
1251 * @return {string} The css style text.
1252 */
1253ClusterIcon.prototype.createCss = function(pos) {
1254  var style = [];
1255  style.push('background-image:url(' + this.url_ + ');');
1256  var backgroundPosition = this.backgroundPosition_ ? this.backgroundPosition_ : '0 0';
1257  style.push('background-position:' + backgroundPosition + ';');
1258
1259  if (typeof this.anchor_ === 'object') {
1260    if (typeof this.anchor_[0] === 'number' && this.anchor_[0] > 0 &&
1261      this.anchor_[0] < this.height_) {
1262      style.push('height:' + (this.height_ - this.anchor_[0]) +
1263        'px; padding-top:' + this.anchor_[0] + 'px;');
1264    } else {
1265      style.push('height:' + this.height_ + 'px; line-height:' + this.height_ +
1266        'px;');
1267    }
1268    if (typeof this.anchor_[1] === 'number' && this.anchor_[1] > 0 &&
1269      this.anchor_[1] < this.width_) {
1270      style.push('width:' + (this.width_ - this.anchor_[1]) +
1271        'px; padding-left:' + this.anchor_[1] + 'px;');
1272    } else {
1273      style.push('width:' + this.width_ + 'px; text-align:center;');
1274    }
1275  } else {
1276    style.push('height:' + this.height_ + 'px; line-height:' +
1277      this.height_ + 'px; width:' + this.width_ + 'px; text-align:center;');
1278  }
1279
1280  var txtColor = this.textColor_ ? this.textColor_ : 'black';
1281  var txtSize = this.textSize_ ? this.textSize_ : 11;
1282
1283  style.push('cursor:pointer; top:' + pos.y + 'px; left:' +
1284    pos.x + 'px; color:' + txtColor + '; position:absolute; font-size:' +
1285    txtSize + 'px; font-family:Arial,sans-serif; font-weight:bold');
1286  return style.join('');
1287};
1288
1289window.addEventListener('load', function() {
1290  jQuery.fn.extend({
1291    multipleActiveFilter: function(filterType) {
1292      var element = filterType === 'tags' ? 'li' : 'ul';
1293      var _this = this;
1294
1295      this.find('.filter input').on('change', loading);
1296      this.find('.wizard input').on('change', change);
1297
1298      function loading() {
1299        _this.find('.overzicht').addClass('is-loading');
1300        window.setTimeout(filter, 500);
1301      }
1302
1303      function filter() {
1304        // reset everything
1305        _this.find('article.category, article.category ' + element).removeClass('hide');
1306
1307        // filter links
1308        var filters = [];
1309        _this.find('.filter input:checked').each(function(i, n) {
1310          filterType === 'tags'
1311            ? filters.push('article.category ' + element + ':has(a[data-categories*="' + _this.find(n).attr('id') + '"])')
1312            : filters.push('article.category ' + element + '[data-categories*="' + _this.find(n).attr('id') + '"]')
1313        });
1314
1315        _this.find('.filter input').each(function(i, n) {
1316          this.setAttribute('aria-checked', this.checked == true);
1317        });
1318
1319        if (filters.length) {
1320          _this.find('article.category ' + element).not( filters.join(',') ).addClass('hide');
1321        }
1322
1323        // hide empty themes
1324        _this.find('article.category').each(function(i, n) {
1325          if (_this.find(n).find(element + ':not(.hide)').length === 0) {
1326            _this.find(n).addClass('hide');
1327          }
1328        });
1329
1330        _this.find('.overzicht').removeClass('is-loading');
1331      }
1332
1333      function change() {
1334        var type = _this.find('.wizard input:checked').attr('id');
1335
1336        // reset everything
1337        _this.find('.selectie').addClass('hide');
1338
1339        // show filtered option
1340        _this.find('.selectie[data-type=' + type + ']').removeClass('hide');
1341      }
1342    }
1343  });
1344});
1345
1346window.addEventListener('load', function () {
1347  jQuery.fn.extend({
1348    singleActiveFilter: function () {
1349      var _this = this;
1350      const tabs = _this.find('.wizard button.tab');
1351
1352      // Apply onclick handler to all tab buttons
1353      tabs.on('click', function(event) {
1354        const target = jQuery(event.target);
1355        const datacontent = target.data('content');
1356
1357        // reset everything
1358        tabs.removeClass('active');
1359        _this.find('.selection').addClass('hide');
1360
1361        // Set clicked button as active
1362        target.addClass('active');
1363        // show content for selected option
1364        _this.find('.selection[data-content=' + datacontent + ']').removeClass('hide');
1365      });
1366    }
1367  });
1368
1369  jQuery('section.single-filter').each(function () {
1370    jQuery(this).singleActiveFilter();
1371  });
1372});
1373
vendor: 16,892 bytes, line 1374
1374!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.datepicker=t():e.datepicker=t()}(window,(function(){return function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(a,r,function(t){return e[t]}.bind(null,r));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);var a=[],r=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],i=["January","February","March","April","May","June","July","August","September","October","November","December"],o={t:"top",r:"right",b:"bottom",l:"left",c:"centered"};function s(){}var l=["click","focusin","keydown","input"];function d(e){l.forEach((function(t){e.addEventListener(t,e===document?L:Y)}))}function c(e){return Array.isArray(e)?e.map(c):"[object Object]"===x(e)?Object.keys(e).reduce((function(t,n){return t[n]=c(e[n]),t}),{}):e}function u(e,t){var n=e.calendar.querySelector(".qs-overlay"),a=n&&!n.classList.contains("qs-hidden");t=t||new Date(e.currentYear,e.currentMonth),e.calendar.innerHTML=[h(t,e,a),f(t,e,a),v(e,a)].join(""),a&&window.requestAnimationFrame((function(){M(!0,e)}))}function h(e,t,n){return['<div class="qs-controls'+(n?" qs-blur":"")+'">','<div class="qs-arrow qs-left"></div>','<div class="qs-month-year'+(t.disableYearOverlay?" qs-disabled-year-overlay":"")+'">','<span class="qs-month">'+t.months[e.getMonth()]+"</span>",'<span class="qs-year">'+e.getFullYear()+"</span>","</div>",'<div class="qs-arrow qs-right"></div>',"</div>"].join("")}function f(e,t,n){var a=t.currentMonth,r=t.currentYear,i=t.dateSelected,o=t.maxDate,s=t.minDate,l=t.showAllDates,d=t.days,c=t.disabledDates,u=t.startDay,h=t.weekendIndices,f=t.events,v=t.getRange?t.getRange():{},m=+v.start,y=+v.end,p=g(new Date(e).setDate(1)),w=p.getDay()-u,D=w<0?7:0;p.setMonth(p.getMonth()+1),p.setDate(0);var b=p.getDate(),q=[],S=D+7*((w+b)/7|0);S+=(w+b)%7?7:0;for(var M=1;M<=S;M++){var E=(M-1)%7,x=d[E],C=M-(w>=0?w:7+w),L=new Date(r,a,C),Y=f[+L],j=C<1||C>b,O=j?C<1?-1:1:0,P=j&&!l,k=P?"":L.getDate(),N=+L==+i,_=E===h[0]||E===h[1],I=m!==y,A="qs-square "+x;Y&&!P&&(A+=" qs-event"),j&&(A+=" qs-outside-current-month"),!l&&j||(A+=" qs-num"),N&&(A+=" qs-active"),(c[+L]||t.disabler(L)||_&&t.noWeekends||s&&+L<+s||o&&+L>+o)&&!P&&(A+=" qs-disabled"),+g(new Date)==+L&&(A+=" qs-current"),+L===m&&y&&I&&(A+=" qs-range-start"),+L>m&&+L<y&&(A+=" qs-range-middle"),+L===y&&m&&I&&(A+=" qs-range-end"),P&&(A+=" qs-empty",k=""),q.push('<div class="'+A+'" data-direction="'+O+'">'+k+"</div>")}var R=d.map((function(e){return'<div class="qs-square qs-day">'+e+"</div>"})).concat(q);return R.unshift('<div class="qs-squares'+(n?" qs-blur":"")+'">'),R.push("</div>"),R.join("")}function v(e,t){var n=e.overlayPlaceholder,a=e.overlayButton;return['<div class="qs-overlay'+(t?"":" qs-hidden")+'">',"<div>",'<input class="qs-overlay-year" placeholder="'+n+'" inputmode="numeric" />','<div class="qs-close">&#10005;</div>',"</div>",'<div class="qs-overlay-month-container">'+e.overlayMonths.map((function(e,t){return'<div class="qs-overlay-month" data-month-num="'+t+'">'+e+"</div>"})).join("")+"</div>",'<div class="qs-submit qs-disabled">'+a+"</div>","</div>"].join("")}function m(e,t,n){var a=t.el,r=t.calendar.querySelector(".qs-active"),i=e.textContent,o=t.sibling;(a.disabled||a.readOnly)&&t.respectDisabledReadOnly||(t.dateSelected=n?void 0:new Date(t.currentYear,t.currentMonth,i),r&&r.classList.remove("qs-active"),n||e.classList.add("qs-active"),p(a,t,n),n||q(t),o&&(y({instance:t,deselect:n}),t.first&&!o.dateSelected&&(o.currentYear=t.currentYear,o.currentMonth=t.currentMonth,o.currentMonthName=t.currentMonthName),u(t),u(o)),t.onSelect(t,n?void 0:new Date(t.dateSelected)))}function y(e){var t=e.instance.first?e.instance:e.instance.sibling,n=t.sibling;t===e.instance?e.deselect?(t.minDate=t.originalMinDate,n.minDate=n.originalMinDate):n.minDate=t.dateSelected:e.deselect?(n.maxDate=n.originalMaxDate,t.maxDate=t.originalMaxDate):t.maxDate=n.dateSelected}function p(e,t,n){if(!t.nonInput)return n?e.value="":t.formatter!==s?t.formatter(e,t.dateSelected,t):void(e.value=t.dateSelected.toDateString())}function w(e,t,n,a){n||a?(n&&(t.currentYear=+n),a&&(t.currentMonth=+a)):(t.currentMonth+=e.contains("qs-right")?1:-1,12===t.currentMonth?(t.currentMonth=0,t.currentYear++):-1===t.currentMonth&&(t.currentMonth=11,t.currentYear--)),t.currentMonthName=t.months[t.currentMonth],u(t),t.onMonthChange(t)}function D(e){if(!e.noPosition){var t=e.position.top,n=e.position.right;if(e.position.centered)return e.calendarContainer.classList.add("qs-centered");var a=e.positionedEl.getBoundingClientRect(),r=e.el.getBoundingClientRect(),i=e.calendarContainer.getBoundingClientRect(),o=r.top-a.top+(t?-1*i.height:r.height)+"px",s=r.left-a.left+(n?r.width-i.width:0)+"px";e.calendarContainer.style.setProperty("top",o),e.calendarContainer.style.setProperty("left",s)}}function b(e){return"[object Date]"===x(e)&&"Invalid Date"!==e.toString()}function g(e){if(b(e)||"number"==typeof e&&!isNaN(e)){var t=new Date(+e);return new Date(t.getFullYear(),t.getMonth(),t.getDate())}}function q(e){e.disabled||!e.calendarContainer.classList.contains("qs-hidden")&&!e.alwaysShow&&("overlay"!==e.defaultView&&M(!0,e),e.calendarContainer.classList.add("qs-hidden"),e.onHide(e))}function S(e){e.disabled||(e.calendarContainer.classList.remove("qs-hidden"),"overlay"===e.defaultView&&M(!1,e),D(e),e.onShow(e))}function M(e,t){var n=t.calendar,a=n.querySelector(".qs-overlay"),r=a.querySelector(".qs-overlay-year"),i=n.querySelector(".qs-controls"),o=n.querySelector(".qs-squares");e?(a.classList.add("qs-hidden"),i.classList.remove("qs-blur"),o.classList.remove("qs-blur"),r.value=""):(a.classList.remove("qs-hidden"),i.classList.add("qs-blur"),o.classList.add("qs-blur"),r.focus())}function E(e,t,n,a){var r=isNaN(+(new Date).setFullYear(t.value||void 0)),i=r?null:t.value;if(13===e.which||13===e.keyCode||"click"===e.type)a?w(null,n,i,a):r||t.classList.contains("qs-disabled")||w(null,n,i);else if(n.calendar.contains(t)){n.calendar.querySelector(".qs-submit").classList[r?"add":"remove"]("qs-disabled")}}function x(e){return{}.toString.call(e)}function C(e){a.forEach((function(t){t!==e&&q(t)}))}function L(e){if(!e.__qs_shadow_dom){var t=e.which||e.keyCode,n=e.type,r=e.target,o=r.classList,s=a.filter((function(e){return e.calendar.contains(r)||e.el===r}))[0],l=s&&s.calendar.contains(r);if(!(s&&s.isMobile&&s.disableMobile))if("click"===n){if(!s)return a.forEach(q);if(s.disabled)return;var d=s.calendar,c=s.calendarContainer,h=s.disableYearOverlay,f=s.nonInput,v=d.querySelector(".qs-overlay-year"),y=!!d.querySelector(".qs-hidden"),p=d.querySelector(".qs-month-year").contains(r),D=r.dataset.monthNum;if(s.noPosition&&!l)(c.classList.contains("qs-hidden")?S:q)(s);else if(o.contains("qs-arrow"))w(o,s);else if(p||o.contains("qs-close"))h||M(!y,s);else if(D)E(e,v,s,D);else{if(o.contains("qs-disabled"))return;if(o.contains("qs-num")){var b=r.textContent,g=+r.dataset.direction,x=new Date(s.currentYear,s.currentMonth+g,b);if(g){s.currentYear=x.getFullYear(),s.currentMonth=x.getMonth(),s.currentMonthName=i[s.currentMonth],u(s);for(var L,Y=s.calendar.querySelectorAll('[data-direction="0"]'),j=0;!L;){var O=Y[j];O.textContent===b&&(L=O),j++}r=L}return void(+x==+s.dateSelected?m(r,s,!0):r.classList.contains("qs-disabled")||m(r,s))}o.contains("qs-submit")?E(e,v,s):f&&r===s.el&&(S(s),C(s))}}else if("focusin"===n&&s)S(s),C(s);else if("keydown"===n&&9===t&&s)q(s);else if("keydown"===n&&s&&!s.disabled){var P=!s.calendar.querySelector(".qs-overlay").classList.contains("qs-hidden");13===t&&P&&l?E(e,r,s):27===t&&P&&l&&M(!0,s)}else if("input"===n){if(!s||!s.calendar.contains(r))return;var k=s.calendar.querySelector(".qs-submit"),N=r.value.split("").reduce((function(e,t){return e||"0"!==t?e+(t.match(/[0-9]/)?t:""):""}),"").slice(0,4);r.value=N,k.classList[4===N.length?"remove":"add"]("qs-disabled")}}}function Y(e){L(e),e.__qs_shadow_dom=!0}function j(e,t){l.forEach((function(n){e.removeEventListener(n,t)}))}function O(){S(this)}function P(){q(this)}function k(e,t){var n=g(e),a=this.currentYear,r=this.currentMonth,i=this.sibling;if(null==e)return this.dateSelected=void 0,p(this.el,this,!0),i&&(y({instance:this,deselect:!0}),u(i)),u(this),this;if(!b(e))throw new Error("`setDate` needs a JavaScript Date object.");if(this.disabledDates[+n]||n<this.minDate||n>this.maxDate)throw new Error("You can't manually set a date that's disabled.");this.dateSelected=n,t&&(this.currentYear=n.getFullYear(),this.currentMonth=n.getMonth(),this.currentMonthName=this.months[n.getMonth()]),p(this.el,this),i&&(y({instance:this}),u(i));var o=a===n.getFullYear()&&r===n.getMonth();return o||t?u(this,n):o||u(this,new Date(a,r,1)),this}function N(e){return I(this,e,!0)}function _(e){return I(this,e)}function I(e,t,n){var a=e.dateSelected,r=e.first,i=e.sibling,o=e.minDate,s=e.maxDate,l=g(t),d=n?"Min":"Max";function c(){return"original"+d+"Date"}function h(){return d.toLowerCase()+"Date"}function f(){return"set"+d}function v(){throw new Error("Out-of-range date passed to "+f())}if(null==t)e[c()]=void 0,i?(i[c()]=void 0,n?(r&&!a||!r&&!i.dateSelected)&&(e.minDate=void 0,i.minDate=void 0):(r&&!i.dateSelected||!r&&!a)&&(e.maxDate=void 0,i.maxDate=void 0)):e[h()]=void 0;else{if(!b(t))throw new Error("Invalid date passed to "+f());i?((r&&n&&l>(a||s)||r&&!n&&l<(i.dateSelected||o)||!r&&n&&l>(i.dateSelected||s)||!r&&!n&&l<(a||o))&&v(),e[c()]=l,i[c()]=l,(n&&(r&&!a||!r&&!i.dateSelected)||!n&&(r&&!i.dateSelected||!r&&!a))&&(e[h()]=l,i[h()]=l)):((n&&l>(a||s)||!n&&l<(a||o))&&v(),e[h()]=l)}return i&&u(i),u(e),e}function A(){var e=this.first?this:this.sibling,t=e.sibling;return{start:e.dateSelected,end:t.dateSelected}}function R(){var e=this.shadowDom,t=this.positionedEl,n=this.calendarContainer,r=this.sibling,i=this;this.inlinePosition&&(a.some((function(e){return e!==i&&e.positionedEl===t}))||t.style.setProperty("position",null));n.remove(),a=a.filter((function(e){return e!==i})),r&&delete r.sibling,a.length||j(document,L);var o=a.some((function(t){return t.shadowDom===e}));for(var s in e&&!o&&j(e,Y),this)delete this[s];a.length||l.forEach((function(e){document.removeEventListener(e,L)}))}function F(e,t){var n=new Date(e);if(!b(n))throw new Error("Invalid date passed to `navigate`");this.currentYear=n.getFullYear(),this.currentMonth=n.getMonth(),u(this),t&&this.onMonthChange(this)}function B(){var e=!this.calendarContainer.classList.contains("qs-hidden"),t=!this.calendarContainer.querySelector(".qs-overlay").classList.contains("qs-hidden");e&&M(t,this)}t.default=function(e,t){var n=function(e,t){var n,l,d=function(e){var t=c(e);t.events&&(t.events=t.events.reduce((function(e,t){if(!b(t))throw new Error('"options.events" must only contain valid JavaScript Date objects.');return e[+g(t)]=!0,e}),{}));["startDate","dateSelected","minDate","maxDate"].forEach((function(e){var n=t[e];if(n&&!b(n))throw new Error('"options.'+e+'" needs to be a valid JavaScript Date object.');t[e]=g(n)}));var n=t.position,i=t.maxDate,l=t.minDate,d=t.dateSelected,u=t.overlayPlaceholder,h=t.overlayButton,f=t.startDay,v=t.id;if(t.startDate=g(t.startDate||d||new Date),t.disabledDates=(t.disabledDates||[]).reduce((function(e,t){var n=+g(t);if(!b(t))throw new Error('You supplied an invalid date to "options.disabledDates".');if(n===+g(d))throw new Error('"disabledDates" cannot contain the same date as "dateSelected".');return e[n]=1,e}),{}),t.hasOwnProperty("id")&&null==v)throw new Error("`id` cannot be `null` or `undefined`");if(null!=v){var m=a.filter((function(e){return e.id===v}));if(m.length>1)throw new Error("Only two datepickers can share an id.");m.length?(t.second=!0,t.sibling=m[0]):t.first=!0}var y=["tr","tl","br","bl","c"].some((function(e){return n===e}));if(n&&!y)throw new Error('"options.position" must be one of the following: tl, tr, bl, br, or c.');function p(e){throw new Error('"dateSelected" in options is '+(e?"less":"greater")+' than "'+(e||"max")+'Date".')}if(t.position=function(e){var t=e[0],n=e[1],a={};a[o[t]]=1,n&&(a[o[n]]=1);return a}(n||"bl"),i<l)throw new Error('"maxDate" in options is less than "minDate".');d&&(l>d&&p("min"),i<d&&p());if(["onSelect","onShow","onHide","onMonthChange","formatter","disabler"].forEach((function(e){"function"!=typeof t[e]&&(t[e]=s)})),["customDays","customMonths","customOverlayMonths"].forEach((function(e,n){var a=t[e],r=n?12:7;if(a){if(!Array.isArray(a)||a.length!==r||a.some((function(e){return"string"!=typeof e})))throw new Error('"'+e+'" must be an array with '+r+" strings.");t[n?n<2?"months":"overlayMonths":"days"]=a}})),f&&f>0&&f<7){var w=(t.customDays||r).slice(),D=w.splice(0,f);t.customDays=w.concat(D),t.startDay=+f,t.weekendIndices=[w.length-1,w.length]}else t.startDay=0,t.weekendIndices=[6,0];"string"!=typeof u&&delete t.overlayPlaceholder;"string"!=typeof h&&delete t.overlayButton;var q=t.defaultView;if(q&&"calendar"!==q&&"overlay"!==q)throw new Error('options.defaultView must either be "calendar" or "overlay".');return t.defaultView=q||"calendar",t}(t||{startDate:g(new Date),position:"bl",defaultView:"calendar"}),u=e;if("string"==typeof u)u="#"===u[0]?document.getElementById(u.slice(1)):document.querySelector(u);else{if("[object ShadowRoot]"===x(u))throw new Error("Using a shadow DOM as your selector is not supported.");for(var h,f=u.parentNode;!h;){var v=x(f);"[object HTMLDocument]"===v?h=!0:"[object ShadowRoot]"===v?(h=!0,n=f,l=f.host):f=f.parentNode}}if(!u)throw new Error("No selector / element found.");if(a.some((function(e){return e.el===u})))throw new Error("A datepicker already exists on that element.");var m=u===document.body,y=n?u.parentElement||n:m?document.body:u.parentElement,w=n?u.parentElement||l:y,D=document.createElement("div"),q=document.createElement("div");D.className="qs-datepicker-container qs-hidden",q.className="qs-datepicker";var M={shadowDom:n,customElement:l,positionedEl:w,el:u,parent:y,nonInput:"INPUT"!==u.nodeName,noPosition:m,position:!m&&d.position,startDate:d.startDate,dateSelected:d.dateSelected,disabledDates:d.disabledDates,minDate:d.minDate,maxDate:d.maxDate,noWeekends:!!d.noWeekends,weekendIndices:d.weekendIndices,calendarContainer:D,calendar:q,currentMonth:(d.startDate||d.dateSelected).getMonth(),currentMonthName:(d.months||i)[(d.startDate||d.dateSelected).getMonth()],currentYear:(d.startDate||d.dateSelected).getFullYear(),events:d.events||{},defaultView:d.defaultView,setDate:k,remove:R,setMin:N,setMax:_,show:O,hide:P,navigate:F,toggleOverlay:B,onSelect:d.onSelect,onShow:d.onShow,onHide:d.onHide,onMonthChange:d.onMonthChange,formatter:d.formatter,disabler:d.disabler,months:d.months||i,days:d.customDays||r,startDay:d.startDay,overlayMonths:d.overlayMonths||(d.months||i).map((function(e){return e.slice(0,3)})),overlayPlaceholder:d.overlayPlaceholder||"4-digit year",overlayButton:d.overlayButton||"Submit",disableYearOverlay:!!d.disableYearOverlay,disableMobile:!!d.disableMobile,isMobile:"ontouchstart"in window,alwaysShow:!!d.alwaysShow,id:d.id,showAllDates:!!d.showAllDates,respectDisabledReadOnly:!!d.respectDisabledReadOnly,first:d.first,second:d.second};if(d.sibling){var E=d.sibling,C=M,L=E.minDate||C.minDate,Y=E.maxDate||C.maxDate;C.sibling=E,E.sibling=C,E.minDate=L,E.maxDate=Y,C.minDate=L,C.maxDate=Y,E.originalMinDate=L,E.originalMaxDate=Y,C.originalMinDate=L,C.originalMaxDate=Y,E.getRange=A,C.getRange=A}d.dateSelected&&p(u,M);var j=getComputedStyle(w).position;m||j&&"static"!==j||(M.inlinePosition=!0,w.style.setProperty("position","relative"));var I=a.filter((function(e){return e.positionedEl===M.positionedEl}));I.some((function(e){return e.inlinePosition}))&&(M.inlinePosition=!0,I.forEach((function(e){e.inlinePosition=!0})));D.appendChild(q),y.appendChild(D),M.alwaysShow&&S(M);return M}(e,t);if(a.length||d(document),n.shadowDom&&(a.some((function(e){return e.shadowDom===n.shadowDom}))||d(n.shadowDom)),a.push(n),n.second){var l=n.sibling;y({instance:n,deselect:!n.dateSelected}),y({instance:l,deselect:!l.dateSelected}),u(l)}return u(n,n.startDate||n.dateSelected),n.alwaysShow&&D(n),n}}]).default}));
1374

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.