PageSourceSearch

https://www.hatanakh.com/sites/default/files/js/js_t6IFF_zoupc30zYKYM4yBsNiuZE8_BozheFMEe_ATgM.js

js hatanakh.com collected 2026-10-02 10:25:34 UTC 171,854 bytes, 3,351 lines download raw bytes

1typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n<s;n+=1)u[n]=str(n,a)||"null";return i=u.length===0?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+o+"]":"["+u.join(",")+"]",gap=o,i}if(rep&&typeof rep=="object"){s=rep.length;for(n=0;n<s;n+=1)typeof rep[n]=="string"&&(r=rep[n],i=str(r,a),i&&u.push(quote(r)+(gap?": ":":")+i))}else for(r in a)Object.prototype.hasOwnProperty.call(a,r)&&(i=str(r,a),i&&u.push(quote(r)+(gap?": ":":")+i));return i=u.length===0?"{}":gap?"{\n"+gap+u.join(",\n"+gap)+"\n"+o+"}":"{"+u.join(",")+"}",gap=o,i}}typeof Date.prototype.toJSON!="function"&&(Date.prototype.toJSON=function(e){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(e){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","	":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;typeof JSON.stringify!="function"&&(JSON.stringify=function(e,t,n){var r;gap="",indent="";if(typeof n=="number")for(r=0;r<n;r+=1)indent+=" ";else typeof n=="string"&&(indent=n);rep=t;if(!t||typeof t=="function"||typeof t=="object"&&typeof t.length=="number")return str("",{"":e});throw new Error("JSON.stringify")}),typeof JSON.parse!="function"&&(JSON.parse=function(text,reviver){function walk(e,t){var n,r,i=e[t];if(i&&typeof i=="object")for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(r=walk(i,n),r!==undefined?i[n]=r:delete i[n]);return reviver.call(e,t,i)}var j;text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(e){return"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),typeof reviver=="function"?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(),function(e,t){"use strict";var n=e.History=e.History||{},r=e.jQuery;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={bind:function(e,t,n){r(e).bind(t,n)},trigger:function(e,t,n){r(e).trigger(t,n)},extractEventData:function(e,n,r){var i=n&&n.originalEvent&&n.originalEvent[e]||r&&r[e]||t;return i},onDomLoad:function(e){r(e)}},typeof n.init!="undefined"&&n.init()}(window),function(e,t){"use strict";var n=e.document,r=e.setTimeout||r,i=e.clearTimeout||i,s=e.setInterval||s,o=e.History=e.History||{};if(typeof o.initHtml4!="undefined")throw new Error("History.js HTML4 Support has already been loaded...");o.initHtml4=function(){if(typeof o.initHtml4.initialized!="undefined")return!1;o.initHtml4.initialized=!0,o.enabled=!0,o.savedHashes=[],o.isLastHash=function(e){var t=o.getHashByIndex(),n;return n=e===t,n},o.isHashEqual=function(e,t){return e=encodeURIComponent(e).replace(/%25/g,"%"),t=encodeURIComponent(t).replace(/%25/g,"%"),e===t},o.saveHash=function(e){return o.isLastHash(e)?!1:(o.savedHashes.push(e),!0)},o.getHashByIndex=function(e){var t=null;return typeof e=="undefined"?t=o.savedHashes[o.savedHashes.length-1]:e<0?t=o.savedHashes[o.savedHashes.length+e]:t=o.savedHashes[e],t},o.discardedHashes={},o.discardedStates={},o.discardState=function(e,t,n){var r=o.getHashByState(e),i;return i={discardedState:e,backState:n,forwardState:t},o.discardedStates[r]=i,!0},o.discardHash=function(e,t,n){var r={discardedHash:e,backState:n,forwardState:t};return o.discardedHashes[e]=r,!0},o.discardedState=function(e){var t=o.getHashByState(e),n;return n=o.discardedStates[t]||!1,n},o.discardedHash=function(e){var t=o.discardedHashes[e]||!1;return t},o.recycleState=function(e){var t=o.getHashByState(e);return o.discardedState(e)&&delete o.discardedStates[t],!0},o.emulated.hashChange&&(o.hashChangeInit=function(){o.checkerFunction=null;
1var t="",r,i,u,a,f=Boolean(o.getHash());return o.isInternetExplorer()?(r="historyjs-iframe",i=n.createElement("iframe"),i.setAttribute("id",r),i.setAttribute("src","#"),i.style.display="none",n.body.appendChild(i),i.contentWindow.document.open(),i.contentWindow.document.close(),u="",a=!1,o.checkerFunction=function(){if(a)return!1;a=!0;var n=o.getHash(),r=o.getHash(i.contentWindow.document);return n!==t?(t=n,r!==n&&(u=r=n,i.contentWindow.document.open(),i.contentWindow.document.close(),i.contentWindow.document.location.hash=o.escapeHash(n)),o.Adapter.trigger(e,"hashchange")):r!==u&&(u=r,f&&r===""?o.back():o.setHash(r,!1)),a=!1,!0}):o.checkerFunction=function(){var n=o.getHash()||"";return n!==t&&(t=n,o.Adapter.trigger(e,"hashchange")),!0},o.intervalList.push(s(o.checkerFunction,o.options.hashChangeInterval)),!0},o.Adapter.onDomLoad(o.hashChangeInit)),o.emulated.pushState&&(o.onHashChange=function(t){var n=t&&t.newURL||o.getLocationHref(),r=o.getHashByUrl(n),i=null,s=null,u=null,a;return o.isLastHash(r)?(o.busy(!1),!1):(o.doubleCheckComplete(),o.saveHash(r),r&&o.isTraditionalAnchor(r)?(o.Adapter.trigger(e,"anchorchange"),o.busy(!1),!1):(i=o.extractState(o.getFullUrl(r||o.getLocationHref()),!0),o.isLastSavedState(i)?(o.busy(!1),!1):(s=o.getHashByState(i),a=o.discardedState(i),a?(o.getHashByIndex(-2)===o.getHashByState(a.forwardState)?o.back(!1):o.forward(!1),!1):(o.pushState(i.data,i.title,encodeURI(i.url),!1),!0))))},o.Adapter.bind(e,"hashchange",o.onHashChange),o.pushState=function(t,n,r,i){r=encodeURI(r).replace(/%25/g,"%");if(o.getHashByUrl(r))throw new Error("History.js does not support states with fragment-identifiers (hashes/anchors).");if(i!==!1&&o.busy())return o.pushQueue({scope:o,callback:o.pushState,args:arguments,queue:i}),!1;o.busy(!0);var s=o.createStateObject(t,n,r),u=o.getHashByState(s),a=o.getState(!1),f=o.getHashByState(a),l=o.getHash(),c=o.expectedStateId==s.id;return o.storeState(s),o.expectedStateId=s.id,o.recycleState(s),o.setTitle(s),u===f?(o.busy(!1),!1):(o.saveState(s),c||o.Adapter.trigger(e,"statechange"),!o.isHashEqual(u,l)&&!o.isHashEqual(u,o.getShortUrl(o.getLocationHref()))&&o.setHash(u,!1),o.busy(!1),!0)},o.replaceState=function(t,n,r,i){r=encodeURI(r).replace(/%25/g,"%");if(o.getHashByUrl(r))throw new Error("History.js does not support states with fragment-identifiers (hashes/anchors).");if(i!==!1&&o.busy())return o.pushQueue({scope:o,callback:o.replaceState,args:arguments,queue:i}),!1;o.busy(!0);var s=o.createStateObject(t,n,r),u=o.getHashByState(s),a=o.getState(!1),f=o.getHashByState(a),l=o.getStateByIndex(-2);return o.discardState(a,s,l),u===f?(o.storeState(s),o.expectedStateId=s.id,o.recycleState(s),o.setTitle(s),o.saveState(s),o.Adapter.trigger(e,"statechange"),o.busy(!1)):o.pushState(s.data,s.title,s.url,!1),!0}),o.emulated.pushState&&o.getHash()&&!o.emulated.hashChange&&o.Adapter.onDomLoad(function(){o.Adapter.trigger(e,"hashchange")})},typeof o.init!="undefined"&&o.init()}(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s=e.sessionStorage,s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.
1clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e<t.length;e++)f(t[e]);h.intervalList=null}},h.debug=function(){(h.options.debug||!1)&&h.log.apply(h,arguments)},h.log=function(){var e=typeof n!="undefined"&&typeof n.log!="undefined"&&typeof n.log.apply!="undefined",t=r.getElementById("log"),i,s,o,u,a;e?(u=Array.prototype.slice.call(arguments),i=u.shift(),typeof n.debug!="undefined"?n.debug.apply(n,[i,u]):n.log.apply(n,[i,u])):i="\n"+arguments[0]+"\n";for(s=1,o=arguments.length;s<o;++s){a=arguments[s];if(typeof a=="object"&&typeof l!="undefined")try{a=l.stringify(a)}catch(f){}i+="\n"+a+"\n"}return t?(t.value+=i+"\n-----\n",t.scrollTop=t.scrollHeight-t.clientHeight):e||c(i),!0},h.getInternetExplorerMajorVersion=function(){var e=h.getInternetExplorerMajorVersion.cached=typeof h.getInternetExplorerMajorVersion.cached!="undefined"?h.getInternetExplorerMajorVersion.cached:function(){var e=3,t=r.createElement("div"),n=t.getElementsByTagName("i");while((t.innerHTML="<!--[if gt IE "+ ++e+"]><i></i><![endif]-->")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}
1:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","&lt;").replace(">","&gt;").replace(" & "," &amp; ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getL
1ocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window);
2/// <reference path="../typings/google.maps.d.ts" />
3function FullScreenControl(map, enterFull, exitFull, isHomePage) {
4    if (enterFull === void 0) { enterFull = null; }
5    if (exitFull === void 0) { exitFull = null; }
6
7    var controlDiv = document.createElement("a");
8    controlDiv.className = "fullScreen";
9    controlDiv.index = 1;
10    if (isHomePage) {
11      controlDiv.href = Drupal.settings.pathPrefix + "map";
12    }
13    // Set CSS for the control border.
14    var controlUI = document.createElement("div");
15    controlUI.style.backgroundColor = "white";
16    controlUI.style.borderStyle = "solid";
17    controlUI.style.borderColor = "#717b87";
18    controlUI.style.cursor = "pointer";
19    controlUI.style.textAlign = "center";
20    controlUI.style.boxShadow = "rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px";
21    // custom styles added
22    controlUI.style.background = 'url("/sites/all/modules/feature/feature_location/images/map_fullscreen.jpg")';
23    controlUI.style.width      = "34px";
24    controlUI.style.height     = "32px";
25
26    controlDiv.appendChild(controlUI);
27    // Set CSS for the control interior.
28    var controlText = document.createElement("div");
29    controlText.style.fontFamily = "Roboto,Arial,sans-serif";
30    controlText.style.fontSize = "11px";
31    controlText.style.fontWeight = "400";
32    controlText.style.paddingTop = "1px";
33    controlText.style.paddingBottom = "1px";
34    controlText.style.paddingLeft = "6px";
35    controlText.style.paddingRight = "6px";
36    controlText.innerHTML = "<strong>" + enterFull + "</strong>";
37    controlUI.appendChild(controlText);
38    // set print CSS so the control is hidden
39    var head = document.getElementsByTagName("head")[0];
40    var newStyle = document.createElement("style");
41    newStyle.setAttribute("type", "text/css");
42    newStyle.setAttribute("media", "print");
43    var cssText = ".fullScreen { display: none;}";
44    var texNode = document.createTextNode(cssText);
45    try {
46        newStyle.appendChild(texNode);
47    }
48    catch (e) {
49        // IE8 hack
50        newStyle.styleSheet.cssText = cssText;
51    }
52    head.appendChild(newStyle);
53    var fullScreen = false;
54    var interval;
55    var mapDiv = map.getDiv();
56    var divStyle = mapDiv.style;
57    if (mapDiv.runtimeStyle) {
58        divStyle = mapDiv.runtimeStyle;
59    }
60    var originalPos = divStyle.position;
61    var originalWidth = divStyle.width;
62    var originalHeight = divStyle.height;
63    // IE8 hack
64    if (originalWidth === "") {
65        originalWidth = mapDiv.style.width;
66    }
67    if (originalHeight === "") {
68        originalHeight = mapDiv.style.height;
69    }
70    var originalTop = divStyle.top;
71    var originalLeft = divStyle.left;
72    var originalZIndex = divStyle.zIndex;
73    var bodyStyle = document.body.style;
74    if (document.body.runtimeStyle) {
75        bodyStyle = document.body.runtimeStyle;
76    }
77    var originalOverflow = bodyStyle.overflow;
78    controlDiv.goFullScreen = function () {
79      jQuery('div.wrapper-figure-modern-map').css({"zIndex":"101" , "position": "fixed"});
80        jQuery('#map-container-wrapper').css("position","fixed");
81
82        var center = map.getCenter();
83        mapDiv.style.position = "fixed";
84        mapDiv.style.width = "100%";
85        mapDiv.style.height = "100%";
86        mapDiv.style.top = "0";
87        mapDiv.style.left = "0";
88        mapDiv.style.zIndex = "100";
89        document.body.style.overflow = "hidden";
90        controlText.innerHTML = "<strong>" + exitFull + "</strong>";
91        fullScreen = true;
92        google.maps.event.trigger(map, "resize");
93        map.setCenter(center);
94        // this works around street view causing the map to disappear, which is caused by Google Maps setting the
95        // CSS position back to relative. There is no event triggered when Street View is shown hence the use of setInterval
96        interval = setInterval(function () {
97            if (mapDiv.style.position !== "fixed") {
98                mapDiv.style.position = "fixed";
99                google.maps.event.trigger(map, "resize");
100            }
101        }, 100);
102    };
103    controlDiv.exitFullScreen = function () {
104        var center = map.getCenter();
105        jQuery('div.wrapper-figure-modern-map').css({"zIndex":"35", "position": "absolute"});
106        jQuery('#map-container-wrapper').css("position","relative");
107
108        if (originalPos === "") {
109            mapDiv.style.position = "relative";
110        }
111        else {
112            mapDiv.style.position = originalPos;
113        }
114        mapDiv.style.width = originalWidth;
115        mapDiv.style.height = originalHeight;
116        mapDiv.style.top = originalTop;
117        mapDiv.style.left = originalLeft;
118        mapDiv.style.zIndex = originalZIndex;
119        document.body.style.overflow = originalOverflow;
120        controlText.innerHTML = "<strong>" + enterFull + "</strong>";
121        fullScreen = false;
122        google.maps.event.trigger(map, "resize");
123        map.setCenter(center);
124        clearInterval(interval);
125    };
126    // Setup the click event listener
127    // issue #654 - Instead of fullscreen redirect to maps page
128
129    if (!isHomePage) {
130      google.maps.event.addDomListener(controlUI, "click", function () {
131        if (!fullScreen) {
132            controlDiv.goFullScreen();
133        }
134        else {
135            controlDiv.exitFullScreen();
136        }
137      });
138    }
139
140    return controlDiv;
141}
142;
143/**
144 * Created by shimonam on 2/16/2017.
145 */
146
147var FeatureLocationLayers = {
148
149    /*
150     * fill variable with all active kmls
151     * */
152    fillAllKmls: function () {
153        var allKmls = {};
154        var isProduction = window.location.hostname === 'www.hatanakh.com' || window.location.hostname === 'hatanakh.com';
155
156        // Check if mapLayers exists before trying to loop through it
157        if (Drupal.settings.mapLayers && typeof Drupal.settings.mapLayers === 'object') {
158            for (var prop in Drupal.settings.mapLayers) {
159                if (Drupal.settings.mapLayers[prop].hasOwnProperty('fieldKml')) {
160                    var kmlUrl = Drupal.settings.mapLayers[prop]['fieldKml'];
161                    if (kmlUrl) {
162                        if (isProduction) {
163                            // Production: Use Google's KmlLayer
164                            try {
165                                var kmlInstance = new google.maps.KmlLayer({
166                                    url: kmlUrl,
167                                    preserveViewport: false,
168                                    suppressInfoWindows: false
169                                });
170
171                                // Add error listener
172                                google.maps.event.addListener(kmlInstance, 'status_changed', function () {
173                                    var status = kmlInstance.getStatus();
174                                    if (status !== google.maps.KmlLayerStatus.OK) {
175                                        console.error('KML Layer Error for ' + prop + ':', status, 'URL:', kmlUrl);
176                                    }
177                                });
178
179                                allKmls[prop] = kmlInstance;
180                            } catch (e) {
181                                console.error('Error creating KML layer for:', prop, kmlUrl, e);
182                            }
183                        } else {
184                            // Local/Dev: Create placeholder that will load via AJAX
185                            allKmls[prop] = {
186                                url: kmlUrl,
187                                overlays: [],
188                                isCustom: true,
189                                isLoaded: false,
190                                setMap: function (map) {
191                                    if (map && !this.isLoaded) {
192                                        // Load and parse KML when layer is activated
193                                        FeatureLocationLayers.loadKmlFile(this, map, prop);
194                                    } else if (!map && this.overlays.length > 0) {
195                                        // Remove overlays
196                                        for (var i = 0; i < this.overlays.length; i++) {
197                                            this.overlays[i].setMap(null);
198                                        }
199                                    } else if (map && this.isLoaded) {
200                                        // Re-add existing overlays
201                                        for (var i = 0; i < this.overlays.length; i++) {
202                                            this.overlays[i].setMap(map);
203                                        }
204                                        if (this.bounds) {
205                                            map.fitBounds(this.bounds);
206                                        }
207                                    }
208                                }
209                            };
210                        }
211                    }
212                }
213            }
214        } else {
215            console.warn('Drupal.settings.mapLayers is not defined or not an object');
216        }
217        return allKmls;
218    },
219
220    /*
221     * Load and parse KML file for local/dev environments
222     * */
223    loadKmlFile: function (kmlObj, map, layerId) {
224        // Check if it's a KMZ file and use extraction endpoint
225        var isKmz = kmlObj.url.toLowerCase().indexOf('.kmz') !== -1;
226        var fetchUrl = kmlObj.url;
227
228        if (isKmz) {
229            // Extract file path from URL and decode it first (it's already URL-encoded)
230            var filePath = kmlObj.url.replace(/^https?:\/\/[^\/]+/, '');
231            // Decode the path first since it's already encoded, then encode it properly for the query param
232            var decodedPath = decodeURIComponent(filePath);
233            fetchUrl = '/feature-location/extract-kml?file=' + encodeURIComponent(decodedPath);
234        }
235
236        jQuery.ajax({
237            url: fetchUrl,
238            dataType: 'xml',
239            success: function (xml) {
240                kmlObj.isLoaded = true;
241                FeatureLocationLayers.parseKml(xml, kmlObj, map);
242            },
243            error: function (xhr, status, error) {
244                console.error('Failed to load KML:', kmlObj.url, error);
245                if (xhr.responseText) {
246                    console.error('Response:', xhr.responseText.substring(0, 200));
247                }
248            }
249        });
250    },
251
252    /*
253     * Parse KML XML and create Google Maps overlays
254     * */
255    parseKml: function (xml, kmlObj, map) {
256        var $ = jQuery;
257        var bounds = new google.maps.LatLngBounds();
258        var hasBounds = false;
259
260        var styles = {};
261        $(xml).find('Style').each(function () {
262            var id = $(this).attr('id');
263            if (id) {
264                styles['#' + id] = {
265                    polyColor: $(this).find('PolyStyle color').text(),
266                    lineColor: $(this).find('LineStyle color').text()
267                };
268            }
269        });
270
271        function parseColor(kmlColor) {
272            kmlColor = $.trim(kmlColor);
273            if (!kmlColor || kmlColor.length < 6) return null;
274            if (kmlColor.length === 6) { kmlColor = 'ff' + kmlColor; }
275
276            var a = parseInt(kmlColor.substring(0, 2), 16) / 255;
277            var b = kmlColor.substring(2, 4);
278            var g = kmlColor.substring(4, 6);
279            var r = kmlColor.substring(6, 8);
280
281            return {
282                color: '#' + r + g + b,
283                opacity: isNaN(a) ? 1 : a
284            };
285        }
286
287        function getStyle(node) {
288            var placemark = $(node).closest('Placemark');
289            var styleUrl = placemark.find('styleUrl').text();
290            var polyColor = placemark.find('> Style PolyStyle color').text();
291            var lineColor = placemark.find('> Style LineStyle color').text();
292
293            if (styleUrl && styles[styleUrl]) {
294                if (!polyColor) polyColor = styles[styleUrl].polyColor;
295                if (!lineColor) lineColor = styles[styleUrl].lineColor;
296            }
297            // Follow nested StyleMaps if possible (very basic fallback to first Style)
298            else if (styleUrl) {
299                var styleMap = $(xml).find('StyleMap[id="' + styleUrl.replace('#', '') + '"]');
300                if (styleMap.length > 0) {
301                    var pairUrl = styleMap.find('Pair styleUrl').first().text();
302                    if (pairUrl && styles[pairUrl]) {
303                        if (!polyColor) polyColor = styles[pairUrl].polyColor;
304                        if (!lineColor) lineColor = styles[pairUrl].lineColor;
305                    }
306                }
307            }
308
309            var result = {
310                strokeColor: '#FF0000',
311                strokeOpacity: 0.8,
312                fillColor: '#FF0000',
313                fillOpacity: 0.35
314            };
315
316            var parsedPoly = parseColor(polyColor);
317            if (parsedPoly) {
318                result.fillColor = parsedPoly.color;
319                result.fillOpacity = parsedPoly.opacity;
320            }
321
322            var parsedLine = parseColor(lineColor);
323            if (parsedLine) {
324                result.strokeColor = parsedLine.color;
325                result.strokeOpacity = parsedLine.opacity;
326            } else if (parsedPoly) {
327                // fallback line color to poly color if missing
328                result.strokeColor = parsedPoly.color;
329                result.strokeOpacity = Math.min(1, parsedPoly.opacity * 1.5);
330            }
331
332            return result;
333        }
334
335        var sharedInfoWindow = new google.maps.InfoWindow();
336
337        function addInfoWindowEvent(overlay, name, description) {
338            if (!name && !description) return;
339            var content = '<div class="kml-info-window">';
340            if (name) content += '<h3>' + name + '</h3>';
341            if (description) content += '<div>' + description + '</div>';
342            content += '</div>';
343
344            google.maps.event.addListener(overlay, 'click', function (event) {
345                var position = event.latLng;
346                if (!position && overlay.getPosition) position = overlay.getPosition();
347
348                sharedInfoWindow.setContent(content);
349                sharedInfoWindow.setPosition(position);
350                sharedInfoWindow.open(map);
351            });
352        }
353
354        // Loop over Placemarks to ensure cohesive rendering and label placement
355        $(xml).find('Placemark').each(function () {
356            var placemark = $(this);
357            var name = $.trim(placemark.find('> name').text());
358            var description = $.trim(placemark.find('> description').text());
359            var style = getStyle(placemark);
360
361            var polyBounds = new google.maps.LatLngBounds();
362            var hasPolygon = false;
363
364            // 1. Draw Polygons
365            placemark.find('Polygon').each(function () {
366                var coords = $(this).find('outerBoundaryIs coordinates').text().trim().split(/\s+/);
367                var path = [];
368                for (var i = 0; i < coords.length; i++) {
369                    var coord = coords[i].split(',');
370                    if (coord.length >= 2) {
371                        var lng = parseFloat(coord[0]);
372                        var lat = parseFloat(coord[1]);
373                        var latLng = new google.maps.LatLng(lat, lng);
374                        path.push(latLng);
375                        polyBounds.extend(latLng);
376                        bounds.extend(latLng);
377                        hasBounds = true;
378                    }
379                }
380                if (path.length > 0) {
381                    hasPolygon = true;
382                    var polygon = new google.maps.Polygon({
383                        paths: path,
384                        strokeColor: style.strokeColor,
385                        strokeOpacity: style.strokeOpacity,
386                        strokeWeight: 2,
387                        fillColor: style.fillColor,
388                        fillOpacity: style.fillOpacity,
389                        map: map
390                    });
391                    kmlObj.overlays.push(polygon);
392                    addInfoWindowEvent(polygon, name, description);
393                }
394            });
395
396            // 2. Draw LineStrings
397            var fullLinePath = [];
398            placemark.find('LineString').each(function () {
399                var coords = $(this).find('coordinates').text().trim().split(/\s+/);
400                var path = [];
401                for (var i = 0; i < coords.length; i++) {
402                    var coord = coords[i].split(',');
403                    if (coord.length >= 2) {
404                        var lng = parseFloat(coord[0]);
405                        var lat = parseFloat(coord[1]);
406                        var latLng = new google.maps.LatLng(lat, lng);
407                        path.push(latLng);
408                        fullLinePath.push(latLng);
409                        bounds.extend(latLng);
410                        hasBounds = true;
411                    }
412                }
413                if (path.length > 0) {
414                    var polyline = new google.maps.Polyline({
415                        path: path,
416                        strokeColor: style.strokeColor,
417                        strokeOpacity: style.strokeOpacity,
418                        strokeWeight: 3,
419                        map: map
420                    });
421                    kmlObj.overlays.push(polyline);
422                    addInfoWindowEvent(polyline, name, description);
423                }
424            });
425
426            // 3. Find Points
427            var pointLatLngs = [];
428            placemark.find('Point').each(function () {
429                var coords = $(this).find('coordinates').text().trim().split(/\s+/);
430                for (var i = 0; i < coords.length; i++) {
431                    var coord = coords[i].split(',');
432                    if (coord.length >= 2) {
433                        var lng = parseFloat(coord[0]);
434                        var lat = parseFloat(coord[1]);
435                        var latLng = new google.maps.LatLng(lat, lng);
436                        pointLatLngs.push(latLng);
437                        bounds.extend(latLng);
438                        hasBounds = true;
439                    }
440                }
441            });
442
443            // 4. Place Label (Only one label per Placemark)
444            if (name) {
445                var labelPos = null;
446                if (pointLatLngs.length > 0) {
447                    labelPos = pointLatLngs[0];
448                } else if (hasPolygon) {
449                    labelPos = polyBounds.getCenter();
450                } else if (fullLinePath.length > 0) {
451                    labelPos = fullLinePath[Math.floor(fullLinePath.length / 2)];
452                }
453
454                if (labelPos) {
455                    console.log("KML PARSER LABEL:", name, "at", labelPos.lat() + "," + labelPos.lng(), "Points count:", fullLinePath.length);
456                    var markerLabel = new MarkerWithLabel({
457                        position: labelPos,
458                        map: map,
459                        icon: ' ',
460                        labelContent: name,
461                        labelAnchor: new google.maps.Point(22, 10),
462                        labelClass: "markerLabelsRegion kml-label",
463                    });
464                    kmlObj.overlays.push(markerLabel);
465                    addInfoWindowEvent(markerLabel, name, description);
466                }
467            }
468
469            // Draw default pins for points ONLY if there is no name label
470            if (pointLatLngs.length > 0 && !name) {
471                for (var i = 0; i < pointLatLngs.length; i++) {
472                    var marker = new google.maps.Marker({
473                        position: pointLatLngs[i],
474                        map: map
475                    });
476                    kmlObj.overlays.push(marker);
477                    addInfoWindowEvent(marker, name, description);
478                }
479            }
480        });
481
482        if (hasBounds) {
483            kmlObj.bounds = bounds;
484            map.fitBounds(bounds);
485        }
486    },
487
488    /*
489     * remove all kmls on map
490     * */
491    resetKmls: function (kmls) {
492        for (var prop in kmls) {
493            if (kmls.hasOwnProperty(prop)) {
494                if (kmls[prop].isCustom) {
495                    // Custom overlay
496                    kmls[prop].setMap(null);
497                } else {
498                    // Google KmlLayer
499                    kmls[prop].setMap(null);
500                }
501            }
502        }
503    }
504};;
505/**
506 * Created by shimonam on 2/16/2017.
507 */
508
509/*
510 * ajax object
511 * */
512function FeatureLocationAjax(settings) {
513    /*
514     * prop
515     * */
516    var $ = window.jQuery;
517    var urlText = Drupal.settings.mapSettings.baseUrl + '/ajax/map/tanachText';
518    var nextChapter = $('.next-chapter');
519    var biblicleTextWrapper = $('.map-biblicle-text-wrapper');
520    var lobbyContainer = $('.lobbyContainer');
521    var multiChapterTitle = $('.multi-chapter-title');
522    var lang = Drupal.settings.pathPrefix.slice(0, -1);
523    var self = this;
524
525    self.kmlInstance = FeatureLocationLayers.fillAllKmls();
526
527    self.updateTanachText = function (filterObj) {
528        $.ajax({
529            type: 'POST',
530            dataType: 'json',
531            url: urlText,
532            data: {
533                chapter: filterObj.chapter,
534                book: filterObj.book,
535                tanachText: 0,
536                lang : lang
537            },
538            success: function (response) {
539                $('.map-biblicle-text').html(response.text);
540                nextChapter.data('next-chapter', response.nextChapter);
541            },
542            error: function (err) {
543                console.log('error');
544                console.log(err);
545            }
546        });
547
548    };
549    self.updateLayers = function (filterObj, kmlInstance, showHideMarkers) {
550
551        $.ajax({
552            type: 'POST',
553            dataType: 'json',
554            url: urlText,
555            data: {
556                chapter: filterObj.chapter,
557                book: filterObj.book,
558                book_to: filterObj.book_to,
559                chapter_to: filterObj.chapter_to,
560                layer: 1,
561                lang : Drupal.settings.pathPrefix
562            },
563            success: function (response) {
564                $('.wrapper-figure-layers').html(response.html);
565                Drupal.settings.mapLayers = response.layers;
566                FeatureLocationLayers.resetKmls(kmlInstance);
567                kmlInstance = FeatureLocationLayers.fillAllKmls();
568                markersDisplay(showHideMarkers.visible);
569                toggleLayers();
570
571            },
572            error: function (err) {
573                console.log('error');
574                console.log(err);
575            }
576        });
577
578    };
579    self.updateLayersByPeriods = function (filterObj, kmlInstance, showHideMarkers) {
580        $.ajax({
581            type: 'POST',
582            dataType: 'json',
583            url: urlText,
584            data: {periods: [filterObj.periods], isPeriods: 1 , lang : Drupal.settings.pathPrefix},
585            success: function (response) {
586                $('.wrapper-figure-layers').html(response.html);
587
588                Drupal.settings.mapLayers = response.layers;
589                FeatureLocationLayers.resetKmls(kmlInstance);
590                self.kmlInstance = FeatureLocationLayers.fillAllKmls();
591                markersDisplay(showHideMarkers.visible);
592                toggleLayers();
593            },
594            error: function (err) {
595                console.log('error');
596                console.log(err);
597            }
598        });
599
600    };
601    self.updateChapter = function (data) {
602        var lang = 'he';
603        if (Drupal.settings.pathPrefix.slice(0, -1) == 'en') {
604            lang = 'en';
605        } else if (Drupal.settings.pathPrefix.slice(0, -1) == 'es') {
606            lang = 'es';
607        }
608        data['lang']= lang;
609        $.ajax({
610            type: 'POST',
611            dataType: 'json',
612            url: urlText,
613            data: data,
614            success: function (response) {
615                nextChapter.data('next-chapter', response.nextChapter);
616                nextChapter.data('prev-chapter', response.prevChapter);
617                $('.map-biblicle-text').html(response.text);
618                multiChapterTitle.text(response.multiTitle);
619                biblicleTextWrapper.scrollTop(0);
620            },
621            error: function (err) {
622                console.log('error');
623                console.log(err);
624            }
625        });
626
627    };
628
629    function toggleLayers() {
630        if (lobbyContainer.hasClass('layer-close')) {
631            $('.wrapper-images-layers').hide();
632        }
633    }
634
635    function markersDisplay(visible) {
636
637        if (!visible) {
638            $('.overlay-img[data-layer-type = markers]').find('.overlay-img-background').hide();
639        }
640    }
641
642
643    this.loadLocationDetails = function (nid, callback) {
644        jQuery.ajax({
645            url: '/' + Drupal.settings.pathPrefix + 'ajax/map/locationDetails',
646            data: {
647                nid: nid
648            },
649            dataType: 'json',
650            success: function (data) {
651                if (callback) callback(data);
652            },
653            error: function () {
654                console.error('Failed to load location details');
655            }
656        });
657    };
658}
659;
660var globalMarkers = [];
661var closeInfo = false;
662
663function isPageMap() {
664    var $ = window.jQuery;
665    return $('body').hasClass('node-type-location') || window.location.pathname.indexOf('map') !== -1;
666}
667function HerzogMapObj(settings) {
668
669    //////////////////////////////////////////////////////////   properties   //////////////////////////////////////////////////////
670    var $ = window.jQuery;
671    var self = this;
672
673    var featureAjaxLocation = new FeatureLocationAjax();
674
675    var isOpenInfo = false;
676    var closeInfoInLocationPage = false;
677
678    var ddlBooks = $('.lobbyContainer .ddlBooksFilter');
679    var ddlChapters = $('.lobbyContainer .ddlChaptersFilter');
680    var ddlBooksRange = $('.book-filter-box .ddlBooksFilterRange');
681    var ddlChaptersRange = $('.book-filter-box .ddlChaptersFilterRange');
682    var timelineItems = $('.lobbyContainer .timelineBox .periodselect');
683    var resetFilter = $('.lobbyContainer .clearFilter');
684    var closeButton = $('.close-button');
685    var infoSelector = $('#draggable');
686    var showHideMarkers = $('.lobbyContainer .showHideMarkers');
687    var modernMapToggle = $('#modern-map');
688    var modernMapToggleText = $('.figcaption-modern-map');
689    var figcaptionBiblicalMap = $('.figcaption-biblical-map');
690    var figcaptionModernMap = $('.figcaption-modern-map');
691    var filterBoxLabel = $('.filterBox .box-label');
692    var clearPeriodFilterButton = $('.period-filter-box .clear-filter');
693    var closeLayers = $('.close-layers');
694    var showFilterRange = $('.book-filter-box .addRange');
695    var showText = $('.showText');
696    var lobbyContainer = $('.lobbyContainer');
697    var goToText = $('.goToText');
698    var multiChapterNext = $('.multi-chapter-next');
699    var multiChapterPrev = $('.multi-chapter-prev');
700    var multiChapter = $('.multi-chapter');
701
702    const RESET_HARD = 10;
703
704
705
706    var filterType = {
707        NONE: 0,        // show all items
708        BOOK: 1,        // show items by selected book
709        CHAPTER: 2,     // show items by selected book and chapter
710        PERIOD: 3,      // show items by selected periods
711        EMPTYPERIOD: 4  // used in location page only
712    };
713
714    var filterObj = {
715        start: '',
716        type: filterType.NONE,
717        book: '',
718        chapter: '',
719        book_to: '',
720        chapter_to: '',
721        verse: '000',   // not in use by now
722        periods: []
723    };
724
725    var locationType = {
726        CITY: 'city',
727        REGION: 'region',
728        COUNTRY: 'country'
729    };
730
731    var infoBoxOptions = {
732        disableAutoPan: false
733        , maxWidth: 0
734        , zIndex: null
735        , boxClass: !isPageMap() ? 'infoBoxWindowPage' : 'infoBoxWindow info-box'
736        , closeBoxMargin: "10px 2px 2px 2px"
737        , closeBoxURL: ""//"http://www.google.com/intl/en_us/mapfiles/close.gif"
738        , infoBoxClearance: new google.maps.Size(1, 1)
739        , isHidden: false
740        , pane: "floatPane"
741        , enableEventPropagation: false
742        , pixelOffset: new google.maps.Size(-100, -40)
743        , alignBottom: true
744
745    };
746
747    var currentMap = undefined;                   // google map object
748    var currentLocation = undefined;                   // holds the nid of the node if in location page. in lobby page this property not set
749    var infoBox = new InfoBox(infoBoxOptions); // google map info window
750    var userLocationMarker = null;                // holds the user location marker
751    var markersCollection = [];                          // holds all the markers that are drawn on the map. updated when filter changes
752    var markersCollectionObj = {};                          // holds all the markers that are drawn on the map. updated when filter changes
753    var globalCollection = settings.mappedLocations || {};
754    var booksCollection = settings.booksWithChaptersArr || [];
755    var filteredArr = [];
756    var isHomePage = (Drupal.settings.urlArgs.indexOf('home') != -1) ? true : false;
757    var mapTypeRoad = true;
758    var lastMapType = "roadmap";
759    var isBiblicalMap = true;
760    var mainContainer = $('.page-map .main-container, .node-type-location .main-container');
761    var overlayImg = $('.wrapper-figure-layers .overlay-img');
762    var wrapperLayers = $('.figure-layers');
763    var viewTanach = $('#view-tanach');
764    var biblicleTextWrapper = $('.map-biblicle-text-wrapper');
765    var nextChapter = $('.next-chapter');
766    var clearFilterBook = $('.clear-filter-book');
767    var moreMatchesSlide = $('.map-references');
768    var filterWrapper = $('.filter-wrapper');
769    var searchResults = $('.map-references .search-results-container');
770    var kmlInstance = FeatureLocationLayers.fillAllKmls();
771    var filterBox = $('.filterBox.book-filter-box');
772    var endOfBooks = 38000350;
773    var nextChapterText = $('.next-chapter-text');
774    var multiChapterTitle = $('.multi-chapter-title');
775
776
777    var mapTypeIndex = 0;
778    var mapTypeView = [
779        google.maps.MapTypeId.TERRAIN,
780        google.maps.MapTypeId.ROADMAP
781    ];
782    var checkRange = function (filterObj) {
783        // Customer Selected Same Range
784        if (filterObj.book == filterObj.book_to && filterObj.chapter == filterObj.chapter_to) {
785            switchMultiChapter('hide', filterObj);
786        } else {
787            switchMultiChapter(false, filterObj);
788        }
789    };
790    //////////////////////////////////////////////////////////   public methods     /////////////////////////////////////////////////
791    self.modernMap = function () {
792        lastMapType = currentMap.getMapTypeId();
793        if (isBiblicalMap) {
794            currentMap.setOptions({ styles: init_map_styles_roads() });
795            currentMap.setMapTypeId(lastMapType);
796            modernMapToggle.addClass("biblical-map-class");
797            modernMapToggle.removeClass("modern-map-class");
798            figcaptionBiblicalMap.show();
799            figcaptionModernMap.hide();
800        }
801        else {
802
803            currentMap.setOptions({ styles: init_map_styles() });
804            currentMap.setMapTypeId(lastMapType);
805            modernMapToggle.addClass("modern-map-class");
806            modernMapToggle.removeClass("biblical-map-class");
807            figcaptionBiblicalMap.hide();
808            figcaptionModernMap.show();
809        }
810
811        isBiblicalMap = !isBiblicalMap;
812    };
813
814    modernMapToggle.on('click', self.modernMap);
815    modernMapToggleText.on('click', self.modernMap);
816    figcaptionBiblicalMap.on('click', self.modernMap);
817
818    viewTanach.on('change', function () {
819        // Check If The Chapter Due To Open Or Not
820        if (!biblicleTextWrapper.is(':visible')) {
821            ddlChaptersEvent(ddlBooksRange, this, true);
822            featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
823            clearFilterBook.show();
824            clearPeriodFilterButton.hide();
825            //nextChapter.show();
826        } else {
827            //nextChapter.hide();
828        }
829        biblicleTextWrapper.toggle();
830        biblicleTextWrapper.perfectScrollbar();
831        biblicleTextWrapper.scrollTop(1);
832        if (nextChapterText.is(':visible')) {
833            nextChapter.css('cursor', 'pointer');
834        } else {
835            nextChapter.css('cursor', 'auto');
836        }
837        checkRange(filterObj);
838    });
839    filterWrapper.on('click', '.marker-location', function (event) {
840
841        if (!isMobile(window.innerWidth)) {
842            var locationId = $(this).data('location-id');
843            var location = Drupal.settings.mapSettings.mappedLocations[locationId];
844
845            if (!location.full_data_loaded) {
846                featureAjaxLocation.loadLocationDetails(location.nid, function (data) {
847                    // Update the location object with full data
848                    jQuery.extend(Drupal.settings.mapSettings.mappedLocations[locationId], data);
849                    var infoHtml = create_info_html(Drupal.settings.mapSettings.mappedLocations[locationId], location.nid);
850                    fillInfoBox(infoBox, infoHtml, markersCollectionObj[location.nid], currentMap);
851                });
852            } else {
853                var infoHtml = create_info_html(location, location.nid);
854                fillInfoBox(infoBox, infoHtml, markersCollectionObj[location.nid], currentMap);
855            }
856            event.preventDefault();
857        }
858    });
859    moreMatchesSlide.on('click', 'ol li h3.title-more-matches a', function () {
860        $(this).parent().next('ol').slideToggle();
861    });
862
863    nextChapter.on('click', function () {
864        if (!nextChapterText.is(':visible')) {
865            return false;
866        }
867        var $next = $('.next-chapter').data('next-chapter');
868        var data = getChapter($next);
869        featureAjaxLocation.updateChapter(data);
870        updateLinkToTanach();
871
872        var qsParams = {
873            book: data.book,
874            chapter: data.chapter
875        };
876        ddlBooks.setSelected(data.book);
877        ddlChapters.setSelected(data.chapter);
878        init_filter(qsParams);
879        filterObj.type = filterType.CHAPTER;
880        filterObj.book = data.book;
881        filterObj.chapter = data.chapter;
882        setStartChapter();
883        filter_locations();
884
885    });
886
887    function switchMultiChapter(single, filterObj) {
888        // Hide All Buttons
889        if (single === 'hide' || !biblicleTextWrapper.is(':visible')) {
890            multiChapter.hide();
891            nextChapter.hide();
892            nextChapterText.hide();
893        } else {
894            // No Range Button
895            if (filterObj === undefined || filterObj.chapter_to === undefined || filterObj.chapter_to === '') {
896                nextChapterText.show();
897                nextChapter.show();
898                multiChapter.hide();
899            } else {
900                // Next/Prev Button
901                if (single) {
902                    nextChapterText.show();
903                    multiChapter.hide();
904                }
905                else {
906                    nextChapterText.hide();
907                    multiChapter.show();
908                }
909            }
910        }
911    }
912
913    function lPadIndex(index) {
914        var splieIndex = index.split('.');
915        splieIndex[0] = '000' + splieIndex[0];
916        splieIndex[1] = '000' + splieIndex[1];
917        return parseInt(splieIndex.join(''));
918    }
919
920    function getChapter(index) {
921
922        var from = index.split('.');
923        return {
924            book: from[0],
925            chapter: from[1],
926            nextChapter: 0
927        };
928    }
929
930    multiChapterNext.on('click', function () {
931        multiChapterPrev.show();
932        var $next = $('.next-chapter').data('next-chapter');
933        var next = lPadIndex($next);
934        var end = '' + filterObj.book_to + '.' + filterObj.chapter_to + '.0';
935        end = lPadIndex(end);
936        var data = getChapter($next);
937        data['isMulti'] = 1;
938        if (next <= end) {
939            if (next == end) {
940                $(this).hide();
941            }
942            featureAjaxLocation.updateChapter(data);
943        }
944    });
945    multiChapterPrev.on('click', function () {
946        multiChapterNext.show();
947        var $prev = $('.next-chapter').data('prev-chapter');
948        var prev = lPadIndex($prev);
949        var start = lPadIndex(filterObj.start);
950        var data = getChapter($prev);
951
952        data['isMulti'] = 1;
953        if (prev >= start && prev != endOfBooks) {
954            if (prev == start) {
955                $(this).hide();
956            }
957            featureAjaxLocation.updateChapter(data);
958        }
959    });
960
961
962
963    self.refreshMarker = function (marker, currentItem) {
964        if (marker) {
965            closeInfo = true;
966            marker.setMap(null);
967            draw_marker(currentItem, currentItem.nid);
968        }
969    }
970
971    self.init = function (mapcontainer) {
972
973        if (!mapcontainer) {
974            mapcontainer = 'mapContainer'
975        }
976
977        if (!self.isMapContainerExists()) {
978            return false;
979        }  // abort init - no map container
980
981        if (settings.currentLocation) {
982            currentLocation = globalCollection[settings.currentLocation];
983
984
985            if (currentLocation) {
986                var objData = {
987                    references: 1,
988                    cityName: currentLocation.title,
989                    nid: currentLocation.nid,
990                    lang: !Drupal.settings.pathPrefix ? '' : Drupal.settings.pathPrefix.slice(0, -1)
991                };
992                updateReferences(objData);
993                filterBox.addClass('open');
994            }
995
996        }
997
998        var positionControl = (Drupal.settings.pathPrefix == 'en/' || Drupal.settings.pathPrefix == 'es/')
999            ? google.maps.ControlPosition.RIGHT_BOTTOM : google.maps.ControlPosition.LEFT_BOTTOM;
1000        var positionControlTop = (Drupal.settings.pathPrefix == 'en/' || Drupal.settings.pathPrefix == 'es/')
1001            ? google.maps.ControlPosition.RIGHT_TOP : google.maps.ControlPosition.LEFT_TOP;
1002        var positionControlAddress = (Drupal.settings.pathPrefix == 'en/' || Drupal.settings.pathPrefix == 'es/')
1003            ? google.maps.ControlPosition.TOP_RIGHT : google.maps.ControlPosition.TOP_LEFT;
1004
1005        var mapOptions = {
1006            center: {
1007                lat: currentLocation && currentLocation.latitude ? currentLocation.latitude : settings.centerLatitude,
1008                lng: currentLocation && currentLocation.longtitude ? currentLocation.longtitude : settings.centerLongtitude
1009            },
1010
1011            minZoom: settings.minZoom,
1012            maxZoom: settings.maxZoom,
1013            zoom: settings.defaultZoom,
1014
1015            streetViewControl: isPageMap(),
1016            scrollwheel: true,
1017            scaleControl: true,
1018            streetViewControlOptions: {
1019                position: positionControl
1020            },
1021            mapTypeControlOptions: {
1022                position: positionControlTop,
1023                style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR
1024            },
1025            scaleControlOptions: {
1026                position: positionControl
1027            },
1028            zoomControlOptions: {
1029                position: positionControl
1030            },
1031            zoomControl: true,
1032            mapTypeControl: !isHomePage,
1033            mapTypeId: mapTypeView[mapTypeIndex],
1034            disableDefaultUI: isHomePage,
1035            fullscreenControl: false,
1036
1037            linksControl: false,
1038            tilt: 45,
1039            panControl: false,
1040            enableCloseButton: true,
1041        };
1042
1043
1044        mapcontainer = document.getElementById(mapcontainer);
1045
1046        currentMap = new google.maps.Map(mapcontainer, mapOptions);
1047
1048        if (mapTypeRoad) {
1049            currentMap.setOptions({ styles: init_map_styles() });
1050        }
1051        else {
1052            currentMap.setOptions({ styles: init_map_styles_roads() });
1053        }
1054
1055        // Initialize User Geolocation features
1056        injectLocationStyles();
1057        setupUserLocation(currentMap, settings, positionControl);
1058
1059        google.maps.event.addListener(currentMap, 'zoom_changed', function () {
1060            set_locations_on_map();
1061        });
1062
1063        var thePanorama = currentMap.getStreetView();
1064
1065        thePanorama.setOptions({
1066            addressControlOptions: {
1067                position: positionControlAddress
1068            }, fullscreenControl: false
1069        });
1070
1071        google.maps.event.addListener(currentMap, "maptypeid_changed", function () {
1072            //set_locations_on_map();
1073        });
1074
1075        google.maps.event.addListener(infoBox, 'domready', function () {
1076            $(".info-box").draggable({ handle: "header" });
1077        });
1078
1079
1080        showHideMarkers.visible = true;
1081
1082        init_timeline();
1083        init_ddl(ddlBooks, ddlChapters, 0, false);
1084        init_ddl(ddlBooksRange, ddlChaptersRange, 0, true);
1085
1086        if (currentLocation && currentLocation.periods && currentLocation.periods.length > 0) {
1087            // location page
1088            resetFilter.hide();
1089            init_location();
1090        }
1091        else {
1092            /*
1093            * if user came from tanach with filter book
1094            * */
1095            var qsParams = {
1096                type: getQueryVariable('t'),
1097                book: getQueryVariable('b'),
1098                chapter: getQueryVariable('c'),
1099                periods: getQueryVariable('p')
1100            };
1101            if (qsParams.book || qsParams.chapter) {
1102                showText.show();
1103                goToText.show();
1104                clearFilterBook.show();
1105
1106                featureAjaxLocation.updateTanachText(filterObj);
1107                featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
1108            }
1109            init_filter(qsParams);
1110
1111        }
1112
1113
1114    };
1115
1116    self.setNewCenterByLocations = function (locations) {
1117        var lons = [];
1118        var lats = [];
1119        var visibleLocations = [];
1120
1121        if (locations !== undefined) {
1122            Object.keys(locations).forEach(function (key) {
1123                var loc = locations[key];
1124                if (loc.latitude && loc.longtitude) {
1125                    // Check if we already have this location (by lat/lng) to avoid duplicates
1126                    var isDuplicate = false;
1127                    for (var i = 0; i < visibleLocations.length; i++) {
1128                        if (visibleLocations[i].latitude == loc.latitude && visibleLocations[i].longtitude == loc.longtitude) {
1129                            isDuplicate = true;
1130                            break;
1131                        }
1132                    }
1133
1134                    if (!isDuplicate) {
1135                        visibleLocations.push(loc);
1136                        lats.push(loc.latitude);
1137                        lons.push(loc.longtitude);
1138                    } else {
1139                        console.log('Skipping duplicate location for bounds:', loc.title);
1140                    }
1141                }
1142            });
1143
1144            console.log('Visible Locations Count:', visibleLocations.length);
1145
1146            if (visibleLocations.length > 1) {
1147                latCenter = (Math.min.apply(Math, lats) + Math.max.apply(Math, lats)) / 2;
1148                lngCenter = (Math.min.apply(Math, lons) + Math.max.apply(Math, lons)) / 2;
1149
1150                minBound = new google.maps.LatLng(Math.max.apply(null, lats), Math.max.apply(Math, lons));
1151                maxBound = new google.maps.LatLng(Math.min.apply(null, lats), Math.min.apply(Math, lons));
1152
1153                herzogMap.setNewCenter(latCenter, lngCenter, [minBound, maxBound]);
1154            } else if (visibleLocations.length === 1) {
1155                var loc = visibleLocations[0];
1156                var zoom = loc.zoomLevel !== undefined ? loc.zoomLevel : (loc.minZoomLevel !== undefined ? loc.minZoomLevel : 10);
1157                console.log('Zooming to single location:', loc.title, zoom);
1158                herzogMap.setNewCenter(loc.latitude, loc.longtitude, null, zoom);
1159            } else if (Object.keys(locations).length > 0) {
1160                // Fallback if no cities but other locations exist (e.g. regions only)
1161                // Maybe show them all?
1162                console.log('No visible cities, fitting all locations.');
1163                lats = []; lons = [];
1164                Object.keys(locations).forEach(function (key) {
1165                    lats.push(locations[key].latitude);
1166                    lons.push(locations[key].longtitude);
1167                });
1168                if (lats.length > 0) {
1169                    minBound = new google.maps.LatLng(Math.max.apply(null, lats), Math.max.apply(Math, lons));
1170                    maxBound = new google.maps.LatLng(Math.min.apply(null, lats), Math.min.apply(Math, lons));
1171                    herzogMap.setNewCenter(lats[0], lons[0], [minBound, maxBound]);
1172                }
1173            }
1174        }
1175    };
1176
1177    self.setNewCenter = function (lat, lng, extBounds, zoom) {
1178        currentMap.setCenter(new google.maps.LatLng(lat, lng));
1179        if (zoom) {
1180            currentMap.setZoom(zoom);
1181        }
1182        if (extBounds) {
1183            var bounds = new google.maps.LatLngBounds();
1184            for (var i = 0; i < extBounds.length; i++) {
1185                bounds.extend(extBounds[i]);
1186            }
1187            currentMap.fitBounds(bounds);
1188        }
1189    }
1190
1191    self.isMapContainerExists = function () {
1192        return (document.getElementById('mapContainer') || document.getElementById('mapContainerDaily')) ? true : false;
1193    }
1194
1195    self.reset = function (newLocations, newBooks) {
1196        if (newLocations) {
1197            globalCollection = undefined;
1198            globalCollection = newLocations;
1199        }
1200        if (newBooks) {
1201            booksCollection = undefined;
1202            booksCollection = newBooks;
1203        }
1204        currentMap.setZoom(settings.defaultZoom);
1205        currentMap.setCenter(new google.maps.LatLng(settings.centerLatitude, settings.centerLongtitude));
1206        reset_filter();
1207    };
1208
1209    //////////////////////////////////////////////////////////   private methods     /////////////////////////////////////////////////
1210
1211    var getLocalizedMessage = function (key) {
1212        var lang = 'he';
1213        if (Drupal.settings.pathPrefix === 'en/') {
1214            lang = 'en';
1215        } else if (Drupal.settings.pathPrefix === 'es/') {
1216            lang = 'es';
1217        }
1218        var messages = {
1219            denied: {
1220                he: "נדרשת גישה למיקום כדי להציג את המיקום שלך על המפה.",
1221                en: "Location access is required to show your position on the map.",
1222                es: "Se requiere acceso a la ubicación para mostrar su posición en el mapa."
1223            },
1224            timeout: {
1225                he: "לא ניתן למצוא את המיקום שלך. אנא בדוק את אות ה-GPS + חיבור האינטרנט הסלולרי שלך ונסה שוב.",
1226                en: "Unable to find your location. Please check your GPS signal + mobile internet connection and try again.",
1227                es: "No se pudo encontrar su ubicación. Verifique su señal de GPS + conexión a Internet móvil e intente nuevamente."
1228            },
1229            outOfBounds: {
1230                he: "אתה נמצא מחוץ לאזור הכיסוי של המפה.",
1231                en: "You are outside the map's coverage area.",
1232                es: "Se encuentra fuera del área de cobertura del mapa."
1233            }
1234        };
1235        return messages[key] ? (messages[key][lang] || messages[key]['en']) : '';
1236    };
1237
1238    var showToastNotification = function (message) {
1239        // Remove existing toast if any
1240        $('.map-toast-notification').remove();
1241
1242        var toast = $('<div class="map-toast-notification"></div>').text(message);
1243        $('#map-container-wrapper').append(toast);
1244
1245        // Trigger reflow to apply transitions
1246        toast[0].offsetHeight;
1247
1248        toast.addClass('show');
1249
1250        setTimeout(function () {
1251            toast.removeClass('show');
1252            setTimeout(function () {
1253                toast.remove();
1254            }, 300);
1255        }, 5000);
1256    };
1257
1258    var injectLocationStyles = function () {
1259        if (document.getElementById('my-location-styles')) {
1260            return;
1261        }
1262        var head = document.getElementsByTagName("head")[0];
1263        var newStyle = document.createElement("style");
1264        newStyle.setAttribute("id", "my-location-styles");
1265        newStyle.setAttribute("type", "text/css");
1266        var cssText =
1267            ".my-location-control-container { margin: 10px; z-index: 10; }\n" +
1268            ".my-location-btn { background-color: #fff; border: none; outline: none; width: 40px; height: 40px; border-radius: 50%; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); cursor: pointer; display: flex; align-items: center; justify-content: center; position: relative; padding: 0; transition: background-color 0.2s ease; }\n" +
1269            ".my-location-btn:hover { background-color: #f4f4f4; }\n" +
1270            ".my-location-btn .gps-icon { width: 20px; height: 20px; fill: none; stroke: #5f6368; stroke-width: 2; transition: stroke 0.2s ease; }\n" +
1271            ".my-location-btn .gps-icon .gps-center { fill: #5f6368; transition: fill 0.2s ease; }\n" +
1272            ".my-location-btn.active .gps-icon { stroke: #1A73E8; }\n" +
1273            ".my-location-btn.active .gps-icon .gps-center { fill: #1A73E8; }\n" +
1274            ".my-location-btn .gps-spinner { display: none; width: 20px; height: 20px; border: 2px solid #1A73E8; border-top: 2px solid transparent; border-radius: 50%; animation: gps-spin 1s linear infinite; position: absolute; }\n" +
1275            ".my-location-btn.loading .gps-icon { visibility: hidden; }\n" +
1276            ".my-location-btn.loading .gps-spinner { display: block; }\n" +
1277            "@keyframes gps-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n" +
1278            ".map-toast-notification { position: absolute; top: 20px; left: 50%; transform: translateX(-50%) translateY(-20px); background-color: rgba(33, 33, 33, 0.9); color: #fff; padding: 12px 24px; border-radius: 8px; font-size: 14px; z-index: 2000; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); opacity: 0; transition: all 0.3s ease; text-align: center; pointer-events: none; max-width: 90%; width: auto; font-family: sans-serif; }\n" +
1279            ".map-toast-notification.show { transform: translateX(-50%) translateY(0); opacity: 1; }";
1280        var texNode = document.createTextNode(cssText);
1281        try {
1282            newStyle.appendChild(texNode);
1283        }
1284        catch (e) {
1285            newStyle.styleSheet.cssText = cssText;
1286        }
1287        head.appendChild(newStyle);
1288    };
1289
1290    var setupUserLocation = function (map, settings, positionControl) {
1291        if (!navigator.geolocation) {
1292            return; // Geolocation not supported by browser
1293        }
1294
1295        // Requirement 4: Button is only added to the map interface on mobile devices.
1296        if (!isMobile(window.innerWidth)) {
1297            return;
1298        }
1299
1300        var controlDiv = document.createElement('div');
1301        controlDiv.className = 'my-location-control-container';
1302
1303        var controlUI = document.createElement('button');
1304        controlUI.className = 'my-location-btn';
1305        controlUI.title = Drupal.t('My Location');
1306        controlUI.type = 'button';
1307
1308        controlUI.innerHTML = '<svg viewBox="0 0 24 24" class="gps-icon"><circle cx="12" cy="12" r="8"></circle><circle cx="12" cy="12" r="3" class="gps-center"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line></svg>
1308' +
1309            '<div class="gps-spinner"></div>';
1310
1311        controlDiv.appendChild(controlUI);
1312        map.controls[positionControl].push(controlDiv);
1313
1314        var $btn = $(controlUI);
1315
1316        google.maps.event.addDomListener(controlUI, 'click', function () {
1317            // Requirement 5: Show a loading state (spinner) on the button
1318            $btn.addClass('loading');
1319            $btn.removeClass('active');
1320
1321            // Requirement 2: Geolocation request
1322            navigator.geolocation.getCurrentPosition(
1323                function (position) {
1324                    $btn.removeClass('loading');
1325
1326                    var userLat = position.coords.latitude;
1327                    var userLng = position.coords.longitude;
1328
1329                    // Requirement 7: Out-of-bounds Check
1330                    var swLat = settings.southWestBoundLat;
1331                    var swLng = settings.southWestBoundLong;
1332                    var neLat = settings.northEastBoundLat;
1333                    var neLng = settings.northEastBoundLong;
1334
1335                    var userLatLng = new google.maps.LatLng(userLat, userLng);
1336                    var bounds = new google.maps.LatLngBounds(
1337                        new google.maps.LatLng(swLat, swLng),
1338                        new google.maps.LatLng(neLat, neLng)
1339                    );
1340
1341                    if (!bounds.contains(userLatLng)) {
1342                        showToastNotification(getLocalizedMessage('outOfBounds'));
1343                        return;
1344                    }
1345
1346                    // Requirement 8 & 9: Blue Dot Representation + Anchor Stability
1347                    if (userLocationMarker) {
1348                        userLocationMarker.setPosition(userLatLng);
1349                    } else {
1350                        userLocationMarker = new google.maps.Marker({
1351                            position: userLatLng,
1352                            map: map,
1353                            icon: {
1354                                url: 'data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="%231A73E8" opacity="0.25"/><circle cx="12" cy="12" r="6" fill="%23FFFFFF"/><circle cx="12" cy="12" r="5" fill="%231A73E8"/></svg>',
1355                                size: new google.maps.Size(24, 24),
1356                                origin: new google.maps.Point(0, 0),
1357                                anchor: new google.maps.Point(12, 12)
1358                            },
1359                            zIndex: 9999
1360                        });
1361                    }
1362
1363                    // Requirement 6: Center and zoom to maximum predefined zoom level
1364                    map.setCenter(userLatLng);
1365                    map.setZoom(12);
1366
1367                    $btn.addClass('active');
1368                },
1369                function (error) {
1370                    $btn.removeClass('loading');
1371
1372                    if (error.code === error.PERMISSION_DENIED) {
1373                        // Requirement 2: Denied callback
1374                        showToastNotification(getLocalizedMessage('denied'));
1375                    } else if (error.code === error.TIMEOUT || error.code === error.POSITION_UNAVAILABLE) {
1376                        // Requirement 3: Timeout / Unavailable callback
1377                        showToastNotification(getLocalizedMessage('timeout'));
1378                    } else {
1379                        showToastNotification(getLocalizedMessage('timeout'));
1380                    }
1381                },
1382                {
1383                    enableHighAccuracy: true,
1384                    timeout: 10000, // Requirement 3: 10 seconds timeout
1385                    maximumAge: 0
1386                }
1387            );
1388        });
1389
1390        if (isPageMap() && isMobile(window.innerWidth)) {
1391            if (!window.localStorage.getItem('geoPermissionRequested')) {
1392                navigator.geolocation.getCurrentPosition(
1393                    function (position) {
1394                        window.localStorage.setItem('geoPermissionRequested', '1');
1395
1396                        var userLat = position.coords.latitude;
1397                        var userLng = position.coords.longitude;
1398
1399                        var swLat = settings.southWestBoundLat;
1400                        var swLng = settings.southWestBoundLong;
1401                        var neLat = settings.northEastBoundLat;
1402                        var neLng = settings.northEastBoundLong;
1403
1404                        var userLatLng = new google.maps.LatLng(userLat, userLng);
1405                        var bounds = new google.maps.LatLngBounds(
1406                            new google.maps.LatLng(swLat, swLng),
1407                            new google.maps.LatLng(neLat, neLng)
1408                        );
1409
1410                        if (!bounds.contains(userLatLng)) {
1411                            showToastNotification(getLocalizedMessage('outOfBounds'));
1412                            return;
1413                        }
1414
1415                        if (userLocationMarker) {
1416                            userLocationMarker.setPosition(userLatLng);
1417                        } else {
1418                            userLocationMarker = new google.maps.Marker({
1419                                position: userLatLng,
1420                                map: map,
1421                                icon: {
1422                                    url: 'data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="%231A73E8" opacity="0.25"/><circle cx="12" cy="12" r="6" fill="%23FFFFFF"/><circle cx="12" cy="12" r="5" fill="%231A73E8"/></svg>',
1423                                    size: new google.maps.Size(24, 24),
1424                                    origin: new google.maps.Point(0, 0),
1425                                    anchor: new google.maps.Point(12, 12)
1426                                },
1427                                zIndex: 9999
1428                            });
1429                        }
1430                        map.setCenter(userLatLng);
1431                        map.setZoom(12);
1432                        $btn.addClass('active');
1433                    },
1434                    function (error) {
1435                        window.localStorage.setItem('geoPermissionRequested', '1');
1436                        if (error.code === error.PERMISSION_DENIED) {
1437                            controlUI.style.display = 'none';
1438                        }
1439                    },
1440                    {
1441                        enableHighAccuracy: true,
1442                        timeout: 10000,
1443                        maximumAge: 0
1444                    }
1445                );
1446            }
1447        }
1448    };
1449
1450    var init_location = function () {
1451
1452
1453        timelineItems.each(function (index, element) {
1454            var result = $.grep(currentLocation.periods, function (item, index) {
1455                return item.tid === element.period;
1456            });
1457            if (result.length === 0) {
1458                //$(element).attr('disabled', 'disabled');
1459                //$(element).addClass('disabled');
1460                // $(element).unbind("click");
1461            }
1462            else {
1463                filterObj.periods.push(element.period);
1464            }
1465        });
1466        if (filterObj.periods.length > 0) {
1467            filterObj.type = filterType.PERIOD;
1468            timelineItems.activateByFilter();
1469        }
1470        filter_locations();
1471
1472    };
1473    ////////////////////////////////////////////////////////////////
1474    var init_filter = function (qsParams) {
1475
1476        filterObj.type = qsParams.type ? parseInt(qsParams.type) : filterType.NONE;
1477        if ((filterObj.type === filterType.BOOK || filterObj.type === filterType.CHAPTER) && qsParams.book) {
1478            filterObj.book = qsParams.book;
1479            ddlBooks.setSelected(filterObj.book);
1480            var selectedBook = booksCollection[filterObj.book];
1481            ddlChapters.bindByBook(selectedBook, filterObj.book);
1482
1483            if (filterObj.type === filterType.CHAPTER && qsParams.chapter) {
1484                filterObj.chapter = qsParams.chapter;
1485                ddlChapters.setSelected(filterObj.chapter);
1486            }
1487        }
1488        if (filterObj.type === filterType.PERIOD && qsParams.periods && qsParams.periods.length > 0) {
1489            filterObj.periods = qsParams.periods;
1490            timelineItems.activateByFilter();
1491        }
1492        filter_locations();
1493    };
1494    /////////////////////////////////////////////////////////
1495
1496    var init_ddl = function (ddlBooks, ddlChapters, selectedValue, range) {
1497
1498        var disabled = '';
1499        var selected = '';
1500        if (booksCollection && booksCollection.length > 0) {
1501            ddlBooks.append("<option value='-1'>
1501" + Drupal.t('Book') + "</option>");
1502
1503            if (range) {
1504                ddlChapters.append("<option value='-1' >" + Drupal.t('To Chapter') + "</option>");
1505            }
1506
1507            else {
1508                ddlChapters.append("<option value='-1' >" + Drupal.t('Chapter') + "</option>");
1509            }
1510
1511            $(booksCollection).each(function (index, item) {
1512                if (index < selectedValue) {
1513                    disabled = 'disabled';
1514                } else {
1515                    disabled = '';
1516                }
1517                if (index == parseInt(filterObj.book)) {
1518                    selected = 'selected';
1519
1520                } else {
1521                    selected = '';
1522                }
1523                ddlBooks.append(
1524                    "<option " + selected + " " + disabled + " value='" + index + "'>" + item.title + "</option>"
1525                );
1526            });
1527        }
1528
1529        // add setter to ddl
1530        ddlBooks.setSelected = function (valueToSet) {
1531            this.find('option').each(function () {
1532                if ($(this).val() === valueToSet) {
1533                    $(this).attr('selected', 'selected');
1534                    ddlBooks.val(valueToSet);
1535                }
1536            });
1537        };
1538
1539        ddlBooks.msDropDown();
1540
1541        ddlChapters.msDropDown();
1542
1543        // add setter to ddl
1544        ddlChapters.setSelected = function (valueToSet) {
1545            this.find('option').each(function () {
1546                if ($(this).val() === valueToSet) {
1547                    $(this).attr('selected', 'selected');
1548                    ddlChapters.val(valueToSet);
1549                }
1550            });
1551        };
1552        disabled = '';
1553
1554        ddlChapters.bindByBook = function (book, bookIndex, reset) {
1555
1556            $(book.chapters).each(function (index, chapter) {
1557                if (filterObj.chapter) {
1558                    var selectedChapter = parseInt(filterObj.chapter);
1559                    if ((index < selectedChapter) && parseInt(filterObj.book_to) == parseInt(filterObj.book)) {
1560                        if (reset != RESET_HARD) {
1561                            disabled = 'disabled';
1562                        }
1563
1564                    }
1565                    else {
1566                        disabled = '';
1567                    }
1568                }
1569                ddlChapters.append("<option " + disabled + " value='" + index + "'>" + chapter + "</option>");
1570            });
1571        };
1572
1573        ddlChapters.clear = function () {
1574            this.attr('value', '');
1575            this.find('option:not(:first)').remove();
1576        };
1577
1578    };
1579    ///////////////////////////////////////////////////////////////
1580
1581    var init_timeline = function () {
1582
1583        timelineItems.each(function (index, element) {
1584            element.period = $(element).attr('data-period');
1585
1586            $(element).on('click', function () {
1587                ddlBooks.setSelected('-1');
1588                ddlChapters.clear();
1589                ddlBooksRange.setSelected('-1');
1590                ddlChaptersRange.clear();
1591
1592                if ($.inArray(element.period, filterObj.periods) > -1) {
1593                    $(element).removeClass('active');
1594                    filterObj.periods.splice($.inArray(element.period, filterObj.periods), 1);
1595                }
1596                else {
1597                    $(element).addClass('active');
1598                    filterObj.periods.push(element.period);
1599                }
1600
1601                var allExceptClicked = jQuery.grep(timelineItems, function (item, index) {
1602                    return (item.period !== element.period);
1603                });
1604
1605                $(allExceptClicked).each(function (index, element) {
1606                    if ($.inArray(element.period, filterObj.periods) === -1 && $(element).hasClass('active')) {
1607                        filterObj.periods.push(element.period);
1608                    }
1609                });
1610
1611                if (filterObj.periods.length > 0) {
1612                    filterObj.type = filterType.PERIOD;
1613                    if (filterObj.periods.length > 1) {
1614                        filterObj.periods.sort();
1615                    }
1616
1617                    clearPeriodFilterButton.css("display", "table-cell");
1618                }
1619                else if (currentLocation) {
1620                    filterObj.type = filterType.EMPTYPERIOD;
1621                    clearPeriodFilterButton.hide();
1622                } else {
1623                    filterObj.type = filterType.NONE;
1624                    clearPeriodFilterButton.hide();
1625                }
1626                featureAjaxLocation.updateLayersByPeriods(filterObj, 
1626kmlInstance, showHideMarkers);
1627                filter_locations();
1628            });
1629        });
1630    };
1631
1632    /////////////////////////////////////////////////////////////////
1633    timelineItems.activateByBook = function (book) {
1634        timelineItems.clearFilter();
1635        timelineItems.each(function (index, element) {
1636            if (book.periods[element.period]) {
1637                var bIsValid = true;
1638                if (filterObj.type === filterType.CHAPTER) {
1639                    if (!isInRange(book.periods[element.period], filterObj)) {
1640                        bIsValid = false;
1641                    }
1642                }
1643                if (bIsValid && !$(element).hasClass('active')) {
1644                    $(element).addClass('active');
1645                }
1646                else {
1647                    return true;
1648                }
1649            }
1650        });
1651    };
1652    /////////////////////////////////////////////////////////////////
1653    timelineItems.activateByFilter = function () {
1654        if (filterObj.periods.length > 0) {
1655            timelineItems.each(function (index, element) {
1656                if ($.inArray(element.period, filterObj.periods) > -1) {
1657                    $(element).addClass('active');
1658                }
1659
1660            });
1661        }
1662    };
1663    /////////////////////////////////////////////////////////////////
1664    timelineItems.clearFilter = function () {
1665        timelineItems.each(function (index, element) {
1666            if ($(element).hasClass('active')) {
1667                $(element).removeClass('active');
1668            }
1669            else {
1670                return true;
1671            }
1672        });
1673        filterObj.periods.length = 0;
1674    };
1675    /////////////////////////////////////////////////////////////////
1676    var init_map_styles = function () {
1677        // Create an array of styles.
1678        var styles = [
1679            {
1680                featureType: "all",
1681                elementType: "labels",
1682                stylers: [{ visibility: "off" }]
1683            }, {
1684                featureType: "administrative",
1685                elementType: "all",
1686                stylers: [{ visibility: "off" }]
1687            }, {
1688                featureType: "poi",
1689                elementType: "all",
1690                stylers: [{ visibility: "off" }]
1691            }, {
1692                featureType: "water",
1693                elementType: "labels",
1694                stylers: [{ visibility: "off" }]
1695            }, {
1696                featureType: "road",
1697                elementType: "all",
1698                stylers: [{ visibility: "off" }]
1699            }, {
1700                featureType: "transit",
1701                elementType: "all",
1702                stylers: [{ visibility: "off" }]
1703            }
1704        ];
1705        return styles;
1706    };
1707
1708    var init_map_styles_roads = function () {
1709        // Create an array of styles.
1710        var styles = [
1711            {
1712                featureType: "all",
1713                elementType: "labels",
1714                stylers: [{ visibility: "on" }]
1715            }, {
1716                featureType: "administrative",
1717                elementType: "all",
1718                stylers: [{ visibility: "on" }]
1719            }, {
1720                featureType: "poi",
1721                elementType: "all",
1722                stylers: [{ visibility: "on" }]
1723            }, {
1724                featureType: "water",
1725                elementType: "labels",
1726                stylers: [{ visibility: "on" }]
1727            }, {
1728                featureType: "road",
1729                elementType: "all",
1730                stylers: [{ visibility: "on" }]
1731            }, {
1732                featureType: "transit",
1733                elementType: "all",
1734                stylers: [{ visibility: "on" }]
1735            }
1736        ];
1737        return styles;
1738    };
1739    /////////////////////////////////////////////////////////////////
1740
1741    var filter_locations = function () {
1742
1743        filteredArr.length = 0;
1744
1745        // checks if item already in array by title
1746        var isItemInArray = function (valueToCheck) {
1747            var bExists = false;
1748            $(filteredArr).each(function (idx, elem) {
1749                if (elem.nid === valueToCheck) {
1750                    bExists = true;
1751                    return false;
1752                }
1753            });
1754            return bExists;
1755        };
1756
1757        switch (filterObj.type) {
1758            case filterType.BOOK:
1759                var currentBook = booksCollection[filterObj.book];
1760                if (currentBook) {
1761                    $(currentBook.locations).each(function (index, item) {
1762                        filteredArr.push(globalCollection[item]);
1763                    });
1764                    timelineItems.activateByBook(currentBook);
1765                }
1766                break;
1767            case filterType.CHAPTER:
1768
1769                var startBook = parseInt(filterObj.book || 0);
1770                var endBook = parseInt(filterObj.book_to || filterObj.book || 0);
1771                var startChapter = parseInt(filterObj.chapter || 0);
1772                var endChapter = parseInt(filterObj.chapter_to || filterObj.chapter || 0);
1773
1774                for (var bi = startBook; bi <= endBook; bi++) {
1775                    var rangeBook = booksCollection[bi];
1776                    if (!rangeBook || !rangeBook.chaptersLocations) { continue; }
1777
1778                    // Determine chapter window for this book
1779                    var chFrom = (bi === startBook) ? startChapter : 0;
1780                    var chTo = (bi === endBook) ? endChapter : Object.keys(rangeBook.chaptersLocations).length;
1781
1782                    for (var ci = chFrom; ci <= chTo; ci++) {
1783                        if (rangeBook.chaptersLocations[ci]) {
1784                            $(rangeBook.chaptersLocations[ci]).each(function (index, nid) {
1785                                var location = globalCollection[nid];
1786                                if (location && !isItemInArray(nid)) {
1787                                    filteredArr.push(location);
1788                                }
1789                            });
1790                        }
1791                    }
1792
1793                    timelineItems.activateByBook(rangeBook);
1794                }
1795                break;
1796            case filterType.PERIOD:
1797                $.each(globalCollection, function (index, item) {
1798                    $(item.periods).each(function (innerIndex, innerItem) {
1799                        var tid = (typeof innerItem === 'object') ? innerItem.tid : innerItem;
1800                        if ($.inArray(tid, filterObj.periods) > -1) {
1801                            if (!isItemInArray(item.nid)) {
1802                                filteredArr.push(item);
1803                            }
1804                        }
1805                    });
1806                });
1807                break;
1808            case filterType.EMPTYPERIOD:
1809                // case for location page only
1810                // when no filter - nothing to show. in lobby page when no filter  - all locations shown. filteredArr is empty
1811                break;
1812            case filterType.NONE:
1813            default:
1814                if (globalCollection && typeof globalCollection === 'object') {
1815                    filteredArr = Object.keys(globalCollection).map(function (key) {
1816                        return globalCollection[key];
1817                    });
1818                }
1819                break;
1820        }
1821        if (settings.updateQueryString) {
1822            // anyway do not filter in load page
1823            //setQueryString();
1824        }
1825        set_locations_on_map(true);
1826        $('.listViewContainer .map-table-scroller').perfectScrollbar();
1827        feature_location_reset_dd(ddlBooks);
1828        feature_location_reset_dd(ddlChapters);
1829    };
1830    /////////////////////////////////////////////////////////////////
1831    var set_locations_on_map = function (bClearMarkers) {
1832        // to do:   clear markers only when filter changed or zoom changed
1833
1834        var currentZoom = currentMap.getZoom();
1835        clear_markers();
1836        //if (infoBox) infoBox.close();
1837        $.each(filteredArr, function (key, currentItem) {
1838
1839            //draw location by zoom range level when no active filter
1840            if (currentZoom <= currentItem.maxZoomLevel && currentZoom >= currentItem.minZoomLevel) {
1841                draw_marker(currentItem, currentItem.nid);
1842                return true;
1843            }
1844
1845            // remove this comment if you need to show location without zoom level !
1846            /* if (filterObj.type !== filterType.NONE || settings.ignoreZoomLevels === true) {
1847            draw_marker(currentItem, currentItem.nid);
1848            }*/
1849            if (filterObj.chapter || !isPageMap()) {
1850                draw_marker(currentItem, currentItem.nid);
1851            }
1852
1853        });
1854    };
1855    /////////////////////////////////////////////////////////////////
1856
1857    var draw_marker = function (currentItem, currentId) {
1858
1859        var currentMarker = new MarkerWithLabel({
1860            nid: currentItem.nid,
1861            position: new google.maps.LatLng(currentItem['latitude'], currentItem['longtitude']),
1862            draggable: false,
1863            raiseOnDrag: false,
1864            map: currentMap,
1865            labelContent: currentItem['title'],
1866            labelAnchor: new google.maps.Point(22, 0),
1867            labelClass: get_marker_class(currentItem), // the CSS class for the label
1868            //labelStyle: {opacity: 0.75},
1869            icon: showHideMarkers.visible ? get_icon_url(currentItem) : " ",
1870            markerVisible: currentItem.locationType !== locationType.CITY ? false : true
1871        });
1872
1873        var target_link = '';
1874        //if the map in the toolbar open the location in new tab
1875        if ($('body').hasClass('page-tanach')) {
1876            target_link = "target='_blank'";
1877        }
1878        var url = Drupal.settings.basePath + Drupal.settings.pathPrefix + 'map/' + getLocationTitle(currentItem);
1879        var infoHtml = "<br/><a class='infoWindowTitle' href='" + url + "' " + target_link + ">" + currentItem['title'] + "<br/></a>";
1880        // Use simple historical UI for sidebar/non-map pages, detailed UI for full map.
1881        if (isPageMap()) {
1882            infoHtml = create_info_html(currentItem, currentId);
1883        } else {
1884            infoHtml = create_simple_info_html(currentItem);
1885        }
1886
1887        google.maps.event.addListener(currentMarker, "click", function () {
1888            var selfHandler = function (currentItem) {
1889                isOpenInfo = true;
1890                var title = getLocationTitle(currentItem);
1891                var titleLang = getLocationTitleLang(currentItem);
1892
1893                // Regenerate infoHtml with full data
1894                if (isPageMap()) {
1895                    infoHtml = create_info_html(currentItem, currentId);
1896                } else {
1897                    infoHtml = create_simple_info_html(currentItem);
1898                }
1899
1900                fillInfoBox(infoBox, infoHtml, currentMarker, currentMap);
1901
1902                if (Drupal.settings.urlArgs[1]) {
1903                    var lid = Drupal.settings.urlArgs[1];
1904                    if (globalMarkers[lid] && lid != currentId) {
1905                        self.refreshMarker(globalMarkers[lid], Drupal.settings.mapSettings.mappedLocations[lid]);
1906                    }
1907                }
1908
1909                var state = History.getState();
1910                if (state.data.title != title && isPageMap()) {
1911                    hideReferences();
1912                    var historyData = { 'locationId': currentId, 'status': 'open', title: title };
1913                    if (!state.data.status) {
1914                        History.pushState(historyData, '', Drupal.settings.pathPrefix + 'map/' + title);
1915                    }
1916                    else {
1917                        History.pushState(historyData, '', Drupal.settings.pathPrefix + '/' + title);
1918                    }
1919
1920                    insertCustomUrl('/' + title, titleLang);
1921                }
1922
1923                if (Drupal.settings.pathPrefix == 'es/') {
1924                    cloneInfo(currentId);
1925                }
1926                if (isMobile(window.innerWidth)) {
1927                    infoBox.close();
1928                    cloneInfo(currentId);
1929                }
1930            };
1931
1932            if (!currentItem.full_data_loaded) {
1933                featureAjaxLocation.loadLocationDetails(currentItem.nid, function (data) {
1934                    // Update currentItem directly with the full data
1935                    jQuery.extend(currentItem, data);
1936
1937                    // Also update in global collection if it exists in this scope
1938                    if (typeof globalCollection !== 'undefined' && globalCollection[currentItem.nid]) {
1939                        jQuery.extend(globalCollection[currentItem.nid], data);
1940                    }
1941
1942                    selfHandler(currentItem);
1943                });
1944            } else {
1945                selfHandler(currentItem);
1946            }
1947        });
1948        if (isPageMap() && (Drupal.settings.urlArgs[1] == currentId || Drupal.settings.urlArgs[1] == getLocationTitle(currentItem)) && !isOpenInfo && !closeInfoInLocationPage && !isMobile(window.innerWidth)) {
1949            closeInfoInLocationPage = true;
1950            if (!currentItem.full_data_loaded) {
1951                featureAjaxLocation.loadLocationDetails(currentItem.nid, function (data) {
1952                    jQuery.extend(currentItem, data);
1953                    if (isPageMap()) {
1954                        infoHtml = create_info_html(currentItem, currentId);
1955                    }
1956                    fillInfoBox(infoBox, infoHtml, currentMarker, currentMap);
1957                    if (isMobile(window.innerWidth) || Drupal.settings.pathPrefix == 'es/') {
1958                        cloneInfo(currentId);
1959                    }
1960                });
1961            } else {
1962                fillInfoBox(infoBox, infoHtml, currentMarker, currentMap);
1963                if (isMobile(window.innerWidth) || Drupal.settings.pathPrefix == 'es/') {
1964                    cloneInfo(currentId);
1965                }
1966            }
1967        }
1968        markersCollection.push(currentMarker);
1969        markersCollectionObj[currentId] = currentMarker;
1970
1971    };
1972
1973    function getLocationTitle(currentItem) {
1974        if (Drupal.settings.mapSettings.isRtl && currentItem.titleLang && currentItem.titleLang.he) {
1975            return currentItem.titleLang.he.split(' ').join('-');
1976        }
1977        return currentItem.title.split(' ').join('-');
1978    }
1979
1980    function getLocationTitleLang(currentItem) {
1981        var tl = currentItem.titleLang || {
1982            he: currentItem.title,
1983            en: currentItem.title,
1984            es: currentItem.title
1985        };
1986        return {
1987            he: (tl.he || currentItem.title || '').split(' ').join('-'),
1988            en: (tl.en || currentItem.title || '').split(' ').join('-'),
1989            es: (tl.es || currentItem.title || '').split(' ').join('-')
1990        };
1991    }
1992
1993    function fillInfoBox(infoBox, infoHtml, currentMarker, currentMap) {
1994        if (!infoBox || !currentMarker) return;
1995
1996        hideExtendWin();
1997
1998        infoBox.setContent(infoHtml);
1999
2000        // Clearance of info window from top
2001        if (isPageMap()) {
2002            infoBox.infoBoxClearance_.height = 130;
2003            infoBox.infoBoxClearance_.width = 480;
2004        }
2005
2006        // Set pixel offset based on marker visibility
2007        infoBox.pixelOffset_.height = currentMarker.markerVisible ? -40 : -5;
2008        infoBox.pixelOffset_.width = -100;
2009
2010        // If ES lang - skip the first popup
2011        if (Drupal.settings.pathPrefix !== 'es/') {
2012            infoBox.close();
2013            infoBox.open(currentMap, currentMarker);
2014        }
2015    }
2016
2017    var get_marker_class = function (currentItem) {
2018
2019        if (isCurrentLocationMarker(currentItem) && !closeInfo) {
2020            return getCurrentLabelClassMarker(currentItem);
2021        }
2022
2023        var cssClass = getLabelClassMarker();
2024
2025        switch (currentItem.locationType) {
2026            default:
2027            case locationType.CITY:
2028                break;
2029            case locationType.REGION:
2030                cssClass += ' ' + 'markerLabelsRegion';
2031                break;
2032            case locationType.COUNTRY:
2033                cssClass += ' ' + 'markerLabelsCountry';
2034                break;
2035        }
2036        return cssClass;
2037    }
2038
2039    /////////////////////////////////////////////////////////////////
2040    var get_icon_url = function (currentItem) {
2041        var image_tid = get_tid_by_period(currentItem);
2042        var image_url = '';
2043        if (isCurrentLocationMarker(currentItem) && !closeInfo) {
2044            image_url = settings.imagesRelativePath + "map_" + image_tid + "_l.png";
2045            return image_url;
2046        }
2047
2048        if (currentItem.locationType === locationType.REGION || currentItem.locationType === locationType.COUNTRY) {  // region or country  - icon not showm
2049            return " ";
2050        }
2051        image_url = settings.imagesRelativePath + "map_" + image_tid + "_m.png";
2052
2053        return image_url;
2054    };
2055    /////////////////////////////////////////////////////////////////
2056    var get_tid_by_period = function (currentItem) {
2057        var image_tid = '';
2058        $(timelineItems).each(function (index, item) {
2059            var exit = false;
2060
2061            $(currentItem.periods).each(function (innerIndex, period) {
2062                var tid = (typeof period === 'object') ? period.tid : period;
2063                if ($(item).hasClass('active') && item.period === tid) {
2064                    image_tid = tid;
2065                    exit = true;
2066                    return false;        // abort inner foreach
2067                }
2068            });
2069            if (exit) {
2070                return false;
2071            } // abort outer foreach
2072        });
2073        if (!image_tid) {
2074            // if  location referenced to period - take the first period - else set the default icon    marker_default.png
2075            var firstP = currentItem.periods && currentItem.periods.length > 0 ? currentItem.periods[0] : null;
2076            image_tid = firstP ? (typeof firstP === 'object' ? firstP.tid : firstP) : 'default';
2077        }
2078        return image_tid;
2079    };
2080    /////////////////////////////////////////////////////////////////
2081    var isCurrentLocationMarker = function (currentItem) {
2082        return currentLocation && currentLocation.nid === currentItem.nid;
2083    };
2084    /////////////////////////////////////////////////////////////////
2085    var getLabelClassMarker = function () {
2086        return (currentMap.mapTypeId == "hybrid") ? "white-marker-label" : "markerLabels";
2087    }
2088    /////////////////////////////////////////////////////////////////
2089    var getCurrentLabelClassMarker = function (currentItem) {
2090        var labelClass = "period-" + get_tid_by_period(currentItem);
2091        return (currentMap.mapTypeId == "hybrid") ? labelClass + " currentMarkerLabel white-marker-label" : labelClass + " currentMarkerLabel";
2092    }
2093    /////////////////////////////////////////////////////////////////
2094    var clear_markers = function () {
2095        for (var i = 0; i < markersCollection.length; i++) {
2096            markersCollection[i].setMap(null);
2097        }
2098        markersCollection.length = 0;
2099    };
2100
2101    ////////////////////////////////////////////////////////////////
2102    var reset_filter = function () {
2103
2104        filterObj.type = filterType.NONE;
2105        filterObj.book = '';
2106        filterObj.chapter = '';
2107        timelineItems.clearFilter();
2108        ddlBooks.setSelected('-1');
2109        ddlBooksRange.setSelected('-1');
2110        ddlChapters.clear();
2111        ddlChaptersRange.clear();
2112        filter_locations();
2113        feature_location_reset_dd(ddlBooks);
2114        feature_location_reset_dd(ddlBooksRange);
2115        feature_location_reset_dd(ddlChapters);
2116        feature_location_reset_dd(ddlChaptersRange);
2117        if (infoBox) infoBox.close();
2118    };
2119    /////////////////////////////////////////////////////////////////
2120    var isInRange = function (rangeItem, selectedItem, range) {
2121
2122        var convertNumber = function (number) {
2123            var digits = 3, i;
2124            if (number) {
2125                var length = number.toString().length;
2126                for (i = 0; i < (digits - length); i++) {
2127                    number = '0' + number;
2128                }
2129            }
2130            return (number);
2131        }                                                                                                     // to check range for verses also  - add the following lines
2132
2133
2134        var from = parseInt(convertNumber(rangeItem['book']) + convertNumber(rangeItem['chapter']));      //+ convertNumber(rangeItem['verse'])
2135        var to = parseInt(convertNumber(rangeItem['book2']) + convertNumber(rangeItem['chapter2']));    //+ convertNumber(rangeItem['verse2'])
2136        var selected = parseInt(convertNumber(selectedItem['book']) + convertNumber(selectedItem['chapter'])); // + convertNumber(selectedItem['verse']);
2137        var selected_to = parseInt(convertNumber(selectedItem['book_to']) + convertNumber(selectedItem['chapter_to'])); // + convertNumber(selectedItem['verse']);
2138
2139        if (selectedItem['book_to'] && selectedItem['chapter_to']) {
2140            return from >= selected && to <= selected_to;
2141        }
2142        return from >= selected && to <= selected;
2143    };
2144    //////////////////////////////////////////////////////
2145    var updateLinkToTanach = function () {
2146        // get book and chapter
2147        var book = filterObj.book;
2148        var chapter = '0';
2149        if (filterObj.chapter) {
2150            chapter = filterObj.chapter;
2151        }
2152        // update link
2153        // TODO: LINK TO ES?? ;
2154        var link = Drupal.settings.mapSettings.isRtl ? '/tanach/' : '/en/tanach/';
2155        if (Drupal.settings.pathPrefix === 'es/') {
2156            link = '/es/?biblia=';
2157        }
2158        $(".book-filter-box .goToText a").attr('href', link + book + '.' + chapter + '.0');
2159    }
2160
2161    /////////////////////////////////////////////////////////////////// events ///////////////////////////////////////////////////
2162
2163    function ddlBooksEvent(ddlChapters, context, range, ddlChaptersRange) {
2164
2165        ddlChapters.clear();
2166        timelineItems.clearFilter();
2167        var selectedValue = $(context).children("option:selected").val();
2168
2169        if (selectedValue !== "-1") {
2170            var selectedBook = booksCollection[selectedValue];
2171
2172
2173            if (range) {
2174                filterObj.book_to = selectedValue;
2175            }
2176            else {
2177                filterObj.book = selectedValue;
2178                ddlBooksRange.msDropdown().data("dd").destroy();
2179                ddlChaptersRange.msDropdown().data("dd").destroy();
2180                jQuery('.ddlBooksFilterRange').children("option").remove();
2181                init_ddl(ddlBooksRange, ddlChaptersRange, parseInt(selectedValue), true);
2182            }
2183
2184            /*
2185            * add chapters to select option by book
2186            * */
2187            ddlChapters.bindByBook(selectedBook, filterObj.book);
2188
2189
2190            filterObj.type = filterType.BOOK;
2191
2192        } else {
2193            filterObj.book = '';
2194            if (filterObj.type === filterType.BOOK) {
2195                filterObj.type = filterType.NONE;
2196            }
2197        }
2198        updateLinkToTanach();
2199        filter_locations();
2200        feature_location_reset_dd(ddlChapters);
2201    }
2202
2203    function ddlChaptersEvent(ddlBooks, context, range) {
2204
2205        var nextChapter = $('.next-chapter').data('next-chapter').split('.');
2206
2207        var selectedValue = $(context).children("option:selected").val();
2208
2209        if (selectedValue !== "-1") {
2210            filterObj.type = filterType.CHAPTER;
2211            if (range) {
2212                if (selectedValue !== undefined) {
2213                    filterObj.chapter_to = selectedValue;
2214                }
2215            }
2216            else {
2217
2218                filterObj.chapter = selectedValue;
2219            }
2220
2221            if (showFilterRange.hasClass('open')) {
2222
2223            }
2224
2225            updateLinkToTanach();
2226        }
2227        else {
2228            filterObj.chapter = '';
2229            if (filterObj.type === filterType.CHAPTER) {
2230                // no chapter selected  - restore filter by book
2231                filterObj.type = filterType.BOOK;
2232                //trigger change event for ddlBooks
2233                ddlBooks.change();
2234            }
2235        }
2236        featureAjaxLocation.updateTanachText(filterObj);
2237        filter_locations();
2238
2239        if (selectedValue >= nextChapter[1] || selectedValue > filterObj.chapter) {
2240            multiChapterNext.show();
2241        }
2242        multiChapterTitle.html('');
2243    }
2244
2245    clearFilterBook.on('click', function () {
2246        filterObj.book = '';
2247        filterObj.chapter = '';
2248        filterObj.book_to = '';
2249        filterObj.chapter_to = '';
2250
2251        insertCustomUrl('');
2252        // window.History.replaceState({'act': 'close'}, '', '/map');
2253
2254        reset_filter();
2255        $(this).hide();
2256        showText.hide();
2257        goToText.hide();
2258        biblicleTextWrapper.hide();
2259        nextChapter.hide();
2260        showFilterRange.removeClass('open');
2261        multiChapterPrev.hide();
2262        hideReferences();
2263        viewTanach.attr('checked', false);
2264        featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
2265        switchMultiChapter(true);
2266        multiChapterTitle.text('');
2267    });
2268
2269    $('.resize-button').on('click', function () {
2270        var locationId = $('.bauble-header .title-section').data('nid');
2271        var location = Drupal.settings.mapSettings.mappedLocations[locationId];
2272        var infoHtml = create_info_html(location, location.nid);
2273        fillInfoBox(infoBox, infoHtml, markersCollectionObj[location.nid], currentMap)
2274    }
2275    );
2276
2277    ddlBooks.on('change', function () {
2278        ddlBooksEvent(ddlChapters, this, false, ddlChaptersRange);
2279        ddlBooksEvent(ddlChaptersRange, this, true, false);
2280        featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
2281        clearFilterBook.show();
2282        clearPeriodFilterButton.hide();
2283        disabledChapters(ddlChapters, RESET_HARD);
2284    });
2285    ddlBooksRange.on('change', function () {
2286        ddlBooksEvent(ddlChaptersRange, this, true, false);
2287        featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
2288        clearFilterBook.show();
2289        clearPeriodFilterButton.hide();
2290    });
2291
2292    ddlChapters.on('change', function () {
2293        ddlChaptersEvent(ddlBooks, this, false);
2294        featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
2295        if (!showFilterRange.hasClass('open')) {
2296            showText.show();
2297            goToText.show();
2298        }
2299        clearFilterBook.show();
2300        clearPeriodFilterButton.hide();
2301        setStartChapter();
2302        multiChapterTitle.text('');
2303        biblicleTextWrapper.scrollTop(1);
2304        checkRange(filterObj);
2305    });
2306    ddlChaptersRange.on('change', function () {
2307        ddlChaptersEvent(ddlBooksRange, this, true);
2308        featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
2309        clearFilterBook.show();
2310        clearPeriodFilterButton.hide();
2311        if (biblicleTextWrapper.is(':visible')) {
2312            switchMultiChapter(false);
2313        }
2314        // Check If There Is A Range If Not Hide Prev Next Buttons
2315        checkRange(filterObj);
2316    });
2317
2318    ddlChaptersRange.on('click', function () {
2319        disabledChapters(ddlChaptersRange);
2320    });
2321
2322    function disabledChapters(chapters, reset) {
2323        chapters.clear();
2324        var selectedValue = ddlBooks.children("option:selected").val();
2325        if (selectedValue !== "-1") {
2326            var selectedBook = booksCollection[selectedValue];
2327            chapters.bindByBook(selectedBook, filterObj.chapter, reset);
2328        }
2329        feature_location_reset_dd(chapters);
2330    }
2331
2332    function setStartChapter() {
2333        filterObj.start = '' + filterObj.book + '.' + filterObj.chapter + '.0';
2334    }
2335
2336    function feature_location_reset_dd(ddName) {
2337        try {
2338            var oHandler = ddName.msDropDown().data("dd");
2339            if (oHandler) {
2340                oHandler.destroy();
2341                ddName.msDropDown();
2342            }
2343        } catch (e) {
2344            alert(e);
2345        }
2346    }
2347
2348    function getQueryVariable(variable) {
2349        var query = window.location.search.substring(1);
2350        var vars = query.split("&");
2351        for (var i = 0; i < vars.length; i++) {
2352            var pair = vars[i].split("=");
2353            if (pair[0] == variable) {
2354                return pair[1];
2355            }
2356        }
2357        return (false);
2358    }
2359
2360    function create_simple_info_html(currentItem) {
2361        var url = Drupal.settings.basePath + Drupal.settings.pathPrefix + 'map/' + getLocationTitle(currentItem);
2362        var target_link = ($('body').hasClass('page-tanach')) ? "target='_blank'" : '';
2363        var isRtl = (Drupal.settings.mapSettings && Drupal.settings.mapSettings.isRtl);
2364
2365        var labels = {
2366            'also': isRtl ? 'נקראת גם' : Drupal.t('Other Names'),
2367            'words': isRtl ? 'כמה מילים' : Drupal.t('More Information'),
2368            'periods': isRtl ? 'מוזכרת בתקופות' : Drupal.t('Mentioned in Periods')
2369        };
2370
2371        var periodsHtml = "";
2372        var mapSettings = Drupal.settings.mapSettings || {};
2373        var pMap = mapSettings.periodsMap || {};
2374
2375        if (currentItem.periods && Array.isArray(currentItem.periods)) {
2376            $(currentItem.periods).each(function (index, p) {
2377                var pName = (typeof p === 'object') ? p.periodName : pMap[p];
2378                if (pName) {
2379                    periodsHtml += "<li>" + pName + "</li>";
2380                }
2381            });
2382        }
2383
2384        var html = "<br/><a class='infoWindowTitle' href='" + url + "' " + target_link + ">" + currentItem['title'] + "<br/></a>";
2385        /*
2386        if (currentItem.alsoCalled) {
2387            html += "<div class='infoWindowAlsoCalled'><span>" + labels.also + "</span>: " + currentItem.alsoCalled + "</div>";
2388        }
2389        if (currentItem.fewWords) {
2390            html += "<div class='infoWindowFewWords'><span>" + labels.words + "</span>: " + currentItem.fewWords + "</div>";
2391        }
2392        */
2393        if (periodsHtml) {
2394            html += "<div class='infoWindowPeriods'><span>" + labels.periods + "</span>:<ul class='periodsList'>" + periodsHtml + "</ul></div>";
2395        }
2396        return html;
2397    }
2398
2399    function isExtends(currentItem) {
2400        if (currentItem) {
2401            // If it's a light marker, we might want to assume it HAS data if extended_data_exists is set
2402            // or just let it fetch and see.
2403            return (currentItem.extended_data_exists || currentItem.youtube || (currentItem.image && currentItem.image.length > 2) || (currentItem.body && currentItem.body.length > 2) || (currentItem.bibliography && currentItem.bibliography.length > 2));
2404        }
2405        return false;
2406    }
2407
2408
2409    function create_info_html(currentItem, currentId) {
2410
2411        // Label mapping to save bytes in the JSON payload
2412        var labelMap = {
2413            'remainderCount': 'References',
2414            'articlesCount': 'Articles',
2415            'lessonsCount': 'Lessons',
2416            'postsCount': 'Posts',
2417            'topics': 'Topics',
2418            'personalities': 'Personalities'
2419        };
2420
2421        var contentAttr = ['remainderCount', 'articlesCount', 'lessonsCount', 'postsCount'];
2422        var taxonomiesAttr = ['topics', 'personalities'];
2423        var taxonomiesArr = ['topicsArr', 'personalitiesArr'];
2424        var blogsArr = ['postsArr', 'lessonsArr', 'articlesArr'];
2425        var p = currentId;
2426        var periods = '';
2427        var hasExtends = isExtends(currentItem);
2428
2429
2430        if (currentItem.periods && Array.isArray(currentItem.periods)) {
2431            var pMap = (Drupal.settings.mapSettings && Drupal.settings.mapSettings.periodsMap) ? Drupal.settings.mapSettings.periodsMap : {};
2432            $(currentItem.periods).each(function (index, p) {
2433                var pName = (typeof p === 'object') ? p.periodName : pMap[p];
2434                if (pName) {
2435                    periods += ' ' + pName + ", ";
2436                }
2437            });
2438            // Remove trailing comma
2439            periods = periods.replace(/, $/, "");
2440        }
2441
2442        var html = '<div id="draggable"  class="bauble-header bounce">' +
2443            '<header id="draggable-handle" class="clearfix">' +
2444            '<div onclick="hideInfoWin(' + p + ')" class="close-button"> &nbsp;</div>';
2445        if (hasExtends) {
2446
2447            html += '<div  onclick="cloneInfo(' + p + ')" class="resize-button open">&nbsp; </div>';
2448        }
2449        html += '</header>' +
2450            '<section class="clearfix">' +
2451            '<span class="bauble-title" data-location-id ="' + currentId + '">' + currentItem.title + '</span>' +
2452            '<span onclick="printThisPage(' + currentItem.nid + ')" class="print-info"></span>' +
2453            '<i onclick="showSummary()" class="arrow-down-info desktop" aria-hidden="true"></i> ' +
2454            '</section> ' +
2455            '<section class="location-summary clearfix">';
2456        if (currentItem.alsoCalled && currentItem.alsoCalled.length > 1) {
2457            html += '<div class="location-text"><span class="font-bold">' + Drupal.t('Other Names') + '</span>:<span>' + currentItem.alsoCalled + '</span></div>';
2458        }
2459        if (periods.length > 1) {
2460            html += '<div class="location-text"><span class="font-bold">' + Drupal.t('Biblical Eras') + '</span>:<span>' + periods + '</span></div>';
2461        }
2462
2463        if (currentItem.fewWords && typeof currentItem.fewWords === 'string' && currentItem.fewWords.length > 1) {
2464            html += '<div class="location-text"><span class="font-bold">' + Drupal.t('More Information') + '</span>:<span>' + currentItem.fewWords + '</span></div>';
2465        }
2466        if (hasExtends) {
2467
2468            html += '<span onclick="cloneInfo(' + p + ')" class="link font-bold"> ' + Drupal.t('Read More') + ' <i class=""></i></span>';
2469        }
2470
2471        html += '</section><section class="clearfix sun-wrapper">';
2472        $.each(contentAttr, function (key, contentName) {
2473            var data = currentItem[contentName];
2474            var countVal = Array.isArray(data) ? data[0] : data;
2475            var label = (Array.isArray(data) && data[1]) ? data[1] : labelMap[contentName];
2476
2477            if (countVal > 0 && label) {
2478                var countHtml = '<div class="sun-map-count">' + countVal + '</div>';
2479                html += '<div class="sun-map-wrapper col-md-2"><div data-name="' + label.toLocaleLowerCase() + 'Arr" onclick="openContentSum(this,\'' + label + '\', \'' + (currentItem.nid || '') + '\' )" class="sun-map sun-' + label.toLocaleLowerCase() + '">' + countHtml + '</div><span class="sun-map-name">' + Drupal.t(label) + '</span></div>';
2480            }
2481        });
2482
2483        $.each(taxonomiesAttr, function (key, taxonomyName) {
2484            var data = currentItem[taxonomyName];
2485            var countVal = Array.isArray(data) ? data[0] : data;
2486            var label = (Array.isArray(data) && data[1]) ? data[1] : labelMap[taxonomyName];
2487
2488            if (countVal > 0 && label) {
2489                html += '<div class="sun-map-wrapper col-md-2"><div onclick="openContentSum(this , true ,' + (currentItem.nid || 0) + ')" data-name="' + label.toLocaleLowerCase() + 'Arr" class="sun-map sun-' + label.toLocaleLowerCase() + '"><div class="sun-map-count">' + countVal + '</div></div><span class="sun-map-name">' + Drupal.t(label) + '</span></div>'
2490            }
2491        });
2492
2493        html += '</section>';
2494
2495        var img_id = get_tid_by_period(currentItem);
2496        if (img_id == 'default') {
2497            img_id = false;
2498        }
2499        globalMarkers = markersCollectionObj;
2500
2501        html += '</section>';
2502        html += '<div class="wrapper-arr">';
2503        $.each(blogsArr, function (key, nodeName) {
2504            if (currentItem[nodeName]) {
2505                html += '<section class="' + nodeName + ' clearfix">' +
2506                    '<div class="blogs content-type"> ';
2507                $.each(currentItem[nodeName], function (index, val) {
2508                    html += '<div class="content-wrapper">' +
2509                        '<a class="content-title font-bold ' + val['icon'] + '" href="' + val['link'] + '" target="_blank">' + val['title'] + '</a>' +
2510                        '<div class="content-author">' + val['author'] + '</div><span class="link font-bold">&nbsp;<i class=""></i></span></div>';
2511                });
2512                html += '</div></section>';
2513            }
2514        });
2515
2516        $.each(taxonomiesArr, function (key, taxonomyName) {
2517            if (currentItem[taxonomyName] && currentItem[taxonomyName].length > 0) {
2518                html += '<section class="' + taxonomyName + '">';
2519                html += '<div class="taxonomies"><ul>';
2520                $.each(currentItem[taxonomyName], function (index, val) {
2521                    html += '<li class="tax font-bold">' + val + '</li>'
2522                });
2523                html += '</ul></div>';
2524                html += '</section>';
2525            }
2526        });
2527
2528        html += '</div></div></div>';
2529        return html;
2530    }
2531
2532    /////////////////////////////////////////////////////////////////
2533    resetFilter.on('click', function () {
2534        reset_filter();
2535    });
2536    clearPeriodFilterButton.on('click', function () {
2537        reset_filter();
2538        clearPeriodFilterButton.css("display", "none");
2539        featureAjaxLocation.updateLayers(filterObj, kmlInstance, showHideMarkers);
2540    });
2541
2542    showFilterRange.on('click', '.showRangeFilter', function () {
2543        showFilterRange.addClass('open');
2544    });
2545    /////////////////////////////////////////////////////////////////
2546    showHideMarkers.on('click', function () {
2547        showHideMarkers.visible = !showHideMarkers.visible;
2548        showHideMarkers.toggleClass("show-Markers");
2549        filter_locations();
2550    });
2551    /////////////////////////////////////////////////////////////////
2552
2553    closeButton.on('click', function () {
2554        infoSelector.hide();
2555    });
2556
2557    // Show filter box.
2558    filterBoxLabel.on('click', function () {
2559        var $context = $(this);
2560        searchResults.hide();
2561        if (!$context.parent().hasClass('open')) {
2562            filterBoxLabel.closest('.open').toggleClass('open');
2563        }
2564
2565        $context.parent().toggleClass('open');
2566        $context.parent().find('.map-references-wrapper').hide();
2567
2568        showFilterBookChapter();
2569        switchColorInBubles(this, true);
2570        if (!biblicleTextWrapper.is(':visible')) {
2571            viewTanach.attr('checked', false);
2572        }
2573
2574
2575    });
2576
2577
2578    /*
2579    * ////////// OVERLAY FUNCTIONS/EVENTS
2580    */
2581
2582    var attachEvents = $('.wrapper-figure-layers');
2583    var layerFirstClick = false;
2584    attachEvents.on('click', '.figure-layers', function () {
2585
2586        lobbyContainer.toggleClass('layer-close');
2587        if (window.innerWidth <= 787) {
2588            if ($('.wrapper-images-layers').is(":visible") && layerFirstClick) {
2589                mainContainer.css('z-index', 10);
2590            } else {
2591                mainContainer.css('z-index', 20);
2592            }
2593        }
2594        if (!layerFirstClick) {
2595            $(this).next('.wrapper-images-layers').css({
2596                'visibility': 'visible',
2597                'display': 'none'
2598            }).animate({ width: 'toggle' }, 300);
2599            layerFirstClick = true;
2600        }
2601        else {
2602            $(this).next('.wrapper-images-layers').css({ 'visibility': 'visible' }).animate({ width: 'toggle' }, 300);
2603
2604        }
2605
2606    });
2607    attachEvents.on('click', '.close-layers', function () {
2608        $(this).parent().animate({ width: 'toggle' }, 300);
2609        mainContainer.css('z-index', 10);
2610        lobbyContainer.addClass('layer-close');
2611    });
2612
2613    function merge_options(obj1, obj2) {
2614        var obj3 = {};
2615        for (var attrname in obj1) {
2616            obj3[attrname] = obj1[attrname];
2617        }
2618        for (var attrname in obj2) {
2619            obj3[attrname] = obj2[attrname];
2620        }
2621        return obj3;
2622    }
2623
2624    attachEvents.on('click', '.overlay-img', function () {
2625        var $context = $(this);
2626        kmlInstance = merge_options(FeatureLocationLayers.fillAllKmls(), kmlInstance);
2627        $context.find('.overlay-img-background').toggle();
2628        var dataName = $context.data('layer-type');
2629        var dataId = $context.data('layer-id');
2630
2631        if (dataName == 'markers') {
2632            showHideMarkers.visible = !showHideMarkers.visible;
2633
2634            showHideMarkers.toggleClass("show-Markers");
2635            filter_locations();
2636        }
2637        else {
2638            if (!currentMap) {
2639                console.error('currentMap is not initialized');
2640                return;
2641            }
2642
2643            if (!kmlInstance[dataId]) {
2644                console.error('KML instance not found for layer:', dataId, 'Available layers:', Object.keys(kmlInstance));
2645                return;
2646            }
2647
2648            if ($context.hasClass('active')) {
2649                kmlInstance[dataId].setMap(null);
2650            }
2651            else {
2652                kmlInstance[dataId].setMap(currentMap);
2653            }
2654            $context.toggleClass('active');
2655        }
2656    });
2657    /*
2658    * ////////// END OVERLAY FUNCTIONS/EVENTS
2659    */
2660};
2661
2662var herzogMap, herzogMapDaily = undefined;
2663
2664// Herzog Mao implementation
2665(function () {
2666
2667    Drupal.behaviors.programmeSearch = {
2668        attach: function (context) {
2669            jQuery("#edit-map-search", context).on('autocompleteSelect', function (event, node) {
2670                jQuery(this).parent().addClass('throbbing');
2671                location.href = Drupal.settings.basePath + Drupal.settings.pathPrefix + 'map/' + jQuery(this).val();
2672            });
2673        }
2674    };
2675
2676    Drupal.t('Articles');
2677    Drupal.t('Lessons');
2678    Drupal.t('References');
2679    Drupal.t('References');
2680    Drupal.t('Subjects');
2681    Drupal.t('Personalities');
2682
2683    jQuery('.wrapper-images-layers').css({ 'display': 'none' });
2684
2685    function initialize() {
2686
2687        if (!Drupal.settings.mapSettings) {
2688            if (console) {
2689                console.log('settings not loaded!');
2690            }
2691        }
2692        if (document.getElementById('mapContainerDaily')) {
2693            herzogMapDaily = new HerzogMapObj(Drupal.settings.mapSettings);
2694            herzogMapDaily.init('mapContainerDaily');
2695        }
2696
2697        herzogMap = new HerzogMapObj(Drupal.settings.mapSettings);
2698        herzogMap.init();
2699
2700
2701    }
2702
2703    window.addEventListener('load', initialize);
2704    // Search bar
2705    jQuery(document).ready(function ($) {
2706        // add class to map type control google maps
2707
2708        if (isPageMap()) {
2709
2710            $("#edit-type option[selected]").removeAttr('selected');
2711            $("#edit-type option[value=location]").attr('selected', 'selected');
2712        }
2713    });
2714})();
2715
2716function feature_location_set_new_center_by_location(locations) {
2717    herzogMap.setNewCenterByLocations(locations);
2718}
2719
2720function feature_location_ajax_map_reset(newBook) {
2721    console.log('feature_location_ajax_map_reset called for:', newBook);
2722    if (typeof herzogMap == 'object') {
2723        herzogMap.cache = (typeof herzogMap.cache == 'undefined') ? {} : herzogMap.cache;
2724        var resetMap = function (data) {
2725            console.log('resetMap callback executed. Locations:', data.allLocations ? Object.keys(data.allLocations).length : 'none');
2726            herzogMap.reset(data.allLocations, data.booksWithChaptersArr);
2727            herzogMap.cache[newBook] = data;
2728            var locations = data.allLocations;
2729
2730            if (locations !== 'undefined') {
2731                herzogMap.setNewCenterByLocations(locations);
2732            }
2733        }
2734        if (herzogMap.cache[newBook]) {
2735            console.log('Using cached map data');
2736            resetMap(herzogMap.cache[newBook]);
2737        } else {
2738            console.log('Fetching map data via AJAX');
2739            jQuery.get('/ajax/home/locations/' + newBook, resetMap);
2740        }
2741    } else {
2742        console.error('herzogMap object not found');
2743    }
2744}
2745
2746
2747/*
2748* GLOBAL FUNCTIONS FOR INFO WINDOW
2749* */
2750
2751function insertCustomUrl(title, titleLang) {
2752    var en = '';
2753    var he = '';
2754    if (titleLang) {
2755        en = titleLang.en;
2756        he = titleLang.he;
2757    }
2758    var baseUrl = Drupal.settings.mapSettings.baseUrl + '/' + Drupal.settings.pathPrefix;
2759    History.replaceState({}, '', baseUrl + 'map' + title);
2760    jQuery('.language-switcher-locale-url .en a').attr('href', '/en/map/' + en);
2761    jQuery('.language-switcher-locale-url .he a').attr('href', '/map/' + he);
2762}
2763function removeAddRangeFields() {
2764
2765}
2766
2767function isMobile(size) {
2768    return size <= 768;
2769}
2770
2771function hideReferences() {
2772    var filterBox = jQuery('.filterBox.book-filter-box');
2773    if (jQuery('.search-results-container').is(':visible')) {
2774        filterBox.removeClass('open');
2775    }
2776    showFilterBookChapter();
2777    jQuery('.search-results-container').hide();
2778}
2779
2780function hideFilterBookChapter() {
2781    var cssObj = { visibility: 'hidden', position: 'absolute' };
2782    jQuery('.firstRange').css(cssObj);
2783    jQuery('.addRange').css(cssObj);
2784    jQuery('.showTanach').css(cssObj);
2785}
2786
2787function showFilterBookChapter() {
2788    var cssObj = { visibility: 'visible', position: 'static' };
2789    jQuery('.firstRange').css(cssObj);
2790    jQuery('.addRange').css(cssObj);
2791    jQuery('.showTanach').css(cssObj);
2792}
2793
2794function updateReferences(data) {
2795
2796    var imgReferencesLoader = jQuery('.wrapper-loader');
2797    imgReferencesLoader.show();
2798    hideFilterBookChapter();
2799    jQuery.ajax({
2800        type: 'POST',
2801        dataType: 'json',
2802        url: '/ajax/map/tanachText',
2803        data: data,
2804        success: function (response) {
2805            jQuery('.map-references').html(response);
2806            jQuery('.map-references .search-results-container').perfectScrollbar();
2807            imgReferencesLoader.hide();
2808
2809        },
2810        error: function (xhr, status, error) {
2811            alert('error');
2812            console.log(error);
2813            console.log(status);
2814            console.log(xhr);
2815        }
2816    });
2817}
2818
2819
2820function openContentSum(context, type, nid) {
2821
2822    if (jQuery(context).parents('.infoBoxWindow').hasClass('extend-v
2822iew')) {
2823        jQuery('.infoBoxWindow.extend-view .bauble-header div.wrapper-arr').animate({ top: '130px' }, 400);
2824    }
2825    var infoTop = isMobile(window.innerWidth) ? 48 : 60;
2826    var locationHeight = jQuery(context).parents('#draggable').find('.location-summary').height();
2827    var filterBox = jQuery('.filterBox.book-filter-box');
2828
2829    if ((type == 'References' || jQuery(context).data('name') == 'referencesArr')) {
2830        jQuery('#draggable').show();
2831        hideExtendWin();
2832        jQuery('.map-biblicle-text-wrapper').hide();
2833        jQuery('.next-chapter').hide();
2834        jQuery('.multi-chapter').hide();
2835        var lid = nid ? nid : jQuery('.bauble-title').data('location-id');
2836        var data = Drupal.settings.mapSettings.mappedLocations[lid];
2837        var cityName = jQuery(context).parents().find('.bauble-title').first().text();
2838        var objData = {
2839            references: 1,
2840            cityName: data.title,
2841            nid: lid,
2842            lang: !Drupal.settings.pathPrefix ? '' : Drupal.settings.pathPrefix.slice(0, -1)// en/ -> en
2843
2844        };
2845        updateReferences(objData);
2846
2847        jQuery('.map-references-wrapper').show();
2848
2849
2850        if (!filterBox.hasClass('open')) {
2851            filterBox.addClass('open');
2852        }
2853        switchColorInBubles(context, true);
2854    }
2855    else {
2856        hideReferences();
2857        hideSummary();
2858        switchColorInBubles(context, false);
2859        var toggleOpen = jQuery(context).data('name');
2860        jQuery('.' + toggleOpen).slideToggle('slow', function () {
2861
2862        });
2863        if (locationHeight < 140) {
2864            locationHeight = 140;
2865        }
2866        jQuery(context).parents('.infoBoxWindow').find('.content-type').css('height', locationHeight - 12);
2867        jQuery(context).parents('.infoBoxWindow').find('.taxonomies').css('height', locationHeight - 12);
2868        jQuery(context).parent().parent().animate({ 'top': infoTop + 'px' }, 400);
2869        jQuery(context).parent().parent().animate({ 'bottom': jQuery('.wrapper-arr').height() + 'px' }, 400);
2870
2871        jQuery('section .content-type').perfectScrollbar();
2872        jQuery('.taxonomies').perfectScrollbar();
2873        jQuery('section .content-type').scrollTop(1);
2874    }
2875
2876}
2877
2878function switchColorInBubles(context, refrences) {
2879    if (jQuery('.sun-map.active').length) {
2880        jQuery('.wrapper-arr section').hide();
2881        jQuery('.sun-map.active').removeClass('active');
2882    }
2883    if (jQuery(context).hasClass('active')) {
2884        jQuery(context).removeClass('active');
2885        if (!refrences) {
2886            jQuery('.wrapper-arr section').hide();
2887        }
2888    }
2889    jQuery(context).addClass('active');
2890}
2891function doDraggable() {
2892
2893}
2894
2895function destroyDrag() {
2896
2897}
2898
2899function hideInfoWin(id) {
2900    if (id) {
2901        insertCustomUrl('');
2902    }
2903    jQuery('.infoBoxWindow').hide();
2904    hideReferences();
2905    showFilterBookChapter();
2906    closeInfo = true;
2907    if (globalMarkers[id]) {
2908        herzogMap.refreshMarker(globalMarkers[id], Drupal.settings.mapSettings.mappedLocations[id]);
2909    }
2910}
2911function hideExtendWin(extend) {
2912
2913    if (extend) {
2914        insertCustomUrl('')
2915    }
2916
2917    var id = jQuery('.bauble-title').data('location-id');
2918    var cssObj = {};
2919    if (Drupal.settings.pathPrefix == 'en/') {
2920        cssObj = {};
2921    }
2922    jQuery('#draggable-side-bar').css({ top: 'auto', left: 'auto' });
2923    jQuery('.infoBoxWindow.extend-view .bauble-header div.wrapper-arr').css({ top: 'auto' });
2924    jQuery('.bauble-header.bounce.ui-draggable').css(cssObj);
2925    jQuery('.infoBoxWindow.extend-view').hide();
2926    showSummary();
2927
2928    if (globalMarkers[id]) {
2929        herzogMap.refreshMarker(globalMarkers[id], Drupal.settings.mapSettings.mappedLocations[id]);
2930    }
2931}
2932function hideSummary() {
2933
2934    jQuery('.add-to-favorite').hide();
2935    if (!isMobile(window.innerWidth)) {
2936        jQuery('.arrow-down-info.desktop').show();
2937    }
2938    else {
2939        jQuery('.arrow-down-info').show();
2940    }
2941    jQuery('.print-info').hide();
2942}
2943
2944function showSummary() {
2945    jQuery('.infoBoxWindow.extend-view .bauble-header div.wrapper-arr').css({ top: 'auto' });
2946    jQuery('.sun-wrapper').css({ 'top': 'auto', bottom: 0 });
2947    jQuery('.wrapper-arr section').hide();
2948    jQuery('.arrow-down-info').hide();
2949    jQuery('.print-info').show();
2950    jQuery('.add-to-favorite').show();
2951    jQuery('.sun-map').removeClass('active');
2952
2953}
2954
2955function closeEntended(context) {
2956    jQuery(".infoBoxWindow.extend-view").hide();
2957
2958}
2959
2960function cloneInfo(currentId) {
2961
2962    if (globalMarkers[currentId]) {
2963        herzogMap.refreshMarker(globalMarkers[currentId], Drupal.settings.mapSettings.mappedLocations[currentId]);
2964    }
2965    var scrollTop = 0;
2966    jQuery('.bauble-header .title-section').data('nid', currentId);
2967    jQuery("#draggable-side-bar").draggable(
2968        {
2969            handle: "#draggable-handle-side-bar",
2970            containment: "#mapContainer",
2971            create: function (event, ui) {
2972                jQuery("#draggable-side-bar").css({ right: "auto" })
2973            }
2974        });
2975
2976    scrollTop += 1;
2977    if (scrollTop > 3) {
2978        scrollTop = 0;
2979    }
2980    var contentAttr = ['remainderCount', 'articlesCount', 'lessonsCount', 'postsCount'];
2981    var taxonomiesAttr = ['topics', 'personalities'];
2982    var taxonomiesArr = ['topicsArr', 'personalitiesArr'];
2983    var blogsArr = ['postsArr', 'lessonsArr', 'articlesArr'];
2984
2985    var location = Drupal.settings.mapSettings.mappedLocations[currentId];
2986
2987    var alsoCalled = jQuery('.location-text .also-called + span.text');
2988    var baubleTitle = jQuery('.bauble-title');
2989    var recalledPeriods = jQuery('.location-text .recalled-periods + span.text');
2990    var fewWords = jQuery('.location-text .few-words + span.text');
2991    var extendBody = jQuery('.location-summary .extend-body');
2992    var extendYoutube = jQuery('.location-summary .extend-youtube');
2993    var extendImage = jQuery('.location-summary .extend-image');
2994    var extendBibliography = jQuery('.location-summary .extend-bibliography');
2995    var sunWrapper = jQuery('section.sun-wrapper');
2996    var wrapperArr = jQuery('.wrapper-arr');
2997    var html = '';
2998
2999
3000    if (location.alsoCalled) {
3001        alsoCalled.prev().text(Drupal.t('Other Names') + ': ');
3002        alsoCalled.text(location.alsoCalled);
3003    }
3004    else {
3005        alsoCalled.prev().text('');
3006        alsoCalled.text('');
3007    }
3008
3009    var periods = '';
3010
3011    jQuery(location.periods).each(function (index, item) {
3012        periods += ' ' + item.periodName + ", ";
3013    });
3014
3015    if (periods) {
3016        recalledPeriods.text(periods);
3017        recalledPeriods.prev().text(Drupal.t('Biblical Eras') + ': ');
3018    }
3019    else {
3020        recalledPeriods.text('');
3021        recalledPeriods.prev().text('');
3022    }
3023
3024
3025
3026    //issue #2186
3027    if (location.fewWords) {
3028        fewWords.html(location.fewWords);
3029    }
3030    else {
3031        fewWords.text('');
3032    }
3033
3034    baubleTitle.text(location.title);
3035    baubleTitle.data('location-id', location.nid);
3036    extendBody.html(location.body);
3037    if (location.youtube) {
3038        extendYoutube.html('<div class="ext-media"><iframe width="100%" height="277" src="https://www.youtube.com/embed/' + location.youtube + '?rel=0" allowfullscreen="allowfullscreen" frameborder="0"/></div>');
3039    }
3040    else {
3041        extendYoutube.html('');
3042    }
3043    if (location.image) {
3044        extendImage.html('<div class="ext-media"><img src=' + location.image + '></div>');
3045    } else {
3046        extendImage.html('');
3047    }
3048    jQuery.each(contentAttr, function (key, contentName) {
3049        if (location[contentName][0] > 0) {
3050            var count = '<div class="sun-map-count">' + location[contentName][0] + '</div>';
3051            html += '<div class="sun-map-wrapper col-md-2 ' + location[contentName][1].toLocaleLowerCase() + '"><div data-name="' + location[contentName][1].toLocaleLowerCase() + 'Arr" onclick="openContentSum(this,' + location[contentName][0] + ')" class="sun-map sun-' + location[contentName][1].toLocaleLowerCase() + '">' + count + '</div><span class="sun-map-name">' + Drupal.t(location[contentName][1]) + '</span></div>';
3052        }
3053    });
3054
3055    jQuery.each(taxonomiesAttr, function (key, taxonomyName) {
3056        if (location[taxonomyName][0] > 0) {
3057            html += '<div class="sun-map-wrapper col-md-2">' +
3058                '<div onclick="openContentSum(this , false)" data-name="' + location[taxonomyName][1].toLocaleLowerCase() + 'Arr" class="sun-map sun-' + location[taxonomyName][1].toLocaleLowerCase() + '">' +
3059                '<div class="sun-map-count">' + location[taxonomyName][0] + '</div>' +
3060                '</div>' +
3061                '<span class="sun-map-name">' + Drupal.t(location[taxonomyName][1]) + '</span>' +
3062                '</div>';
3063        }
3064    });
3065
3066    sunWrapper.html(html);
3067    html = '';
3068    jQuery.each(blogsArr, function (key, nodeName) {
3069        html += '<section class="' + nodeName + ' clearfix">' +
3070            '<div class="blogs content-type"> ';
3071        jQuery.each(location[nodeName], function (index, val) {
3072            html += '<div class="content-wrapper">' +
3073                '<a class="content-title font-bold article" href="' + val['link'] + '" target="_blank">' + val['title'] + '</a>' +
3074                '<div class="content-author">' + val['author'] + '</div><span class="link font-bold">&nbsp;<i class=""></i></span></div>';
3075        });
3076        html += '</div></section>';
3077
3078    });
3079
3080    jQuery.each(taxonomiesArr, function (key, taxonomyName) {
3081        html += '<section class="' + taxonomyName + '">';
3082        if (location[taxonomyName].length > 0) {
3083            html += '<div class="taxonomies"><ul>';
3084            jQuery.each(location[taxonomyName], function (index, val) {
3085                html += '<li class="tax font-bold">' + val + '</li>'
3086            });
3087            html += '</ul></div>';
3088        }
3089        html += '</section>';
3090    });
3091
3092    wrapperArr.html(html);
3093
3094    if (location.bibliography) {
3095        extendBibliography.html('<div class="to-extend font-bold">' + Drupal.t('Bibliography') + '</div>' + location.bibliography.value);
3096    }
3097    else {
3098        extendBibliography.html('');
3099    }
3100    hideInfoWin();
3101    jQuery('.infoBoxWindow.extend-view').show();
3102
3103    jQuery('.infoBoxWindow.extend-view .location-summary').perfectScrollbar();
3104    jQuery('.infoBoxWindow.extend-view .location-summary').scrollTop(scrollTop);
3105}
3106
3107function printThisPage(nid) {
3108    if (!nid) {
3109        nid = jQuery('.bauble-header .title-section').data('nid');
3110    }
3111    jQuery('#printframe').attr('src', Drupal.settings.basePath + Drupal.settings.pathPrefix + 'print/' + nid);
3112    jQuery('#printframe').load(function () {
3113        jQuery(this)[0].contentWindow.print();
3114    });
3115}
3116
3117
3118;
3119(function(c){c.extend(c.fn,{validate:function(a){if(this.length){var b=c.data(this[0],"validator");if(b)return b;this.attr("novalidate","novalidate");b=new c.validator(a,this[0]);c.data(this[0],"validator",b);b.settings.onsubmit&&(this.validateDelegate(":submit","click",function(a){b.settings.submitHandler&&(b.submitButton=a.target);c(a.target).hasClass("cancel")&&(b.cancelSubmit=!0)}),this.submit(function(a){function e(){var e;return b.settings.submitHandler?(b.submitButton&&(e=c("<input type='hidden'/>").attr("name",
3120b.submitButton.name).val(b.submitButton.value).appendTo(b.currentForm)),b.settings.submitHandler.call(b,b.currentForm,a),b.submitButton&&e.remove(),!1):!0}b.settings.debug&&a.preventDefault();if(b.cancelSubmit)return b.cancelSubmit=!1,e();if(b.form())return b.pendingRequest?(b.formSubmitted=!0,!1):e();b.focusInvalid();return!1}));return b}a&&(a.debug&&window.console)&&console.warn("nothing selected, can't validate, returning nothing")},valid:function(){if(c(this[0]).is("form"))return this.validate().form();
3121var a=!0,b=c(this[0].form).validate();this.each(function(){a&=b.element(this)});return a},removeAttrs:function(a){var b={},d=this;c.each(a.split(/\s/),function(a,c){b[c]=d.attr(c);d.removeAttr(c)});return b},rules:function(a,b){var d=this[0];if(a){var e=c.data(d.form,"validator").settings,f=e.rules,g=c.validator.staticRules(d);switch(a){case "add":c.extend(g,c.validator.normalizeRule(b));f[d.name]=g;b.messages&&(e.messages[d.name]=c.extend(e.messages[d.name],b.messages));break;case "remove":if(!b)return delete f[d.name],
3122g;var h={};c.each(b.split(/\s/),function(a,b){h[b]=g[b];delete g[b]});return h}}d=c.validator.normalizeRules(c.extend({},c.validator.classRules(d),c.validator.attributeRules(d),c.validator.dataRules(d),c.validator.staticRules(d)),d);d.required&&(e=d.required,delete d.required,d=c.extend({required:e},d));return d}});c.extend(c.expr[":"],{blank:function(a){return!c.trim(""+a.value)},filled:function(a){return!!c.trim(""+a.value)},unchecked:function(a){return!a.checked}});c.validator=function(a,b){this.settings=
3123c.extend(!0,{},c.validator.defaults,a);this.currentForm=b;this.init()};c.validator.format=function(a,b){if(1===arguments.length)return function(){var b=c.makeArray(arguments);b.unshift(a);return c.validator.format.apply(this,b)};2<arguments.length&&b.constructor!==Array&&(b=c.makeArray(arguments).slice(1));b.constructor!==Array&&(b=[b]);c.each(b,function(b,c){a=a.replace(RegExp("\\{"+b+"\\}","g"),c)});return a};c.extend(c.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",
3124errorElement:"label",focusInvalid:!0,errorContainer:c([]),errorLabelContainer:c([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a;this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(a)).hide())},onfocusout:function(a){!this.checkable(a)&&(a.name in this.submitted||!this.optional(a))&&this.element(a)},onkeyup:function(a,
3125b){9===b.which&&""===this.elementValue(a)||(a.name in this.submitted||a===this.lastElement)&&this.element(a)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(a,b,d){"radio"===a.type?this.findByName(a.name).addClass(b).removeClass(d):c(a).addClass(b).removeClass(d)},unhighlight:function(a,b,d){"radio"===a.type?this.findByName(a.name).removeClass(b).addClass(d):c(a).removeClass(b).addClass(d)}},setDefaults:function(a){c.extend(c.validator.defaults,
3126a)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:c.validator.format("Please enter no more than {0} characters."),minlength:c.validator.format("Please enter at least {0} characters."),
3127rangelength:c.validator.format("Please enter a value between {0} and {1} characters long."),range:c.validator.format("Please enter a value between {0} and {1}."),max:c.validator.format("Please enter a value less than or equal to {0}."),min:c.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function a(a){var b=c.data(this[0].form,"validator"),d="on"+a.type.replace(/^validate/,"");b.settings[d]&&b.settings[d].call(b,this[0],a)}this.labelContainer=
3128c(this.settings.errorLabelContainer);this.errorContext=this.labelContainer.length&&this.labelContainer||c(this.currentForm);this.containers=c(this.settings.errorContainer).add(this.settings.errorLabelContainer);this.submitted={};this.valueCache={};this.pendingRequest=0;this.pending={};this.invalid={};this.reset();var b=this.groups={};c.each(this.settings.groups,function(a,d){"string"===typeof d&&(d=d.split(/\s/));c.each(d,function(c,d){b[d]=a})});var d=this.settings.rules;c.each(d,function(a,b){d[a]=
3129c.validator.normalizeRule(b)});c(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",a).val
3129idateDelegate("[type='radio'], [type='checkbox'], select, option","click",a);this.settings.invalidHandler&&c(this.currentForm).bind("invalid-form.validate",
3130this.settings.invalidHandler)},form:function(){this.checkForm();c.extend(this.submitted,this.errorMap);this.invalid=c.extend({},this.errorMap);this.valid()||c(this.currentForm).triggerHandler("invalid-form",[this]);this.showErrors();return this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(a){this.lastElement=a=this.validationTargetFor(this.clean(a));this.prepareElement(a);this.currentElements=
3131c(a);var b=!1!==this.check(a);b?delete this.invalid[a.name]:this.invalid[a.name]=!0;this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers));this.showErrors();return b},showErrors:function(a){if(a){c.extend(this.errorMap,a);this.errorList=[];for(var b in a)this.errorList.push({message:a[b],element:this.findByName(b)[0]});this.successList=c.grep(this.successList,function(b){return!(b.name in a)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):
3132this.defaultShowErrors()},resetForm:function(){c.fn.resetForm&&c(this.currentForm).resetForm();this.submitted={};this.lastElement=null;this.prepareForm();this.hideErrors();this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b=0,c;for(c in a)b++;return b},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},
3133focusInvalid:function(){if(this.settings.focusInvalid)try{c(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(a){}},findLastActive:function(){var a=this.lastActive;return a&&1===c.grep(this.errorList,function(b){return b.element.name===a.name}).length&&a},elements:function(){var a=this,b={};return c(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){!this.name&&
3134(a.settings.debug&&window.console)&&console.error("%o has no name assigned",this);return this.name in b||!a.objectLength(c(this).rules())?!1:b[this.name]=!0})},clean:function(a){return c(a)[0]},errors:function(){var a=this.settings.errorClass.replace(" ",".");return c(this.settings.errorElement+"."+a,this.errorContext)},reset:function(){this.successList=[];this.errorList=[];this.errorMap={};this.toShow=c([]);this.toHide=c([]);this.currentElements=c([])},prepareForm:function(){this.reset();this.toHide=
3135this.errors().add(this.containers)},prepareElement:function(a){this.reset();this.toHide=this.errorsFor(a)},elementValue:function(a){var b=c(a).attr("type"),d=c(a).val();return"radio"===b||"checkbox"===b?c('input[name="'+c(a).attr("name")+'"]:checked').val():"string"===typeof d?d.replace(/\r/g,""):d},check:function(a){a=this.validationTargetFor(this.clean(a));var b=c(a).rules(),d=!1,e=this.elementValue(a),f,g;for(g in b){var h={method:g,parameters:b[g]};try{if(f=c.validator.methods[g].call(this,e,
3136a,h.parameters),"dependency-mismatch"===f)d=!0;else{d=!1;if("pending"===f){this.toHide=this.toHide.not(this.errorsFor(a));return}if(!f)return this.formatAndAdd(a,h),!1}}catch(k){throw this.settings.debug&&window.console&&console.log("exception occured when checking element "+a.id+", check the '"+h.method+"' method",k),k;}}if(!d)return this.objectLength(b)&&this.successList.push(a),!0},customDataMessage:function(a,b){return c(a).data("msg-"+b.toLowerCase())||a.attributes&&c(a).attr("data-msg-"+b.toLowerCase())},
3137customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(a,b){return this.findDefined(this.customMessage(a.name,b),this.customDataMessage(a,b),!this.settings.ignoreTitle&&a.title||void 0,c.validator.messages[b],"<strong>Warning: No message defined for "+a.name+"</strong>")}
3137,formatAndAdd:function(a,b){var d=this.defaultMessage(a,
3138b.method),e=/\$?\{(\d+)\}/g;"function"===typeof d?d=d.call(this,b.parameters,a):e.test(d)&&(d=c.validator.format(d.replace(e,"{$1}"),b.parameters));this.errorList.push({message:d,element:a});this.errorMap[a.name]=d;this.submitted[a.name]=d},addWrapper:function(a){this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper)));return a},defaultShowErrors:function(){var a,b;for(a=0;this.errorList[a];a++)b=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,b.element,this.settings.errorClass,
3139this.settings.validClass),this.showLabel(b.element,b.message);this.errorList.length&&(this.toShow=this.toShow.add(this.containers));if(this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight){a=0;for(b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass)}this.toHide=this.toHide.not(this.toShow);this.hideErrors();this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},
3140invalidElements:function(){return c(this.errorList).map(function(){return this.element})},showLabel:function(a,b){var d=this.errorsFor(a);d.length?(d.removeClass(this.settings.validClass).addClass(this.settings.errorClass),d.attr("generated")&&d.html(b)):(d=c("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(a),generated:!0}).addClass(this.settings.errorClass).html(b||""),this.settings.wrapper&&(d=d.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.append(d).length||
3141(this.settings.errorPlacement?this.settings.errorPlacement(d,c(a)):d.insertAfter(a)));!b&&this.settings.success&&(d.text(""),"string"===typeof this.settings.success?d.addClass(this.settings.success):this.settings.success(d,a));this.toShow=this.toShow.add(d)},errorsFor:function(a){var b=this.idOrName(a);return this.errors().filter(function(){return c(this).attr("for")===b})},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(a){this.checkable(a)&&
3142(a=this.findByName(a.name).not(this.settings.ignore)[0]);return a},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(a){return c(this.currentForm).find('[name="'+a+'"]')},getLength:function(a,b){switch(b.nodeName.toLowerCase()){case "select":return c("option:selected",b).length;case "input":if(this.checkable(b))return this.findByName(b.name).filter(":checked").length}return a.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,
3143b):!0},dependTypes:{"boolean":function(a){return a},string:function(a,b){return!!c(a,b.form).length},"function":function(a,b){return a(b)}},optional:function(a){var b=this.elementValue(a);return!c.validator.methods.required.call(this,b,a)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(a,b){this.pendingRequest--;0>this.pendingRequest&&(this.pendingRequest=0);delete this.pending[a.name];b&&0===this.pendingRequest&&
3144this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.formSubmitted=!1):!b&&(0===this.pendingRequest&&this.formSubmitted)&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(a){return c.data(a,"previousValue")||c.data(a,"previousValue",{old:null,valid:!0,message:this.defaultMessage(a,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},
3145creditcard:{creditcard:!0}},addClassRules:function(a,b){a.constructor===String?this.classRuleSettings[a]=b:c.extend(this.classRuleSettings,a)},classRules:function(a){var b={};(a=c(a).attr("class"))&&c.each(a.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(b,c.validator.classRuleSettings[this])});return b},attributeRules:function(a){var b={};a=c(a);for(var d in c.validator.methods){var e;"required"===d?(e=a.get(0).getAttribute(d),""===e&&(e=!0),e=!!e):e=a.attr(d);e?b[d]=e:a[0].getAttribute("type")===
3146d&&(b[d]=!0)}b.maxlength&&/-1|2147483647|524288/.test(b.maxlength)&&delete b.maxlength;return b},dataRules:function(a){var b,d={},e=c(a);for(b in c.validator.methods)a=e.data("rule-"+b.toLowerCase()),void 0!==a&&(d[b]=a);return d},staticRules:function(a){var b={},d=c.data(a.form,"validator");d.settings.rules&&(b=c.validator.normalizeRule(d.settings.rules[a.name])||{});return b},normalizeRules:function(a,b){c.each(a,function(d,e){if(!1===e)delete a[d];else if(e.param||e.depends){var f=!0;switch(typeof e.depends){case "string":f=
3147!!c(e.depends,b.form).length;break;
3147case "function":f=e.depends.call(b,b)}f?a[d]=void 0!==e.param?e.param:!0:delete a[d]}});c.each(a,function(d,e){a[d]=c.isFunction(e)?e(b):e});c.each(["minlength","maxlength","min","max"],function(){a[this]&&(a[this]=Number(a[this]))});c.each(["rangelength","range"],function(){var b;a[this]&&(c.isArray(a[this])?a[this]=[Number(a[this][0]),Number(a[this][1])]:"string"===typeof a[this]&&(b=a[this].split(/[\s,]+/),a[this]=[Number(b[0]),Number(b[1])]))});c.validator.autoCreateRanges&&
3148(a.min&&a.max&&(a.range=[a.min,a.max],delete a.min,delete a.max),a.minlength&&a.maxlength&&(a.rangelength=[a.minlength,a.maxlength],delete a.minlength,delete a.maxlength));return a},normalizeRule:function(a){if("string"===typeof a){var b={};c.each(a.split(/\s/),function(){b[this]=!0});a=b}return a},addMethod:function(a,b,d){c.validator.methods[a]=b;c.validator.messages[a]=void 0!==d?d:c.validator.messages[a];3>b.length&&c.validator.addClassRules(a,c.validator.normalizeRule(a))},methods:{required:function(a,
3149b,d){return!this.depend(d,b)?"dependency-mismatch":"select"===b.nodeName.toLowerCase()?(a=c(b).val())&&0<a.length:this.checkable(b)?0<this.getLength(a,b):0<c.trim(a).length},remote:function(a,b,d){if(this.optional(b))return"dependency-mismatch";var e=this.previousValue(b);this.settings.messages[b.name]||(this.settings.messages[b.name]={});e.originalMessage=this.settings.messages[b.name].remote;this.settings.messages[b.name].remote=e.message;d="string"===typeof d&&{url:d}||d;if(e.old===a)return e.valid;
3150e.old=a;var f=this;this.startRequest(b);var g={};g[b.name]=a;c.ajax(c.extend(!0,{url:d,mode:"abort",port:"validate"+b.name,dataType:"json",data:g,success:function(d){f.settings.messages[b.name].remote=e.originalMessage;var g=!0===d||"true"===d;if(g){var j=f.formSubmitted;f.prepareElement(b);f.formSubmitted=j;f.successList.push(b);delete f.invalid[b.name];f.showErrors()}else j={},d=d||f.defaultMessage(b,"remote"),j[b.name]=e.message=c.isFunction(d)?d(a):d,f.invalid[b.name]=!0,f.showErrors(j);e.valid=
3151g;f.stopRequest(b,g)}},d));return"pending"},minlength:function(a,b,d){a=c.isArray(a)?a.length:this.getLength(c.trim(a),b);return this.optional(b)||a>=d},maxlength:function(a,b,d){a=c.isArray(a)?a.length:this.getLength(c.trim(a),b);return this.optional(b)||a<=d},rangelength:function(a,b,d){a=c.isArray(a)?a.length:this.getLength(c.trim(a),b);return this.optional(b)||a>=d[0]&&a<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,
3152b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},email:function(a,b){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(a)},
3153url:function(a,b){return this.optional(b)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},
3154date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test((new Date(a)).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c=0,e=0,f=!1;a=a.replace(/\D/g,"");for(var g=a.length-
31551;0<=g;g--){e=a.charAt(g);e=parseInt(e,10);if(f&&9<(e*=2))e-=9;c+=e;f=!f}return 0===c%10},equalTo:function(a,b,d){d=c(d);this.settings.onfocusout&&d.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){c(b).valid()});return a===d.val()}}});c.format=c.validator.format})(jQuery);
3156(function(c){var a={};
3156if(c.ajaxPrefilter)c.ajaxPrefilter(function(b,c,f){c=b.port;"abort"===b.mode&&(a[c]&&a[c].abort(),a[c]=f)});else{var b=c.ajax;c.ajax=function(d){var e=("port"in d?d:c.ajaxSettings).port;return"abort"===("mode"in d?d:c.ajaxSettings).mode?(a[e]&&a[e].abort(),a[e]=b.apply(this,arguments)):b.apply(this,arguments)}}})(jQuery);(function(c){c.extend(c.fn,{validateDelegate:function(a,b,d){return this.bind(b,function(b){var f=c(b.target);if(f.is(a))return d.apply(f,arguments)})}})})(jQuery);;
3157(function ($) {
3158
3159Drupal.googleanalytics = {};
3160
3161$(document).ready(function() {
3162
3163  // Attach mousedown, keyup, touchstart events to document only and catch
3164  // clicks on all elements.
3165  $(document.body).bind("mousedown keyup touchstart", function(event) {
3166
3167    // Catch the closest surrounding link of a clicked element.
3168    $(event.target).closest("a,area").each(function() {
3169
3170      // Is the clicked URL internal?
3171      if (Drupal.googleanalytics.isInternal(this.href)) {
3172        // Skip 'click' tracking, if custom tracking events are bound.
3173        if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
3174          // Do nothing here. The custom event will handle all tracking.
3175          //console.info("Click on .colorbox item has been detected.");
3176        }
3177        // Is download tracking activated and the file extension configured for download tracking?
3178        else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
3179          // Download link clicked.
3180          gtag('event', Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), {
3181            event_category: 'Downloads',
3182            event_label: Drupal.googleanalytics.getPageUrl(this.href),
3183            transport_type: 'beacon'
3184          });
3185        }
3186        else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
3187          // Keep the internal URL for Google Analytics website overlay intact.
3188          // @todo: May require tracking ID
3189          var target = this;
3190          $.each(Drupal.settings.googleanalytics.account, function () {
3191            gtag('config', this, {
3192              page_path: Drupal.googleanalytics.getPageUrl(target.href),
3193              transport_type: 'beacon'
3194            });
3195          });
3196        }
3197      }
3198      else {
3199        if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
3200          // Mailto link clicked.
3201          gtag('event', 'Click', {
3202            event_category: 'Mails',
3203            event_label: this.href.substring(7),
3204            transport_type: 'beacon'
3205          });
3206        }
3207        else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
3208          if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
3209            // External link clicked / No top-level cross domain clicked.
3210            gtag('event', 'Click', {
3211              event_category: 'Outbound links',
3212              event_label: this.href,
3213              transport_type: 'beacon'
3214            });
3215          }
3216        }
3217      }
3218    });
3219  });
3220
3221  // Track hash changes as unique pageviews, if this option has been enabled.
3222  if (Drupal.settings.googleanalytics.trackUrlFragments) {
3223    window.onhashchange = function() {
3224      $.each(Drupal.settings.googleanalytics.account, function () {
3225        gtag('config', this, {
3226          page_path: location.pathname + location.search + location.hash
3227        });
3228      });
3229    };
3230  }
3231
3232  // Colorbox: This event triggers when the transition has completed and the
3233  // newly loaded content has been revealed.
3234  if (Drupal.settings.googleanalytics.trackColorbox) {
3235    $(document).bind("cbox_complete", function () {
3236      var href = $.colorbox.element().attr("href");
3237      if (href) {
3238        $.each(Drupal.settings.googleanalytics.account, function () {
3239          gtag('config', this, {
3240            page_path: Drupal.googleanalytics.getPageUrl(href)
3241          });
3242        });
3243      }
3244    });
3245  }
3246
3247});
3248
3249/**
3250 * Check whether the hostname is part of the cross domains or not.
3251 *
3252 * @param string hostname
3253 *   The hostname of the clicked URL.
3254 * @param array crossDomains
3255 *   All cross domain hostnames as JS array.
3256 *
3257 * @return boolean
3258 */
3259Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) {
3260  /**
3261   * jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is
3262   * `null` or `undefined`, https://bugs.jquery.com/ticket/10076,
3263   * https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174
3264   *
3265   * @todo: Remove/Refactor in D8
3266   */
3267  if (!crossDomains) {
3268    return false;
3269  }
3270  else {
3271    return $.inArray(hostname, crossDomains) > -1 ? true : false;
3272  }
3273};
3274
3275/**
3276 * Check whether this is a download URL or not.
3277 *
3278 * @param string url
3279 *   The web url to check.
3280 *
3281 * @return boolean
3282 */
3283Drupal.googleanalytics.isDownload = function (url) {
3284  var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
3285  return isDownload.test(url);
3286};
3287
3288/**
3289 * Check whether this is an absolute internal URL or not.
3290 *
3291 * @param string url
3292 *   The web url to check.
3293 *
3294 * @return boolean
3295 */
3296Drupal.googleanalytics.isInternal = function (url) {
3297  var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
3298  return isInternal.test(url);
3299};
3300
3301/**
3302 * Check whether this is a special URL or not.
3303 *
3304 * URL types:
3305 *  - gotwo.module /go/* links.
3306 *
3307 * @param string url
3308 *   The web url to check.
3309 *
3310 * @return boolean
3311 */
3312Drupal.googleanalytics.isInternalSpecial = function (url) {
3313  var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
3314  return isInternalSpecial.test(url);
3315};
3316
3317/**
3318 * Extract the relative internal URL from an absolute internal URL.
3319 *
3320 * Examples:
3321 * - https://mydomain.com/node/1 -> /node/1
3322 * - https://example.com/foo/bar -> https://example.com/foo/bar
3323 *
3324 * @param string url
3325 *   The web url to check.
3326 *
3327 * @return string
3328 *   Internal website URL
3329 */
3330Drupal.googleanalytics.getPageUrl = function (url) {
3331  var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i");
3332  return url.replace(extractInternalUrl, '');
3333};
3334
3335/**
3336 * Extract the download file extension from the URL.
3337 *
3338 * @param string url
3339 *   The web url to check.
3340 *
3341 * @return string
3342 *   The file extension of the passed url. e.g. "zip", "txt"
3343 */
3344Drupal.googleanalytics.getDownloadExtension = function (url) {
3345  var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
3346  var extension = extractDownloadextension.exec(url);
3347  return (extension === null) ? '' : extension[1];
3348};
3349
3350})(jQuery);
3351;

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.