1!function(){"use strict";var e,t={noop:function(){},texturize:function(e){return(e=(e=(e=(e+="").replace(/'/g,"’").replace(/'/g,"’")).replace(/"/g,"”").replace(/"/g,"”").replace(/"/g,"”").replace(/[\u201D]/g,"”")).replace(/([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g,'$1="$2"')).trim()},applyReplacements:function(e,t){if(e)return t?e.replace(/{(\d+)}/g,function(e,r){return void 0!==t[r]?t[r]:e}):e},getBackgroundImage:function(e){var t=document.createElement("canvas"),r=t.getContext&&t.getContext("2d");if(e){r.filter="blur(20px) ",r.drawImage(e,0,0);var o=t.toDataURL("image/png");return t=null,o}}},r=function(){function e(e,t){return Element.prototype.matches?e.matches(t):Element.prototype.msMatchesSelector?e.msMatchesSelector(t):void 0}function r(e,t,r,o){if(!e)return o();e.jpCarouselCancelFade&&e.jpCarouselCancelFade(),e.classList.remove("jp-carousel-fade"),e.style.removeProperty("display"),e.style.opacity=t,e.style.pointerEvents="none",e.offsetWidth,e.classList.add("jp-carousel-fade"),e.style.opacity=r;var a=1e3*parseFloat(getComputedStyle(e).transitionDuration)||0,i=setTimeout(function(){e.jpCarouselCancelFade=null,e.style.removeProperty("pointer-events"),o()},a+50);e.jpCarouselCancelFade=function(){clearTimeout(i),e.jpCarouselCancelFade=null}}return{closest:function(t,r){if(t.closest)return t.closest(r);var o=t;do{if(e(o,r))return o;o=o.parentElement||o.parentNode}while(null!==o&&1===o.nodeType);return null},matches:e,hide:function(e){e&&(e.style.display="none")},show:function(e){e&&(e.style.display="block")},fadeIn:function(e,o){r(e,0,1,o=o||t.noop)},fadeOut:function(e,o){o=o||t.noop,r(e,1,0,function(){e&&(e.style.display="none"),o()})},scrollToElement:function(e,t,r){if(!e||!t)return r?r():void 0;var o=t.querySelector(".jp-carousel-info-extra");o&&(o.style.minHeight=window.innerHeight-64+"px");var a=!0,i=Date.now(),n=t.scrollTop,l=Math.max(0,e.offsetTop-Math.max(0,window.innerHeight-function(e){var t=e.querySelector(".jp-carousel-info-footer"),r=e.querySelector(".jp-carousel-info-extra"),o=e.querySelector(".jp-carousel-info-content-wrapper");if(t&&r&&o){var a=window.getComputedStyle(r),i=parseInt(a.paddingTop,10)+parseInt(a.paddingBottom,10);return i=isNaN(i)?0:i,o.offsetHeight+t.offsetHeight+i}return 0}(t)))-t.scrollTop;function s(){a=!1}l=Math.min(l,t.scrollHeight-window.innerHeight),t.addEventListener("wheel",s),function e(){var c,u=Date.now(),d=(c=(u-i)/300)<.5?2*c*c:1-Math.pow(-2*c+2,2)/2,p=(d=d>1?1:d)*l;if(t.scrollTop=n+p,u<=i+300&&a)return requestAnimationFrame(e);r&&r(),o&&(o.style.minHeight=""),a=!1,t.removeEventListener("wheel",s)}()},getJSONAttribute:function(e,t){if(e&&e.hasAttribute(t))try{return JSON.parse(e.getAttribute(t))}catch{return}},convertToPlainText:function(e){var t=document.createElement("div");return t.textContent=e,t.innerHTML},stripHTML:function(e){var t=document.createElement("div");return t.innerHTML=e.replace(/<[^>]*>?/gm,""),t.textContent},emitEvent:function(e,t,r){var o;try{o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:r||null})}catch{(o=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,r||null)}e.dispatchEvent(o)},isTouch:function(){return"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch}}}();function o(){var o,a,i,n,l="",s=!1,c="div.gallery, div.tiled-gallery, ul.wp-block-gallery, ul.blocks-gallery-grid, figure.wp-block-gallery.has-nested-images, div.wp-block-jetpack-tiled-gallery, a.single-image-gallery",u=".gallery-item, .tiled-gallery-item, .blocks-gallery-item, .tiled-gallery__item",d=u+", .wp-block-image",p={},m="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.stat?wpcom.carousel.stat:t.noop,g="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.pageview?wpcom.carousel.pageview:t.noop;function h(t){if(!s)switch(t.which){case 38:t.preventDefault(),p.overlay.scrollTop-=100;break;case 40:t.preventDefault(),p.overlay.scrollTop+=100;break;case 39:t.preventDefault(),e.slideNext();break;case 37:case 8:t.preventDefault(),e.slidePrev();break;case 27:t.preventDefault(),x()}}function f(){s=!0}function v(){s=!1}function y(e){e.role="button",e.tabIndex=0,e.ariaLabel=jetpackCarouselStrings.image_label}function w(){p.overlay||(p.overlay=document.querySelector(".jp-carousel-overlay"),p.container=p.overlay.querySelector(".jp-carousel-wrap"),p.gallery=p.container.querySelector(".jp-carousel"),p.info=p.overlay.querySelector(".jp-carousel-info"),p.caption=p.info.querySelector(".jp-carousel-caption"),p.commentField=p.overlay.querySelector("#jp-carousel-comment-form-comment-field"),p.emailField=p.overlay.querySelector("#jp-carousel-comment-form-email-field"),p.authorField=p.overlay.querySelector("#jp-carousel-comment-form-author-field"),p.urlField=p.overlay.querySelector("#jp-carousel-comment-form-url-field"),window.innerWidth<=760&&Math.round(window.innerWidth/760*110)<40&&r.isTouch(),[p.commentField,p.emailField,p.authorField,p.urlField].forEac
1h(function(e){e&&(e.addEventListener("focus",f),e.addEventListener("blur",v))}),p.overlay.addEventListener("click",function(e){var t,o,a=e.target,i=!!r.closest(a,".jp-carousel-close-hint"),n=!!window.matchMedia("(max-device-width: 760px)").matches;a===p.overlay?n||x():i?x():a.classList.contains("jp-carousel-image-download")?m("download_original_click"):a.classList.contains("jp-carousel-comment-login")?(t=p.currentSlide,o=t?t.attrs.attachmentId:"0",window.location.href=jetpackCarouselStrings.login_url+"%23jp-carousel-"+o):r.closest(a,"#jp-carousel-comment-form-container")?function(e){var t=e.target,o=r.getJSONAttribute(p.container,"data-carousel-extra")||{},a=p.currentSlide.attrs.attachmentId,i=document.querySelector("#jp-carousel-comment-form-submit-and-info-wrapper"),n=document.querySelector("#jp-carousel-comment-form-spinner"),l=document.querySelector("#jp-carousel-comment-form-button-submit"),s=document.querySelector("#jp-carousel-comment-form");if(p.commentField&&p.commentField.getAttribute("id")===t.getAttribute("id"))f(),r.show(i);else if(r.matches(t,'input[type="submit"]')){e.preventDefault(),e.stopPropagation(),r.show(n),s.classList.add("jp-carousel-is-disabled");var c={action:"post_attachment_comment",nonce:jetpackCarouselStrings.nonce,blog_id:o.blog_id,id:a,comment:p.commentField.value};if(!c.comment.length)return void j(jetpackCarouselStrings.no_comment_text,!1);if(1!==Number(jetpackCarouselStrings.is_logged_in)&&(c.email=p.emailField.value,c.author=p.authorField.value,c.url=p.urlField.value,1===Number(jetpackCarouselStrings.require_name_email))){if(!c.email.length||!c.email.match("@"))return void j(jetpackCarouselStrings.no_comment_email,!1);if(!c.author.length)return void j(jetpackCarouselStrings.no_comment_author,!1)}var u=new XMLHttpRequest;u.open("POST",jetpackCarouselStrings.ajaxurl,!0),u.setRequestHeader("X-Requested-With","XMLHttpRequest"),u.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),u.onreadystatechange=function(){if(this.readyState===XMLHttpRequest.DONE&&this.status>=200&&this.status<300){var e;try{e=JSON.parse(this.response)}catch{return void j(jetpackCarouselStrings.comment_post_error,!1)}"approved"===e.comment_status?j(jetpackCarouselStrings.comment_approved,!0):"unapproved"===e.comment_status?j(jetpackCarouselStrings.comment_unapproved,!0):j(jetpackCarouselStrings.comment_post_error,!1),H(),q(a),l.value=jetpackCarouselStrings.post_comment,r.hide(n),s.classList.remove("jp-carousel-is-disabled")}else j(jetpackCarouselStrings.comment_post_error,!1)};var d=[];for(var m in c)if(m){var g=encodeURIComponent(m)+"="+encodeURIComponent(c[m]);d.push(g.replace(/%20/g,"+"))}var h=d.join("&");u.send(h)}}(e):(r.closest(a,".jp-carousel-photo-icons-container")||a.classList.contains("jp-carousel-photo-title"))&&function(e){e.preventDefault();var t=e.target,o=p.info.querySelector(".jp-carousel-info-extra"),a=p.info.querySelector(".jp-carousel-image-meta"),i=p.info.querySelector(".jp-carousel-comments-wrapper"),n=p.info.querySelector(".jp-carousel-icon-info"),l=p.info.querySelector(".jp-carousel-icon-comments");function s(){l&&l.classList.remove("jp-carousel-selected"),n.classList.toggle("jp-carousel-selected"),i&&i.classList.remove("jp-carousel-show"),a&&(a.classList.toggle("jp-carousel-show"),a.classList.contains("jp-carousel-show")?o.classList.add("jp-carousel-show"):o.classList.remove("jp-carousel-show"))}function c(){n&&n.classList.remove("jp-carousel-selected"),l.classList.toggle("jp-carousel-selected"),a&&a.classList.remove("jp-carousel-show"),i&&(i.classList.toggle("jp-carousel-show"),i.classList.contains("jp-carousel-show")?o.classList.add("jp-carousel-show"):o.classList.remove("jp-carousel-show"))}(r.closest(t,".jp-carousel-icon-info")||t.classList.contains("jp-carousel-photo-title"))&&(a&&a.classList.contains("jp-carousel-show")?r.scrollToElement(p.overlay,p.overlay,s):(s(),r.scrollToElement(p.info,p.overlay))),r.closest(t,".jp-carousel-icon-comments")&&(i&&i.classList.contains("jp-carousel-show")?r.scrollToElement(p.overlay,p.overlay,c):(c(),r.scrollToElement(p.info,p.overlay)))}(e)}),window.addEventListener("keydown",h),p.overlay.addEventListener("jp_carousel.afterOpen",function(){v(),p.slides.length<=1||(p.slides.length<=5?r.show(p.info.querySelector(".jp-swiper-pagination")):r.show(p.info.querySelector(".jp-carousel-pagination")))}),p.overlay.addEventListener("jp_carousel.beforeClose",function(){f(),document.documentElement.style.removeProperty("height"),e&&e.enable(),r.hide(p.info.querySelector(".jp-swiper-pagination")),r.hide(p.info.querySelector(".jp-carousel-pagination"))}),p.overlay.addEventListener("jp_carousel.afterClose",function(){window.history.pushState?history.pushState("",document.title,window.location.pathname+window.location.search):window.location.href="",l="",p.isOpen=!1}),p.overlay.addEventListener("touchstart",function(e){e.touches.length>1&&e.preventDefault()}))}function j(e,t){var o=p.overlay.querySelector("#jp-carousel-comment-post-results"),a="jp-carousel-comment-post-"+(t?"success":"error");o.innerHTML='<span class="'+a+'">'+e+"</span>",r.hide(p.overlay.querySelector("#jp-carousel-comment-form-spinner")),p.overlay.querySelector("#jp-carousel-comment-form").classList.remove("jp-carousel-is-disabled"),r.show(o)}function b(){var e=document.querySelectorAll("a img[data-attachment-id]");Array.prototype.forEach.call(e,function(e){var t=e.parentElement,o=t.parentElement;if(!o.classList.contains("gallery-icon")&&!r.closest(o,u)&&t.hasAttribute("href")){var a=!1;t.getAttribute("href").split("?")[0]===e.getAttribute("data-orig-file").split("?")[0]&&1===Number(jetpackCarouselStrings.single_image_gallery_media_file)&&(a=!0),t.getAttribute("href")===e.getAttribute("data-permalink")&&(a=!0),a&&(y(e),t.classList.add("single-image-gallery"),t.setAttribute("data-carousel-extra",JSON.stringify({blog_id:Number(jetpackCarouselStrings.blog_id)})))}})}function S(t,r){p.isOpen?(L(r),e.slideTo(r+1)):M(t,{startIndex:r})}function L(e){(!e||e<0||e>p.slides.length)&&(e=0),p.currentSlide=p.slides[e];var o,a,i=p.currentSlide,n=i.attrs.attachmentId;A(p.slides[e]),function(e){var t=[],r=p.slides.length;if(r>1){var o=e>0?e-1:r-1;t.push(o);var a=e<r-1?e+1:0;t.push(a)}t.forEach(function(e){var t=p.slides[e];t&&(A(t),1!==Number(jetpackCarouselStrings.display_background_image)||t.backgroundImage||_(t))})}(e),1!==Number(jetpackCarouselStrings.display_background_image)||p.slides[e].backgroundImage||_(p.slides[e]),r.hide(p.caption),function(e){var t,o,a,i,n,l,s;if(i=p.overlay.querySelector(".jp-carousel-photo-caption"),n=p.overlay.querySelector(".jp-carousel-caption"),l=p.overlay.querySelector(".jp-carousel-photo-title"),s=p.overlay.querySelector(".jp-carousel-photo-description"),r.hide(i),r.hide(n),r.hide(l),r.hide(s),t=E(e.caption)||"",o=E(e.title)||"",a=E(e.desc)||"",(t||o||a)&&(t&&(i.innerHTML=t,n.innerHTML=t,r.show(i),r.show(n)),r.stripHTML(t)===r.stripHTML(o)&&(o=""),r.stripHTML(t)===r.stripHTML(a)&&(a=""),r.stripHTML(o)===r.stripHTML(a)&&(a=""),a&&(s.innerHTML=a,r.show(s),o||t||(i.textContent=r.stripHTML(a),r.show(i))),o)){var c=r.stripHTML(o);l.textContent=c,t||(i.textContent=c,n.textContent=c,r.show(i)),r.show(l)}}
1({caption:i.attrs.caption,title:i.attrs.title,desc:i.attrs.desc}),function(e){if(!e||1!==Number(jetpackCarouselStrings.display_exif))return!1;var t=p.info.querySelector(".jp-carousel-image-meta");if(!t)return!1;var r="";for(var o in e){var a=e[o],i=jetpackCarouselStrings.meta_data||[];if(0!==parseFloat(a)&&a.length&&-1!==i.indexOf(o)){switch(o){case"focal_length":a+="mm";break;case"shutter_speed":a=C(a);break;case"aperture":a="f/"+a}r+="<li><h5>"+jetpackCarouselStrings[o]+"</h5>"+a+"</li>"}}var n=t.querySelector("ul.jp-carousel-image-exif");if(""!==r){if(!n){(n=document.createElement("ul")).className="jp-carousel-image-exif";var l=t.querySelector(".jp-carousel-title-and-caption");l&&l.nextSibling?t.insertBefore(n,l.nextSibling):t.insertBefore(n,t.firstChild)}n.innerHTML=r,n.style.removeProperty("display")}else n&&n.parentNode.removeChild(n)}(p.slides[e].attrs.imageMeta),function(e){if(!e)return!1;var r,o=[e.attrs.origWidth,e.attrs.origHeight],a=document.createElement("a");a.href=e.attrs.src.replace(/\?.+$/,""),r=null!==a.hostname.match(/^i[\d]{1}\.wp\.com$/i)?a.href:e.attrs.origFile.replace(/\?.+$/,"");var i=p.info.querySelector(".jp-carousel-download-text"),n=p.info.querySelector(".jp-carousel-image-download");i.innerHTML=t.applyReplacements(jetpackCarouselStrings.download_original,o),n.setAttribute("href",r),n.style.removeProperty("display")}(i),1===Number(jetpackCarouselStrings.display_comments)&&(o=p.slides[e].attrs.commentsOpened,a=p.info.querySelector("#jp-carousel-comment-form-container"),1===parseInt(o,10)?r.fadeIn(a):r.fadeOut(a),q(n),r.hide(p.info.querySelector("#jp-carousel-comment-post-results")));var s=p.info.querySelector(".jp-carousel-pagination");if(s&&p.slides.length>5){var c=e+1;s.innerHTML="<span>"+c+" / "+p.slides.length+"</span>"}jetpackCarouselStrings.stats&&p.isOpen&&((new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?"+jetpackCarouselStrings.stats+"&post="+encodeURIComponent(n)+"&rand="+Math.random()),p.isOpen&&g(n),l="#jp-carousel-"+n,window.location.hash=l}function x(){document.body.style.overflow=a,document.documentElement.style.overflow=i,H(),f(),r.emitEvent(p.overlay,"jp_carousel.beforeClose"),window.scrollTo(window.scrollX||window.pageXOffset||0,n||0),p.isOpen=!1,e.destroy(),p.slides=[],p.currentSlide=void 0,p.gallery.innerHTML="",r.fadeOut(p.overlay,function(){r.emitEvent(p.overlay,"jp_carousel.afterClose")})}function k(e){if("object"!=typeof e&&(e={}),void 0===e.origFile)return"";if(void 0===e.origWidth||void 0===e.maxWidth)return e.origFile;if(!e.largeFile)return e.origFile;var t=document.createElement("a");t.href=e.largeFile;var r=/^i[0-2]\.wp\.com$/i.test(t.hostname),o=function(e,t,r){var o,a=r?e.replace(/.*=([\d]+%2C[\d]+).*$/,"$1"):e.replace(/.*-([\d]+x[\d]+)\..+$/,"$1");return"9999"===(o=a!==e?r?a.split("%2C"):a.split("x"):[t,0])[0]&&(o[0]="0"),"9999"===o[1]&&(o[1]="0"),o}(e.largeFile,e.origWidth,r),a=parseInt(o[0],10),i=parseInt(o[1],10);if(e.origMaxWidth=e.maxWidth,e.origMaxHeight=e.maxHeight,void 0!==window.devicePixelRatio&&window.devicePixelRatio>1&&(e.maxWidth=e.maxWidth*window.devicePixelRatio,e.maxHeight=e.maxHeight*window.devicePixelRatio),a>=e.maxWidth||i>=e.maxHeight)return e.largeFile;if(r){if(-1===e.largeFile.lastIndexOf("?"))return e.largeFile;var n=function(e){var t;try{t=new URL(e)}catch(t){return e}var r=["quality","ssl","filter","brightness","contrast","colorize","smooth"],o=Array.from(t.searchParams.entries());return t.search="",o.forEach(([e,o])=>{r.includes(e)&&t.searchParams.append(e,o)}),t}(e.largeFile);return(e.origWidth>e.maxWidth||e.origHeight>e.maxHeight)&&(e.origMaxWidth=2*e.maxWidth,e.origMaxHeight=2*e.maxHeight,n.searchParams.set("fit",e.origMaxWidth+","+e.origMaxHeight)),n.toString()}return e.origFile}function C(e){return e>=1?Math.round(10*e)/10+"s":"1/"+Math.round(1/e)+"s"}function E(e){return!e.match(" ")&&e.match("_")?"":e}function q(e,t){var a=void 0===t,i=p.info.querySelector(".jp-carousel-icon-comments .jp-carousel-has-comments-indicator");if(i.classList.remove("jp-carousel-show"),clearInterval(o),e){(!t||t<1)&&(t=0);var n=p.info.querySelector(".jp-carousel-comments"),l=p.info.querySelector("#jp-carousel-comments-loading");r.show(l),a&&(r.hide(n),n.innerHTML="");var s=new XMLHttpRequest,c=jetpackCarouselStrings.ajaxurl+"?action=get_attachment_comments&nonce="+jetpackCarouselStrings.nonce+"&id="+e+"&offset="+t;s.open("GET",c),s.setRequestHeader("X-Requested-With","XMLHttpRequest");var u=function(){r.fadeIn(n),r.fadeOut(l)};s.onload=function(){if(p.currentSlide&&p.currentSlide.attrs.attachmentId===e){var c,d=s.status>=200&&s.status<300;try{c=JSON.parse(s.responseText)}catch{}if(!d||!c||!Array.isArray(c))return u();a&&(n.innerHTML="");for(var m=0;m<c.length;m++){var g=c[m],h=document.createElement("div");h.classList.add("jp-carousel-comment"),h.setAttribute("id","jp-carousel-comment-"+g.id),h.innerHTML='<div class="comment-gravatar">'+g.gravatar_markup+'</div><div class="comment-content"><div class="comment-author">'+g.author_markup+'</div><div class="comment-date">'+g.date_gmt+"</div>"+g.content+"</div>",n.appendChild(h),clearInterval(o),o=setInterval(function(){p.container.scrollTop+150>window.innerHeight&&(q(e,t+10),clearInterval(o))},300)}c.length>0&&(r.show(n),i.innerText=c.length,i.classList.add("jp-carousel-show")),r.hide(l)}},s.onerror=u,s.send()}}function A(e){var t=e.attrs,r=e.el.querySelector("img");if(!r.hasAttribute("data-loaded"))if(r.setAttribute("itemprop","image"),r.setAttribute("data-loaded",1),t.previewImage&&t.previewImage!==t.src){r.src=t.previewImage,r.style.filter="blur(8px)";var o=new window.Image;o.addEventListener("load",function(){r.src=t.src,r.style.filter=""},{once:!0}),o.addEventListener("error",function(){r.style.filter=""},{once:!0}),o.src=t.src}else r.src=t.src}function _(e){var t=e.attrs.originalElement;if(t)if(t.complete&&0!==t.naturalHeight)T(e,t);else{var r=function(){t.removeEventListener("error",o),T(e,t)},o=function(){t.removeEventListener("load",r)};t.addEventListener("load",r,{once:!0}),t.addEventListener("error",o,{once:!0})}}
1function T(e,r){var o=t.getBackgroundImage(r);o&&(e.backgroundImage=o,e.el.style.backgroundImage="url("+o+")",e.el.style.backgroundSize="cover",e.el.style.backgroundPosition="center")}function H(){p.commentField&&(p.commentField.value="")}function I(e,o){p.slides=[];var a={width:window.innerWidth,height:window.innerHeight-64};0!==o&&null!==e[o].getAttribute("data-gallery-src")&&((new Image).src=e[o].getAttribute("data-gallery-src")),Array.prototype.forEach.call(e,function(e,o){var i=r.closest(e,"a"),n=e.getAttribute("data-orig-file")||e.getAttribute("src-orig"),l=e.getAttribute("data-attachment-id")||e.getAttribute("data-id")||"0",s=document.querySelector('img[data-attachment-id="'+l+'"] + figcaption');s=s?s.innerHTML:e.getAttribute("data-image-caption");var c={originalElement:e,attachmentId:l,commentsOpened:e.getAttribute("data-comments-opened")||"0",imageMeta:r.getJSONAttribute(e,"data-image-meta")||{},title:e.getAttribute("data-image-title")||"",desc:e.getAttribute("data-image-description")||"",largeFile:e.getAttribute("data-large-file")||"",origFile:n||"",thumbSize:{width:e.naturalWidth,height:e.naturalHeight},caption:s||"",permalink:i&&i.getAttribute("href"),src:n||e.getAttribute("src")||""},u=r.closest(e,".tiled-gallery-item"),d=u&&u.querySelector(".tiled-gallery-caption"),m=d&&d.innerHTML;m&&(c.caption=m);var g=function(e){var t=e.getAttribute("data-orig-size")||"";if(t){var r=t.split(",");return{width:parseInt(r[0],10),height:parseInt(r[1],10)}}return{width:e.getAttribute("data-original-width")||e.getAttribute("width")||void 0,height:e.getAttribute("data-original-height")||e.getAttribute("height")||void 0}}(e);if(c.origWidth=g.width||c.thumbSize.width,c.origHeight=g.height||c.thumbSize.height,"undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.generateImgSrc?c.src=wpcom.carousel.generateImgSrc(e,a):c.src=k({origFile:c.src,origWidth:c.origWidth,origHeight:c.origHeight,maxWidth:a.width,maxHeight:a.height,largeFile:c.largeFile}),e.setAttribute("data-gallery-src",c.src),"0"!==c.attachmentId){c.title=t.texturize(c.title),c.desc=t.texturize(c.desc),c.caption=t.texturize(c.caption);var h=new Image,f=document.createElement("div");f.classList.add("swiper-slide"),f.setAttribute("itemprop","associatedMedia"),f.setAttribute("itemscope",""),f.setAttribute("itemtype","https://schema.org/ImageObject");var v=document.createElement("div");v.classList.add("swiper-zoom-container"),p.gallery.appendChild(f),f.appendChild(v),v.appendChild(h),f.setAttribute("data-attachment-id",c.attachmentId),f.setAttribute("data-permalink",c.permalink),f.setAttribute("data-orig-file",c.origFile),c.previewImage=e.currentSrc||e.getAttribute("src")||"";var y={el:f,attrs:c,index:o};p.slides.push(y)}})}function M(e,t){if(!window.JetpackSwiper){var o=document.querySelector("#jp-carousel-loading-overlay");r.show(o);var a=document.createElement("script");return a.id="jetpack-carousel-swiper-js",a.src=window.jetpackSwiperLibraryPath.url,a.async=!0,a.onload=function(){r.hide(o),F(e,t)},a.onerror=function(){r.hide(o)},void document.head.appendChild(a)}F(e,t)}function F(t,o){var l,s={imgSelector:".gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id], img[data-attachment-id], img[data-id]",startIndex:0},c=r.getJSONAttribute(t,"data-carousel-extra");if(!c)return;const u=t.querySelectorAll(s.imgSelector);if(u.length&&(w(),!p.isOpen)){for(var d in p.isOpen=!0,a=getComputedStyle(document.body).overflow,document.body.style.overflow="hidden",i=getComputedStyle(document.documentElement).overflow,document.documentElement.style.overflow="hidden",n=window.scrollY||window.pageYOffset||0,p.container.setAttribute("data-carousel-extra",JSON.stringify(c)),m(["open","view_image"]),o||{})s[d]=o[d];-1===s.startIndex&&(s.startIndex=0),r.emitEvent(p.overlay,"jp_carousel.beforeOpen"),p.gallery.innerHTML="",p.overlay.style.opacity=1,p.overlay.style.display="block",I(u,s.startIndex),(e=new window.JetpackSwiper(".jp-carousel-swiper-container",{centeredSlides:!0,zoom:!0,loop:p.slides.length>1,enabled:p.slides.length>1,pagination:{el:".jp-swiper-pagination",clickable:!0},navigation:{nextEl:".jp-swiper-button-next",prevEl:".jp-swiper-button-prev"},initialSlide:s.startIndex,on:{init:function(){L(s.startIndex)}},preventClicks:!1,preventClicksPropagation:!1,preventInteractionOnTransition:!r.isTouch(),threshold:5})).on("slideChange",function(e){p.isOpen&&(L(e.realIndex),p.overlay.classList.remove("jp-carousel-hide-control
1s"))}),e.on("zoomChange",function(e,t){t>1&&p.overlay.classList.add("jp-carousel-hide-controls"),1===t&&p.overlay.classList.remove("jp-carousel-hide-controls")}),e.on("doubleTap",function(e){if(clearTimeout(l),1===e.zoom.scale)var t=setTimeout(function(){p.overlay.classList.remove("jp-carousel-hide-controls"),clearTimeout(t)},150)}),e.on("tap",function(){e.zoom.scale>1&&(l=setTimeout(function(){p.overlay.classList.toggle("jp-carousel-hide-controls")},150))}),r.fadeIn(p.overlay,function(){r.emitEvent(p.overlay,"jp_carousel.afterOpen")})}}function O(e){if("click"!==e.type){if("keydown"===e.type){const t=document.activeElement.parentElement,r=t&&t.classList.contains("tiled-gallery__item");" "!==e.key&&"Enter"!==e.key||!r||R(e)}}else R(e)}function N(e){return(e||"").split("?")[0].replace(/\/$/,"")}function W(e){"A"===e.tagName&&(e=e.querySelector("img")||e);var t=e.parentElement,o=t?t.parentElement:null,a=null;if(o&&o.classList.contains("wp-block-image")?a=t.getAttribute("href"):t&&t.classList.contains("wp-block-image")&&t.querySelector(":scope > a")&&(a=t.querySelector(":scope > a").getAttribute("href")),a){var i=N(a),n=N(e.getAttribute("data-orig-file")),l=N(e.getAttribute("data-permalink"));if(i!==n&&i!==l)return!1}return!(t&&t.classList.contains("gallery-caption")||r.matches(t,"figcaption"))}function R(e){if(window.CSS&&window.CSS.supports&&window.CSS.supports("display","grid")){var t,o=e.target,a=r.closest(o,c);if(a){if(!(t=a)||!t.getAttribute("data-carousel-extra"))return;if(!W(o))return;document.documentElement.style.height="auto",e.preventDefault(),e.stopPropagation();var i=r.closest(o,d),n=Array.prototype.indexOf.call(a.querySelectorAll(d),i);M(a,{startIndex:n})}}}document.body.addEventListener("click",O),document.body.addEventListener("keydown",O),document.querySelectorAll(u+"img").forEach(function(e){W(e)&&y(e)}),1===Number(jetpackCarouselStrings.single_image_gallery)&&(b(),document.body.addEventListener("is.post-load",function(){b()})),window.addEventListener("hashchange",function(){var e=/jp-carousel-(\d+)/;if(window.location.hash&&e.test(window.location.hash)){if(window.location.hash!==l||!p.isOpen)if(window.location.hash&&p.gallery&&!p.isOpen&&history.back)history.back();else{l=window.location.hash;for(var t=window.location.hash.match(e),r=parseInt(t[1],10),o=document.querySelectorAll(c),a=0;a<o.length;a++){for(var i,n=o[a],s=n.querySelectorAll("img"),u=0;u<s.length;u++)if(parseInt(s[u].getAttribute("data-attachment-id"),10)===r||parseInt(s[u].getAttribute("data-id"),10)===r){i=u;break}if(void 0!==i){S(n,i);break}}}}else p.isOpen&&x()}),window.location.hash&&r.emitEvent(window,"hashchange")}"loading"!==document.readyState?o():document.addEventListener("DOMContentLoaded",o)}();; 2/* @preserve 3 * Leaflet 1.3.1, a JS library for interactive maps. http://leafletjs.com 4 * (c) 2010-2017 Vladimir Agafonkin, (c) 2010-2011 CloudMade 5 */ 6!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function i(t){var i,e,n,o;for(e=1,n=arguments.length;e<n;e++){o=arguments[e];for(i in o)t[i]=o[i]}return t}function e(t,i){var e=Array.prototype.slice;if(t.bind)return t.bind.apply(t,e.call(arguments,1));var n=e.call(arguments,2);return function(){return t.apply(i,n.length?n.concat(e.call(arguments)):arguments)}}function n(t){return t._leaflet_id=t._leaflet_id||++ti,t._leaflet_id}function o(t,i,e){var n,o,s,r;return r=function(){n=!1,o&&(s.apply(e,o),o=!1)},s=function(){n?o=arguments:(t.apply(e,arguments),setTimeout(r,i),n=!0)}}function s(t,i,e){var n=i[1],o=i[0],s=n-o;return t===n&&e?t:((t-o)%s+s)%s+o}function r(){return!1}function a(t,i){var e=Math.pow(10,void 0===i?6:i);return Math.round(t*e)/e}function h(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function u(t){return h(t).split(/\s+/)}function l(t,i){t.hasOwnProperty("options")||(t.options=t.options?Qt(t.options):{});for(var e in i)t.options[e]=i[e];return t.options}function c(t,i,e){var n=[];for(var o in t)n.push(encodeURIComponent(e?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(i&&-1!==i.indexOf("?")?"&":"?")+n.join("&")}function _(t,i){return t.replace(ii,function(t,e){var n=i[e];if(void 0===n)throw new Error("No value provided for variable "+t);return"function"==typeof n&&(n=n(i)),n})}function d(t,i){for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1}function p(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}function m(t){var i=+new Date,e=Math.max(0,16-(i-oi));return oi=i+e,window.setTimeout(t,e)}function f(t,i,n){if(!n||si!==m)return si.call(window,e(t,i));t.call(i)}function g(t){t&&ri.call(window,t)}function v(){}function y(t){if("undefined"!=typeof L&&L&&L.Mixin){t=ei(t)?t:[t];for(var i=0;i<t.length;
6i++)t[i]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",(new Error).stack)}}function x(t,i,e){this.x=e?Math.round(t):t,this.y=e?Math.round(i):i}function w(t,i,e){return t instanceof x?t:ei(t)?new x(t[0],t[1]):void 0===t||null===t?t:"object"==typeof t&&"x"in t&&"y"in t?new x(t.x,t.y):new x(t,i,e)}function P(t,i){if(t)for(var e=i?[t,i]:t,n=0,o=e.length;n<o;n++)this.extend(e[n])}function b(t,i){return!t||t instanceof P?t:new P(t,i)}function T(t,i){if(t)for(var e=i?[t,i]:t,n=0,o=e.length;n<o;n++)this.extend(e[n])}function z(t,i){return t instanceof T?t:new T(t,i)}function M(t,i,e){if(isNaN(t)||isNaN(i))throw new Error("Invalid LatLng object: ("+t+", "+i+")");this.lat=+t,this.lng=+i,void 0!==e&&(this.alt=+e)}function C(t,i,e){return t instanceof M?t:ei(t)&&"object"!=typeof t[0]?3===t.length?new M(t[0],t[1],t[2]):2===t.length?new M(t[0],t[1]):null:void 0===t||null===t?t:"object"==typeof t&&"lat"in t?new M(t.lat,"lng"in t?t.lng:t.lon,t.alt):void 0===i?null:new M(t,i,e)}function Z(t,i,e,n){if(ei(t))return this._a=t[0],this._b=t[1],this._c=t[2],void(this._d=t[3]);this._a=t,this._b=i,this._c=e,this._d=n}function S(t,i,e,n){return new Z(t,i,e,n)}function E(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function k(t,i){var e,n,o,s,r,a,h="";for(e=0,o=t.length;e<o;e++){for(n=0,s=(r=t[e]).length;n<s;n++)a=r[n],h+=(n?"L":"M")+a.x+" "+a.y;h+=i?Xi?"z":"x":""}return h||"M0 0"}function I(t){return navigator.userAgent.toLowerCase().indexOf(t)>=0}function A(t,i,e,n){return"touchstart"===i?O(t,e,n):"touchmove"===i?W(t,e,n):"touchend"===i&&H(t,e,n),this}function B(t,i,e){var n=t["_leaflet_"+i+e];return"touchstart"===i?t.removeEventListener(Qi,n,!1):"touchmove"===i?t.removeEventListener(te,n,!1):"touchend"===i&&(t.removeEventListener(ie,n,!1),t.removeEventListener(ee,n,!1)),this}function O(t,i,n){var o=e(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(ne.indexOf(t.target.tagName)<0))return;$(t)}j(t,i)});t["_leaflet_touchstart"+n]=o,t.addEventListener(Qi,o,!1),se||(document.documentElement.addEventListener(Qi,R,!0),document.documentElement.addEventListener(te,D,!0),document.documentElement.addEventListener(ie,N,!0),document.documentElement.addEventListener(ee,N,!0),se=!0)}function R(t){oe[t.pointerId]=t,re++}function D(t){oe[t.pointerId]&&(oe[t.pointerId]=t)}function N(t){delete oe[t.pointerId],re--}function j(t,i){t.touches=[];for(var e in oe)t.touches.push(oe[e]);t.changedTouches=[t],i(t)}function W(t,i,e){var n=function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&j(t,i)};t["_leaflet_touchmove"+e]=n,t.addEventListener(te,n,!1)}function H(t,i,e){var n=function(t){j(t,i)};t["_leaflet_touchend"+e]=n,t.addEventListener(ie,n,!1),t.addEventListener(ee,n,!1)}function F(t,i,e){function n(t){var i;if(Ui){if(!Pi||"mouse"===t.pointerType)return;i=re}else i=t.touches.length;if(!(i>1)){var e=Date.now(),n=e-(s||e);r=t.touches?t.touches[0]:t,a=n>0&&n<=h,s=e}}function o(t){if(a&&!r.cancelBubble){if(Ui){if(!Pi||"mouse"===t.pointerType)return;var e,n,o={};for(n in r)e=r[n],o[n]=e&&e.bind?e.bind(r):e;r=o}r.type="dblclick",i(r),s=null}}var s,r,a=!1,h=250;return t[ue+ae+e]=n,t[ue+he+e]=o,t[ue+"dblclick"+e]=i,t.addEventListener(ae,n,!1),t.addEventListener(he,o,!1),t.addEventListener("dblclick",i,!1),this}function U(t,i){var e=t[ue+ae+i],n=t[ue+he+i],o=t[ue+"dblclick"+i];return t.removeEventListener(ae,e,!1),t.removeEventListener(he,n,!1),Pi||t.removeEventListener("dblclick",o,!1),this}function V(t,i,e,n){if("object"==typeof i)for(var o in i)G(t,o,i[o],e);else for(var s=0,r=(i=u(i)).length;s<r;s++)G(t,i[s],e,n);return this}function q(t,i,e,n){if("object"==typeof i)for(var o in i)K(t,o,i[o],e);else if(i)for(var s=0,r=(i=u(i)).length;s<r;s++)K(t,i[s],e,n);else{for(var a in t[le])K(t,a,t[le][a]);delete t[le]}return this}function G(t,i,e,o){var s=i+n(e)+(o?"_"+n(o):"");if(t[le]&&t[le][s])return this;var r=function(i){return e.call(o||t,i||window.event)},a=r;Ui&&0===i.indexOf("touch")?A(t,i,r,s):!Vi||"dblclick"!==i||!F||Ui&&Si?"addEventListener"in t?"mousewheel"===i?t.addEventListener("onw
6heel"in t?"wheel":"mousewheel",r,!1):"mouseenter"===i||"mouseleave"===i?(r=function(i){i=i||window.event,ot(t,i)&&a(i)},t.addEventListener("mouseenter"===i?"mouseover":"mouseout",r,!1)):("click"===i&&Ti&&(r=function(t){st(t,a)}),t.addEventListener(i,r,!1)):"attachEvent"in t&&t.attachEvent("on"+i,r):F(t,r,s),t[le]=t[le]||{},t[le][s]=r}function K(t,i,e,o){var s=i+n(e)+(o?"_"+n(o):""),r=t[le]&&t[le][s];if(!r)return this;Ui&&0===i.indexOf("touch")?B(t,i,s):!Vi||"dblclick"!==i||!U||Ui&&Si?"removeEventListener"in t?"mousewheel"===i?t.removeEventListener("onwheel"in t?"wheel":"mousewheel",r,!1):t.removeEventListener("mouseenter"===i?"mouseover":"mouseleave"===i?"mouseout":i,r,!1):"detachEvent"in t&&t.detachEvent("on"+i,r):U(t,s),t[le][s]=null}function Y(t){return t.stopPropagation?t.stopPropagation():t.originalEvent?t.originalEvent._stopped=!0:t.cancelBubble=!0,nt(t),this}function X(t){return G(t,"mousewheel",Y),this}function J(t){return V(t,"mousedown touchstart dblclick",Y),G(t,"click",et),this}function $(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,this}function Q(t){return $(t),Y(t),this}function tt(t,i){if(!i)return new x(t.clientX,t.clientY);var e=i.getBoundingClientRect(),n=e.width/i.offsetWidth||1,o=e.height/i.offsetHeight||1;return new x(t.clientX/n-e.left-i.clientLeft,t.clientY/o-e.top-i.clientTop)}function it(t){return Pi?t.wheelDeltaY/2:t.deltaY&&0===t.deltaMode?-t.deltaY/ce:t.deltaY&&1===t.deltaMode?20*-t.deltaY:t.deltaY&&2===t.deltaMode?60*-t.deltaY:t.deltaX||t.deltaZ?0:t.wheelDelta?(t.wheelDeltaY||t.wheelDelta)/2:t.detail&&Math.abs(t.detail)<32765?20*-t.detail:t.detail?t.detail/-32765*60:0}function et(t){_e[t.type]=!0}function nt(t){var i=_e[t.type];return _e[t.type]=!1,i}function ot(t,i){var e=i.relatedTarget;if(!e)return!0;try{for(;e&&e!==t;)e=e.parentNode}catch(t){return!1}return e!==t}function st(t,i){var e=t.timeStamp||t.originalEvent&&t.originalEvent.timeStamp,n=pi&&e-pi;n&&n>100&&n<500||t.target._simulatedClick&&!t._simulated?Q(t):(pi=e,i(t))}function rt(t){return"string"==typeof t?document.getElementById(t):t}function at(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!e||"auto"===e)&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);e=n?n[i]:null}return"auto"===e?null:e}function ht(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function ut(t){var i=t.parentNode;i&&i.removeChild(t)}function lt(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function ct(t){var i=t.parentNode;i.lastChild!==t&&i.appendChild(t)}function _t(t){var i=t.parentNode;i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function dt(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=gt(t);return e.length>0&&new RegExp("(^|\\s)"+i+"(\\s|$)").test(e)}function pt(t,i){if(void 0!==t.classList)for(var e=u(i),n=0,o=e.length;n<o;n++)t.classList.add(e[n]);else if(!dt(t,i)){var s=gt(t);ft(t,(s?s+" ":"")+i)}}function mt(t,i){void 0!==t.classList?t.classList.remove(i):ft(t,h((" "+gt(t)+" ").replace(" "+i+" "," ")))}function ft(t,i){void 0===t.className.baseVal?t.className=i:t.className.baseVal=i}function gt(t){return void 0===t.className.baseVal?t.className:t.className.baseVal}function vt(t,i){"opacity"in t.style?t.style.opacity=i:"filter"in t.style&&yt(t,i)}function yt(t,i){var e=!1,n="DXImageTransform.Microsoft.Alpha";try{e=t.filters.item(n)}catch(t){if(1===i)return}i=Math.round(100*i),e?(e.Enabled=100!==i,e.Opacity=i):t.style.filter+=" progid:"+n+"(opacity="+i+")"}function xt(t){for(var i=document.documentElement.style,e=0;e<t.length;e++)if(t[e]in i)return t[e];return!1}function wt(t,i,e){var n=i||new x(0,0);t.style[pe]=(Oi?"translate("+n.x+"px,"+n.y+"px)":"translate3d("+n.x+"px,"+n.y+"px,0)")+(e?" scale("+e+")":"")}function Lt(t,i){t._leaflet_pos=i,Ni?wt(t,i):(t.style.left=i.x+"px",t.style.top=i.y+"px")}function Pt(t){return t._leaflet_pos||new x(0,0)}function bt(){V(window,"dragstart",$)}function Tt(){q(window,"dragstart",$)}function zt(t){for(;-1===t.tabIndex;)t=t.parentNode;t.style&&(Mt(),ve=t,ye=t.style.outline,t.style.outline="none",V(window,"keydown",Mt))}function Mt(){ve&&(ve.style.outline=ye,ve=void 0,ye=void 0,q(window,"keydown",Mt))}function Ct(t,i){if(!i||!t.length)return t.slice();var e=i*i;return t=kt(t,e),t=St(t,e)}function Zt(t,i,e){return Math.sqrt(Rt(t,i,e,!0))}function St(t,i){var e=t.length,n=new(typeof Uint8Array!=void 0+""?Uint8Array:Array)(e);n[0]=n[e-1]=1,Et(t,n,i,0,e-1);var o,s=[];for(o=0;o<e;o++)n[o]&&s.push(t[o]);return s}function Et(t,i,e,n,o){var s,r,a,h=0;for(r=n+1;r<=o-1;r++)(a=Rt(t[r],t[n],t[o],!0))>h&&(s=r,h=a);h>e&&(i[s]=1,Et(t,i,e,n,s),Et(t,i,e,s,o))}function kt(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;n<s;n++)Ot(t[n],t[o])>i&&(e.push(t[n]),o=n);return o<s-1&&e.push(t[s-1]),e}function It(t,i,e,n,o){var s,r,a,h=n?Se:Bt(t,e),u=Bt(i,e);for(Se=u;;){if(!(h|u))return[t,i];if(h&u)return!1;a=Bt(r=At(t,i,s=h||u,e,o),e),s===h?(t=r,h=a):(i=r,u=a)}}function At(t,i,e,n,o){var s,r,a=i.x-t.x,h=i.y-t.y,u=n.min,l=n.max;return 8&e?(s=t.x+a*(l.y-t.y)/h,r=l.y):4&e?(s=t.x+a*(u.y-t.y)/h,r=u.y):2&e?(s=l.x,r=t.y+h*(l.x-t.x)/a):1&e&&(s=u.x,r=t.y+h*(u.x-t.x)/a),new x(s,r,o)}function Bt(t,i){var e=0;return t.x<i.min.x?e|=1:t.x>i.max.x&&(e|=2),t.y<i.min.y?e|=4:t.y>i.max.y&&(e|=8),e}function Ot(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}function Rt(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return u>0&&((o=((t.x-s)*a+(t.y-r)*h)/u)>1?(s=e.x,r=e.y):o>0&&(s+=a*o,r+=h*o)),a=t.x-s,h=t.y-r,n?a*a+h*h:new x(s,r)}function Dt(t){return!ei(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}function Nt(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),Dt(t)}function jt(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;o<u;o++)t[o]._code=Bt(t[o],i);for(r=0;r<4;r++){for(l=_[r],n=[],o=0,s=(u=t.length)-1;o<u;s=o++)a=t[o],h=t[s],a._code&l?h._code&l||((c=At(h,a,l,i,e))._code=Bt(c,i),n.push(c)):(h._code&l&&((c=At(h,a,l,i,e))._code=Bt(c,i),n.push(c)),n.push(a));t=n}return t}function Wt(t,i){var e,n,o,s,r="Feature"===t.type?t.geometry:t,a=r?r.coordinates:null,h=[],u=i&&i.pointToLayer,l=i&&i.coordsToLatLng||Ht;if(!a&&!r)return null;switch(r.type){case"Point":return e=l(a),u?u(t,e):new Xe(e);case"MultiPoint":for(o=0,s=a.length;o<s;o++)e=l(a[o]),h.push(u?u(t,e):new Xe(e));return new qe(h);case"LineString":case"MultiLineString":return n=Ft(a,"LineString"===r.type?0:1,l),new tn(n,i);case"Polygon":case"MultiPolygon":return n=Ft(a,"Polygon"===r.type?1:2,l),new en(n,i);case"GeometryCollection":for(o=0,s=r.geometries.length;o<s;o++){var c=Wt({geometry:r.geometries[o],type:"Feature",properties:t.properties},i);c&&h.push(c)}return new qe(h);default:throw new Error("Invalid GeoJSON object.")}}function Ht(t){return new M(t[1],t[0],t[2])}function Ft(t,i,e){for(var n,o=[],s=0,r=t.length;s<r;s++)n=i?Ft(t[s],i-1,e):(e||Ht)(t[s]),o.push(n);return o}function Ut(t,i){return i="number"==typeof i?i:6,void 0!==t.alt?[a(t.lng,i),a(t.lat,i),a(t.alt,i)]:[a(t.lng,i),a(t.lat,i)]}function Vt(t,i,e,n){for(var o=[],s=0,r=t.length;s<r;s++)o.push(i?Vt(t[s],i-1,e,n):Ut(t[s],n));return!i&&e&&o.push(o[0]),o}function qt(t,e){return t.feature?i({},t.feature,{geometry:e}):Gt(e)}function Gt(t){return"Feature"===t.type||"FeatureCollection"===t.type?t:{type:"Feature",properties:{},geometry:t}}function Kt(t,i){return new nn(t,i)}function Yt(t,i){return new dn(t,i)}function Xt(t){return Yi?new fn(t):null}function Jt(t){return Xi||Ji?new xn(t):null}var $t=Object.freeze;Object.freeze=function(t){return t};var Qt=Object.create||function(){function t(){}return function(i){return t.prototype=i,new t}}(),ti=0,ii=/\{ *([\w_-]+) *\}/g,ei=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},ni="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=",oi=0,si=window.requestAnimationFrame||p("RequestAnimationFrame")||m,ri=window.cancelAnimationFrame||p("CancelAnimationFrame")||p("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)},ai=(Object.freeze||Object)({freeze:$t,extend:i,create:Qt,bind:e,lastId:ti,stamp:n,throttle:o,wrapNum:s,falseFn:r,formatNum:a,trim:h,splitWords:u,setOptions:l,getParamString:c,template:_,isArray:ei,indexOf:d,emptyImageUrl:ni,requestFn:si,cancelFn:ri,requestAnimFrame:f,cancelAnimFrame:g});v.extend=function(t){var e=function(){this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},n=e.__super__=this.prototype,o=Qt(n);o.constructor=e,e.prototype=o;for(var s in this)this.hasOwnProperty(s)&&"prototype"!==s&&"__super__"!==s&&(e[s]=this[s]);return t.statics&&(i(e,t.statics),delete t.statics),t.includes&&(y(t.includes),i.apply(null,[o].concat(t.includes)),delete t.includes),o.options&&(t.options=i(Qt(o.options),t.options)),i(o,t),o._initHooks=[],o.callInitHooks=function(){if(!this._initHooksCalled){n.c
vendor: 6,244 bytes, line 6
6allInitHooks&&n.callInitHooks.call(this),this._initHooksCalled=!0;for(var t=0,i=o._initHooks.length;t<i;t++)o._initHooks[t].call(this)}},e},v.include=function(t){return i(this.prototype,t),this},v.mergeOptions=function(t){return i(this.prototype.options,t),this},v.addInitHook=function(t){var i=Array.prototype.slice.call(arguments,1),e="function"==typeof t?t:function(){this[t].apply(this,i)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(e),this};var hi={on:function(t,i,e){if("object"==typeof t)for(var n in t)this._on(n,t[n],i);else for(var o=0,s=(t=u(t)).length;o<s;o++)this._on(t[o],i,e);return this},off:function(t,i,e){if(t)if("object"==typeof t)for(var n in t)this._off(n,t[n],i);else for(var o=0,s=(t=u(t)).length;o<s;o++)this._off(t[o],i,e);else delete this._events;return this},_on:function(t,i,e){this._events=this._events||{};var n=this._events[t];n||(n=[],this._events[t]=n),e===this&&(e=void 0);for(var o={fn:i,ctx:e},s=n,r=0,a=s.length;r<a;r++)if(s[r].fn===i&&s[r].ctx===e)return;s.push(o)},_off:function(t,i,e){var n,o,s;if(this._events&&(n=this._events[t]))if(i){if(e===this&&(e=void 0),n)for(o=0,s=n.length;o<s;o++){var a=n[o];if(a.ctx===e&&a.fn===i)return a.fn=r,this._firingCount&&(this._events[t]=n=n.slice()),void n.splice(o,1)}}else{for(o=0,s=n.length;o<s;o++)n[o].fn=r;delete this._events[t]}},fire:function(t,e,n){if(!this.listens(t,n))return this;var o=i({},e,{type:t,target:this,sourceTarget:e&&e.sourceTarget||this});if(this._events){var s=this._events[t];if(s){this._firingCount=this._firingCount+1||1;for(var r=0,a=s.length;r<a;r++){var h=s[r];h.fn.call(h.ctx||this,o)}this._firingCount--}}return n&&this._propagateEvent(o),this},listens:function(t,i){var e=this._events&&this._events[t];if(e&&e.length)return!0;if(i)for(var n in this._eventParents)if(this._eventParents[n].listens(t,i))return!0;return!1},once:function(t,i,n){if("object"==typeof t){for(var o in t)this.once(o,t[o],i);return this}var s=e(function(){this.off(t,i,n).off(t,s,n)},this);return this.on(t,i,n).on(t,s,n)},addEventParent:function(t){return this._eventParents=this._eventParents||{},this._eventParents[n(t)]=t,this},removeEventParent:function(t){return this._eventParents&&delete this._eventParents[n(t)],this},_propagateEvent:function(t){for(var e in this._eventParents)this._eventParents[e].fire(t.type,i({layer:t.target,propagatedFrom:t.target},t),!0)}};hi.addEventListener=hi.on,hi.removeEventListener=hi.clearAllEventListeners=hi.off,hi.addOneTimeEventListener=hi.once,hi.fireEvent=hi.fire,hi.hasEventListeners=hi.listens;var ui=v.extend(hi),li=Math.trunc||function(t){return t>0?Math.floor(t):Math.ceil(t)};x.prototype={clone:function(){return new x(this.x,this.y)},add:function(t){return this.clone()._add(w(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(w(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new x(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new x(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=li(this.x),this.y=li(this.y),this},distanceTo:function(t){var i=(t=w(t)).x-this.x,e=t.y-this.y;return Math.sqrt(i*i+e*e)},equals:function(t){return(t=w(t)).x===this.x&&t.y===this.y},contains:function(t){return t=w(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+a(this.x)+", "+a(this.y)+")"}},P.prototype={extend:function(t){return t=w(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new x((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new x(this.min.x,this.max.y)},getTopRight:function(){return new x(this.max.x,this.min.y)},getTopLeft:function(){return this.min},getBottomRight:function(){return this.max},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var i,e;return(t="number"==typeof t[0]||t instanceof x?w(t):b(t))instanceof P?(i=t.min,e=t.max):i=e=t,i.x>=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.x<e.x,r=o.y>i.y&&n.y<e.y;return s&&r},isValid:function(){return!(!this.min||!this.max)}},T.prototype={extend:function(t){var i,e,n=this._southWest,o=this._northEast;if(t instanceof M)i=t,e=t;else{if(!(t instanceof T))return t?this.extend(C(t)||z(t)):this;if(i=t._southWest,e=t._northEast,!i||!e)return this}return n||o?(n.lat=Math.min(i.lat,n.lat),n.lng=Math.min(i.lng,n.lng),o.lat=Math.max(e.lat,o.lat),o.lng=Math.max(e.lng,o.lng)):(this._southWest=new M(i.lat,i.lng),this._northEast=new M(e.lat,e.lng)),this},pad:function(t){var i=this._southWest,e=this._northEast,n=Math.abs(i.lat-e.lat)*t,o=Math.abs(i.lng-e.lng)*t;return new T(new M(i.lat-n,i.lng-o),new M(e.lat+n,e.lng+o))},getCenter:function(){return new M((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new M(this.getNorth(),this.getWest())},getSouthEast:function(){return new M(this.getSouth(),this.getEast())},getWest:function(){return this._southWest.lng},getSouth:function(){return this._southWest.lat}
vendor: 2,436 bytes, line 6
6,getEast:function(){return this._northEast.lng},getNorth:function(){return this._northEast.lat},contains:function(t){t="number"==typeof t[0]||t instanceof M||"lat"in t?C(t):z(t);var i,e,n=this._southWest,o=this._northEast;return t instanceof T?(i=t.getSouthWest(),e=t.getNorthEast()):i=e=t,i.lat>=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lat<e.lat,r=o.lng>i.lng&&n.lng<e.lng;return s&&r},toBBoxString:function(){return[this.getWest(),this.getSouth(),this.getEast(),this.getNorth()].join(",")},equals:function(t,i){return!!t&&(t=z(t),this._southWest.equals(t.getSouthWest(),i)&&this._northEast.equals(t.getNorthEast(),i))},isValid:function(){return!(!this._southWest||!this._northEast)}},M.prototype={equals:function(t,i){return!!t&&(t=C(t),Math.max(Math.abs(this.lat-t.lat),Math.abs(this.lng-t.lng))<=(void 0===i?1e-9:i))},toString:function(t){return"LatLng("+a(this.lat,t)+", "+a(this.lng,t)+")"},distanceTo:function(t){return _i.distance(this,C(t))},wrap:function(){return _i.wrapLatLng(this)},toBounds:function(t){var i=180*t/40075017,e=i/Math.cos(Math.PI/180*this.lat);return z([this.lat-i,this.lng-e],[this.lat+i,this.lng+e])},clone:function(){return new M(this.lat,this.lng,this.alt)}};var ci={latLngToPoint:function(t,i){var e=this.projection.project(t),n=this.scale(i);return this.transformation._transform(e,n)},pointToLatLng:function(t,i){var e=this.scale(i),n=this.transformation.untransform(t,e);return this.projection.unproject(n)},project:function(t){return this.projection.project(t)},unproject:function(t){return this.projection.unproject(t)},scale:function(t){return 256*Math.pow(2,t)},zoom:function(t){return Math.log(t/256)/Math.LN2},getProjectedBounds:function(t){if(this.infinite)return null;var i=this.projection.bounds,e=this.scale(t);return new P(this.transformation.transform(i.min,e),this.transformation.transform(i.max,e))},infinite:!1,wrapLatLng:function(t){var i=this.wrapLng?s(t.lng,this.wrapLng,!0):t.lng;return new M(this.wrapLat?s(t.lat,this.wrapLat,!0):t.lat,i,t.alt)},wrapLatLngBounds:function(t){var i=t.getCenter(),e=this.wrapLatLng(i),n=i.lat-e.lat,o=i.lng-e.lng;if(0===n&&0===o)return t;
6var s=t.getSouthWest(),r=t.getNorthEast();return new T(new M(s.lat-n,s.lng-o),new M(r.lat-n,r.lng-o))}},_i=i({},ci,{wrapLng:[-180,180],R:6371e3,distance:function(t,i){var e=Math.PI/180,n=t.lat*e,o=i.lat*e,s=Math.sin((i.lat-t.lat)*e/2),r=Math.sin((i.lng-t.lng)*e/2),a=s*s+Math.cos(n)*Math.cos(o)*r*r,h=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));return this.R*h}}),di={R:6378137,MAX_LATITUDE:85.0511287798,project:function(t){var i=Math.PI/180,e=this.MAX_LATITUDE,n=Math.max(Math.min(e,t.lat),-e),o=Math.sin(n*i);return new x(this.R*t.lng*i,this.R*Math.log((1+o)/(1-o))/2)},unproject:function(t){var i=180/Math.PI;return new M((2*Math.atan(Math.exp(t.y/this.R))-Math.PI/2)*i,t.x*i/this.R)},bounds:function(){var t=6378137*Math.PI;return new P([-t,-t],[t,t])}()};Z.prototype={transform:function(t,i){return this._transform(t.clone(),i)},_transform:function(t,i){return i=i||1,t.x=i*(this._a*t.x+this._b),t.y=i*(this._c*t.y+this._d),t},untransform:function(t,i){return i=i||1,new x((t.x/i-this._b)/this._a,(t.y/i-this._d)/this._c)}};var pi,mi,fi,gi,vi=i({},_i,{code:"EPSG:3857",projection:di,transformation:function(){var t=.5/(Math.PI*di.R);return S(t,.5,-t,.5)}()}),yi=i({},vi,{code:"EPSG:900913"}),xi=document.documentElement.style,wi="ActiveXObject"in window,Li=wi&&!document.addEventListener,Pi="msLaunchUri"in navigator&&!("documentMode"in document),bi=I("webkit"),Ti=I("android"),zi=I("android 2")||I("android 3"),Mi=parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1],10),Ci=Ti&&I("Google")&&Mi<537&&!("AudioNode"in window),Zi=!!window.opera,Si=I("chrome"),Ei=I("gecko")&&!bi&&!Zi&&!wi,ki=!Si&&I("safari"),Ii=I("phantom"),Ai="OTransition"in xi,Bi=0===navigator.platform.indexOf("Win"),Oi=wi&&"transition"in xi,Ri="WebKitCSSMatrix"in window&&"m11"in new window.WebKitCSSMatrix&&!zi,Di="MozPerspective"in xi,Ni=!window.L_DISABLE_3D&&(Oi||Ri||Di)&&!Ai&&!Ii,ji="undefined"!=typeof orientation||I("mobile"),Wi=ji&&bi,Hi=ji&&Ri,Fi=!window.PointerEvent&&window.MSPointerEvent,Ui=!(!window.PointerEvent&&!Fi),Vi=!window.L_NO_TOUCH&&(Ui||"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch),qi=ji&&Zi,Gi=ji&&Ei,Ki=(window.devicePixelRatio||window.screen.deviceXDPI/window.screen.logicalXDPI)>1,Yi=!!document.createElement("canvas").getContext,Xi=!(!document.createElementNS||!E("svg").createSVGRect),Ji=!Xi&&function(){try{var t=document.createElement("div");t.innerHTML='<v:shape adj="1"/>';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),$i=(Object.freeze||Object)({ie:wi,ielt9:Li,edge:Pi,webkit:bi,android:Ti,android23:zi,androidStock:Ci,opera:Zi,chrome:Si,gecko:Ei,safari:ki,phantom:Ii,opera12:Ai,win:Bi,ie3d:Oi,webkit3d:Ri,gecko3d:Di,any3d:Ni,mobile:ji,mobileWebkit:Wi,mobileWebkit3d:Hi,msPointer:Fi,pointer:Ui,touch:Vi,mobileOpera:qi,mobileGecko:Gi,retina:Ki,canvas:Yi,svg:Xi,vml:Ji}),Qi=Fi?"MSPointerDown":"pointerdown",te=Fi?"MSPointerMove":"pointermove",ie=Fi?"MSPointerUp":"pointerup",ee=Fi?"MSPointerCancel":"pointercancel",ne=["INPUT","SELECT","OPTION"],oe={},se=!1,re=0,ae=Fi?"MSPointerDown":Ui?"pointerdown":"touchstart",he=Fi?"MSPointerUp":Ui?"pointerup":"touchend",ue="_leaflet_",le="_leaflet_events",ce=Bi&&Si?2*window.devicePixelRatio:Ei?window.devicePixelRatio:1,_e={},de=(Object.freeze||Object)({on:V,off:q,stopPropagation:Y,disableScrollPropagation:X,disableClickPropagation:J,preventDefault:$,stop:Q,getMousePosition:tt,getWheelDelta:it,fakeStop:et,skipped:nt,isExternalTarget:ot,addListener:V,removeListener:q}),pe=xt(["transform","WebkitTransform","OTransform","MozTransform","msTransform"]),me=xt(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),fe="webkitTransition"===me||"OTransition"===me?me+"End":"transitionend";if("onselectstart"in document)mi=function(){V(window,"selectstart",$)},fi=function(){q(window,"selectstart",$)};else{var ge=xt(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);mi=function(){if(ge){var t=document.documentElement.style;gi=t[ge],t[ge]="none"}},fi=function(){ge&&(document.documentElement.style[ge]=gi,gi=void 0)}}var ve,ye,xe=(Object.freeze||Object)({TRANSFORM:pe,TRANSITION:me,TRANSITION_END:fe,get:rt,getStyle:at,create:ht,remove:ut,empty:lt,toFront:ct,toBack:_t,hasClass:dt,addClass:pt,removeClass:mt,setClass:ft,getClass:gt,setOpacity:vt,testProp:xt,setTransform:wt,setPosition:Lt,getPosition:Pt,disableTextSelection:mi,enableTextSelection:fi,disableImageDrag:bt,enableImageDrag:Tt,preventOutline:zt,restoreOutline:Mt}),we=ui.extend({run:function(t,i,e,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=e||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=Pt(t),this._offset=i.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=f(this._animate,this),this._step()},_step:function(t){var i=+new Date-this._startTime,e=1e3*this._duration;i<e?this._runFrame(this._easeOut(i/e),t):(this._runFrame(1),this._complete())},_runFrame:function(t,i){var e=this._startPos.add(this._offset.multiplyBy(t));
vendor: 2,358 bytes, line 6
6i&&e._round(),Lt(this._el,e),this.fire("step")},_complete:function(){g(this._animId),this._inProgress=!1,this.fire("end")},_easeOut:function(t){return 1-Math.pow(1-t,this._easeOutPower)}}),Le=ui.extend({options:{crs:vi,center:void 0,zoom:void 0,minZoom:void 0,maxZoom:void 0,layers:[],maxBounds:void 0,renderer:void 0,zoomAnimation:!0,zoomAnimationThreshold:4,fadeAnimation:!0,markerZoomAnimation:!0,transform3DLimit:8388608,zoomSnap:1,zoomDelta:1,trackResize:!0},initialize:function(t,i){i=l(this,i),this._initContainer(t),this._initLayout(),this._onResize=e(this._onResize,this),this._initEvents(),i.maxBounds&&this.setMaxBounds(i.maxBounds),void 0!==i.zoom&&(this._zoom=this._limitZoom(i.zoom)),i.center&&void 0!==i.zoom&&this.setView(C(i.center),i.zoom,{reset:!0}),this._handlers=[],this._layers={},this._zoomBoundLayers={},this._sizeChanged=!0,this.callInitHooks(),this._zoomAnimated=me&&Ni&&!qi&&this.options.zoomAnimation,this._zoomAnimated&&(this._createAnimProxy(),V(this._proxy,fe,this._catchTransitionEnd,this)),this._addLayers(this.options.layers)},setView:function(t,e,n){return e=void 0===e?this._zoom:this._limitZoom(e),t=this._limitCenter(C(t),e,this.options.maxBounds),n=n||{},this._stop(),this._loaded&&!n.reset&&!0!==n&&(void 0!==n.animate&&(n.zoom=i({animate:n.animate},n.zoom),n.pan=i({animate:n.animate,duration:n.duration},n.pan)),this._zoom!==e?this._tryAnimatedZoom&&this._tryAnimatedZoom(t,e,n.zoom):this._tryAnimatedPan(t,n.pan))?(clearTimeout(this._sizeTimer),this):(this._resetView(t,e),this)},setZoom:function(t,i){return this._loaded?this.setView(this.getCenter(),t,{zoom:i}):(this._zoom=t,this)},zoomIn:function(t,i){return t=t||(Ni?this.options.zoomDelta:1),this.setZoom(this._zoom+t,i)},zoomOut:function(t,i){return t=t||(Ni?this.options.zoomDelta:1),this.setZoom(this._zoom-t,i)},setZoomAround:function(t,i,e){var n=this.getZoomScale(i),o=this.getSize().divideBy(2),s=(t instanceof x?t:this.latLngToContainerPoint(t)).subtract(o).multiplyBy(1-1/n),r=this.containerPointToLatLng(o.add(s));return this.setView(r,i,{zoom:e})},_getBoundsCenterZoom:function(t,i){i=i||{},t=t.getBounds?t.getBounds():z(t);var e=w(i.paddingTopLeft||i.padding||[0,0]),n=w(i.paddingBottomRight||i.padding||[0,0]),o=this.getBoundsZoom(t,!1,e.add(n));if((o="number"==typeof i.maxZoom?Math.min(i.maxZoom,o):o)===1/0)return{center:t.getCenter(),zoom:o};
vendor: 14,212 bytes, line 6
6var s=n.subtract(e).divideBy(2),r=this.project(t.getSouthWest(),o),a=this.project(t.getNorthEast(),o);return{center:this.unproject(r.add(a).divideBy(2).add(s),o),zoom:o}},fitBounds:function(t,i){if(!(t=z(t)).isValid())throw new Error("Bounds are not valid.");var e=this._getBoundsCenterZoom(t,i);return this.setView(e.center,e.zoom,i)},fitWorld:function(t){return this.fitBounds([[-90,-180],[90,180]],t)},panTo:function(t,i){return this.setView(t,this._zoom,{pan:i})},panBy:function(t,i){if(t=w(t).round(),i=i||{},!t.x&&!t.y)return this.fire("moveend");if(!0!==i.animate&&!this.getSize().contains(t))return this._resetView(this.unproject(this.project(this.getCenter()).add(t)),this.getZoom()),this;if(this._panAnim||(this._panAnim=new we,this._panAnim.on({step:this._onPanTransitionStep,end:this._onPanTransitionEnd},this)),i.noMoveStart||this.fire("movestart"),!1!==i.animate){pt(this._mapPane,"leaflet-pan-anim");var e=this._getMapPanePos().subtract(t).round();this._panAnim.run(this._mapPane,e,i.duration||.25,i.easeLinearity)}else this._rawPanBy(t),this.fire("move").fire("moveend");return this},flyTo:function(t,i,e){function n(t){var i=(g*g-m*m+(t?-1:1)*x*x*v*v)/(2*(t?g:m)*x*v),e=Math.sqrt(i*i+1)-i;return e<1e-9?-18:Math.log(e)}function o(t){return(Math.exp(t)-Math.exp(-t))/2}function s(t){return(Math.exp(t)+Math.exp(-t))/2}function r(t){return o(t)/s(t)}function a(t){return m*(s(w)/s(w+y*t))}function h(t){return m*(s(w)*r(w+y*t)-o(w))/x}function u(t){return 1-Math.pow(1-t,1.5)}function l(){var e=(Date.now()-L)/b,n=u(e)*P;e<=1?(this._flyToFrame=f(l,this),this._move(this.unproject(c.add(_.subtract(c).multiplyBy(h(n)/v)),p),this.getScaleZoom(m/a(n),p),{flyTo:!0})):this._move(t,i)._moveEnd(!0)}if(!1===(e=e||{}).animate||!Ni)return this.setView(t,i,e);this._stop();var c=this.project(this.getCenter()),_=this.project(t),d=this.getSize(),p=this._zoom;t=C(t),i=void 0===i?p:i;var m=Math.max(d.x,d.y),g=m*this.getZoomScale(p,i),v=_.distanceTo(c)||1,y=1.42,x=y*y,w=n(0),L=Date.now(),P=(n(1)-w)/y,b=e.duration?1e3*e.duration:1e3*P*.8;return this._moveStart(!0,e.noMoveStart),l.call(this),this},flyToBounds:function(t,i){var e=this._getBoundsCenterZoom(t,i);return this.flyTo(e.center,e.zoom,i)},setMaxBounds:function(t){return(t=z(t)).isValid()?(this.options.maxBounds&&this.off("moveend",this._panInsideMaxBounds),this.options.maxBounds=t,this._loaded&&this._panInsideMaxBounds(),this.on("moveend",this._panInsideMaxBounds)):(this.options.maxBounds=null,this.off("moveend",this._panInsideMaxBounds))},setMinZoom:function(t){var i=this.options.minZoom;return this.options.minZoom=t,this._loaded&&i!==t&&(this.fire("zoomlevelschange"),this.getZoom()<this.options.minZoom)?this.setZoom(t):this},setMaxZoom:function(t){var i=this.options.maxZoom;return this.options.maxZoom=t,this._loaded&&i!==t&&(this.fire("zoomlevelschange"),this.getZoom()>this.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,z(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},invalidateSize:function(t){if(!this._loaded)return this;t=i({animate:!1,pan:!0},!0===t?{animate:!0}:t);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var o=this.getSize(),s=n.divideBy(2).round(),r=o.divideBy(2).round(),a=s.subtract(r);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(e(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:n,newSize:o})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=i({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var n=e(this._handleGeolocationResponse,this),o=e(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,o,t):navigator.geolocation.getCurrentPosition(n,o,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var i=t.code,e=t.message||(1===i?"permission denied":2===i?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:i,message:"Geolocation error: "+e+"."})},_handleGeolocationResponse:function(t){var i=new M(t.coords.latitude,t.coords.longitude),e=i.toBounds(t.coords.accuracy),n=this._locateOptions;if(n.setView){var o=this.getBoundsZoom(e);this.setView(i,n.maxZoom?Math.min(o,n.maxZoom):o)}var s={latlng:i,bounds:e,timestamp:t.timestamp};for(var r in t.coords)"number"==typeof t.coords[r]&&(s[r]=t.coords[r]);this.fire("locationfound",s)},addHandler:function(t,i){if(!i)return this;var e=this[t]=new i(this);return this._handlers.push(e),this.options[t]&&e.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),ut(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)ut(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,i){var e=ht("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),i||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new T(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,i,e){t=z(t),e=w(e||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(e),u=b(this.project(a,n),this.project(r,n)).getSize(),l=Ni?this.options.zoomSnap:1,c=h.x/u.x,_=h.y/u.y,d=i?Math.max(c,_):Math.min(c,_);return n=this.getScaleZoom(d,n),l&&(n=Math.round(n/(l/100))*(l/100),n=i?Math.ceil(n/l)*l:Math.floor(n/l)*l),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new x(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,i){var e=this._getTopLeftPoint(t,i);return new P(e,e.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,i){var e=this.options.crs;return i=void 0===i?this._zoom:i,e.scale(t)/e.scale(i)},getScaleZoom:function(t,i){var e=this.options.crs;i=void 0===i?this._zoom:i;var n=e.zoom(t*e.scale(i));return isNaN(n)?1/0:n},project:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.latLngToPoint(C(t),i)},unproject:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.pointToLatLng(w(t),i)},layerPointToLatLng:function(t){var i=w(t).add(this.getPixelOrigin());return this.unproject(i)},latLngToLayerPoint:function(t){return this.project(C(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(C(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(z(t))},distance:function(t,i){return this.options.crs.distance(C(t),C(i))},containerPointToLayerPoint:function(t){return w(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return w(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var i=this.containerPointToLayerPoint(w(t));return this.layerPointToLatLng(i)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(C(t)))},mouseEventToContainerPoint:function(t){return tt(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var i=this._container=rt(t);if(!i)throw new Error("Map container not found.");if(i._leaflet_id)throw new Error("Map container is already initialized.");V(i,"scroll",this._onScroll,this),this._containerId=n(i)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&Ni,pt(t,"leaflet-container"+(Vi?" leaflet-touch":"")+(Ki?" leaflet-retina":"")+(Li?" leaflet-oldie":"")+(ki?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var i=at(t,"position");"absolute"!==i&&"relative"!==i&&"fixed"!==i&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),Lt(this._mapPane,new x(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(pt(t.markerPane,"leaflet-zoom-hide"),pt(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,i){Lt(this._mapPane,new x(0,0));var e=!this._loaded;this._loaded=!0,i=this._limitZoom(i),this.fire("viewprereset");var n=this._zoom!==i;this._moveStart(n,!1)._move(t,i)._moveEnd(n),this.fire("viewreset"),e&&this.fire("load")},_moveStart:function(t,i){return t&&this.fire("zoomstart"),i||this.fire("movestart"),this},_move:function(t,i,e){void 0===i&&(i=this._zoom);var n=this._zoom!==i;return this._zoom=i,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(n||e&&e.pinch)&&this.fire("zoom",e),this.fire("move",e)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return g(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){Lt(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={},this._targets[n(this._container)]=this;var i=t?q:V;i(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&i(window,"resize",this._onResize,this),Ni&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){g(this._resizeRequest),this._resizeRequest=f(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,o=[],s="mouseout"===i||"mouseover"===i,r=t.target||t.srcElement,a=!1;r;){if((e=this._targets[n(r)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){a=!0;break}if(e&&e.listens(i,!0)){if(s&&!ot(r,t))break;if(o.push(e),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!ot(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!nt(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i||zt(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,n){if("click"===t.type){var o=i({},t);o.type="preclick",this._fireDOMEvent(o,o.type,n)}if(!t._stopped&&(n=(n||[]).concat(this._findEventTargets(t,e))).length){var s=n[0];"contextmenu"===e&&s.listens(e,!0)&&$(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s.getLatLng&&(!s._radius||s._radius<=10);r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h<n.length;h++)if(n[h].fire(e,r,!0),r.originalEvent._stopped||!1===n[h].options.bubblingMouseEvents&&-1!==d(this._mouseEvents,e))return}},_draggableMoved:function(t){return(t=t.dragging&&t.dragging.enabled()?t:this).dragging&&t.dragging.moved()||this.boxZoom&&this.boxZoom.moved()},_clearHandlers:function(){for(var t=0,i=this._handlers.length;t<i;t++)this._handlers[t].disable()},whenReady:function(t,i){return this._loaded?t.call(i||this,{target:this}):this.on("load",t,i),this},_getMapPanePos:function(){return Pt(this._mapPane)||new x(0,0)},_moved:function(){var t=this._getMapPanePos();return t&&!t.equals([0,0])},_getTopLeftPoint:function(t,i){return(t&&void 0!==i?this._getNewPixelOrigin(t,i):this.getPixelOrigin()).subtract(this._getMapPanePos())},_getNewPixelOrigin:function(t,i){var e=this.getSize()._divideBy(2);return this.project(t,i)._subtract(e)._add(this._getMapPanePos())._round()},_latLngToNewLayerPoint:function(t,i,e){var n=this._getNewPixelOrigin(e,i);return this.project(t,i)._subtract(n)},_latLngBoundsToNewLayerBounds:function(t,i,e){var n=this._getNewPixelOrigin(e,i);
6return b([this.project(t.getSouthWest(),i)._subtract(n),this.project(t.getNorthWest(),i)._subtract(n),this.project(t.getSouthEast(),i)._subtract(n),this.project(t.getNorthEast(),i)._subtract(n)])},_getCenterLayerPoint:function(){return this.containerPointToLayerPoint(this.getSize()._divideBy(2))},_getCenterOffset:function(t){return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint())},_limitCenter:function(t,i,e){if(!e)return t;var n=this.project(t,i),o=this.getSize().divideBy(2),s=new P(n.subtract(o),n.add(o)),r=this._getBoundsOffset(s,e,i);return r.round().equals([0,0])?t:this.unproject(n.add(r),i)},_limitOffset:function(t,i){if(!i)return t;var e=this.getPixelBounds(),n=new P(e.min.add(t),e.max.add(t));return t.add(this._getBoundsOffset(n,i))},_getBoundsOffset:function(t,i,e){var n=b(this.project(i.getNorthEast(),e),this.project(i.getSouthWest(),e)),o=n.min.subtract(t.min),s=n.max.subtract(t.max);return new x(this._rebound(o.x,-s.x),this._rebound(o.y,-s.y))},_rebound:function(t,i){return t+i>0?Math.round(t-i)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(i))},_limitZoom:function(t){var i=this.getMinZoom(),e=this.getMaxZoom(),n=Ni?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(i,Math.min(e,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){mt(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,i){var e=this._getCenterOffset(t)._trunc();return!(!0!==(i&&i.animate)&&!this.getSize().contains(e))&&(this.panBy(e,i),!0)},_createAnimProxy:function(){var t=this._proxy=ht("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(t){var i=pe,e=this._proxy.style[i];wt(this._proxy,this.project(t.center,t.zoom),this.getZoomScale(t.zoom,1)),e===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var t=this.getCenter(),i=this.getZoom();wt(this._proxy,this.project(t,i),this.getZoomScale(i,1))},this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){ut(this._proxy),delete this._proxy},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,i,e){if(this._animatingZoom)return!0;if(e=e||{},!this._zoomAnimated||!1===e.animate||this._nothingToAnimate()||Math.abs(i-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(f(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,n,o){this._mapPane&&(n&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,pt(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:o}),setTimeout(e(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&mt(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),f(function(){this._moveEnd(!0)},this))}}),Pe=v.extend({options:{position:"topright"},initialize:function(t){l(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return pt(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this},remove:function(){return this._map?(ut(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),be=function(t){return new Pe(t)};Le.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this}
vendor: 6,603 bytes, line 6
6,_initControlPos:function(){function t(t,o){var s=e+t+" "+e+o;i[t+o]=ht("div",s,n)}var i=this._controlCorners={},e="leaflet-",n=this._controlContainer=ht("div",e+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)ut(this._controlCorners[t]);ut(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Te=Pe.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,i,e,n){return e<n?-1:n<e?1:0}},initialize:function(t,i,e){l(this,e),this._layerControlInputs=[],this._layers=[],this._lastZIndex=0,this._handlingClick=!1;for(var n in t)this._addLayer(t[n],n);for(n in i)this._addLayer(i[n],n,!0)},onAdd:function(t){this._initLayout(),this._update(),this._map=t,t.on("zoomend",this._checkDisabledLayers,this);for(var i=0;i<this._layers.length;i++)this._layers[i].layer.on("add remove",this._onLayerChange,this);return this._container},addTo:function(t){return Pe.prototype.addTo.call(this,t),this._expandIfNotCollapsed()},onRemove:function(){this._map.off("zoomend",this._checkDisabledLayers,this);for(var t=0;t<this._layers.length;t++)this._layers[t].layer.off("add remove",this._onLayerChange,this)},addBaseLayer:function(t,i){return this._addLayer(t,i),this._map?this._update():this},addOverlay:function(t,i){return this._addLayer(t,i,!0),this._map?this._update():this},removeLayer:function(t){t.off("add remove",this._onLayerChange,this);var i=this._getLayer(n(t));return i&&this._layers.splice(this._layers.indexOf(i),1),this._map?this._update():this},expand:function(){pt(this._container,"leaflet-control-layers-expanded"),this._form.style.height=null;var t=this._map.getSize().y-(this._container.offsetTop+50);return t<this._form.clientHeight?(pt(this._form,"leaflet-control-layers-scrollbar"),this._form.style.height=t+"px"):mt(this._form,"leaflet-control-layers-scrollbar"),this._checkDisabledLayers(),this},collapse:function(){return mt(this._container,"leaflet-control-layers-expanded"),this},_initLayout:function(){var t="leaflet-control-layers",i=this._container=ht("div",t),e=this.options.collapsed;i.setAttribute("aria-haspopup",!0),J(i),X(i);var n=this._form=ht("form",t+"-list");e&&(this._map.on("click",this.collapse,this),Ti||V(i,{mouseenter:this.expand,mouseleave:this.collapse},this));var o=this._layersLink=ht("a",t+"-toggle",i);o.href="#",o.title="Layers",Vi?(V(o,"click",Q),V(o,"click",this.expand,this)):V(o,"focus",this.expand,this),e||this.expand(),this._baseLayersList=ht("div",t+"-base",n),this._separator=ht("div",t+"-separator",n),this._overlaysList=ht("div",t+"-overlays",n),i.appendChild(n)},_getLayer:function(t){for(var i=0;i<this._layers.length;i++)if(this._layers[i]&&n(this._layers[i].layer)===t)return this._layers[i]},_addLayer:function(t,i,n){this._map&&t.on("add remove",this._onLayerChange,this),this._layers.push({layer:t,name:i,overlay:n}),this.options.sortLayers&&this._layers.sort(e(function(t,i){return this.options.sortFunction(t.layer,i.layer,t.name,i.name)},this)),this.options.autoZIndex&&t.setZIndex&&(this._lastZIndex++,t.setZIndex(this._lastZIndex)),this._expandIfNotCollapsed()},_update:function(){if(!this._container)return this;lt(this._baseLayersList),lt(this._overlaysList),this._layerControlInputs=[];var t,i,e,n,o=0;for(e=0;e<this._layers.length;e++)n=this._layers[e],this._addItem(n),i=i||n.overlay,t=t||!n.overlay,o+=n.overlay?0:1;return this.options.hideSingleBase&&(t=t&&o>1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=i&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var i=this._getLayer(n(t.target)),e=i.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;e&&this._map.fire(e,i)},_createRadioElement:function(t,i){var e='<input type="radio" class="leaflet-control-layers-selector" name="'+t+'"'+(i?' checked="checked"':"")+"/>",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),o=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=o):i=this._createRadioElement("leaflet-base-layers",o),this._layerControlInputs.push(i),i.layerId=n(t.layer),V(i,"click",this._onInputClick,this);var s=document.createElement("span");s.innerHTML=" "+t.name;var r=document.createElement("div");return e.appendChild(r),r.appendChild(i),r.appendChild(s),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;s>=0;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;s<o.length;s++)this._map.hasLayer(o[s])&&this._map.removeLayer(o[s]);for(s=0;s<n.length;s++)this._map.hasLayer(n[s])||this._map.addLayer(n[s]);this._handlingClick=!1,this._refocusOnMap()},_checkDisabledLayers:function(){for(var t,i,e=this._layerControlInputs,n=this._map.getZoom(),o=e.length-1;o>=0;o--)t=e[o],i=this._getLayer(t.layerId).layer,t.disabled=void 0!==i.options.minZoom&&n<i.options.minZoom||void 0!==i.options.maxZoom&&n>i.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),ze=Pe.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=ht("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoom<this._map.getMaxZoom()&&this._map.zoomIn(this._map.options.zoomDelta*(t.shiftKey?3:1))},_zoomOut:function(t){!this._disabled&&this._map._zoom>this._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=ht("a",e,n);
6return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),J(s),V(s,"click",Q),V(s,"click",o,this),V(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";mt(this._zoomInButton,i),mt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMinZoom())&&pt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMaxZoom())&&pt(this._zoomInButton,i)}});Le.mergeOptions({zoomControl:!0}),Le.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new ze,this.addControl(this.zoomControl))});var Me=Pe.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i=ht("div","leaflet-control-scale"),e=this.options;return this._addScales(e,"leaflet-control-scale-line",i),t.on(e.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=ht("div",i,e)),t.imperial&&(this._iScale=ht("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;o>5280?(i=o/5280,e=this._getRoundNum(i),this._updateScale(this._iScale,e+" mi",e/i)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,i,e){t.style.width=Math.round(this.options.maxWidth*e)+"px",t.innerHTML=i},_getRoundNum:function(t){var i=Math.pow(10,(Math.floor(t)+"").length-1),e=t/i;return e=e>=10?10:e>=5?5:e>=3?3:e>=2?2:1,i*e}}),Ce=Pe.extend({options:{position:"bottomright",prefix:'<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'},initialize:function(t){l(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=ht("div","leaflet-control-attribution"),J(this._container);for(var i in t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});Le.mergeOptions({attributionControl:!0}),Le.addInitHook(function(){this.options.attributionControl&&(new Ce).addTo(this)});Pe.Layers=Te,Pe.Zoom=ze,Pe.Scale=Me,Pe.Attribution=Ce,be.layers=function(t,i,e){return new Te(t,i,e)},be.zoom=function(t){return new ze(t)},be.scale=function(t){return new Me(t)},be.attribution=function(t){return new Ce(t)};var Ze=v.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});Ze.addTo=function(t,i){return t.addHandler(i,this),this};var Se,Ee={Events:hi},ke=Vi?"touchstart mousedown":"mousedown",Ie={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},Ae={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},Be=ui.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){l(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(V(this._dragStartTarget,ke,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Be._dragging===this&&this.finishDrag(),q(this._dragStartTarget,ke,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!dt(this._element,"leaflet-zoom-anim")&&!(Be._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(Be._dragging=this,this._preventOutline&&zt(this._element),bt(),mi(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t;this._startPoint=new x(i.clientX,i.clientY),V(document,Ae[t.type],this._onMove,this),V(document,Ie[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&t.touches.length>1)this._moved=!0;else{var i=t.touches&&1===t.touches.length?t.touches[0]:t,e=new x(i.clientX,i.clientY).subtract(this._startPoint);(e.x||e.y)&&(Math.abs(e.x)+Math.abs(e.y)<this.options.clickTolerance||($(t),this._moved||(this.fire("dragstart"),this._moved=!0,this._startPos=Pt(this._element).subtract(e),pt(document.body,"leaflet-dragging"),this._lastTarget=t.target||t.srcElement,window.SVGElementInstance&&this._lastTarget instanceof SVGElementInstance&&(this._lastTarget=this._lastTarget.correspondingUseElement),pt(this._lastTarget,"leaflet-drag-target")),this._newPos=this._startPos.add(e),this._moving=!0,g(this._animRequest),this._lastEvent=t,this._animRequest=f(this._updatePosition,this,!0)))}},_updatePosition:function(){var t={originalEvent:this._lastEvent};this.fire("predrag",t),Lt(this._element,this._newPos),this.fire("drag",t)},_onUp:function(t){!t._simulated&&this._enabled&&this.finishDrag()},finishDrag:function(){mt(document.body,"leaflet-dragging"),this._lastTarget&&(mt(this._lastTarget,"leaflet-drag-target"),this._lastTarget=null);for(var t in Ae)q(document,Ae[t],this._onMove,this),q(document,Ie[t],this._onUp,this);Tt(),fi(),this._moved&&this._moving&&(g(this._animRequest),this.fire("dragend",{distance:this._newPos.distanceTo(this._startPos)})),this._moving=!1,Be._dragging=!1}}),Oe=(Object.freeze||Object)({simplify:Ct,pointToSegmentDistance:Zt,closestPointOnSegment:function(t,i,e){return Rt(t,i,e)},clipSegment:It,_getEdgeIntersection:At,_getBitCode:Bt,_sqClosestPointOnSegment:Rt,isFlat:Dt,_flat:Nt}),Re=(Object.freeze||Object)({clipPolygon:jt}),De={project:function(t){return new x(t.lng,t.lat)},unproject:function(t){return new M(t.y,t.x)},bounds:new P([-180,-90],[180,90])},Ne={R:6378137,R_MINOR:6356752.314245179,bounds:new P([-20037508.34279,-15496570.73972],[20037508.34279,18764656.23138]),project:function(t){var i=Math.PI/180,e=this.R,n=t.lat*i,o=this.R_MINOR/e,s=Math.sqrt(1-o*o),r=s*Math.sin(n),a=Math.tan(Math.PI/4-n/2)/Math.pow((1-r)/(1+r),s/2);return n=-e*Math.log(Math.max(a,1e-10)),new x(t.lng*i*e,n)},unproject:function(t){for(var i,e=180/Math.PI,n=this.R,o=this.R_MINOR/n,s=Math.sqrt(1-o*o),r=Math.exp(-t.y/n),a=Math.PI/2-2*Math.atan(r),h=0,u=.1;h<15&&Math.abs(u)>1e-7;h++)i=s*Math.sin(a),i=Math.pow((1-i)/(1+i),s/2),a+=u=Math.PI/2-2*Math.atan(r*i)-a;return new M(a*e,t.x*e/n)}},je=(Object.freeze||Object)({LonLat:De,Mercator:Ne,SphericalMercator:di}),We=i({},_i,{code:"EPSG:3395",projection:Ne,transformation:function(){var t=.5/(Math.PI*Ne.R);return S(t,.5,-t,.5)}()}
6),He=i({},_i,{code:"EPSG:4326",projection:De,transformation:S(1/180,1,-1/180,.5)}),Fe=i({},ci,{projection:De,transformation:S(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,i){var e=i.lng-t.lng,n=i.lat-t.lat;return Math.sqrt(e*e+n*n)},infinite:!0});ci.Earth=_i,ci.EPSG3395=We,ci.EPSG3857=vi,ci.EPSG900913=yi,ci.EPSG4326=He,ci.Simple=Fe;var Ue=ui.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var i=t.target;if(i.hasLayer(this)){if(this._map=i,this._zoomAnimated=i._zoomAnimated,this.getEvents){var e=this.getEvents();i.on(e,this),this.once("remove",function(){i.off(e,this)},this)}this.onAdd(i),this.getAttribution&&i.attributionControl&&i.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),i.fire("layeradd",{layer:this})}}});Le.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var i=n(t);return this._layers[i]?this:(this._layers[i]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var i=n(t);return this._layers[i]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[i],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n(t)in this._layers},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},_addLayers:function(t){for(var i=0,e=(t=t?ei(t)?t:[t]:[]).length;i<e;i++)this.addLayer(t[i])},_addZoomLimit:function(t){!isNaN(t.options.maxZoom)&&isNaN(t.options.minZoom)||(this._zoomBoundLayers[n(t)]=t,this._updateZoomLevels())},_removeZoomLimit:function(t){var i=n(t);this._zoomBoundLayers[i]&&(delete this._zoomBoundLayers[i],this._updateZoomLevels())},_updateZoomLevels:function(){var t=1/0,i=-1/0,e=this._getZoomSpan();for(var n in this._zoomBoundLayers){var o=this._zoomBoundLayers[n].options;t=void 0===o.minZoom?t:Math.min(t,o.minZoom),i=void 0===o.maxZoom?i:Math.max(i,o.maxZoom)}this._layersMaxZoom=i===-1/0?void 0:i,this._layersMinZoom=t===1/0?void 0:t,e!==this._getZoomSpan()&&this.fire("zoomlevelschange"),void 0===this.options.maxZoom&&this._layersMaxZoom&&this.getZoom()>this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()<this._layersMinZoom&&this.setZoom(this._layersMinZoom)}});var Ve=Ue.extend({initialize:function(t,i){l(this,i),this._layers={};var e,n;if(t)for(e=0,n=t.length;e<n;e++)this.addLayer(t[e])},addLayer:function(t){var i=this.getLayerId(t);return this._layers[i]=t,this._map&&this._map.addLayer(t),this},removeLayer:function(t){var i=t in this._layers?t:this.getLayerId(t);return this._map&&this._layers[i]&&this._map.removeLayer(this._layers[i]),delete this._layers[i],this},hasLayer:function(t){return!!t&&(t in this._layers||this.getLayerId(t)in this._layers)},clearLayers:function(){return this.eachLayer(this.removeLayer,this)},invoke:function(t){var i,e,n=Array.prototype.slice.call(arguments,1);for(i in this._layers)(e=this._layers[i])[t]&&e[t].apply(e,n);return this},onAdd:function(t){this.eachLayer(t.addLayer,t)},onRemove:function(t){this.eachLayer(t.removeLayer,t)},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},getLayer:function(t){return this._layers[t]},getLayers:function(){var t=[];return this.eachLayer(t.push,t),t},setZIndex:function(t){return this.invoke("setZIndex",t)},getLayerId:function(t){return n(t)}}),qe=Ve.extend({addLayer:function(t){return this.hasLayer(t)?this:(t.addEventParent(this),Ve.prototype.addLayer.call(this,t),this.fire("layeradd",{layer:t}))},removeLayer:function(t){return this.hasLayer(t)?(t in this._layers&&(t=this._layers[t]),t.removeEventParent(this),Ve.prototype.removeLayer.call(this,t),this.fire("layerremove",{layer:t})):this},setStyle:function(t){return this.invoke("setStyle",t)},bringToFront:function(){return this.invoke("bringToFront")},bringToBack:function(){return this.invoke("bringToBack")},getBounds:function(){var t=new T;for(var i in this._layers){var e=this._layers[i];t.extend(e.getBounds?e.getBounds():e.getLatLng())}return t}}),Ge=v.extend({options:{popupAnchor:[0,0],tooltipAnchor:[0,0]},initialize:function(t){l(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,i){var e=this._getIconUrl(t);if(!e){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n=this._createImg(e,i&&"IMG"===i.tagName?i:null);return this._setIconStyles(n,t),n},_setIconStyles:function(t,i){var e=this.options,n=e[i+"Size"];"number"==typeof n&&(n=[n,n]);
6var o=w(n),s=w("shadow"===i&&e.shadowAnchor||e.iconAnchor||o&&o.divideBy(2,!0));t.className="leaflet-marker-"+i+" "+(e.className||""),s&&(t.style.marginLeft=-s.x+"px",t.style.marginTop=-s.y+"px"),o&&(t.style.width=o.x+"px",t.style.height=o.y+"px")},_createImg:function(t,i){return i=i||document.createElement("img"),i.src=t,i},_getIconUrl:function(t){return Ki&&this.options[t+"RetinaUrl"]||this.options[t+"Url"]}}),Ke=Ge.extend({options:{iconUrl:"marker-icon.png",iconRetinaUrl:"marker-icon-2x.png",shadowUrl:"marker-shadow.png",iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],tooltipAnchor:[16,-28],shadowSize:[41,41]},_getIconUrl:function(t){return Ke.imagePath||(Ke.imagePath=this._detectIconPath()),(this.options.imagePath||Ke.imagePath)+Ge.prototype._getIconUrl.call(this,t)},_detectIconPath:function(){var t=ht("div","leaflet-default-icon-path",document.body),i=at(t,"background-image")||at(t,"backgroundImage");return document.body.removeChild(t),i=null===i||0!==i.indexOf("url")?"":i.replace(/^url\(["']?/,"").replace(/marker-icon\.png["']?\)$/,"")}}),Ye=Ze.extend({initialize:function(t){this._marker=t},addHooks:function(){var t=this._marker._icon;this._draggable||(this._draggable=new Be(t,t,!0)),this._draggable.on({dragstart:this._onDragStart,predrag:this._onPreDrag,drag:this._onDrag,dragend:this._onDragEnd},this).enable(),pt(t,"leaflet-marker-draggable")},removeHooks:function(){this._draggable.off({dragstart:this._onDragStart,predrag:this._onPreDrag,drag:this._onDrag,dragend:this._onDragEnd},this).disable(),this._marker._icon&&mt(this._marker._icon,"leaflet-marker-draggable")},moved:function(){return this._draggable&&this._draggable._moved},_adjustPan:function(t){var i=this._marker,e=i._map,n=this._marker.options.autoPanSpeed,o=this._marker.options.autoPanPadding,s=L.DomUtil.getPosition(i._icon),r=e.getPixelBounds(),a=e.getPixelOrigin(),h=b(r.min._subtract(a).add(o),r.max._subtract(a).subtract(o));if(!h.contains(s)){var u=w((Math.max(h.max.x,s.x)-h.max.x)/(r.max.x-h.max.x)-(Math.min(h.min.x,s.x)-h.min.x)/(r.min.x-h.min.x),(Math.max(h.max.y,s.y)-h.max.y)/(r.max.y-h.max.y)-(Math.min(h.min.y,s.y)-h.min.y)/(r.min.y-h.min.y)).multiplyBy(n);e.panBy(u,{animate:!1}),this._draggable._newPos._add(u),this._draggable._startPos._add(u),L.DomUtil.setPosition(i._icon,this._draggable._newPos),this._onDrag(t),this._panRequest=f(this._adjustPan.bind(this,t))}},_onDragStart:function(){this._oldLatLng=this._marker.getLatLng(),this._marker.closePopup().fire("movestart").fire("dragstart")},_onPreDrag:function(t){this._marker.options.autoPan&&(g(this._panRequest),this._panRequest=f(this._adjustPan.bind(this,t)))},_onDrag:function(t){var i=this._marker,e=i._shadow,n=Pt(i._icon),o=i._map.layerPointToLatLng(n);e&&Lt(e,n),i._latlng=o,t.latlng=o,t.oldLatLng=this._oldLatLng,i.fire("move",t).fire("drag",t)},_onDragEnd:function(t){g(this._panRequest),delete this._oldLatLng,this._marker.fire("moveend").fire("dragend",t)}}),Xe=Ue.extend({options:{icon:new Ke,interactive:!0,draggable:!1,autoPan:!1,autoPanPadding:[50,50],autoPanSpeed:10,keyboard:!0,title:"",alt:"",zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250,pane:"markerPane",bubblingMouseEvents:!1},initialize:function(t,i){l(this,i),this._latlng=C(t)},onAdd:function(t){this._zoomAnimated=this._zoomAnimated&&t.options.markerZoomAnimation,this._zoomAnimated&&t.on("zoomanim",this._animateZoom,this),this._initIcon(),this.update()},onRemove:function(t){this.dragging&&this.dragging.enabled()&&(this.options.draggable=!0,this.dragging.removeHooks()),delete this.dragging,this._zoomAnimated&&t.off("zoomanim",this._animateZoom,this),this._removeIcon(),this._removeShadow()},getEvents:function(){return{zoom:this.update,viewreset:this.update}},getLatLng:function(){return this._latlng},setLatLng:function(t){var i=this._latlng;return this._latlng=C(t),this.update(),this.fire("move",{oldLatLng:i,latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update()},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup,this._popup.options),this},getElement:function(){return this._icon},update:function(){if(this._icon&&this._map){var t=this._map.latLngToLayerPoint(this._latlng).round();this._setPos(t)}return this},_initIcon:function(){var t=this.options,i="leaflet-zoom-"+(this._zoomAnimated?"animated":"hide"),e=t.icon.createIcon(this._icon),n=!1;e!==this._icon&&(this._icon&&this._removeIcon(),n=!0,t.title&&(e.title=t.title),"IMG"===e.tagName&&(e.alt=t.alt||"")),pt(e,i),t.keyboard&&(e.tabIndex="0"),this._icon=e,t.riseOnHover&&this.on({mouseover:this._bringToFront,mouseout:this._resetZIndex});var o=t.icon.createShadow(this._shadow),s=!1;o!==this._shadow&&(this._removeShadow(),s=!0),o&&(pt(o,i),o.alt=""),this._shadow=o,t.opacity<1&&this._updateOpacity(),n&&this.getPane().appendChild(this._icon),this._initInteraction(),o&&s&&this.getPane("shadowPane").appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&this.off({mouseover:this._bringToFront,mouseout:this._resetZIndex}),ut(this._icon),this.removeInteractiveTarget(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&ut(this._shadow),this._shadow=null},_setPos:function(t){Lt(this._icon,t),this._shadow&&Lt(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(i)},_initInteraction:function(){if(this.options.interactive&&(pt(this._icon,"leaflet-interactive"),this.addInteractiveTarget(this._icon),Ye)){var t=this.options.draggable;this.dragging&&(t=this.dragging.enabled(),this.dragging.disable()),this.dragging=new Ye(this),t&&this.dragging.enable()}},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},_updateOpacity:function(){var t=this.options.opacity;vt(this._icon,t),this._shadow&&vt(this._shadow,t)},_bringToFront:function(){this._updateZIndex(this.options.riseOffset)},_resetZIndex:function(){this._updateZIndex(0)},_getPopupAnchor:function(){return this.options.icon.options.popupAnchor},_getTooltipAnchor:function(){return this.options.icon.options.tooltipAnchor}}),Je=Ue.extend({options:{stroke:!0,color:"#3388ff",weight:3,opacity:1,lineCap:"round",lineJoin:"round",dashArray:null,dashOffset:null,fill:!1,fillColor:null,fillOpacity:.2,f
vendor: 12,355 bytes, line 6
6illRule:"evenodd",interactive:!0,bubblingMouseEvents:!0},beforeAdd:function(t){this._renderer=t.getRenderer(this)},onAdd:function(){this._renderer._initPath(this),this._reset(),this._renderer._addPath(this)},onRemove:function(){this._renderer._removePath(this)},redraw:function(){return this._map&&this._renderer._updatePath(this),this},setStyle:function(t){return l(this,t),this._renderer&&this._renderer._updateStyle(this),this},bringToFront:function(){return this._renderer&&this._renderer._bringToFront(this),this},bringToBack:function(){return this._renderer&&this._renderer._bringToBack(this),this},getElement:function(){return this._path},_reset:function(){this._project(),this._update()},_clickTolerance:function(){return(this.options.stroke?this.options.weight/2:0)+this._renderer.options.tolerance}}),$e=Je.extend({options:{fill:!0,radius:10},initialize:function(t,i){l(this,i),this._latlng=C(t),this._radius=this.options.radius},setLatLng:function(t){return this._latlng=C(t),this.redraw(),this.fire("move",{latlng:this._latlng})},getLatLng:function(){return this._latlng},setRadius:function(t){return this.options.radius=this._radius=t,this.redraw()},getRadius:function(){return this._radius},setStyle:function(t){var i=t&&t.radius||this._radius;return Je.prototype.setStyle.call(this,t),this.setRadius(i),this},_project:function(){this._point=this._map.latLngToLayerPoint(this._latlng),this._updateBounds()},_updateBounds:function(){var t=this._radius,i=this._radiusY||t,e=this._clickTolerance(),n=[t+e,i+e];this._pxBounds=new P(this._point.subtract(n),this._point.add(n))},_update:function(){this._map&&this._updatePath()},_updatePath:function(){this._renderer._updateCircle(this)},_empty:function(){return this._radius&&!this._renderer._bounds.intersects(this._pxBounds)},_containsPoint:function(t){return t.distanceTo(this._point)<=this._radius+this._clickTolerance()}}),Qe=$e.extend({initialize:function(t,e,n){if("number"==typeof e&&(e=i({},n,{radius:e})),l(this,e),this._latlng=C(t),isNaN(this.options.radius))throw new Error("Circle radius cannot be NaN");this._mRadius=this.options.radius},setRadius:function(t){return this._mRadius=t,this.redraw()},getRadius:function(){return this._mRadius},getBounds:function(){var t=[this._radius,this._radiusY||this._radius];return new T(this._map.layerPointToLatLng(this._point.subtract(t)),this._map.layerPointToLatLng(this._point.add(t)))},setStyle:Je.prototype.setStyle,_project:function(){var t=this._latlng.lng,i=this._latlng.lat,e=this._map,n=e.options.crs;if(n.distance===_i.distance){var o=Math.PI/180,s=this._mRadius/_i.R/o,r=e.project([i+s,t]),a=e.project([i-s,t]),h=r.add(a).divideBy(2),u=e.unproject(h).lat,l=Math.acos((Math.cos(s*o)-Math.sin(i*o)*Math.sin(u*o))/(Math.cos(i*o)*Math.cos(u*o)))/o;(isNaN(l)||0===l)&&(l=s/Math.cos(Math.PI/180*i)),this._point=h.subtract(e.getPixelOrigin()),this._radius=isNaN(l)?0:h.x-e.project([u,t-l]).x,this._radiusY=h.y-r.y}else{var c=n.unproject(n.project(this._latlng).subtract([this._mRadius,0]));this._point=e.latLngToLayerPoint(this._latlng),this._radius=this._point.x-e.latLngToLayerPoint(c).x}this._updateBounds()}}),tn=Je.extend({options:{smoothFactor:1,noClip:!1},initialize:function(t,i){l(this,i),this._setLatLngs(t)},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._setLatLngs(t),this.redraw()},isEmpty:function(){return!this._latlngs.length},closestLayerPoint:function(t){for(var i,e,n=1/0,o=null,s=Rt,r=0,a=this._parts.length;r<a;r++)for(var h=this._parts[r],u=1,l=h.length;u<l;u++){var c=s(t,i=h[u-1],e=h[u],!0);c<n&&(n=c,o=s(t,i,e))}return o&&(o.distance=Math.sqrt(n)),o},getCenter:function(){if(!this._map)throw new Error("Must add layer to map before using getCenter()");var t,i,e,n,o,s,r,a=this._rings[0],h=a.length;if(!h)return null;for(t=0,i=0;t<h-1;t++)i+=a[t].distanceTo(a[t+1])/2;if(0===i)return this._map.layerPointToLatLng(a[0]);for(t=0,n=0;t<h-1;t++)if(o=a[t],s=a[t+1],e=o.distanceTo(s),(n+=e)>i)return r=(n-i)/e,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,i){return i=i||this._defaultShape(),t=C(t),i.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new T,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return Dt(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var i=[],e=Dt(t),n=0,o=t.length;n<o;n++)e?(i[n]=C(t[n]),this._bounds.extend(i[n])):i[n]=this._convertLatLngs(t[n]);return i},_project:function(){var t=new P;this._rings=[],this._projectLatlngs(this._latlngs,this._rings,t);var i=this._clickTolerance(),e=new x(i,i);this._bounds.isValid()&&t.isValid()&&(t.min._subtract(e),t.max._add(e),this._pxBounds=t)},_projectLatlngs:function(t,i,e){var n,o,s=t[0]instanceof M,r=t.length;if(s){for(o=[],n=0;n<r;n++)o[n]=this._map.latLngToLayerPoint(t[n]),e.extend(o[n]);i.push(o)}else for(n=0;n<r;n++)this._projectLatlngs(t[n],i,e)},_clipPoints:function(){var t=this._renderer._bounds;if(this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else{var i,e,n,o,s,r,a,h=this._parts;for(i=0,n=0,o=this._rings.length;i<o;i++)for(e=0,s=(a=this._rings[i]).length;e<s-1;e++)(r=It(a[e],a[e+1],t,e,!0))&&(h[n]=h[n]||[],h[n].push(r[0]),r[1]===a[e+1]&&e!==s-2||(h[n].push(r[1]),n++))}},_simplifyPoints:function(){for(var t=this._parts,i=this.options.smoothFactor,e=0,n=t.length;e<n;e++)t[e]=Ct(t[e],i)},_update:function(){this._map&&(this._clipPoints(),this._simplifyPoints(),this._updatePath())},_updatePath:function(){this._renderer._updatePoly(this)},_containsPoint:function(t,i){var e,n,o,s,r,a,h=this._clickTolerance();if(!this._pxBounds||!this._pxBounds.contains(t))return!1;for(e=0,s=this._parts.length;e<s;e++)for(n=0,o=(r=(a=this._parts[e]).length)-1;n<r;o=n++)if((i||0!==n)&&Zt(t,a[o],a[n])<=h)return!0;return!1}});tn._flat=Nt;var en=tn.extend({options:{fill:!0},isEmpty:function(){return!this._latlngs.length||!this._latlngs[0].length},getCenter:function(){if(!this._map)throw new Error("Must add layer to map before using getCenter()");var t,i,e,n,o,s,r,a,h,u=this._rings[0],l=u.length;if(!l)return null;for(s=r=a=0,t=0,i=l-1;t<l;i=t++)e=u[t],n=u[i],o=e.y*n.x-n.y*e.x,r+=(e.x+n.x)*o,a+=(e.y+n.y)*o,s+=3*o;return h=0===s?u[0]:[r/s,a/s],this._map.layerPointToLatLng(h)},_convertLatLngs:function(t){var i=tn.prototype._convertLatLngs.call(this,t),e=i.length;return e>=2&&i[0]instanceof M&&i[0].equals(i[e-1])&&i.pop(),i},_setLatLngs:function(t){tn.prototype._setLatLngs.call(this,t),Dt(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return Dt(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,i=this.options.weight,e=new x(i,i);if(t=new P(t.min.subtract(e),t.max.add(e)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else for(var n,o=0,s=this._rings.length;o<s;o++)(n=jt(this._rings[o],t,!0)).length&&this._parts.push(n)},_updatePath:function(){this._renderer._updatePoly(this,!0)},_containsPoint:function(t){var i,e,n,o,s,r,a,h,u=!1;if(!this._pxBounds.contains(t))return!1;for(o=0,a=this._parts.length;o<a;o++)for(s=0,r=(h=(i=this._parts[o]).length)-1;s<h;r=s++)e=i[s],n=i[r],e.y>t.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||tn.prototype._containsPoint.call(this,t,!0)}}),nn=qe.extend({initialize:function(t,i){l(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=ei(t)?t:t.features;if(o){for(i=0,e=o.length;i<e;i++)((n=o[i]).geometries||n.geometry||n.features||n.coordinates)&&this.addData(n);return this}var s=this.options;if(s.filter&&!s.filter(t))return this;var r=Wt(t,s);return r?(r.feature=Gt(t),r.defaultOptions=r.options,this.resetStyle(r),s.onEachFeature&&s.onEachFeature(t,r),this.addLayer(r)):this},resetStyle:function(t){return t.options=i({},t.defaultOptions),this._setLayerStyle(t,this.options.style),this},setStyle:function(t){return this.eachLayer(function(i){this._setLayerStyle(i,t)},this)},_setLayerStyle:function(t,i){"function"==typeof i&&(i=i(t.feature)),t.setStyle&&t.setStyle(i)}}),on={toGeoJSON:function(t){return qt(this,{type:"Point",coordinates:Ut(this.getLatLng(),t)})}};Xe.include(on),Qe.include(on),$e.include(on),tn.include({toGeoJSON:function(t){var i=!Dt(this._latlngs),e=Vt(this._latlngs,i?1:0,!1,t);return qt(this,{type:(i?"Multi":"")+"LineString",coordinates:e})}}),en.include({toGeoJSON:function(t){var i=!Dt(this._latlngs),e=i&&!Dt(this._latlngs[0]),n=Vt(this._latlngs,e?2:i?1:0,!0,t);return i||(n=[n]),qt(this,{type:(e?"Multi":"")+"Polygon",coordinates:n})}}),Ve.include({toMultiPoint:function(t){var i=[];return this.eachLayer(function(e){i.push(e.toGeoJSON(t).geometry.coordinates)}),qt(this,{type:"MultiPoint",coordinates:i})},toGeoJSON:function(t){var i=this.feature&&this.feature.geometry&&this.feature.geometry.type;if("MultiPoint"===i)return this.toMultiPoint(t);var e="GeometryCollection"===i,n=[];return this.eachLayer(function(i){if(i.toGeoJSON){var o=i.toGeoJSON(t);if(e)n.push(o.geometry);else{var s=Gt(o);"FeatureCollection"===s.type?n.push.apply(n,s.features):n.push(s)}}}),e?qt(this,{geometries:n,type:"GeometryCollection"}):{type:"FeatureCollection",features:n}}});var sn=Kt,rn=Ue.extend({options:{opacity:1,alt:"",interactive:!1,crossOrigin:!1,errorOverlayUrl:"",zIndex:1,className:""},initialize:function(t,i,e){this._url=t,this._bounds=z(i),l(this,e)},onAdd:function(){this._image||(this._initImage(),this.options.opacity<1&&this._updateOpacity()),this.options.interactive&&(pt(this._image,"leaflet-interactive"),this.addInteractiveTarget(this._image)),this.getPane().appendChild(this._image),this._reset()},onRemove:function(){ut(this._image),this.options.interactive&&this.removeInteractiveTarget(this._image)},setOpacity:function(t){return this.options.opacity=t,this._image&&this._updateOpacity(),this},setStyle:function(t){return t.opacity&&this.setOpacity(t.opacity),this},bringToFront:function(){return this._map&&ct(this._image),this},bringToBack:function(){return this._map&&_t(this._image),this},setUrl:function(t){return this._url=t,this._image&&(this._image.src=t),this},setBounds:function(t){return this._bounds=z(t),this._map&&this._reset(),this},getEvents:function(){var t={zoom:this._reset,viewreset:this._reset};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},getBounds:function(){return this._bounds},getElement:function(){return this._image},_initImage:function(){var t="IMG"===this._url.tagName,i=this._image=t?this._url:ht("img");pt(i,"leaflet-image-layer"),this._zoomAnimated&&pt(i,"leaflet-zoom-animated"),this.options.className&&pt(i,this.options.className),i.onselectstart=r,i.onmousemove=r,i.onload=e(this.fire,this,"load"),i.onerror=e(this._overlayOnError,this,"error"),this.options.crossOrigin&&(i.crossOrigin=""),this.options.zIndex&&this._updateZIndex(),t?this._url=i.src:(i.src=this._url,i.alt=this.options.alt)},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),e=this._map._latLngBoundsToNewLayerBounds(this._bounds,t.zoom,t.center).min;wt(this._image,e,i)},_reset:function(){var t=this._image,i=new P(this._map.latLngToLayerPoint(this._bounds.getNorthWest()),this._map.latLngToLayerPoint(this._bounds.getSouthEast())),e=i.getSize();Lt(t,i.min),t.style.width=e.x+"px",t.style.height=e.y+"px"},_updateOpacity:function(){vt(this._image,this.options.opacity)},_updateZIndex:function(){this._image&&void 0!==this.options.zIndex&&null!==this.options.zIndex&&(this._image.style.zIndex=this.options.zIndex)},_overlayOnError:function(){this.fire("error");var t=this.options.errorOverlayUrl;t&&this._url!==t&&(this._url=t,this._image.src=t)}}),an=rn.extend({options:{autoplay:!0,loop:!0},_initImage:function(){var t="VIDEO"===this._url.tagName,i=this._image=t?this._url:ht("video");if(pt(i,"leaflet-image-layer"),this._zoomAnimated&&pt(i,"leaflet-zoom-animated"),i.onselectstart=r,i.onmousemove=r,i.onloadeddata=e(this.fire,this,"load"),t){for(var n=i.getElementsByTagName("source"),o=[],s=0;s<n.length;s++)o.push(n[s].src);this._url=n.length>0?o:[i.src]}else{ei(this._url)||(this._url=[this._url]),i.autoplay=!!this.options.autoplay,i.loop=!!this.options.loop;for(var a=0;a<this._url.length;
6a++){var h=ht("source");h.src=this._url[a],i.appendChild(h)}}}}),hn=Ue.extend({options:{offset:[0,7],className:"",pane:"popupPane"},initialize:function(t,i){l(this,t),this._source=i},onAdd:function(t){this._zoomAnimated=t._zoomAnimated,this._container||this._initLayout(),t._fadeAnimated&&vt(this._container,0),clearTimeout(this._removeTimeout),this.getPane().appendChild(this._container),this.update(),t._fadeAnimated&&vt(this._container,1),this.bringToFront()},onRemove:function(t){t._fadeAnimated?(vt(this._container,0),this._removeTimeout=setTimeout(e(ut,void 0,this._container),200)):ut(this._container)},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=C(t),this._map&&(this._updatePosition(),this._adjustPan()),this},getContent:function(){return this._content},setContent:function(t){return this._content=t,this.update(),this},getElement:function(){return this._container},update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updateLayout(),this._updatePosition(),this._container.style.visibility="",this._adjustPan())},getEvents:function(){var t={zoom:this._updatePosition,viewreset:this._updatePosition};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},isOpen:function(){return!!this._map&&this._map.hasLayer(this)},bringToFront:function(){return this._map&&ct(this._container),this},bringToBack:function(){return this._map&&_t(this._container),this},_updateContent:function(){if(this._content){var t=this._contentNode,i="function"==typeof this._content?this._content(this._source||this):this._content;if("string"==typeof i)t.innerHTML=i;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(i)}this.fire("contentupdate")}},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),i=w(this.options.offset),e=this._getAnchor();this._zoomAnimated?Lt(this._container,t.add(e)):i=i.add(t).add(e);var n=this._containerBottom=-i.y,o=this._containerLeft=-Math.round(this._containerWidth/2)+i.x;this._container.style.bottom=n+"px",this._container.style.left=o+"px"}},_getAnchor:function(){return[0,0]}}),un=hn.extend({options:{maxWidth:300,minWidth:50,maxHeight:null,autoPan:!0,autoPanPaddingTopLeft:null,autoPanPaddingBottomRight:null,autoPanPadding:[5,5],keepInView:!1,closeButton:!0,autoClose:!0,closeOnEscapeKey:!0,className:""},openOn:function(t){return t.openPopup(this),this},onAdd:function(t){hn.prototype.onAdd.call(this,t),t.fire("popupopen",{popup:this}),this._source&&(this._source.fire("popupopen",{popup:this},!0),this._source instanceof Je||this._source.on("preclick",Y))},onRemove:function(t){hn.prototype.onRemove.call(this,t),t.fire("popupclose",{popup:this}),this._source&&(this._source.fire("popupclose",{popup:this},!0),this._source instanceof Je||this._source.off("preclick",Y))},getEvents:function(){var t=hn.prototype.getEvents.call(this);return(void 0!==this.options.closeOnClick?this.options.closeOnClick:this._map.options.closePopupOnClick)&&(t.preclick=this._close),this.options.keepInView&&(t.moveend=this._adjustPan),t},_close:function(){this._map&&this._map.closePopup(this)},_initLayout:function(){var t="leaflet-popup",i=this._container=ht("div",t+" "+(this.options.className||"")+" leaflet-zoom-animated"),e=this._wrapper=ht("div",t+"-content-wrapper",i);if(this._contentNode=ht("div",t+"-content",e),J(e),X(this._contentNode),V(e,"contextmenu",Y),this._tipContainer=ht("div",t+"-tip-container",i),this._tip=ht("div",t+"-tip",this._tipContainer),this.options.closeButton){var n=this._closeButton=ht("a",t+"-close-button",i);n.href="#close",n.innerHTML="×",V(n,"click",this._onCloseButtonClick,this)}},_updateLayout:function(){var t=this._contentNode,i=t.style;i.width="",i.whiteSpace="nowrap";var e=t.offsetWidth;e=Math.min(e,this.options.maxWidth),e=Math.max(e,this.options.minWidth),i.width=e+1+"px",i.whiteSpace="",i.height="";var n=t.offsetHeight,o=this.options.maxHeight;o&&n>o?(i.height=o+"px",pt(t,"leaflet-popup-scrolled")):mt(t,"leaflet-popup-scrolled"),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),e=this._getAnchor();Lt(this._container,i.add(e))},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress)){var t=this._map,i=parseInt(at(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+i,n=this._containerWidth,o=new x(this._containerLeft,-e-this._containerBottom);o._add(Pt(this._container));var s=t.layerPointToContainerPoint(o),r=w(this.options.autoPanPadding),a=w(this.options.autoPanPaddingTopLeft||r),h=w(this.options.autoPanPaddingBottomRight||r),u=t.getSize(),l=0,c=0;s.x+n+h.x>u.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Q(t)},_getAnchor:function(){return w(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});Le.mergeOptions({closePopupOnClick:!0}),Le.include({openPopup:function(t,i,e){return t instanceof un||(t=new un(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),Ue.include({bindPopup:function(t,i){return t instanceof un?(l(t,i),this._popup=t,t._source=this):(this._popup&&!i||(this._popup=new un(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){if(t instanceof Ue||(i=t,t=this),t instanceof qe)for(var e in this._layers){t=this._layers[e];break}
6return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Q(t),i instanceof Je?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var ln=hn.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){hn.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){hn.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=hn.prototype.getEvents.call(this);return Vi&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=ht("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=w(this.options.offset),u=this._getAnchor();"top"===s?t=t.add(w(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t=t.subtract(w(r/2-h.x,-h.y,!0)):"center"===s?t=t.subtract(w(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.x<n.x?(s="right",t=t.add(w(h.x+u.x,u.y-a/2+h.y,!0))):(s="left",t=t.subtract(w(r+u.x-h.x,a/2-u.y-h.y,!0))),mt(e,"leaflet-tooltip-right"),mt(e,"leaflet-tooltip-left"),mt(e,"leaflet-tooltip-top"),mt(e,"leaflet-tooltip-bottom"),pt(e,"leaflet-tooltip-"+s),Lt(e,t)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},setOpacity:function(t){this.options.opacity=t,this._container&&vt(this._container,t)},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);this._setPosition(i)},_getAnchor:function(){return w(this._source&&this._source._getTooltipAnchor&&!this.options.sticky?this._source._getTooltipAnchor():[0,0])}});Le.include({openTooltip:function(t,i,e){return t instanceof ln||(t=new ln(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:this.addLayer(t)},closeTooltip:function(t){return t&&this.removeLayer(t),this}}),Ue.include({bindTooltip:function(t,i){return t instanceof ln?(l(t,i),this._tooltip=t,t._source=this):(this._tooltip&&!i||(this._tooltip=new ln(i,this)),this._tooltip.setContent(t)),this._initTooltipInteractions(),this._tooltip.options.permanent&&this._map&&this._map.hasLayer(this)&&this.openTooltip(),this},unbindTooltip:function(){return this._tooltip&&(this._initTooltipInteractions(!0),this.closeTooltip(),this._tooltip=null),this},_initTooltipInteractions:function(t){if(t||!this._tooltipHandlersAdded){var i=t?"off":"on",e={remove:this.closeTooltip,move:this._moveTooltip};this._tooltip.options.permanent?e.add=this._openTooltip:(e.mouseover=this._openTooltip,e.mouseout=this.closeTooltip,this._tooltip.options.sticky&&(e.mousemove=this._moveTooltip),Vi&&(e.click=this._openTooltip)),this[i](e),this._tooltipHandlersAdded=!t}},openTooltip:function(t,i){if(t instanceof Ue||(i=t,t=this),t instanceof qe)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._tooltip&&this._map&&(this._tooltip._source=t,this._tooltip.update(),this._map.openTooltip(this._tooltip,i),this._tooltip.options.interactive&&this._tooltip._container&&(pt(this._tooltip._container,"leaflet-clickable"),this.addInteractiveTarget(this._tooltip._container))),this},closeTooltip:function(){return this._tooltip&&(this._tooltip._close(),this._tooltip.options.interactive&&this._tooltip._container&&(mt(this._tooltip._container,"leaflet-clickable"),this.removeInteractiveTarget(this._tooltip._container))),this},toggleTooltip:function(t){return this._tooltip&&(this._tooltip._map?this.closeTooltip():this.openTooltip(t)),this},isTooltipOpen:function(){return this._tooltip.isOpen()},setTooltipContent:function(t){return this._tooltip&&this._tooltip.setContent(t),this},getTooltip:function(){return this._tooltip},_openTooltip:function(t){var i=t.layer||t.target;this._tooltip&&this._map&&this.openTooltip(i,this._tooltip.options.sticky?t.latlng:void 0)},_moveTooltip:function(t){var i,e,n=t.latlng;this._tooltip.options.sticky&&t.originalEvent&&(i=this._map.mouseEventToContainerPoint(t.originalEvent),e=this._map.containerPointToLayerPoint(i),n=this._map.layerPointToLatLng(e)),this._tooltip.setLatLng(n)}});var cn=Ge.extend({options:{iconSize:[12,12],html:!1,bgPos:null,className:"leaflet-div-icon"},createIcon:function(t){var i=t&&"DIV"===t.tagName?t:document.createElement("div"),e=this.options;if(i.innerHTML=!1!==e.html?e.html:"",e.bgPos){var n=w(e.bgPos);i.style.backgroundPosition=-n.x+"px "+-n.y+"px"}return this._setIconStyles(i,"icon"),i},createShadow:function(){return null}});Ge.Default=Ke;var _n=Ue.extend({options:{tileSize:256,opacity:1,updateWhenIdle:ji,updateWhenZooming:!0,updateInterval:200,zIndex:1,bounds:null,minZoom:0,maxZoom:void 0,maxNativeZoom:void 0,minNativeZoom:void 0,noWrap:!1,pane:"tilePane",className:"",keepBuffer:2},initialize:function(t){l(this,t)},onAdd:function(){this._initContainer(),this._levels={},this._tiles={},this._resetView(),this._update()},beforeAdd:function(t){t._addZoomLimit(this)},onRemove:function(t){this._removeAllTiles(),ut(this._container),t._removeZoomLimit(this),this._container=null,this._tileZoom=void 0},bringToFront:function(){return this._map&&(ct(this._container),this._setAutoZIndex(Math.max)),this},bringToBack:function(){return this._map&&(_t(this._container),this._setAutoZIndex(Math.min)),this},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},isLoading:function(){return this._loading},redraw:function(){return this._map&&(this._removeAllTiles(),this._update()),this},getEvents:function(){var t={viewprereset:this._invalidateAll,viewreset:this._resetView,zoom:this._resetView,moveend:this._onMoveEnd};return this.options.updateWhenIdle||(this._onMove||(this._onMove=o(this._onMoveEnd,this.options.updateInterval,this)),t.move=this._onMove),this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},createTile:function(){return document.createElement("div")},getTileSize:function(){var t=this.options.tileSize;return t instanceof x?t:new x(t,t)},_updateZIndex:function(){this._container&&void 0!==this.options.zIndex&&null!==this.options.zIndex&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t){for(var i,e=this.getPane().children,n=-t(-1/0,1/0),o=0,s=e.length;o<s;o++)i=e[o].style.zIndex,e[o]!==this._container&&i&&(n=t(n,+i));isFinite(n)&&(this.options.zIndex=n+t(-1,1),this._updateZIndex())},_updateOpacity:function(){if(this._map&&!Li){vt(this._container,this.options.opacity);var t=+new Date,i=!1,e=!1;for(var n in this._tiles){var o=this._tiles[n];if(o.current&&o.loaded){var s=Math.min(1,(t-o.loaded)/200);vt(o.el,s),s<1?i=!0:(o.active?e=!0:this._onOpaqueTile(o),o.active=!0)}}e&&!this._noPrune&&this._pruneTiles(),i&&(g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this))}},_onOpaqueTile:r,_initContainer:function(){this._container||(this._container=ht("div","leaflet-layer "+(this.options.className||"")),this._updateZIndex(),this.options.opacity<1&&this._updateOpacity(),this.getPane().appendChild(this._container))},_updateLevels:function(){var t=this._tileZoom,i=this.options.maxZoom;if(void 0!==t){for(var e in this._levels)this._levels[e].el.children.length||e===t?(this._levels[e].el.style.zIndex=i-Math.abs(t-e),this._onUpdateLevel(e)):(ut(this._levels[e].el),this._removeTilesAtZoom(e),this._onRemoveLevel(e),delete this._levels[e]);var n=this._levels[t],o=this._map;return n||((n=this._levels[t]={}).el=ht("div","leaflet-tile-container leaflet-zoom-animated",this._container),n.el.style.zIndex=i,n.origin=o.project(o.unproject(o.getPixelOrigin()),t).round(),n.zoom=t,this._setZoomTransform(n,o.getCenter(),o.getZoom()),n.el.offsetWidth,this._onCreateLevel(n)),this._level=n,n}},_onUpdateLevel:r,_onRemoveLevel:r,_onCreateLevel:r,_pruneTiles:function(){if(this._map){var t,i,e=this._map.getZoom();if(e>this.options.maxZoom||e<this.options.minZoom)this._removeAllTiles();else{for(t in this._tiles)(i=this._tiles[t]).retain=i.current;for(t in this._tiles)if((i=this._tiles[t]).current&&!i.active){var n=i.coords;this._retainParent(n.x,n.y,n.z,n.z-5)||this._retainChildren(n.x,n.y,n.z,n.z+2)}for(t in this._tiles)this._tiles[t].retain||this._removeTile(t)}}},_removeTilesAtZoom:function(t){for(var i in this._tiles)this._tiles[i].coords.z===t&&this._removeTile(i)},_removeAllTiles:function(){for(var t in this._tiles)this._removeTile(t)},_invalidateAll:function(){for(var t in this._levels)ut(this._levels[t].el),this._onRemoveLevel(t),delete this._levels[t];this._removeAllTiles(),this._tileZoom=void 0},_retainParent:function(t,i,e,n){var o=Math.floor(t/2),s=Math.floor(i/2),r=e-1,a=new x(+o,+s);a.z=+r;var h=this._tileCoordsToKey(a),u=this._tiles[h];return u&&u.active?(u.retain=!0,!0):(u&&u.loaded&&(u.retain=!0),r>n&&this._retainParent(o,s,r,n))},_retainChildren:function(t,i,e,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*i;s<2*i+2;s++){var r=new x(o,s);r.z=e+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];h&&h.active?h.retain=!0:(h&&h.loaded&&(h.retain=!0),e+1<n&&this._retainChildren(o,s,e+1,n))}},_resetView:function(t){var i=t&&(t.pinch||t.flyTo);
vendor: 5,850 bytes, line 6
6this._setView(this._map.getCenter(),this._map.getZoom(),i,i)},_animateZoom:function(t){this._setView(t.center,t.zoom,!0,t.noUpdate)},_clampZoom:function(t){var i=this.options;return void 0!==i.minNativeZoom&&t<i.minNativeZoom?i.minNativeZoom:void 0!==i.maxNativeZoom&&i.maxNativeZoom<t?i.maxNativeZoom:t},_setView:function(t,i,e,n){var o=this._clampZoom(Math.round(i));(void 0!==this.options.maxZoom&&o>this.options.maxZoom||void 0!==this.options.minZoom&&o<this.options.minZoom)&&(o=void 0);var s=this.options.updateWhenZooming&&o!==this._tileZoom;n&&!s||(this._tileZoom=o,this._abortLoading&&this._abortLoading(),this._updateLevels(),this._resetGrid(),void 0!==o&&this._update(t),e||this._pruneTiles(),this._noPrune=!!e),this._setZoomTransforms(t,i)},_setZoomTransforms:function(t,i){for(var e in this._levels)this._setZoomTransform(this._levels[e],t,i)},_setZoomTransform:function(t,i,e){var n=this._map.getZoomScale(e,t.zoom),o=t.origin.multiplyBy(n).subtract(this._map._getNewPixelOrigin(i,e)).round();Ni?wt(t.el,o,n):Lt(t.el,o)},_resetGrid:function(){var t=this._map,i=t.options.crs,e=this._tileSize=this.getTileSize(),n=this._tileZoom,o=this._map.getPixelWorldBounds(this._tileZoom);o&&(this._globalTileRange=this._pxBoundsToTileRange(o)),this._wrapX=i.wrapLng&&!this.options.noWrap&&[Math.floor(t.project([0,i.wrapLng[0]],n).x/e.x),Math.ceil(t.project([0,i.wrapLng[1]],n).x/e.y)],this._wrapY=i.wrapLat&&!this.options.noWrap&&[Math.floor(t.project([i.wrapLat[0],0],n).y/e.x),Math.ceil(t.project([i.wrapLat[1],0],n).y/e.y)]},_onMoveEnd:function(){this._map&&!this._map._animatingZoom&&this._update()},_getTiledPixelBounds:function(t){var i=this._map,e=i._animatingZoom?Math.max(i._animateToZoom,i.getZoom()):i.getZoom(),n=i.getZoomScale(e,this._tileZoom),o=i.project(t,this._tileZoom).floor(),s=i.getSize().divideBy(2*n);return new P(o.subtract(s),o.add(s))},_update:function(t){var i=this._map;if(i){var e=this._clampZoom(i.getZoom());if(void 0===t&&(t=i.getCenter()),void 0!==this._tileZoom){var n=this._getTiledPixelBounds(t),o=this._pxBoundsToTileRange(n),s=o.getCenter(),r=[],a=this.options.keepBuffer,h=new P(o.getBottomLeft().subtract([a,-a]),o.getTopRight().add([a,-a]));if(!(isFinite(o.min.x)&&isFinite(o.min.y)&&isFinite(o.max.x)&&isFinite(o.max.y)))throw new Error("Attempted to load an infinite number of tiles");for(var u in this._tiles){var l=this._tiles[u].coords;l.z===this._tileZoom&&h.contains(new x(l.x,l.y))||(this._tiles[u].current=!1)}if(Math.abs(e-this._tileZoom)>1)this._setView(t,e);else{for(var c=o.min.y;c<=o.max.y;c++)for(var _=o.min.x;_<=o.max.x;_++){var d=new x(_,c);if(d.z=this._tileZoom,this._isValidTile(d)){var p=this._tiles[this._tileCoordsToKey(d)];p?p.current=!0:r.push(d)}}if(r.sort(function(t,i){return t.distanceTo(s)-i.distanceTo(s)}),0!==r.length){this._loading||(this._loading=!0,this.fire("loading"));var m=document.createDocumentFragment();for(_=0;_<r.length;_++)this._addTile(r[_],m);this._level.el.appendChild(m)}}}}},_isValidTile:function(t){var i=this._map.options.crs;if(!i.infinite){var e=this._globalTileRange;if(!i.wrapLng&&(t.x<e.min.x||t.x>e.max.x)||!i.wrapLat&&(t.y<e.min.y||t.y>e.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return z(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new T(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new x(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(Ci||i.el.setAttribute("src",ni),ut(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){pt(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=r,t.onmousemove=r,Li&&this.options.opacity<1&&vt(t,this.options.opacity),Ti&&!zi&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var n=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),e(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&f(e(this._tileReady,this,t,null,s)),Lt(s,n),this._tiles[o]={el:s,coords:t,current:!0},i.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,i,n){if(this._map){i&&this.fire("tileerror",{error:i,tile:n,coords:t});var o=this._tileCoordsToKey(t);(n=this._tiles[o])&&(n.loaded=+new Date,this._map._fadeAnimated?(vt(n.el,0),g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this)):(n.active=!0,this._pruneTiles()),i||(pt(n.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:n.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),Li||!this._map._fadeAnimated?f(this._pruneTiles,this):setTimeout(e(this._pruneTiles,this),250)))}},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new x(this._wrapX?s(t.x,this._wrapX):t.x,this._wrapY?s(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new P(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),dn=_n.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=l(this,i)).detectRetina&&Ki&&i.maxZoom>0&&(i.tileSize=Math.floor(i.tileSize/2),i.zoomReverse?(i.zoomOffset--,i.minZ
6oom++):(i.zoomOffset++,i.maxZoom--),i.minZoom=Math.max(0,i.minZoom)),"string"==typeof i.subdomains&&(i.subdomains=i.subdomains.split("")),Ti||this.on("tileunload",this._onTileRemove)},setUrl:function(t,i){return this._url=t,i||this.redraw(),this},createTile:function(t,i){var n=document.createElement("img");return V(n,"load",e(this._tileOnLoad,this,i,n)),V(n,"error",e(this._tileOnError,this,i,n)),this.options.crossOrigin&&(n.crossOrigin=""),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:Ki?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var n=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=n),e["-y"]=n}return _(this._url,i(e,this.options))},_tileOnLoad:function(t,i){Li?setTimeout(e(t,this,null,i),0):t(null,i)},_tileOnError:function(t,i,e){var n=this.options.errorTileUrl;n&&i.getAttribute("src")!==n&&(i.src=n),t(e,i)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,i=this.options.maxZoom,e=this.options.zoomReverse,n=this.options.zoomOffset;return e&&(t=i-t),t+n},_getSubdomain:function(t){var i=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[i]},_abortLoading:function(){var t,i;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&((i=this._tiles[t].el).onload=r,i.onerror=r,i.complete||(i.src=ni,ut(i),delete this._tiles[t]))}}),pn=dn.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var n=i({},this.defaultWmsParams);for(var o in e)o in this.options||(n[o]=e[o]);var s=(e=l(this,e)).detectRetina&&Ki?2:1,r=this.getTileSize();n.width=r.x*s,n.height=r.y*s,this.wmsParams=n},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var i=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[i]=this._crs.code,dn.prototype.onAdd.call(this,t)},getTileUrl:function(t){var i=this._tileCoordsToNwSe(t),e=this._crs,n=b(e.project(i[0]),e.project(i[1])),o=n.min,s=n.max,r=(this._wmsVersion>=1.3&&this._crs===He?[o.y,o.x,s.y,s.x]:[o.x,o.y,s.x,s.y]).join(","),a=L.TileLayer.prototype.getTileUrl.call(this,t);return a+c(this.wmsParams,a,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+r},setParams:function(t,e){return i(this.wmsParams,t),e||this.redraw(),this}});dn.WMS=pn,Yt.wms=function(t,i){return new pn(t,i)};var mn=Ue.extend({options:{padding:.1,tolerance:0},initialize:function(t){l(this,t),n(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&pt(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,i){var e=this._map.getZoomScale(i,this._zoom),n=Pt(this._container),o=this._map.getSize().multiplyBy(.5+this.options.padding),s=this._map.project(this._center,i),r=this._map.project(t,i).subtract(s),a=o.multiplyBy(-e).add(n).add(o).subtract(r);Ni?wt(this._container,a,e):Lt(this._container,a)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,i=this._map.getSize(),e=this._map.containerPointToLayerPoint(i.multiplyBy(-t)).round();
6this._bounds=new P(e,e.add(i.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),fn=mn.extend({getEvents:function(){var t=mn.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){mn.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");V(t,"mousemove",o(this._onMouseMove,32,this),this),V(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),V(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_destroyContainer:function(){delete this._ctx,ut(this._container),q(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){this._redrawBounds=null;for(var t in this._layers)this._layers[t]._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){this._drawnLayers={},mn.prototype._update.call(this);var t=this._bounds,i=this._container,e=t.getSize(),n=Ki?2:1;Lt(i,t.min),i.width=n*e.x,i.height=n*e.y,i.style.width=e.x+"px",i.style.height=e.y+"px",Ki&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){mn.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n(t)]=t;var i=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=i),this._drawLast=i,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var i=t._order,e=i.next,n=i.prev;e?e.prev=n:this._drawLast=n,n?n.next=e:this._drawFirst=e,delete t._order,delete this._layers[L.stamp(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(t.options.dashArray){var i,e=t.options.dashArray.split(","),n=[];for(i=0;i<e.length;i++)n.push(Number(e[i]));t.options._dashArray=n}},_requestRedraw:function(t){this._map&&(this._extendRedrawBounds(t),this._redrawRequest=this._redrawRequest||f(this._redraw,this))},_extendRedrawBounds:function(t){if(t._pxBounds){var i=(t.options.weight||0)+1;this._redrawBounds=this._redrawBounds||new P,this._redrawBounds.extend(t._pxBounds.min.subtract([i,i])),this._redrawBounds.extend(t._pxBounds.max.add([i,i]))}},_redraw:function(){this._redrawRequest=null,this._redrawBounds&&(this._redrawBounds.min._floor(),this._redrawBounds.max._ceil()),this._clear(),this._draw(),this._redrawBounds=null},_clear:function(){var t=this._redrawBounds;if(t){var i=t.getSize();this._ctx.clearRect(t.min.x,t.min.y,i.x,i.y)}else this._ctx.clearRect(0,0,this._container.width,this._container.height)},_draw:function(){var t,i=this._redrawBounds;if(this._ctx.save(),i){var e=i.getSize();this._ctx.beginPath(),this._ctx.rect(i.min.x,i.min.y,e.x,e.y),this._ctx.clip()}this._drawing=!0;for(var n=this._drawFirst;n;n=n.next)t=n.layer,(!i||t._pxBounds&&t._pxBounds.intersects(i))&&t._updatePath();this._drawing=!1,this._ctx.restore()},_updatePoly:function(t,i){if(this._drawing){var e,n,o,s,r=t._parts,a=r.length,h=this._ctx;if(a){for(this._drawnLayers[t._leaflet_id]=t,h.beginPath(),e=0;e<a;e++){for(n=0,o=r[e].length;n<o;n++)s=r[e][n],h[n?"lineTo":"moveTo"](s.x,s.y);i&&h.closePath()}this._fillStroke(h,t)}}},_updateCircle:function(t){if(this._drawing&&!t._empty()){var i=t._point,e=this._ctx,n=Math.max(Math.round(t._radius),1),o=(Math.max(Math.round(t._radiusY),1)||n)/n;this._drawnLayers[t._leaflet_id]=t,1!==o&&(e.save(),e.scale(1,o)),e.beginPath(),e.arc(i.x,i.y/o,n,0,2*Math.PI,!1),1!==o&&e.restore(),this._fillStroke(e,t)}},_fillStroke:function(t,i){var e=i.options;e.fill&&(t.globalAlpha=e.fillOpacity,t.fillStyle=e.fillColor||e.color,t.fill(e.fillRule||"evenodd")),e.stroke&&0!==e.weight&&(t.setLineDash&&t.setLineDash(i.options&&i.options._dashArray||[]),t.globalAlpha=e.opacity,t.lineWidth=e.weight,t.strokeStyle=e.color,t.lineCap=e.lineCap,t.lineJoin=e.lineJoin,t.stroke())},_onClick:function(t){for(var i,e,n=this._map.mouseEventToLayerPoint(t),o=this._drawFirst;o;o=o.next)(i=o.layer).options.interactive&&i._containsPoint(n)&&!this._map._draggableMoved(i)&&(e=i);e&&(et(t),this._fireEvent([e],t))},_onMouseMove:function(t){if(this._map&&!this._map.dragging.moving()&&!this._map._animatingZoom){var i=this._map.mouseEventToLayerPoint(t);this._handleMouseHover(t,i)}},_handleMouseOut:function(t){var i=this._hoveredLayer;i&&(mt(this._container,"leaflet-interactive"),this._fireEvent([i],t,"mouseout"),this._hoveredLayer=null)},_handleMouseHover:function(t,i){for(var e,n,o=this._drawFirst;o;o=o.next)(e=o.layer).options.interactive&&e._containsPoint(i)&&(n=e);n!==this._hoveredLayer&&(this._handleMouseOut(t),n&&(pt(this._container,"leaflet-interactive"),this._fireEvent([n],t,"mouseover"),this._hoveredLayer=n)),this._hoveredLayer&&this._fireEvent([this._hoveredLayer],t)},_fireEvent:function(t,i,e){this._map._fireDOMEvent(i,e||i.type,t)},_bringToFront:function(t){var i=t._order,e=i.next,n=i.prev;e&&(e.prev=n,n?n.next=e:e&&(this._drawFirst=e),i.prev=this._drawLast,this._drawLast.next=i,i.next=null,this._drawLast=i,this._requestRedraw(t))},_bringToBack:function(t){var i=t._order,e=i.next,n=i.prev;n&&(n.next=e,e?e.prev=n:n&&(this._drawLast=n),i.prev=null,i.next=this._drawFirst,this._drawFirst.prev=i,this._drawFirst=i,this._requestRedraw(t))}}),gn=function(){try{return document.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return document.createElement("<lvml:"+t+' class="lvml">')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),vn={_initContainer:function(){this._container=ht("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(mn.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=gn("shape");pt(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=gn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;ut(i),t.removeInteractiveTarget(i),delete this._layers[n(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=gn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=ei(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=gn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){ct(t._container)},_bringToBack:function(t){_t(t._container)}},yn=Ji?gn:E,xn=mn.extend({getEvents:function(){var t=mn.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=yn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=yn("g"),this._container.appendChild(this._rootGroup)}
vendor: 8,823 bytes, line 6
6,_destroyContainer:function(){ut(this._container),q(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){mn.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),Lt(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=yn("path");t.options.className&&pt(i,t.options.className),t.options.interactive&&pt(i,"leaflet-interactive"),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){ut(t._path),t.removeInteractiveTarget(t._path),delete this._layers[n(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,k(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){ct(t._path)},_bringToBack:function(t){_t(t._path)}});Ji&&xn.include(vn),Le.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this.options.preferCanvas&&Xt()||Jt()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=xn&&Jt({pane:t})||fn&&Xt({pane:t}),this._paneRenderers[t]=i),i}});var wn=en.extend({initialize:function(t,i){en.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=z(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});xn.create=yn,xn.pointsToPath=k,nn.geometryToLayer=Wt,nn.coordsToLatLng=Ht,nn.coordsToLatLngs=Ft,nn.latLngToCoords=Ut,nn.latLngsToCoords=Vt,nn.getFeature=qt,nn.asFeature=Gt,Le.mergeOptions({boxZoom:!0});var Ln=Ze.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){V(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){q(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){ut(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),mi(),bt(),this._startPoint=this._map.mouseEventToContainerPoint(t),V(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=ht("div","leaflet-zoom-box",this._container),pt(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new P(this._point,this._startPoint),e=i.getSize();Lt(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(ut(this._box),mt(this._container,"leaflet-crosshair")),fi(),Tt(),q(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(e(this._resetState,this),0);var i=new T(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});Le.addInitHook("addHandler","boxZoom",Ln),Le.mergeOptions({doubleClickZoom:!0});var Pn=Ze.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});Le.addInitHook("addHandler","doubleClickZoom",Pn),Le.mergeOptions({dragging:!0,inertia:!zi,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var bn=Ze.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new Be(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}pt(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){mt(this._map._container,"leaflet-grab"),mt(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=z(this._map.options.maxBounds);this._offsetLimit=b(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;this._positions.length>1&&t-this._times[0]>50;)this._positions.shift(),this._times.shift()},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),i=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=i.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,i){return t-(t-i)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),i=this._offsetLimit;t.x<i.min.x&&(t.x=this._viscousLimit(t.x,i.min.x)),t.y<i.min.y&&(t.y=this._viscousLimit(t.y,i.min.y)),t.x>i.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)<Math.abs(s+e)?o:s;this._draggable._absPos=this._draggable._newPos.clone(),this._draggable._newPos.x=r},_onDragEnd:function(t){var i=this._map,e=i.options,n=!e.inertia||this._times.length<2;if(i.fire("dragend",t),n)i.fire("moveend");else{this._prunePositions(+new Date);var o=this._lastPos.subtract(this._positions[0]),s=(this._lastTime-this._times[0])/1e3,r=e.easeLinearity,a=o.multiplyBy(r/s),h=a.distanceTo([0,0]),u=Math.min(e.inertiaMaxSpeed,h),l=a.multiplyBy(u/h),c=u/(e.inertiaDeceleration*r),_=l.multiplyBy(-c/2).round();_.x||_.y?(_=i._limitOffset(_,i.options.maxBounds),f(function(){i.panBy(_,{duration:c,easeLinearity:r,noMoveStart:!0,animate:!0})}
6)):i.fire("moveend")}}});Le.addInitHook("addHandler","dragging",bn),Le.mergeOptions({keyboard:!0,keyboardPanDelta:80});var Tn=Ze.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,54,173]},initialize:function(t){this._map=t,this._setPanDelta(t.options.keyboardPanDelta),this._setZoomDelta(t.options.zoomDelta)},addHooks:function(){var t=this._map._container;t.tabIndex<=0&&(t.tabIndex="0"),V(t,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.on({focus:this._addHooks,blur:this._removeHooks},this)},removeHooks:function(){this._removeHooks(),q(this._map._container,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.off({focus:this._addHooks,blur:this._removeHooks},this)},_onMouseDown:function(){if(!this._focused){var t=document.body,i=document.documentElement,e=t.scrollTop||i.scrollTop,n=t.scrollLeft||i.scrollLeft;this._map._container.focus(),window.scrollTo(n,e)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanDelta:function(t){var i,e,n=this._panKeys={},o=this.keyCodes;for(i=0,e=o.left.length;i<e;i++)n[o.left[i]]=[-1*t,0];for(i=0,e=o.right.length;i<e;i++)n[o.right[i]]=[t,0];for(i=0,e=o.down.length;i<e;i++)n[o.down[i]]=[0,t];for(i=0,e=o.up.length;i<e;i++)n[o.up[i]]=[0,-1*t]},_setZoomDelta:function(t){var i,e,n=this._zoomKeys={},o=this.keyCodes;for(i=0,e=o.zoomIn.length;i<e;i++)n[o.zoomIn[i]]=t;for(i=0,e=o.zoomOut.length;i<e;i++)n[o.zoomOut[i]]=-t},_addHooks:function(){V(document,"keydown",this._onKeyDown,this)},_removeHooks:function(){q(document,"keydown",this._onKeyDown,this)},_onKeyDown:function(t){if(!(t.altKey||t.ctrlKey||t.metaKey)){var i,e=t.keyCode,n=this._map;if(e in this._panKeys){if(n._panAnim&&n._panAnim._inProgress)return;i=this._panKeys[e],t.shiftKey&&(i=w(i).multiplyBy(3)),n.panBy(i),n.options.maxBounds&&n.panInsideBounds(n.options.maxBounds)}else if(e in this._zoomKeys)n.setZoom(n.getZoom()+(t.shiftKey?3:1)*this._zoomKeys[e]);else{if(27!==e||!n._popup||!n._popup.options.closeOnEscapeKey)return;n.closePopup()}Q(t)}}});Le.addInitHook("addHandler","keyboard",Tn),Le.mergeOptions({scrollWheelZoom:!0,wheelDebounceTime:40,wheelPxPerZoomLevel:60});var zn=Ze.extend({addHooks:function(){V(this._map._container,"mousewheel",this._onWheelScroll,this),this._delta=0},removeHooks:function(){q(this._map._container,"mousewheel",this._onWheelScroll,this)},_onWheelScroll:function(t){var i=it(t),n=this._map.options.wheelDebounceTime;this._delta+=i,this._lastMousePos=this._map.mouseEventToContainerPoint(t),this._startTime||(this._startTime=+new Date);var o=Math.max(n-(+new Date-this._startTime),0);clearTimeout(this._timer),this._timer=setTimeout(e(this._performZoom,this),o),Q(t)},_performZoom:function(){var t=this._map,i=t.getZoom(),e=this._map.options.zoomSnap||0;t._stop();var n=this._delta/(4*this._map.options.wheelPxPerZoomLevel),o=4*Math.log(2/(1+Math.exp(-Math.abs(n))))/Math.LN2,s=e?Math.ceil(o/e)*e:o,r=t._limitZoom(i+(this._delta>0?s:-s))-i;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(i+r):t.setZoomAround(this._lastMousePos,i+r))}});Le.addInitHook("addHandler","scrollWheelZoom",zn),Le.mergeOptions({tap:!0,tapTolerance:15});var Mn=Ze.extend({addHooks:function(){V(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){q(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if($(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new x(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&pt(n,"leaflet-active"),this._holdTimeout=setTimeout(e(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),V(document,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),q(document,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],e=i.target;e&&e.tagName&&"a"===e.tagName.toLowerCase()&&mt(e,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var i=t.touches[0];this._newPos=new x(i.clientX,i.clientY),this._simulateEvent("mousemove",i)},_simulateEvent:function(t,i){var e=document.createEvent("MouseEvents");e._simulated=!0,i.target._simulatedClick=!0,e.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(e)}});Vi&&!Ui&&Le.addInitHook("addHandler","tap",Mn),Le.mergeOptions({touchZoom:Vi&&!zi,bounceAtZoomLimits:!0});var Cn=Ze.extend({addHooks:function(){pt(this._map._container,"leaflet-touch-zoom"),V(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){mt(this._map._container,"leaflet-touch-zoom"),q(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var e=i.mouseEventToContainerPoint(t.touches[0]),n=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(e.add(n)._divideBy(2))),this._startDist=e.distanceTo(n),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),V(document,"touchmove",this._onTouchMove,this),V(document,"touchend",this._onTouchEnd,this),$(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var i=this._map,n=i.mouseEventToContainerPoint(t.touches[0]),o=i.mouseEventToContainerPoint(t.touches[1]),s=n.distanceTo(o)/this._startDist;if(this._zoom=i.getScaleZoom(s,this._startZoom),!i.options.bounceAtZoomLimits&&(this._zoom<i.getMinZoom()&&s<1||this._zoom>i.getMaxZoom()&&s>1)&&(this._zoom=i._limitZoom(this._zoom)),"center"===i.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=n._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=i.unproject(i.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(i._moveStart(!0,!1),this._moved=!0),g(this._animRequest);var a=e(i._move,i,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=f(a,this,!0),$(t)}},_onTouchEnd:function(){this._moved&&this._zooming?(this._zooming=!1,g(this._animRequest),q(document,"touchmove",this._onTouchMove),q(document,"touchend",this._onTouchEnd),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))):this._zooming=!1}});Le.addInitHook("addHandler","touchZoom",Cn),Le.BoxZoom=Ln,Le.DoubleClickZoom=Pn,Le.Drag=bn,Le.Keyboard=Tn,Le.ScrollWheelZoom=zn,Le.Tap=Mn,Le.TouchZoom=Cn;var Zn=window.L;window.L=t,Object.freeze=$t,t.version="1.3.1",t.noConflict=function(){return window.L=Zn,this},t.Control=Pe,t.control=be,t.Browser=$i,t.Evented=ui,t.Mixin=Ee,t.Util=ai,t.Class=v,t.Handler=Ze,t.extend=i,t.bind=e,t.stamp=n,t.setOptions=l,t.DomEvent=de,t.DomUtil=xe,t.PosAnimation=we,t.Draggable=Be,t.LineUtil=Oe,t.PolyUtil=Re,t.Point=x,t.point=w,t.Bounds=P,t.bounds=b,t.Transformation=Z,t.transformation=S,t.Projection=je,t.LatLng=M,t.latLng=C,t.LatLngBounds=T,t.latLngBounds=z,t.CRS=ci,t.GeoJSON=nn,t.geoJSON=Kt,t.geoJ
6son=sn,t.Layer=Ue,t.LayerGroup=Ve,t.layerGroup=function(t,i){return new Ve(t,i)},t.FeatureGroup=qe,t.featureGroup=function(t){return new qe(t)},t.ImageOverlay=rn,t.imageOverlay=function(t,i,e){return new rn(t,i,e)},t.VideoOverlay=an,t.videoOverlay=function(t,i,e){return new an(t,i,e)},t.DivOverlay=hn,t.Popup=un,t.popup=function(t,i){return new un(t,i)},t.Tooltip=ln,t.tooltip=function(t,i){return new ln(t,i)},t.Icon=Ge,t.icon=function(t){return new Ge(t)},t.DivIcon=cn,t.divIcon=function(t){return new cn(t)},t.Marker=Xe,t.marker=function(t,i){return new Xe(t,i)},t.TileLayer=dn,t.tileLayer=Yt,t.GridLayer=_n,t.gridLayer=function(t){return new _n(t)},t.SVG=xn,t.svg=Jt,t.Renderer=mn,t.Canvas=fn,t.canvas=Xt,t.Path=Je,t.CircleMarker=$e,t.circleMarker=function(t,i){return new $e(t,i)},t.Circle=Qe,t.circle=function(t,i,e){return new Qe(t,i,e)},t.Polyline=tn,t.polyline=function(t,i){return new tn(t,i)},t.Polygon=en,t.polygon=function(t,i){return new en(t,i)},t.Rectangle=wn,t.rectangle=function(t,i){return new wn(t,i)},t.Map=Le,t.map=function(t,i){return new Le(t,i)}}); 7; 8/*! 9Copyright (c) 2016 Dominik Moritz 10 11This file is part of the leaflet locate control. It is licensed under the MIT license. 12You can find the project at: https://github.com/domoritz/leaflet-locatecontrol 13*/ 14(function (factory, window) { 15 // see https://github.com/Leaflet/Leaflet/blob/master/PLUGIN-GUIDE.md#module-loaders 16 // for details on how to structure a leaflet plugin. 17 18 // define an AMD module that relies on 'leaflet' 19 if (typeof define === 'function' && define.amd) { 20 define(['leaflet'], factory); 21 22 // define a Common JS module that relies on 'leaflet' 23 } else if (typeof exports === 'object') { 24 if (typeof window !== 'undefined' && window.L) { 25 module.exports = factory(L); 26 } else { 27 module.exports = factory(require('leaflet')); 28 } 29 } 30 31 // attach your plugin to the global 'L' variable 32 if (typeof window !== 'undefined' && window.L){ 33 window.L.Control.Locate = factory(L); 34 } 35} (function (L) { 36 var LDomUtilApplyClassesMethod = function(method, element, classNames) { 37 classNames = classNames.split(' '); 38 classNames.forEach(function(className) { 39 L.DomUtil[method].call(this, element, className); 40 }); 41 }; 42 43 var addClasses = function(el, names) { LDomUtilApplyClassesMethod('addClass', el, names); }; 44 var removeClasses = function(el, names) { LDomUtilApplyClassesMethod('removeClass', el, names); }; 45 46 /** 47 * Compatible with L.Circle but a true marker instead of a path 48 */ 49 var LocationMarker = L.Marker.extend({ 50 initialize: function (latlng, options) { 51 L.Util.setOptions(this, options); 52 this._latlng = latlng; 53 this.createIcon(); 54 }, 55 56 /** 57 * Create a styled circle location marker 58 */ 59 createIcon: function() { 60 var opt = this.options; 61 62 var style = ''; 63 64 if (opt.color !== undefined) { 65 style += 'stroke:'+opt.color+';'; 66 } 67 if (opt.weight !== undefined) { 68 style += 'stroke-width:'+opt.weight+';'; 69 } 70 if (opt.fillColor !== undefined) { 71 style += 'fill:'+opt.fillColor+';'; 72 } 73 if (opt.fillOpacity !== undefined) { 74 style += 'fill-opacity:'+opt.fillOpacity+';'; 75 } 76 if (opt.opacity !== undefined) { 77 style += 'opacity:'+opt.opacity+';'; 78 } 79 80 var icon = this._getIconSVG(opt, style); 81 82 this._locationIcon = L.divIcon({ 83 className: icon.className, 84 html: icon.svg, 85 iconSize: [icon.w,icon.h], 86 }); 87 88 this.setIcon(this._locationIcon); 89 }, 90 91 /** 92 * Return the raw svg for the shape 93 * 94 * Split so can be easily overridden 95 */ 96 _getIconSVG: function(options, style) { 97 var r = options.radius; 98 var w = options.weight; 99 var s = r + w; 100 var s2 = s * 2; 101 var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="'+s2+'" height="'+s2+'" version="1.1" viewBox="-'+s+' -'+s+' '+s2+' '+s2+'">' + 102 '<circle r="'+r+'" style="'+style+'" />' + 103 '</svg>'; 104 return { 105 className: 'leaflet-control-locate-location', 106 svg: svg, 107 w: s2, 108 h: s2 109 }; 110 }, 111 112 setStyle: function(style) { 113 L.Util.setOptions(this, style); 114 this.createIcon(); 115 } 116 }); 117 118 var CompassMarker = LocationMarker.extend({ 119 initialize: function (latlng, heading, options) { 120 L.Util.setOptions(this, options); 121 this._latlng = latlng; 122 this._heading = heading; 123 this.createIcon(); 124 }, 125 126 setHeading: function(heading) { 127 this._heading = heading; 128 }, 129 130 /** 131 * Create a styled arrow compass marker 132 */ 133 _getIconSVG: function(options, style) { 134 var r = options.radius; 135 var w = (options.width + options.weight); 136 var h = (r+options.depth + options.weight)*2; 137 var path = 'M0,0 l'+(options.width/2)+','+options.depth+' l-'+(w)+',0 z'; 138 var svgstyle = 'transform: rotate('+this._heading+'deg)'; 139 var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="'+(w)+'" height="'+h+'" version="1.1" viewBox="-'+(w/2)+' 0 '+w+' '+h+'" style="'+svgstyle+'">'+ 140 '<path d="'+path+'" style="'+style+'" />'+ 141 '</svg>'; 142 return { 143 className: 'leaflet-control-locate-heading', 144 svg: svg, 145 w: w, 146 h: h 147 }; 148 }, 149 }); 150 151 152 var LocateControl = L.Control.extend({ 153 options: { 154 /** Position of the control */ 155 position: 'topleft', 156 /** The layer that the user's location should be drawn on. By default creates a new layer. */ 157 layer: undefined, 158 /** 159 * Automatically sets the map view (zoom and pan) to the user's location as it updates. 160 * While the map is following the user's location, the control is in the `following` state, 161 * which changes the style of the control and the circle marker. 162 * 163 * Possible values: 164 * - false: never updates the map view when location changes. 165 * - 'once': set the view when the location is first determined 166 * - 'always': always updates the map view when location changes. 167 * The map view follows the user's location. 168 * - 'untilPan': like 'always', except stops updating the 169 * view if the user has manually panned the map. 170 * The map view follows the user's location until she pans. 171 * - 'untilPanOrZoom': (default) like 'always', except stops updating the 172 * view if the user has manually panned the map. 173 * The map view follows the user's location until she pans. 174 */
175 setView: 'untilPanOrZoom', 176 /** Keep the current map zoom level when setting the view and only pan. */ 177 keepCurrentZoomLevel: false, 178 /** 179 * This callback can be used to override the viewport tracking 180 * This function should return a LatLngBounds object. 181 * 182 * For example to extend the viewport to ensure that a particular LatLng is visible: 183 * 184 * getLocationBounds: function(locationEvent) { 185 * return locationEvent.bounds.extend([-33.873085, 151.219273]); 186 * }, 187 */ 188 getLocationBounds: function (locationEvent) { 189 return locationEvent.bounds; 190 }, 191 /** Smooth pan and zoom to the location of the marker. Only works in Leaflet 1.0+. */ 192 flyTo: false, 193 /** 194 * The user location can be inside and outside the current view when the user clicks on the 195 * control that is already active. Both cases can be configures separately. 196 * Possible values are: 197 * - 'setView': zoom and pan to the current location 198 * - 'stop': stop locating and remove the location marker 199 */ 200 clickBehavior: { 201 /** What should happen if the user clicks on the control while the location is within the current view. */ 202 inView: 'stop', 203 /** What should happen if the user clicks on the control while the location is outside the current view. */ 204 outOfView: 'setView', 205 /** 206 * What should happen if the user clicks on the control while the location is within the current view 207 * and we could be following but are not. Defaults to a special value which inherits from 'inView'; 208 */ 209 inViewNotFollowing: 'inView', 210 }, 211 /** 212 * If set, save the map bounds just before centering to the user's 213 * location. When control is disabled, set the view back to the 214 * bounds that were saved. 215 */ 216 returnToPrevBounds: false, 217 /** 218 * Keep a cache of the location after the user deactivates the control. If set to false, the user has to wait 219 * until the locate API returns a new location before they see where they are again. 220 */ 221 cacheLocation: true, 222 /** If set, a circle that shows the location accuracy is drawn. */ 223 drawCircle: true, 224 /** If set, the marker at the users' location is drawn. */ 225 drawMarker: true, 226 /** If set and supported then show the compass heading */ 227 showCompass: true, 228 /** The class to be used to create the marker. For example L.CircleMarker or L.Marker */ 229 markerClass: LocationMarker, 230 /** The class us be used to create the compass bearing arrow */ 231 compassClass: CompassMarker, 232 /** Accuracy circle style properties. NOTE these styles should match the css animations styles */ 233 circleStyle: { 234 className: 'leaflet-control-locate-circle', 235 color: '#136AEC', 236 fillColor: '#136AEC', 237 fillOpacity: 0.15, 238 weight: 0 239 }, 240 /** Inner marker style properties. Only works if your marker class supports `setStyle`. */ 241 markerStyle: { 242 className: 'leaflet-control-locate-marker', 243 color: '#fff', 244 fillColor: '#2A93EE', 245 fillOpacity: 1, 246 weight: 3, 247 opacity: 1, 248 radius: 9 249 }, 250 /** Compass */ 251 compassStyle: { 252 fillColor: '#2A93EE', 253 fillOpacity: 1, 254 weight: 0, 255 color: '#fff', 256 opacity: 1, 257 radius: 9, // How far is the arrow is from the center of of the marker 258 width: 9, // Width of the arrow 259 depth: 6 // Length of the arrow 260 }, 261 /** 262 * Changes to accuracy circle and inner marker while following. 263 * It is only necessary to provide the properties that should change. 264 */ 265 followCircleStyle: {}, 266 followMarkerStyle: {
267 // color: '#FFA500', 268 // fillColor: '#FFB000' 269 }, 270 followCompassStyle: {}, 271 /** The CSS class for the icon. For example fa-location-arrow or fa-map-marker */ 272 icon: 'fa fa-map-marker', 273 iconLoading: 'fa fa-spinner fa-spin', 274 /** The element to be created for icons. For example span or i */ 275 iconElementTag: 'span', 276 /** Padding around the accuracy circle. */ 277 circlePadding: [0, 0], 278 /** Use metric units. */ 279 metric: true, 280 /** 281 * This callback can be used in case you would like to override button creation behavior. 282 * This is useful for DOM manipulation frameworks such as angular etc. 283 * This function should return an object with HtmlElement for the button (link property) and the icon (icon property). 284 */ 285 createButtonCallback: function (container, options) { 286 var link = L.DomUtil.create('a', 'leaflet-bar-part leaflet-bar-part-single', container); 287 link.title = options.strings.title; 288 var icon = L.DomUtil.create(options.iconElementTag, options.icon, link); 289 return { link: link, icon: icon }; 290 }, 291 /** This event is called in case of any location error that is not a time out error. */ 292 onLocationError: function(err, control) { 293 alert(err.message); 294 }, 295 /** 296 * This event is called when the user's location is outside the bounds set on the map. 297 * The event is called repeatedly when the location changes. 298 */ 299 onLocationOutsideMapBounds: function(control) { 300 control.stop(); 301 alert(control.options.strings.outsideMapBoundsMsg); 302 }, 303 /** Display a pop-up when the user click on the inner marker. */ 304 showPopup: true, 305 strings: { 306 title: "Show me where I am", 307 metersUnit: "meters", 308 feetUnit: "feet", 309 popup: "You are within {distance} {unit} from this point", 310 outsideMapBoundsMsg: "You seem located outside the boundaries of the map" 311 }, 312 /** The default options passed to leaflets locate method. */ 313 locateOptions: { 314 maxZoom: Infinity, 315 watch: true, // if you overwrite this, visualization cannot be updated 316 setView: false // have to set this to false because we have to 317 // do setView manually 318 } 319 }, 320 321 initialize: function (options) { 322 // set default options if nothing is set (merge one step deep) 323 for (var i in options) { 324 if (typeof this.options[i] === 'object') { 325 L.extend(this.options[i], options[i]); 326 } else { 327 this.options[i] = options[i]; 328 } 329 } 330 331 // extend the follow marker style and circle from the normal style 332 this.options.followMarkerStyle = L.extend({}, this.options.markerStyle, this.options.followMarkerStyle); 333 this.options.followCircleStyle = L.extend({}, this.options.circleStyle, this.options.followCircleStyle); 334 this.options.followCompassStyle = L.extend({}, this.options.compassStyle, this.options.followCompassStyle); 335 }, 336 337 /** 338 * Add control to map. Returns the container for the control. 339 */ 340 onAdd: function (map) { 341 var container = L.DomUtil.create('div', 342 'leaflet-control-locate leaflet-bar leaflet-control'); 343 344 this._layer = this.options.layer || new L.LayerGroup(); 345 this._layer.addTo(map); 346 this._event = undefined; 347 this._compassHeading = null; 348 this._prevBounds = null; 349 350 var linkAndIcon = this.options.createButtonCallback(container, this.options); 351 this._link = linkAndIcon.link; 352 this._icon = linkAndIcon.icon; 353 354 L.DomEvent 355 .on(this._link, 'click', L.DomEvent.stopPropagation) 356 .on(this._link, 'click', L.DomEvent.preventDefault) 357 .on(this._link, 'click', this._onClick, this) 358 .on(this._link, 'dblclick', L.DomEvent.stopPropagation); 359 360 this._resetVariables(); 361 362 this._map.on('unload', this._unload, this); 363 364 return container; 365 }, 366 367 /** 368 * This method is called when the user clicks on the control. 369 */ 370 _onClick: function() { 371 this._justClicked = true; 372 var wasFollowing = this._isFollowing(); 373 this._userPanned = false;
374 this._userZoomed = false; 375 376 if (this._active && !this._event) { 377 // click while requesting 378 this.stop(); 379 } else if (this._active && this._event !== undefined) { 380 var behaviors = this.options.clickBehavior; 381 var behavior = behaviors.outOfView; 382 if (this._map.getBounds().contains(this._event.latlng)) { 383 behavior = wasFollowing ? behaviors.inView : behaviors.inViewNotFollowing; 384 } 385 386 // Allow inheriting from another behavior 387 if (behaviors[behavior]) { 388 behavior = behaviors[behavior]; 389 } 390 391 switch (behavior) { 392 case 'setView': 393 this.setView(); 394 break; 395 case 'stop': 396 this.stop(); 397 if (this.options.returnToPrevBounds) { 398 var f = this.options.flyTo ? this._map.flyToBounds : this._map.fitBounds; 399 f.bind(this._map)(this._prevBounds); 400 } 401 break; 402 } 403 } else { 404 if (this.options.returnToPrevBounds) { 405 this._prevBounds = this._map.getBounds(); 406 } 407 this.start(); 408 } 409 410 this._updateContainerStyle(); 411 }, 412 413 /** 414 * Starts the plugin: 415 * - activates the engine 416 * - draws the marker (if coordinates available) 417 */ 418 start: function() { 419 this._activate(); 420 421 if (this._event) { 422 this._drawMarker(this._map); 423 424 // if we already have a location but the user clicked on the control 425 if (this.options.setView) { 426 this.setView(); 427 } 428 } 429 this._updateContainerStyle(); 430 }, 431 432 /** 433 * Stops the plugin: 434 * - deactivates the engine 435 * - reinitializes the button 436 * - removes the marker 437 */ 438 stop: function() { 439 this._deactivate(); 440 441 this._cleanClasses(); 442 this._resetVariables(); 443 444 this._removeMarker(); 445 }, 446 447 /** 448 * Keep the control active but stop following the location 449 */ 450 stopFollowing: function() { 451 this._userPanned = true; 452 this._updateContainerStyle(); 453 this._drawMarker(); 454 }, 455 456 /** 457 * This method launches the location engine. 458 * It is called before the marker is updated, 459 * event if it does not mean that the event will be ready. 460 * 461 * Override it if you want to add more functionalities. 462 * It should set the this._active to true and do nothing if 463 * this._active is true. 464 */ 465 _activate: function() { 466 if (!this._active) { 467 this._map.locate(this.options.locateOptions); 468 this._active = true; 469 470 // bind event listeners 471 this._map.on('locationfound', this._onLocationFound, this); 472 this._map.on('locationerror', this._onLocationError, this); 473 this._map.on('dragstart', this._onDrag, this); 474 this._map.on('zoomstart', this._onZoom, this); 475 this._map.on('zoomend', this._onZoomEnd, this); 476 if (this.options.showCompass) { 477 if ('ondeviceorientationabsolute' in window) { 478 L.DomEvent.on(window, 'deviceorientationabsolute', this._onDeviceOrientation, this); 479 } else if ('ondeviceorientation' in window) { 480 L.DomEvent.on(window, 'deviceorientation', this._onDeviceOrientation, this); 481 } 482 } 483 } 484 }, 485 486 /** 487 * Called to stop the location engine. 488 * 489 * Override it to shutdown any functionalities you added on start. 490 */ 491 _deactivate: function() { 492 this._map.stopLocate(); 493 this._active = false;
494 495 if (!this.options.cacheLocation) { 496 this._event = undefined; 497 } 498 499 // unbind event listeners 500 this._map.off('locationfound', this._onLocationFound, this); 501 this._map.off('locationerror', this._onLocationError, this); 502 this._map.off('dragstart', this._onDrag, this); 503 this._map.off('zoomstart', this._onZoom, this); 504 this._map.off('zoomend', this._onZoomEnd, this); 505 if (this.options.showCompass) { 506 this._compassHeading = null; 507 if ('ondeviceorientationabsolute' in window) { 508 L.DomEvent.off(window, 'deviceorientationabsolute', this._onDeviceOrientation, this); 509 } else if ('ondeviceorientation' in window) { 510 L.DomEvent.off(window, 'deviceorientation', this._onDeviceOrientation, this); 511 } 512 } 513 }, 514 515 /** 516 * Zoom (unless we should keep the zoom level) and an to the current view. 517 */ 518 setView: function() { 519 this._drawMarker(); 520 if (this._isOutsideMapBounds()) { 521 this._event = undefined; // clear the current location so we can get back into the bounds 522 this.options.onLocationOutsideMapBounds(this); 523 } else { 524 if (this.options.keepCurrentZoomLevel) { 525 var f = this.options.flyTo ? this._map.flyTo : this._map.panTo; 526 f.bind(this._map)([this._event.latitude, this._event.longitude]); 527 } else { 528 var f = this.options.flyTo ? this._map.flyToBounds : this._map.fitBounds; 529 // Ignore zoom events while setting the viewport as these would stop following 530 this._ignoreEvent = true; 531 f.bind(this._map)(this.options.getLocationBounds(this._event), { 532 padding: this.options.circlePadding, 533 maxZoom: this.options.locateOptions.maxZoom 534 }); 535 L.Util.requestAnimFrame(function(){ 536 // Wait until after the next animFrame because the flyTo can be async 537 this._ignoreEvent = false; 538 }, this); 539 540 } 541 } 542 }, 543 544 /** 545 * 546 */ 547 _drawCompass: function() { 548 if (!this._event) { 549 return; 550 } 551 552 var latlng = this._event.latlng; 553 554 if (this.options.showCompass && latlng && this._compassHeading !== null) { 555 var cStyle = this._isFollowing() ? this.options.followCompassStyle : this.options.compassStyle; 556 if (!this._compass) { 557 this._compass = new this.options.compassClass(latlng, this._compassHeading, cStyle).addTo(this._layer); 558 } else { 559 this._compass.setLatLng(latlng); 560 this._compass.setHeading(this._compassHeading); 561 // If the compassClass can be updated with setStyle, update it. 562 if (this._compass.setStyle) { 563 this._compass.setStyle(cStyle); 564 } 565 } 566 // 567 } 568 if (this._compass && (!this.options.showCompass || this._compassHeading === null)) { 569 this._compass.removeFrom(this._layer); 570 this._compass = null; 571 } 572 }, 573 574 /** 575 * Draw the marker and accuracy circle on the map. 576 * 577 * Uses the event retrieved from onLocationFound from the map. 578 */ 579 _drawMarker: function() { 580 if (this._event.accuracy === undefined) { 581 this._event.accuracy = 0; 582 } 583 584 var radius = this._event.accuracy; 585 var latlng = this._event.latlng; 586 587 // circle with the radius of the location's accuracy 588 if (this.options.drawCircle) { 589 var style = this._isFollowing() ? this.options.followCircleStyle : this.options.circleStyle; 590 591 if (!this._circle) { 592 this._circle = L.circle(latlng, radius, style).addTo(this._layer); 593 } else { 594 this._circle.setLatLng(latlng).setRadius(radius).setStyle(style); 595 } 596 } 597 598 var distance, unit; 599 if (this.options.metric) { 600 distance = radius.toFixed(0); 601 unit = this.options.strings.metersUnit; 602 } else { 603 distance = (radius * 3.2808399).toFixed(0); 604 unit = this.options.strings.feetUnit; 605 } 606 607 // small inner marker 608 if (this.options.drawMarker) { 609 var mStyle = this._isFollowing() ? this.options.followMarkerStyle : this.options.markerStyle; 610 if (!this._marker) { 611 this._marker = new this.options.markerClass(latlng, mStyle).addTo(this._layer); 612 } else { 613 this._marker.setLatLng(latlng); 614 // If the markerClass can be updated with setStyle, update it. 615 if (this._marker.setStyle) { 616 this._marker.setStyle(mStyle); 617 } 618 } 619 } 620 621 this._drawCompass(); 622 623 var t = this.options.strings.popup; 624 if (this.options.showPopup && t && this._marker) { 625 this._marker 626 .bindPopup(L.Util.template(t, {distance: distance, unit: unit})) 627 ._popup.setLatLng(latlng); 628 } 629 if (this.options.showPopup && t && this._compass) { 630 this._compass 631 .bindPopup(L.Util.template(t, {distance: distance, unit: unit})) 632 ._popup.setLatLng(latlng); 633 } 634 }, 635 636 /** 637 * Remove the marker from map. 638 */ 639 _removeMarker: function() { 640 this._layer.clearLayers(); 641 this._marker = undefined; 642 this._circle = undefined; 643 }, 644 645 /** 646 * Unload the plugin and all event listeners. 647 * Kind of the opposite of onAdd. 648 */ 649 _unload: function() { 650 this.stop(); 651 this._map.off('unload', this._unload, this); 652 }, 653 654 /** 655 * Sets the compass heading 656 */ 657 _setCompassHeading: function(angle) { 658 if (!isNaN(parseFloat(angle)) && isFinite(angle)) { 659 angle = Math.round(angle); 660 661 this._compassHeading = angle;
662 L.Util.requestAnimFrame(this._drawCompass, this); 663 } else { 664 this._compassHeading = null; 665 } 666 }, 667 668 /** 669 * If the compass fails calibration just fail safely and remove the compass 670 */ 671 _onCompassNeedsCalibration: function() { 672 this._setCompassHeading(); 673 }, 674 675 /** 676 * Process and normalise compass events 677 */ 678 _onDeviceOrientation: function(e) { 679 if (!this._active) { 680 return; 681 } 682 683 if (e.webkitCompassHeading) { 684 // iOS 685 this._setCompassHeading(e.webkitCompassHeading); 686 } else if (e.absolute && e.alpha) { 687 // Android 688 this._setCompassHeading(360 - e.alpha) 689 } 690 }, 691 692 /** 693 * Calls deactivate and dispatches an error. 694 */ 695 _onLocationError: function(err) { 696 // ignore time out error if the location is watched 697 if (err.code == 3 && this.options.locateOptions.watch) { 698 return; 699 } 700 701 this.stop(); 702 this.options.onLocationError(err, this); 703 }, 704 705 /** 706 * Stores the received event and updates the marker. 707 */ 708 _onLocationFound: function(e) { 709 // no need to do anything if the location has not changed 710 if (this._event && 711 (this._event.latlng.lat === e.latlng.lat && 712 this._event.latlng.lng === e.latlng.lng && 713 this._event.accuracy === e.accuracy)) { 714 return; 715 } 716 717 if (!this._active) { 718 // we may have a stray event 719 return; 720 } 721 722 this._event = e; 723 724 this._drawMarker(); 725 this._updateContainerStyle(); 726 727 switch (this.options.setView) { 728 case 'once': 729 if (this._justClicked) { 730 this.setView(); 731 } 732 break; 733 case 'untilPan': 734 if (!this._userPanned) { 735 this.setView(); 736 } 737 break; 738 case 'untilPanOrZoom': 739 if (!this._userPanned && !this._userZoomed) { 740 this.setView(); 741 } 742 break; 743 case 'always': 744 this.setView(); 745 break; 746 case false: 747 // don't set the view 748 break; 749 } 750 751 this._justClicked = false; 752 }, 753 754 /** 755 * When the user drags. Need a separate event so we can bind and unbind event listeners. 756 */ 757 _onDrag: function() { 758 // only react to drags once we have a location 759 if (this._event && !this._ignoreEvent) { 760 this._userPanned = true; 761 this._updateContainerStyle(); 762 this._drawMarker(); 763 } 764 }, 765 766 /** 767 * When the user zooms. Need a separate event so we can bind and unbind event listeners. 768 */ 769 _onZoom: function() { 770 // only react to drags once we have a location 771 if (this._event && !this._ignoreEvent) { 772 this._userZoomed = true; 773 this._updateContainerStyle(); 774 this._drawMarker(); 775 } 776 }, 777 778 /** 779 * After a zoom ends update the compass and handle sideways zooms 780 */ 781 _onZoomEnd: function() { 782 if (this._event) { 783 this._drawCompass(); 784 } 785 786 if (this._event && !this._ignoreEvent) { 787 // If we have zoomed in and out and ended up sideways treat it as a pan 788 if (this._marker && !this._map.getBounds().pad(-.3).contains(this._marker.getLatLng())) { 789 this._userPanned = true; 790 this._updateContainerStyle(); 791 this._drawMarker(); 792 } 793 } 794 }, 795 796 /** 797 * Compute whether the map is following the user location with pan and zoom. 798 */ 799 _isFollowing: function() { 800 if (!this._active) { 801 return false;
802 } 803 804 if (this.options.setView === 'always') { 805 return true; 806 } else if (this.options.setView === 'untilPan') { 807 return !this._userPanned; 808 } else if (this.options.setView === 'untilPanOrZoom') { 809 return !this._userPanned && !this._userZoomed; 810 } 811 }, 812 813 /** 814 * Check if location is in map bounds 815 */ 816 _isOutsideMapBounds: function() { 817 if (this._event === undefined) { 818 return false; 819 } 820 return this._map.options.maxBounds && 821 !this._map.options.maxBounds.contains(this._event.latlng); 822 }, 823 824 /** 825 * Toggles button class between following and active. 826 */ 827 _updateContainerStyle: function() { 828 if (!this._container) { 829 return; 830 } 831 832 if (this._active && !this._event) { 833 // active but don't have a location yet 834 this._setClasses('requesting'); 835 } else if (this._isFollowing()) { 836 this._setClasses('following'); 837 } else if (this._active) { 838 this._setClasses('active'); 839 } else { 840 this._cleanClasses(); 841 } 842 }, 843 844 /** 845 * Sets the CSS classes for the state. 846 */ 847 _setClasses: function(state) { 848 if (state == 'requesting') { 849 removeClasses(this._container, "active following"); 850 addClasses(this._container, "requesting"); 851 852 removeClasses(this._icon, this.options.icon); 853 addClasses(this._icon, this.options.iconLoading); 854 } else if (state == 'active') { 855 removeClasses(this._container, "requesting following"); 856 addClasses(this._container, "active"); 857 858 removeClasses(this._icon, this.options.iconLoading); 859 addClasses(this._icon, this.options.icon); 860 } else if (state == 'following') { 861 removeClasses(this._container, "requesting"); 862 addClasses(this._container, "active following"); 863 864 removeClasses(this._icon, this.options.iconLoading); 865 addClasses(this._icon, this.options.icon); 866 } 867 }, 868 869 /** 870 * Removes all classes from button. 871 */ 872 _cleanClasses: function() { 873 L.DomUtil.removeClass(this._container, "requesting"); 874 L.DomUtil.removeClass(this._container, "active"); 875 L.DomUtil.removeClass(this._container, "following"); 876 877 removeClasses(this._icon, this.options.iconLoading); 878 addClasses(this._icon, this.options.icon); 879 }, 880 881 /** 882 * Reinitializes state variables. 883 */ 884 _resetVariables: function() { 885 // whether locate is active or not 886 this._active = false; 887 888 // true if the control was clicked for the first time 889 // we need this so we can pan and zoom once we have the location 890 this._justClicked = false; 891 892 // true if the user has panned the map after clicking the control 893 this._userPanned = false; 894 895 // true if the user has zoomed the map after clicking the control 896 this._userZoomed = false; 897 } 898 }); 899 900 L.control.locate = function (options) { 901 return new L.Control.Locate(options); 902 }; 903 904 return LocateControl; 905}, window));; 906L.Control.Fullscreen=L.Control.extend({options:{position:"topleft",title:{"false":"View Fullscreen","true":"Exit Fullscreen"}},onAdd:function(map){var container=L.DomUtil.create("div","leaflet-control-fullscreen leaflet-bar leaflet-control");this.link=L.DomUtil.create("a","leaflet-control-fullscreen-button leaflet-bar-part",container);this.link.href="#";this._map=map;this._map.on("fullscreenchange",this._toggleTitle,this);this._toggleTitle();L.DomEvent.on(this.link,"click",this._click,this);return container},_click:function(e){L.DomEvent.stopPropagation(e);L.DomEvent.preventDefault(e);this._map.toggleFullscreen(this.options)},_toggleTitle:function(){this.link.title=this.options.title[this._map.isFullscreen()]}});L.Map.include({isFullscreen:function(){return this._isFullscreen||false},toggleFullscreen:function(options){var container=this.getContainer();if(this.isFullscreen()){if(options&&options.pseudoFullscreen){this._disablePseudoFullscreen(container)}else if(document.exitFullscreen){document.exitFullscreen()}else if(document.mozCancelFullScreen){document.mozCancelFullScreen()}else if(document.webkitCancelFullScreen){document.webkitCancelFullScreen()}else if(document.msExitFullscreen){document.msExitFullscreen()}else{this._disablePseudoFullscreen(container)}}else{if(options&&options.pseudoFullscreen){this._enablePseudoFullscreen(container)}else if(container.requestFullscreen){container.requestFullscreen()}else if(container.mozRequestFullScreen){container.mozRequestFullScreen()}else if(container.webkitRequestFullscreen){container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}else if(container.msRequestFullscreen){container.msRequestFullscreen()}else{this._enablePseudoFullscreen(container)}}},_enablePseudoFullscreen:function(container){L.DomUtil.addClass(container,"leaflet-pseudo-fullscreen");this._setFullscreen(true);this.invalidateSize();this.fire("fullscreenchange")},_disablePseudoFullscreen:function(container){L.DomUtil.removeClass(container,"leaflet-pseudo-fullscreen");this._setFullscreen(false);this.invalidateSize();this.fire("fullscreenchange")},_setFullscreen:function(fullscreen){this._isFullscreen=fullscreen;var container=this.getContainer();if(fullscreen){L.DomUtil.addClass(container,"leaflet-fullscreen-on")}else{L.DomUtil.removeClass(container,"leaflet-fullscreen-on")}},_onFullscreenChange:function(e){var fullscreenElement=document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement;if(fullscreenElement===this.getContainer()&&!this._isFullscreen){this._setFullscreen(true);this.fire("fullscreenchange")}else if(fullscreenElement!==this.getContainer()&&this._isFullscreen){this._setFullscreen(false);this.fire("fullscreenchange")}}});L.Map.mergeOptions({fullscreenControl:false});L.Map.addInitHook(function(){if(this.options.fullscreenControl){this.fullscreenControl=new L.Control.Fullscreen(this.options.fullscreenControl);this.addControl(this.fullscreenControl)}var fullscreenchange;if("onfullscreenchange"in document){fullscreenchange="fullscreenchange"}else if("onmozfullscreenchange"in document){fullscreenchange="mozfullscreenchange"}else if("onwebkitfullscreenchange"in document){fullscreenchange="webkitfullscreenchange"}else if("onmsfullscreenchange"in document){fullscreenchange="MSFullscreenChange"}if(fullscreenchange){var onFullscreenChange=L.bind(this._onFullscreenChange,this);this.whenReady(function(){L.DomEvent.on(document,fullscreenchange,onFullscreenChange)});this.on("unload",function(){L.DomEvent.off(document,fullscreenchange,onFullscreenChange)})}});L.control.fullscreen=function(options){return new L.Control.Fullscreen(options)};; 907/* 908 Created on : Aug 31, 2015 909 Author : [email protected] 910*/ 911; 912(function ($) { 913 914 var options = { 915 geojsonServiceAddress: "http://yourGeoJsonSearchAddress", 916 placeholderMessage: "Search...", 917 foundRecordsMessage: "showing results.", 918 limit: 10, 919 notFoundMessage: "not found.", 920 notFoundHint: "Make sure your search criteria is correct and try again.", 921 drawColor: "blue", 922 pointGeometryZoomLevel: -1, //Set zoom level for point geometries -1 means use leaflet default. 923 pagingActive: true, 924 map_obj: null, 925 serachboxID:null 926 927 }; 928 929 var activeResult = -1; 930 var resultCount = 0; 931 var lastSearch = ""; 932 var searchLayer; 933 var focusLayer;
934 var searchLayerType; // 0 --> One geometry, 1--> Multiple 935 var features = []; 936 var featureCollection = []; 937 var offset = 0; 938 var collapseOnBlur = true; 939 var searchID = null; 940 941 $.fn.GeoJsonAutocomplete = function (userDefinedOptions) { 942 943 var keys = Object.keys(userDefinedOptions); 944 for (var i = 0; i < keys.length; i++) { 945 options[keys[i]] = userDefinedOptions[keys[i]]; 946 } 947 948 map = options.map_obj.map; 949 950 var searchBox = options.serachboxID; 951 searchID = options.serachboxID; 952 953 $(this).each(function () { 954 var element = $(this); 955 $(element).parent().addClass("searchContainer"); 956 957 $(this)[0].value = ""; 958 $(this).delayKeyup(function (event) { 959 var target = $(event.target); 960 961 switch (event.keyCode) { 962 case 13: // enter 963 searchButtonClick(target); 964 break; 965 case 38: // up arrow 966 prevResult(target); 967 break; 968 case 40: // down arrow 969 nextResult(target); 970 break; 971 case 37: //left arrow, Do Nothing 972 case 39: //right arrow, Do Nothing 973 break; 974 default: 975 976 if ($(searchBox)[0].value.length > 0) { 977 offset = 0; 978 getValuesAsGeoJson(false,target); 979 } 980 else { 981 clearButtonClick(target); 982 } 983 break; 984 } 985 }, 300); 986 987 $(searchID).focus(function () { 988 if ($("#resultsDiv")[0] !== undefined) { 989 $("#resultsDiv")[0].style.visibility = "visible"; 990 } 991 }); 992 993 $(searchID).blur(function (event) { 994 if ($("#resultsDiv")[0] !== undefined) { 995 if (collapseOnBlur) { 996 $("#resultsDiv")[0].style.visibility = "collapse"; 997 } 998 else { 999 collapseOnBlur = true; 1000 1001 window.setTimeout(function () 1002 { 1003 $(event.target).focus(); 1004 }, 0); 1005 } 1006 } 1007 1008 }); 1009 1010 $(document).on('click','#searchButton',function(){ 1011 searchButtonClick(); 1012 }); 1013 1014 $(document).on('click','#clearButton',function(){ 1015 clearButtonClick(); 1016 }); 1017 }); 1018 }; 1019 1020 $.fn.delayKeyup = function (callback, ms) { 1021 var timer = 0; 1022 $(this).keyup(function (event) { 1023 1024 if (event.keyCode !== 13 && event.keyCode !== 38 && event.keyCode !== 40) { 1025 clearTimeout(timer); 1026 timer = setTimeout(function () { 1027 callback(event); 1028 }, ms); 1029 } 1030 else { 1031 callback(event); 1032 } 1033 }); 1034 return $(this); 1035 }; 1036 1037 function getValuesAsGeoJson(withPaging,target) { 1038 activeResult = -1; 1039 features = []; 1040 featureCollection = []; 1041 var limitToSend = options.limit; 1042 if (withPaging) { 1043 limitToSend++; 1044 } 1045 lastSearch = target[0].value; 1046 1047 if (lastSearch === "") { 1048 return; 1049 } 1050 1051 var data = { 1052 q: lastSearch, 1053 limit: limitToSend, 1054 format: 'json', 1055 addressdetails: true 1056 }; 1057 1058 if(options.pagingActive){ 1059 data.offset = offset; 1060 } 1061 1062 $.ajax({ 1063 url: options.geojsonServiceAddress, 1064 type: 'GET', 1065 data: data, 1066 dataType: 'json', 1067 success: function (json) { 1068 resultCount = json.length; 1069 features = json; 1070 1071 if (limitToSend === resultCount) 1072 featureCollection = json.slice(0, json.length - 1); 1073 else 1074 featureCollection = json; 1075 1076 createDropDown(withPaging,target); 1077 searchLayerType = (withPaging ? 1 : 0); 1078 }, 1079 error: function () { 1080 processNoRecordsFoundOrError(target); 1081 } 1082 }); 1083 1084 } 1085 1086 function createDropDown(withPaging,target) { 1087 var parent = target.parent(); 1088 1089 $("#resultsDiv").remove(); 1090 parent.append("<div id='resultsDiv' class='result'><ul id='resultList' class='list'></ul><div>"); 1091 1092 $("#resultsDiv")[0].style.position = target[0].style.position; 1093 $("#resultsDiv")[0].style.left = (parseInt(target[0].style.left) - 10) + "px"; 1094 $("#resultsDiv")[0].style.bottom = target[0].style.bottom; 1095 $("#resultsDiv")[0].style.right = target[0].style.right; 1096 $("#resultsDiv")[0].style.top = (parseInt(target[0].style.top) + 25) + "px"; 1097 $("#resultsDiv")[0].style.zIndex = target[0].style.zIndex; 1098 1099 var loopCount = features.length; 1100 var hasMorePages = false;
1101 if (withPaging && features.length === options.limit + 1) { //Has more pages 1102 loopCount--; 1103 hasMorePages = true; 1104 resultCount--; 1105 } 1106 1107 for (var i = 0; i < loopCount; i++) { 1108 1109 var html = "<li id='listElement" + i + "' class='listResult'>"; 1110 html += "<span id='listElementContent" + i + "' class='content'>"; 1111 html += "<font size='2' color='#333' class='title'>" + features[i].display_name + "</font><font size='1' color='#8c8c8c'> " + features[i].lat + " -- " + features[i].lon + "<font></span></li>"; 1112 1113 $("#resultList").append(html); 1114 1115 $("#listElement" + i).mouseenter(function () { 1116 listElementMouseEnter(this,target); 1117 }); 1118 1119 $("#listElement" + i).mouseleave(function () { 1120 listElementMouseLeave(this,target); 1121 }); 1122 1123 $("#listElement" + i).mousedown(function () { 1124 listElementMouseDown(this,target); 1125 }); 1126 } 1127 1128 if (withPaging) { 1129 var prevPic = "prev.png"; 1130 var nextPic = "next.png"; 1131 var prevDisabled = ""; 1132 var nextDisabled = ""; 1133 1134 if (offset === 0) { 1135 prevPic = "prev_dis.png"; 1136 prevDisabled = "disabled"; 1137 } 1138 1139 if (!hasMorePages) { 1140 nextPic = "next_dis.png"; 1141 nextDisabled = "disabled"; 1142 } 1143 var image_url = options.map_obj.settings.images_url; 1144 var htmlPaging = "<div align='right' class='pagingDiv'>" + (offset + 1) + " - " + (offset + loopCount) + " " + options.foundRecordsMessage + " "; 1145 htmlPaging += "<input id='pagingPrev' type='image' src='"+image_url + prevPic + "' width='16' height='16' class='pagingArrow' " + prevDisabled + ">"; 1146 htmlPaging += "<input id='pagingNext' type='image' src='"+image_url + nextPic + "' width='16' height='16' class='pagingArrow' " + nextDisabled + "></div>"; 1147 $("#resultsDiv").append(htmlPaging); 1148 1149 $("#pagingPrev").mousedown(function () { 1150 prevPaging(target); 1151 }); 1152 1153 $("#pagingNext").mousedown(function () { 1154 nextPaging(target); 1155 }); 1156 1157 drawGeoJsonList(target); 1158 } 1159 } 1160 1161 function listElementMouseEnter(listElement,target) { 1162 1163 var index = parseInt(listElement.id.substr(11)); 1164 if (index !== activeResult) { 1165 $('#listElement' + index).toggleClass('mouseover'); 1166 } 1167 } 1168 1169 function listElementMouseLeave(listElement,target) { 1170 var index = parseInt(listElement.id.substr(11)); 1171 1172 if (index !== activeResult) { 1173 $('#listElement' + index).removeClass('mouseover'); 1174 } 1175 } 1176 1177 function listElementMouseDown(listElement,target) { 1178 var index = parseInt(listElement.id.substr(11)); 1179 1180 if (index !== activeResult) { 1181 if (activeResult !== -1) { 1182 $('#listElement' + activeResult).removeClass('active'); 1183 } 1184 1185 $('#listElement' + index).removeClass('mouseover'); 1186 $('#listElement' + index).addClass('active'); 1187 1188 activeResult = index; 1189 fillSearchBox(target); 1190 1191 if (searchLayerType === 0) { 1192 drawGeoJson(activeResult,target); 1193 } 1194 else { 1195 focusGeoJson(activeResult,target); 1196 } 1197 } 1198 } 1199 1200 1201 function drawGeoJsonList(target) { 1202 if (searchLayer !== undefined) { 1203 map.removeLayer(searchLayer); 1204 searchLayer = undefined; 1205 } 1206 1207 searchLayer = L.geoJson(featureCollection, { 1208 style: function (feature) { 1209 return {color: "#D0473B"}; 1210 }, 1211 pointToLayer: function (feature, latlng) { 1212 return new L.CircleMarker(latlng, {radius: 5, fillOpacity: 0.85}); 1213 }, 1214 onEachFeature: function (feature, layer) { 1215 layer.bindPopup(feature.properties.popupContent); 1216 } 1217 }); 1218 1219 map.addLayer(searchLayer); 1220 1221 } 1222 1223 function focusGeoJson(index,target) { 1224 1225 drawGeoJsonOnFocusLayer(index,target); 1226 } 1227 1228 function getBoundsOfGeoJsonObject(geometry) { 1229 1230 var geojsonObject = L.geoJson(geometry, { 1231 onEachFeature: function (feature, layer) { 1232 } 1233 }); 1234 1235 return geojsonObject.getBounds(); 1236 } 1237 1238 function drawGeoJson(index,target) { 1239 1240 if (searchLayer !== undefined) { 1241 searchLayer = undefined; 1242 } 1243 1244 if (index === -1) 1245 return; 1246 1247 var drawStyle = { 1248 color: options.drawColor, 1249 weight: 5, 1250 opacity: 0.65, 1251 fill: false 1252 }; 1253 1254 searchLayer = L.geoJson(features[index].geometry, { 1255 style: drawStyle, 1256 onEachFeature: function (feature, layer) { 1257 layer.bindPopup(features[index].properties.popupContent); 1258 } 1259 }); 1260 1261 var center = new L.LatLng(features[index].lat, features[index].lon); 1262 1263 if(!($(target).hasClass('wpomp_search_input'))){ 1264 1265 var marker = new L.Marker(center,{ 1266 icon: L.icon({
1267 iconUrl: options.map_obj.settings.marker_default_icon, 1268 iconAnchor: [15, 55], 1269 popupAnchor: [0, -55], 1270 1271 }), 1272 }); 1273 marker.addTo(map); 1274 var content = features[index].display_name; 1275 marker.bindPopup('<div class="wpomp_infowindow"><div class="wpomp_iw_content">'+content+'</div></div>'); 1276 1277 } 1278 1279 if($(target).hasClass('wpomp_search_input')){ 1280 if( typeof options.map_obj.map_data.listing !='undefined' && typeof options.map_obj.map_data.listing.display_radius_filter !='undefined' && options.map_obj.map_data.listing.display_radius_filter === true ) { 1281 options.map_obj.search_area = center; 1282 } 1283 options.map_obj.update_filters(); 1284 } 1285 map.panTo(center); 1286 1287 } 1288 1289 function drawGeoJsonOnFocusLayer(index,target) { 1290 1291 if (focusLayer !== undefined) { 1292 map.removeLayer(focusLayer); 1293 focusLayer = undefined; 1294 } 1295 1296 if (index === -1) 1297 return; 1298 1299 var drawStyle = { 1300 color: options.color, 1301 weight: 5, 1302 opacity: 0.65, 1303 fill: false 1304 }; 1305 1306 focusLayer = L.geoJson(features[index].geometry, { 1307 style: drawStyle, 1308 onEachFeature: function (feature, layer) { 1309 layer.bindPopup(features[index].properties.popupContent); 1310 } 1311 }); 1312 1313 map.addLayer(focusLayer); 1314 1315 } 1316 1317 1318 function fillSearchBox(target) { 1319 1320 1321 try { 1322 1323 if (activeResult === -1) { 1324 target[0].value = lastSearch; 1325 } 1326 else { 1327 target[0].value = features[activeResult].display_name; 1328 } 1329 1330 var locationform = target.closest('form'); 1331 1332 if (activeResult === -1) { 1333 target[0].value = lastSearch; 1334 } 1335 else { 1336 target[0].value = features[activeResult].display_name; 1337 } 1338 1339 var locationform = target.closest('form'); 1340 $(locationform).find('.google_latitude').val(features[activeResult].lat); 1341 1342 $(locationform).find('.wpomp_metabox_location_hidden').val(features[activeResult].display_name); 1343 1344 $(locationform).find('.google_longitude').val(features[activeResult].lon); 1345 1346 $(locationform).find('.google_city').val(features[activeResult].address.county); 1347 1348 $(locationform).find('.google_state').val(features[activeResult].address.state); 1349 1350 $(locationform).find('.google_country').val(features[activeResult].address.country); 1351 1352 1353 } catch(e) { 1354 1355 } 1356 1357 } 1358 1359 function nextResult(target) { 1360 1361 if (resultCount > 0) { 1362 if (activeResult !== -1) { 1363 $('#listElement' + activeResult).toggleClass('active'); 1364 } 1365 1366 if (activeResult < resultCount - 1) { 1367 $('#listElement' + (activeResult + 1)).toggleClass('active'); 1368 activeResult++; 1369 } 1370 else { 1371 activeResult = -1; 1372 } 1373 1374 fillSearchBox(target); 1375 1376 if (activeResult !== -1) { 1377 if (searchLayerType === 0) { 1378 drawGeoJson(activeResult,target); 1379 } 1380 else { 1381 focusGeoJson(activeResult,target); 1382 } 1383 } 1384 1385 } 1386 } 1387 1388 function prevResult(target) { 1389 if (resultCount > 0) { 1390 if (activeResult !== -1) { 1391 $('#listElement' + activeResult).toggleClass('active'); 1392 } 1393 1394 if (activeResult === -1) { 1395 $('#listElement' + (resultCount - 1)).toggleClass('active'); 1396 activeResult = resultCount - 1; 1397 } 1398 else if (activeResult === 0) { 1399 activeResult--; 1400 } 1401 else { 1402 $('#listElement' + (activeResult - 1)).toggleClass('active'); 1403 activeResult--; 1404 } 1405 1406 fillSearchBox(target); 1407 1408 if (activeResult !== -1) { 1409 if (searchLayerType === 0) { 1410 drawGeoJson(activeResult,target); 1411 } 1412 else { 1413 focusGeoJson(activeResult,target); 1414 } 1415 } 1416 } 1417 } 1418 1419 function clearButtonClick(target) { 1420 target[0].value = ""; 1421 lastSearch = ""; 1422 resultCount = 0; 1423 features = []; 1424 activeResult = -1; 1425 $("#resultsDiv").remove(); 1426 if (searchLayer !== undefined) { 1427 map.removeLayer(searchLayer); 1428 searchLayer = undefined; 1429 } 1430 if (focusLayer !== undefined) { 1431 map.removeLayer(focusLayer); 1432 focusLayer = undefined; 1433 } 1434 } 1435 1436 function searchButtonClick(target) { 1437 getValuesAsGeoJson(options.pagingActive,target); 1438 1439 } 1440 1441 function processNoRecordsFoundOrError(target) { 1442 resultCount = 0; 1443 features = []; 1444 activeResult = -1; 1445 $("#resultsDiv").remove(); 1446 if (searchLayer !== undefined) { 1447 map.removeLayer(searchLayer); 1448 searchLayer = undefined; 1449 } 1450 1451 var parent = target.parent(); 1452 $("#resultsDiv").remove(); 1453 parent.append("<div id='resultsDiv' class='result'><i>" + lastSearch + " " + options.notFoundMessage + " <p><small>" + options.notFoundHint + "</small></i><div>"); 1454 } 1455 1456 function prevPaging(target) { 1457 target[0].value = lastSearch; 1458 offset = offset - options.limit; 1459 getValuesAsGeoJson(true,target); 1460 collapseOnBlur = false;
1461 activeResult = -1; 1462 } 1463 1464 function nextPaging(target) { 1465 target[0].value = lastSearch; 1466 offset = offset + options.limit; 1467 getValuesAsGeoJson(true,target); 1468 collapseOnBlur = false; 1469 activeResult = -1; 1470 } 1471})(jQuery); 1472; 1473/** 1474 * Accordion, jQuery Plugin 1475 * 1476 * This plugin provides an accordion with cookie support. 1477 * 1478 * Copyright (c) 2011 John Snyder (snyderplace.com) 1479 * @license http://www.snyderplace.com/accordion/license.txt New BSD 1480 * @version 1.1 1481 */ 1482(function($) { 1483 $.fn.accordion = function(options) { 1484 1485 //firewalling 1486 if (!this || this.length < 1) { 1487 return this; 1488 } 1489 1490 initialize(this, options); 1491 1492 }; 1493 1494 //create the initial accordion 1495 function initialize(obj, options) { 1496 1497 //build main options before element iteration 1498 var opts = $.extend({}, $.fn.accordion.defaults, options); 1499 1500 //store any opened default values to set cookie later 1501 var opened = ''; 1502 1503 //iterate each matched object, bind, and open/close 1504 obj.each(function() { 1505 var $this = $(this); 1506 saveOpts($this, opts); 1507 1508 //bind it to the event 1509 if (opts.bind == 'mouseenter') { 1510 $this.bind('mouseenter', function(e) { 1511 e.preventDefault(); 1512 toggle($this, opts); 1513 }); 1514 } 1515 1516 //bind it to the event 1517 if (opts.bind == 'mouseover') { 1518 $this.bind('mouseover', function(e) { 1519 e.preventDefault(); 1520 toggle($this, opts); 1521 }); 1522 } 1523 1524 //bind it to the event 1525 if (opts.bind == 'click') { 1526 $this.bind('click', function(e) { 1527 e.preventDefault(); 1528 toggle($this, opts); 1529 }); 1530 } 1531 1532 //bind it to the event 1533 if (opts.bind == 'dblclick') { 1534 $this.bind('dblclick', function(e) { 1535 e.preventDefault(); 1536 toggle($this, opts); 1537 }); 1538 } 1539 1540 //initialize the panels 1541 //get the id for this element 1542 var id = $this.attr('id'); 1543 1544 //if not using cookies, open defaults 1545 if (!useCookies(opts)) { 1546 //close it if not defaulted to open 1547 if (id != opts.defaultOpen) { 1548 $this.addClass(opts.cssClose); 1549 opts.loadClose($this, opts); 1550 } else { //its a default open, open it 1551 $this.addClass(opts.cssOpen); 1552 opts.loadOpen($this, opts); 1553 opened = id; 1554 } 1555 } else { //can use cookies, use them now 1556 //has a cookie been set, this overrides default open 1557 if (issetCookie(opts)) { 1558 if (inCookie(id, opts) === false) { 1559 $this.addClass(opts.cssClose); 1560 opts.loadClose($this, opts); 1561 } else { 1562 $this.addClass(opts.cssOpen); 1563 opts.loadOpen($this, opts); 1564 opened = id; 1565 } 1566 } else { //a cookie hasn't been set open defaults 1567 if (id != opts.defaultOpen) { 1568 $this.addClass(opts.cssClose); 1569 opts.loadClose($this, opts); 1570 } else { //its a default open, open it 1571 $this.addClass(opts.cssOpen); 1572 opts.loadOpen($this, opts); 1573 opened = id; 1574 } 1575 } 1576 } 1577 }); 1578 1579 //now that the loop is done, set the cookie 1580 if (opened.length > 0 && useCookies(opts)) { 1581 setCookie(opened, opts); 1582 } else { //there are none open, set cookie 1583 setCookie('', opts); 1584 } 1585 1586 return obj; 1587 }; 1588 1589 //load opts from object 1590 function loadOpts($this) { 1591 return $this.data('accordion-opts'); 1592 } 1593 1594 //save opts into object 1595 function saveOpts($this, opts) { 1596 return $this.data('accordion-opts', opts); 1597 } 1598 1599 //hides a accordion panel 1600 function close(opts) { 1601 opened = $(document).find('.' + opts.cssOpen); 1602 $.each(opened, function() { 1603 //give the proper class to the linked element 1604 $(this).addClass(opts.cssClose).removeClass(opts.cssOpen); 1605 opts.animateClose($(this), opts); 1606 }); 1607 } 1608 1609 //opens a accordion panel 1610 function open($this, opts) { 1611 close(opts); 1612 //give the proper class to the linked element 1613 $this.removeClass(opts.cssClose).addClass(opts.cssOpen); 1614 1615 //open the element 1616 opts.animateOpen($this, opts); 1617 1618 //do cookies if plugin available 1619 if (useCookies(opts)) { 1620 // split the cookieOpen string by "," 1621 id = $this.attr('id');
1622 setCookie(id, opts); 1623 } 1624 } 1625 1626 //toggle a accordion on an event 1627 function toggle($this, opts) { 1628 // close the only open item 1629 if ($this.hasClass(opts.cssOpen)) { 1630 close(opts); 1631 //do cookies if plugin available 1632 if (useCookies(opts)) { 1633 // split the cookieOpen string by "," 1634 setCookie('', opts); 1635 } 1636 return false; 1637 } 1638 close(opts); 1639 //open a closed element 1640 open($this, opts); 1641 return false; 1642 } 1643 1644 //use cookies? 1645 function useCookies(opts) { 1646 //return false if cookie plugin not present or if a cookie name is not provided 1647 if (!$.cookie || opts.cookieName == '') { 1648 return false; 1649 } 1650 1651 //we can use cookies 1652 return true; 1653 } 1654 1655 //set a cookie 1656 function setCookie(value, opts) { 1657 //can use the cookie plugin 1658 if (!useCookies(opts)) { //no, quit here 1659 return false; 1660 } 1661 1662 //cookie plugin is available, lets set the cookie 1663 $.cookie(opts.cookieName, value, opts.cookieOptions); 1664 } 1665 1666 //check if a accordion is in the cookie 1667 function inCookie(value, opts) { 1668 //can use the cookie plugin 1669 if (!useCookies(opts)) { 1670 return false; 1671 } 1672 1673 //if its not there we don't need to remove from it 1674 if (!issetCookie(opts)) { //quit here, don't have a cookie 1675 return false; 1676 } 1677 1678 //unescape it 1679 cookie = unescape($.cookie(opts.cookieName)); 1680 1681 //is this value in the cookie arrray 1682 if (cookie != value) { //no, quit here 1683 return false; 1684 } 1685 1686 return true; 1687 } 1688 1689 //check if a cookie is set 1690 function issetCookie(opts) { 1691 //can we use the cookie plugin 1692 if (!useCookies(opts)) { //no, quit here 1693 return false; 1694 } 1695 1696 //is the cookie set 1697 if ($.cookie(opts.cookieName) == null) { //no, quit here 1698 return false; 1699 } 1700 1701 return true; 1702 } 1703 1704 // settings 1705 $.fn.accordion.defaults = { 1706 cssClose: 'accordion-close', //class you want to assign to a closed accordion header 1707 cssOpen: 'accordion-open', //class you want to assign an opened accordion header 1708 cookieName: 'accordion', //name of the cookie you want to set for this accordion 1709 cookieOptions: { //cookie options, see cookie plugin for details 1710 path: '/', 1711 expires: 7, 1712 domain: '', 1713 secure: '' 1714 }, 1715 defaultOpen: '', //id that you want opened by default 1716 speed: 'slow', //speed of the slide effect 1717 bind: 'click', //event to bind to, supports click, dblclick, mouseover and mouseenter 1718 animateOpen: function(elem, opts) { //replace the standard slideDown with custom function 1719 elem.next().stop(true, true).slideDown(opts.speed); 1720 }, 1721 animateClose: function(elem, opts) { //replace the standard slideUp with custom function 1722 elem.next().stop(true, true).slideUp(opts.speed); 1723 }, 1724 loadOpen: function(elem, opts) { //replace the default open state with custom function 1725 elem.next().show(); 1726 }, 1727 loadClose: function(elem, opts) { //replace the default close state with custom function 1728 elem.next().hide(); 1729 } 1730 }; 1731})(jQuery);; 1732/* 1733 * This combined file was created by the DataTables downloader builder: 1734 * https://datatables.net/download 1735 * 1736 * To rebuild or modify this file with the latest versions of the included 1737 * software please visit: 1738 * https://datatables.net/download/#dt/dt-1.10.18 1739 * 1740 * Included libraries: 1741 * DataTables 1.10.18 1742 */ 1743 1744/*! DataTables 1.10.18 1745 * ©2008-2018 SpryMedia Ltd - datatables.net/license 1746 */ 1747 1748/** 1749 * @summary DataTables 1750 * @description Paginate, search and order HTML tables 1751 * @version 1.10.18 1752 * @file jquery.dataTables.js 1753 * @author SpryMedia Ltd 1754 * @contact www.datatables.net 1755 * @copyright Copyright 2008-2018 SpryMedia Ltd. 1756 * 1757 * This source file is free software, available under the following license: 1758 * MIT license - http://datatables.net/license 1759 * 1760 * This source file is distributed in the hope that it will be useful, but 1761 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1762 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. 1763 * 1764 * For details please refer to: http://www.datatables.net 1765 */ 1766 1767/*jslint evil: true, undef: true, browser: true */ 1768/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_plu
1768ck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ 1769 1770(function( factory ) { 1771 "use strict"; 1772 1773 if ( typeof define === 'function' && define.amd ) { 1774 // AMD 1775 define( ['jquery'], function ( $ ) { 1776 return factory( $, window, document ); 1777 } ); 1778 } 1779 else if ( typeof exports === 'object' ) { 1780 // CommonJS 1781 module.exports = function (root, $) { 1782 if ( ! root ) { 1783 // CommonJS environments without a window global must pass a 1784 // root. This will give an error otherwise 1785 root = window; 1786 } 1787 1788 if ( ! $ ) { 1789 $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window 1790 require('jquery') : 1791 require('jquery')( root ); 1792 } 1793 1794 return factory( $, root, root.document ); 1795 }; 1796 } 1797 else { 1798 // Browser 1799 factory( jQuery, window, document ); 1800 } 1801} 1802(function( $, window, document, undefined ) { 1803 "use strict"; 1804 1805 /** 1806 * DataTables is a plug-in for the jQuery Javascript library. It is a highly 1807 * flexible tool, based upon the foundations of progressive enhancement, 1808 * which will add advanced interaction controls to any HTML table. For a 1809 * full list of features please refer to 1810 * [DataTables.net](href="http://datatables.net). 1811 * 1812 * Note that the `DataTable` object is not a global variable but is aliased 1813 * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may 1814 * be accessed. 1815 * 1816 * @class 1817 * @param {object} [init={}] Configuration object for DataTables. Options 1818 * are defined by {@link DataTable.defaults} 1819 * @requires jQuery 1.7+ 1820 * 1821 * @example 1822 * // Basic initialisation 1823 * $(document).ready( function { 1824 * $('#example').dataTable(); 1825 * } ); 1826 * 1827 * @example 1828 * // Initialisation with configuration options - in this case, disable 1829 * // pagination and sorting. 1830 * $(document).ready( function { 1831 * $('#example').dataTable( { 1832 * "paginate": false, 1833 * "sort": false 1834 * } ); 1835 * } ); 1836 */ 1837 var DataTable = function ( options ) 1838 { 1839 /** 1840 * Perform a jQuery selector action on the table's TR elements (from the tbody) and 1841 * return the resulting jQuery object. 1842 * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on 1843 * @param {object} [oOpts] Optional parameters for modifying the rows to be included 1844 * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter 1845 * criterion ("applied") or all TR elements (i.e. no filter). 1846 * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. 1847 * Can be either 'current', whereby the current sorting of the table is used, or 1848 * 'original' whereby the original order the data was read into the table is used. 1849 * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page 1850 * ("current") or not ("all"). If 'current' is given, then order is assumed to be 1851 * 'current' and filter is 'applied', regardless of what they might be given as. 1852 * @returns {object} jQuery object, filtered by the given selector. 1853 * @dtopt API 1854 * @deprecated Since v1.10 1855 * 1856 * @example 1857 * $(document).ready(function() { 1858 * var oTable = $('#example').dataTable(); 1859 * 1860 * // Highlight every second row 1861 * oTable.$('tr:odd').css('backgroundColor', 'blue'); 1862 * } ); 1863 * 1864 * @example 1865 * $(document).ready(function() { 1866 * var oTable = $('#example').dataTable(); 1867 * 1868 * // Filter to rows with 'Webkit' in them, add a background colour and then 1869 * // remove the filter, thus highlighting the 'Webkit' rows only. 1870 * oTable.fnFilter('Webkit'); 1871 * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue'); 1872 * oTable.fnFilter(''); 1873 * } ); 1874 */ 1875 this.$ = function ( sSelector, oOpts ) 1876 { 1877 return this.api(true).$( sSelector, oOpts ); 1878 }; 1879
1880 1881 /** 1882 * Almost identical to $ in operation, but in this case returns the data for the matched 1883 * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes 1884 * rather than any descendants, so the data can be obtained for the row/cell. If matching 1885 * rows are found, the data returned is the original data array/object that was used to 1886 * create the row (or a generated array if from a DOM source). 1887 * 1888 * This method is often useful in-combination with $ where both functions are given the 1889 * same parameters and the array indexes will match identically. 1890 * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on 1891 * @param {object} [oOpts] Optional parameters for modifying the rows to be included 1892 * @param {string} [oOpts.filter=none] Select elements that meet the current filter 1893 * criterion ("applied") or all elements (i.e. no filter). 1894 * @param {string} [oOpts.order=current] Order of the data in the processed array. 1895 * Can be either 'current', whereby the current sorting of the table is used, or 1896 * 'original' whereby the original order the data was read into the table is used. 1897 * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page 1898 * ("current") or not ("all"). If 'current' is given, then order is assumed to be 1899 * 'current' and filter is 'applied', regardless of what they might be given as. 1900 * @returns {array} Data for the matched elements. If any elements, as a result of the 1901 * selector, were not TR, TD or TH elements in the DataTable, they will have a null 1902 * entry in the array. 1903 * @dtopt API 1904 * @deprecated Since v1.10 1905 * 1906 * @example 1907 * $(document).ready(function() { 1908 * var oTable = $('#example').dataTable(); 1909 * 1910 * // Get the data from the first row in the table 1911 * var data = oTable._('tr:first'); 1912 * 1913 * // Do something useful with the data 1914 * alert( "First cell is: "+data[0] ); 1915 * } ); 1916 * 1917 * @example 1918 * $(document).ready(function() { 1919 * var oTable = $('#example').dataTable(); 1920 * 1921 * // Filter to 'Webkit' and get all data for 1922 * oTable.fnFilter('Webkit'); 1923 * var data = oTable._('tr', {"search": "applied"}); 1924 * 1925 * // Do something with the data 1926 * alert( data.length+" rows matched the search" ); 1927 * } ); 1928 */ 1929 this._ = function ( sSelector, oOpts ) 1930 { 1931 return this.api(true).rows( sSelector, oOpts ).data(); 1932 }; 1933 1934 1935 /** 1936 * Create a DataTables Api instance, with the currently selected tables for 1937 * the Api's context. 1938 * @param {boolean} [traditional=false] Set the API instance's context to be 1939 * only the table referred to by the `DataTable.ext.iApiIndex` option, as was 1940 * used in the API presented by DataTables 1.9- (i.e. the traditional mode), 1941 * or if all tables captured in the jQuery object should be used. 1942 * @return {DataTables.Api} 1943 */ 1944 this.api = function ( traditional ) 1945 { 1946 return traditional ? 1947 new _Api( 1948 _fnSettingsFromNode( this[ _ext.iApiIndex ] ) 1949 ) : 1950 new _Api( this ); 1951 }; 1952 1953 1954 /** 1955 * Add a single new row or multiple rows of data to the table. Please note 1956 * that this is suitable for client-side processing only - if you are using 1957 * server-side processing (i.e. "bServerSide": true), then to add data, you 1958 * must add it to the data source, i.e. the server-side, through an Ajax call. 1959 * @param {array|object} data The data to be added to the table. This can be: 1960 * <ul> 1961 * <li>1D array of data - add a single row with the data provided</li> 1962 * <li>2D array of arrays - add multiple rows in a single call</li> 1963 * <li>object - data object when using <i>mData</i></li> 1964 * <li>array of objects - multiple data objects when using <i>mData</i></li> 1965 * </ul> 1966 * @param {bool} [redraw=true] redraw the table or not 1967 * @returns {array} An array of integers, representing the list of indexes in 1968 * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to 1969 * the table. 1970 * @dtopt API 1971 * @deprecated Since v1.10 1972 * 1973 * @example 1974 * // Global var for counter 1975 * var giCount = 2; 1976 * 1977 * $(document).ready(function() { 1978 * $('#example').dataTable(); 1979 * } ); 1980 * 1981 * function fnClickAddRow() { 1982 * $('#example').dataTable().fnAddData( [ 1983 * giCount+".1", 1984 * giCount+".2", 1985 * giCount+".3", 1986 * giCount+".4" ] 1987 * ); 1988 * 1989 * giCount++; 1990 * } 1991 */ 1992 this.fnAddData = function( data, redraw ) 1993 { 1994 var api = this.api( true ); 1995 1996 /* Check if we want to add multiple rows or not */ 1997 var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ? 1998 api.rows.add( data ) : 1999 api.row.add( data ); 2000 2001 if ( redraw === undefined || redraw ) { 2002 api.draw(); 2003 } 2004 2005 return rows.flatten().toArray(); 2006 }; 2007
2008 2009 /** 2010 * This function will make DataTables recalculate the column sizes, based on the data 2011 * contained in the table and the sizes applied to the columns (in the DOM, CSS or 2012 * through the sWidth parameter). This can be useful when the width of the table's 2013 * parent element changes (for example a window resize). 2014 * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to 2015 * @dtopt API 2016 * @deprecated Since v1.10 2017 * 2018 * @example 2019 * $(document).ready(function() { 2020 * var oTable = $('#example').dataTable( { 2021 * "sScrollY": "200px", 2022 * "bPaginate": false 2023 * } ); 2024 * 2025 * $(window).on('resize', function () { 2026 * oTable.fnAdjustColumnSizing(); 2027 * } ); 2028 * } ); 2029 */ 2030 this.fnAdjustColumnSizing = function ( bRedraw ) 2031 { 2032 var api = this.api( true ).columns.adjust(); 2033 var settings = api.settings()[0]; 2034 var scroll = settings.oScroll; 2035 2036 if ( bRedraw === undefined || bRedraw ) { 2037 api.draw( false ); 2038 } 2039 else if ( scroll.sX !== "" || scroll.sY !== "" ) { 2040 /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */ 2041 _fnScrollDraw( settings ); 2042 } 2043 }; 2044 2045 2046 /** 2047 * Quickly and simply clear a table 2048 * @param {bool} [bRedraw=true] redraw the table or not 2049 * @dtopt API 2050 * @deprecated Since v1.10 2051 * 2052 * @example 2053 * $(document).ready(function() { 2054 * var oTable = $('#example').dataTable(); 2055 * 2056 * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...) 2057 * oTable.fnClearTable(); 2058 * } ); 2059 */ 2060 this.fnClearTable = function( bRedraw ) 2061 { 2062 var api = this.api( true ).clear(); 2063 2064 if ( bRedraw === undefined || bRedraw ) { 2065 api.draw(); 2066 } 2067 }; 2068 2069 2070 /** 2071 * The exact opposite of 'opening' a row, this function will close any rows which 2072 * are currently 'open'. 2073 * @param {node} nTr the table row to 'close' 2074 * @returns {int} 0 on success, or 1 if failed (can't find the row) 2075 * @dtopt API 2076 * @deprecated Since v1.10 2077 * 2078 * @example 2079 * $(document).ready(function() { 2080 * var oTable; 2081 * 2082 * // 'open' an information row when a row is clicked on 2083 * $('#example tbody tr').click( function () { 2084 * if ( oTable.fnIsOpen(this) ) { 2085 * oTable.fnClose( this ); 2086 * } else { 2087 * oTable.fnOpen( this, "Temporary row opened", "info_row" ); 2088 * } 2089 * } ); 2090 * 2091 * oTable = $('#example').dataTable(); 2092 * } ); 2093 */ 2094 this.fnClose = function( nTr ) 2095 { 2096 this.api( true ).row( nTr ).child.hide(); 2097 }; 2098 2099 2100 /** 2101 * Remove a row for the table 2102 * @param {mixed} target The index of the row from aoData to be deleted, or 2103 * the TR element you want to delete 2104 * @param {function|null} [callBack] Callback function 2105 * @param {bool} [redraw=true] Redraw the table or not 2106 * @returns {array} The row that was deleted 2107 * @dtopt API 2108 * @deprecated Since v1.10 2109 * 2110 * @example 2111 * $(document).ready(function() { 2112 * var oTable = $('#example').dataTable(); 2113 * 2114 * // Immediately remove the first row 2115 * oTable.fnDeleteRow( 0 ); 2116 * } ); 2117 */ 2118 this.fnDeleteRow = function( target, callback, redraw ) 2119 { 2120 var api = this.api( true ); 2121 var rows = api.rows( target ); 2122 var settings = rows.settings()[0]; 2123 var data = settings.aoData[ rows[0][0] ]; 2124 2125 rows.remove(); 2126 2127 if ( callback ) { 2128 callback.call( this, settings, data ); 2129 } 2130 2131 if ( redraw === undefined || redraw ) { 2132 api.draw(); 2133 } 2134 2135 return data; 2136 }; 2137 2138 2139 /** 2140 * Restore the table to it's original state in the DOM by removing all of DataTables 2141 * enhancements, alterations to the DOM structure of the table and event listeners. 2142 * @param {boolean} [remove=false] Completely remove the table from the DOM 2143 * @dtopt API 2144 * @deprecated Since v1.10 2145 * 2146 * @example 2147 * $(document).ready(function() { 2148 * // This example is fairly pointless in reality, but shows how fnDestroy can be used 2149 * var oTable = $('#example').dataTable(); 2150 * oTable.fnDestroy(); 2151 * } ); 2152 */ 2153 this.fnDestroy = function ( remove ) 2154 { 2155 this.api( true ).destroy( remove ); 2156 }; 2157
2158 2159 /** 2160 * Redraw the table 2161 * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw. 2162 * @dtopt API 2163 * @deprecated Since v1.10 2164 * 2165 * @example 2166 * $(document).ready(function() { 2167 * var oTable = $('#example').dataTable(); 2168 * 2169 * // Re-draw the table - you wouldn't want to do it here, but it's an example :-) 2170 * oTable.fnDraw(); 2171 * } ); 2172 */ 2173 this.fnDraw = function( complete ) 2174 { 2175 // Note that this isn't an exact match to the old call to _fnDraw - it takes 2176 // into account the new data, but can hold position. 2177 this.api( true ).draw( complete ); 2178 }; 2179 2180 2181 /** 2182 * Filter the input based on data 2183 * @param {string} sInput String to filter the table on 2184 * @param {int|null} [iColumn] Column to limit filtering to 2185 * @param {bool} [bRegex=false] Treat as regular expression or not 2186 * @param {bool} [bSmart=true] Perform smart filtering or not 2187 * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es) 2188 * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false) 2189 * @dtopt API 2190 * @deprecated Since v1.10 2191 * 2192 * @example 2193 * $(document).ready(function() { 2194 * var oTable = $('#example').dataTable(); 2195 * 2196 * // Sometime later - filter... 2197 * oTable.fnFilter( 'test string' ); 2198 * } ); 2199 */ 2200 this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive ) 2201 { 2202 var api = this.api( true ); 2203 2204 if ( iColumn === null || iColumn === undefined ) { 2205 api.search( sInput, bRegex, bSmart, bCaseInsensitive ); 2206 } 2207 else { 2208 api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive ); 2209 } 2210 2211 api.draw(); 2212 }; 2213 2214 2215 /** 2216 * Get the data for the whole table, an individual row or an individual cell based on the 2217 * provided parameters. 2218 * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as 2219 * a TR node then the data source for the whole row will be returned. If given as a 2220 * TD/TH cell node then iCol will be automatically calculated and the data for the 2221 * cell returned. If given as an integer, then this is treated as the aoData internal 2222 * data index for the row (see fnGetPosition) and the data for that row used. 2223 * @param {int} [col] Optional column index that you want the data of. 2224 * @returns {array|object|string} If mRow is undefined, then the data for all rows is 2225 * returned. If mRow is defined, just data for that row, and is iCol is 2226 * defined, only data for the designated cell is returned. 2227 * @dtopt API 2228 * @deprecated Since v1.10 2229 * 2230 * @example 2231 * // Row data 2232 * $(document).ready(function() { 2233 * oTable = $('#example').dataTable(); 2234 * 2235 * oTable.$('tr').click( function () { 2236 * var data = oTable.fnGetData( this ); 2237 * // ... do something with the array / object of data for the row 2238 * } ); 2239 * } ); 2240 * 2241 * @example 2242 * // Individual cell data 2243 * $(document).ready(function() { 2244 * oTable = $('#example').dataTable(); 2245 * 2246 * oTable.$('td').click( function () { 2247 * var sData = oTable.fnGetData( this ); 2248 * alert( 'The cell clicked on had the value of '+sData ); 2249 * } ); 2250 * } ); 2251 */ 2252 this.fnGetData = function( src, col ) 2253 { 2254 var api = this.api( true ); 2255 2256 if ( src !== undefined ) { 2257 var type = src.nodeName ? src.nodeName.toLowerCase() : ''; 2258 2259 return col !== undefined || type == 'td' || type == 'th' ? 2260 api.cell( src, col ).data() : 2261 api.row( src ).data() || null; 2262 } 2263 2264 return api.data().toArray(); 2265 }; 2266 2267 2268 /** 2269 * Get an array of the TR nodes that are used in the table's body. Note that you will 2270 * typically want to use the '$' API method in preference to this as it is more 2271 * flexible. 2272 * @param {int} [iRow] Optional row index for the TR element you want 2273 * @returns {array|node} If iRow is undefined, returns an array of all TR elements 2274 * in the table's body, or iRow is defined, just the TR element requested. 2275 * @dtopt API 2276 * @deprecated Since v1.10 2277 * 2278 * @example 2279 * $(document).ready(function() { 2280 * var oTable = $('#example').dataTable(); 2281 * 2282 * // Get the nodes from the table 2283 * var nNodes = oTable.fnGetNodes( ); 2284 * } ); 2285 */ 2286 this.fnGetNodes = function( iRow ) 2287 { 2288 var api = this.api( true ); 2289 2290 return iRow !== undefined ? 2291 api.row( iRow ).node() : 2292 api.rows().nodes().flatten().toArray(); 2293 }; 2294
2295 2296 /** 2297 * Get the array indexes of a particular cell from it's DOM element 2298 * and column index including hidden columns 2299 * @param {node} node this can either be a TR, TD or TH in the table's body 2300 * @returns {int} If nNode is given as a TR, then a single index is returned, or 2301 * if given as a cell, an array of [row index, column index (visible), 2302 * column index (all)] is given. 2303 * @dtopt API 2304 * @deprecated Since v1.10 2305 * 2306 * @example 2307 * $(document).ready(function() { 2308 * $('#example tbody td').click( function () { 2309 * // Get the position of the current data from the node 2310 * var aPos = oTable.fnGetPosition( this ); 2311 * 2312 * // Get the data array for this row 2313 * var aData = oTable.fnGetData( aPos[0] ); 2314 * 2315 * // Update the data array and return the value 2316 * aData[ aPos[1] ] = 'clicked'; 2317 * this.innerHTML = 'clicked'; 2318 * } ); 2319 * 2320 * // Init DataTables 2321 * oTable = $('#example').dataTable(); 2322 * } ); 2323 */ 2324 this.fnGetPosition = function( node ) 2325 { 2326 var api = this.api( true ); 2327 var nodeName = node.nodeName.toUpperCase(); 2328 2329 if ( nodeName == 'TR' ) { 2330 return api.row( node ).index(); 2331 } 2332 else if ( nodeName == 'TD' || nodeName == 'TH' ) { 2333 var cell = api.cell( node ).index(); 2334 2335 return [ 2336 cell.row, 2337 cell.columnVisible, 2338 cell.column 2339 ]; 2340 } 2341 return null; 2342 }; 2343 2344 2345 /** 2346 * Check to see if a row is 'open' or not. 2347 * @param {node} nTr the table row to check 2348 * @returns {boolean} true if the row is currently open, false otherwise 2349 * @dtopt API 2350 * @deprecated Since v1.10 2351 * 2352 * @example 2353 * $(document).ready(function() { 2354 * var oTable; 2355 * 2356 * // 'open' an information row when a row is clicked on 2357 * $('#example tbody tr').click( function () { 2358 * if ( oTable.fnIsOpen(this) ) { 2359 * oTable.fnClose( this ); 2360 * } else { 2361 * oTable.fnOpen( this, "Temporary row opened", "info_row" ); 2362 * } 2363 * } ); 2364 * 2365 * oTable = $('#example').dataTable(); 2366 * } ); 2367 */ 2368 this.fnIsOpen = function( nTr ) 2369 { 2370 return this.api( true ).row( nTr ).child.isShown(); 2371 }; 2372 2373 2374 /** 2375 * This function will place a new row directly after a row which is currently 2376 * on display on the page, with the HTML contents that is passed into the 2377 * function. This can be used, for example, to ask for confirmation that a 2378 * particular record should be deleted. 2379 * @param {node} nTr The table row to 'open' 2380 * @param {string|node|jQuery} mHtml The HTML to put into the row 2381 * @param {string} sClass Class to give the new TD cell 2382 * @returns {node} The row opened. Note that if the table row passed in as the 2383 * first parameter, is not found in the table, this method will silently 2384 * return. 2385 * @dtopt API 2386 * @deprecated Since v1.10 2387 * 2388 * @example 2389 * $(document).ready(function() { 2390 * var oTable; 2391 * 2392 * // 'open' an information row when a row is clicked on 2393 * $('#example tbody tr').click( function () { 2394 * if ( oTable.fnIsOpen(this) ) { 2395 * oTable.fnClose( this ); 2396 * } else { 2397 * oTable.fnOpen( this, "Temporary row opened", "info_row" ); 2398 * } 2399 * } ); 2400 * 2401 * oTable = $('#example').dataTable(); 2402 * } ); 2403 */ 2404 this.fnOpen = function( nTr, mHtml, sClass ) 2405 { 2406 return this.api( true ) 2407 .row( nTr ) 2408 .child( mHtml, sClass ) 2409 .show() 2410 .child()[0]; 2411 }; 2412 2413 2414 /** 2415 * Change the pagination - provides the internal logic for pagination in a simple API 2416 * function. With this function you can have a DataTables table go to the next, 2417 * previous, first or last pages. 2418 * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" 2419 * or page number to jump to (integer), note that page 0 is the first page. 2420 * @param {bool} [bRedraw=true] Redraw the table or not 2421 * @dtopt API 2422 * @deprecated Since v1.10 2423 * 2424 * @example 2425 * $(document).ready(function() { 2426 * var oTable = $('#example').dataTable(); 2427 * oTable.fnPageChange( 'next' ); 2428 * } ); 2429 */ 2430 this.fnPageChange = function ( mAction, bRedraw ) 2431 { 2432 var api = this.api( true ).page( mAction ); 2433 2434 if ( bRedraw === undefined || bRedraw ) { 2435 api.draw(false); 2436 } 2437 }; 2438 2439 2440 /** 2441 * Show a particular column 2442 * @param {int} iCol The column whose display should be changed 2443 * @param {bool} bShow Show (true) or hide (false) the column 2444 * @param {bool} [bRedraw=true] Redraw the table or not 2445 * @dtopt API 2446 * @deprecated Since v1.10 2447 * 2448 * @example 2449 * $(document).ready(function() { 2450 * var oTable = $('#example').dataTable(); 2451 * 2452 * // Hide the second column after initialisation 2453 * oTable.fnSetColumnVis( 1, false ); 2454 * } ); 2455 */ 2456 this.fnSetColumnVis = function ( iCol, bShow, bRedraw ) 2457 { 2458 var api = this.api( true ).column( iCol ).visible( bShow ); 2459 2460 if ( bRedraw === undefined || bRedraw ) { 2461 api.columns.adjust().draw(); 2462 } 2463 }; 2464 2465 2466 /** 2467 * Get the settings for a particular table for external manipulation 2468 * @returns {object} DataTables settings object. See 2469 * {@link DataTable.models.oSettings} 2470 * @dtopt API 2471 * @deprecated Since v1.10 2472 * 2473 * @example 2474 * $(document).ready(function() { 2475 * var oTable = $('#example').dataTable(); 2476 * var oSettings = oTable.fnSettings(); 2477 * 2478 * // Show an example parameter from the settings 2479 * alert( oSettings._iDisplayStart ); 2480 * } ); 2481 */ 2482 this.fnSettings = function() 2483 {
2484 return _fnSettingsFromNode( this[_ext.iApiIndex] ); 2485 }; 2486 2487 2488 /** 2489 * Sort the table by a particular column 2490 * @param {int} iCol the data index to sort on. Note that this will not match the 2491 * 'display index' if you have hidden data entries 2492 * @dtopt API 2493 * @deprecated Since v1.10 2494 * 2495 * @example 2496 * $(document).ready(function() { 2497 * var oTable = $('#example').dataTable(); 2498 * 2499 * // Sort immediately with columns 0 and 1 2500 * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] ); 2501 * } ); 2502 */ 2503 this.fnSort = function( aaSort ) 2504 { 2505 this.api( true ).order( aaSort ).draw(); 2506 }; 2507 2508 2509 /** 2510 * Attach a sort listener to an element for a given column 2511 * @param {node} nNode the element to attach the sort listener to 2512 * @param {int} iColumn the column that a click on this node will sort on 2513 * @param {function} [fnCallback] callback function when sort is run 2514 * @dtopt API 2515 * @deprecated Since v1.10 2516 * 2517 * @example 2518 * $(document).ready(function() { 2519 * var oTable = $('#example').dataTable(); 2520 * 2521 * // Sort on column 1, when 'sorter' is clicked on 2522 * oTable.fnSortListener( document.getElementById('sorter'), 1 ); 2523 * } ); 2524 */ 2525 this.fnSortListener = function( nNode, iColumn, fnCallback ) 2526 { 2527 this.api( true ).order.listener( nNode, iColumn, fnCallback ); 2528 }; 2529 2530 2531 /** 2532 * Update a table cell or row - this method will accept either a single value to 2533 * update the cell with, an array of values with one element for each column or 2534 * an object in the same format as the original data source. The function is 2535 * self-referencing in order to make the multi column updates easier. 2536 * @param {object|array|string} mData Data to update the cell/row with 2537 * @param {node|int} mRow TR element you want to update or the aoData index 2538 * @param {int} [iColumn] The column to update, give as null or undefined to 2539 * update a whole row. 2540 * @param {bool} [bRedraw=true] Redraw the table or not 2541 * @param {bool} [bAction=true] Perform pre-draw actions or not 2542 * @returns {int} 0 on success, 1 on error 2543 * @dtopt API 2544 * @deprecated Since v1.10 2545 * 2546 * @example 2547 * $(document).ready(function() { 2548 * var oTable = $('#example').dataTable(); 2549 * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell 2550 * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row 2551 * } ); 2552 */ 2553 this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction ) 2554 { 2555 var api = this.api( true ); 2556 2557 if ( iColumn === undefined || iColumn === null ) { 2558 api.row( mRow ).data( mData ); 2559 } 2560 else { 2561 api.cell( mRow, iColumn ).data( mData ); 2562 } 2563 2564 if ( bAction === undefined || bAction ) { 2565 api.columns.adjust(); 2566 } 2567 2568 if ( bRedraw === undefined || bRedraw ) { 2569 api.draw(); 2570 } 2571 return 0; 2572 }; 2573 2574 2575 /** 2576 * Provide a common method for plug-ins to check the version of DataTables being used, in order 2577 * to ensure compatibility. 2578 * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the 2579 * formats "X" and "X.Y" are also acceptable. 2580 * @returns {boolean} true if this version of DataTables is greater or equal to the required 2581 * version, or false if this version of DataTales is not suitable 2582 * @method 2583 * @dtopt API 2584 * @deprecated Since v1.10 2585 * 2586 * @example 2587 * $(document).ready(function() { 2588 * var oTable = $('#example').dataTable(); 2589 * alert( oTable.fnVersionCheck( '1.9.0' ) ); 2590 * } ); 2591 */ 2592 this.fnVersionCheck = _ext.fnVersionCheck; 2593 2594 2595 var _that = this; 2596 var emptyInit = options === undefined; 2597 var len = this.length; 2598 2599 if ( emptyInit ) { 2600 options = {}; 2601 } 2602 2603 this.oApi = this.internal = _ext.internal; 2604 2605 // Extend with old style plug-in API methods 2606 for ( var fn in DataTable.ext.internal ) { 2607 if ( fn ) { 2608 this[fn] = _fnExternApiFunc(fn); 2609 } 2610 } 2611 2612 this.each(function() { 2613 // For each initialisation we want to give it a clean initialisation 2614 // object that can be bashed around 2615 var o = {}; 2616 var oInit = len > 1 ? // optimisation for single table case 2617 _fnExtend( o, options, true ) : 2618 options; 2619 2620 /*global oInit,_that,emptyInit*/ 2621 var i=0, iLen, j, jLen, k, kLen; 2622 var sId = this.getAttribute( 'id' ); 2623 var bInitHandedOff = false;
2624 var defaults = DataTable.defaults; 2625 var $this = $(this); 2626 2627 2628 /* Sanity check */ 2629 if ( this.nodeName.toLowerCase() != 'table' ) 2630 { 2631 _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); 2632 return; 2633 } 2634 2635 /* Backwards compatibility for the defaults */ 2636 _fnCompatOpts( defaults ); 2637 _fnCompatCols( defaults.column ); 2638 2639 /* Convert the camel-case defaults to Hungarian */ 2640 _fnCamelToHungarian( defaults, defaults, true ); 2641 _fnCamelToHungarian( defaults.column, defaults.column, true ); 2642 2643 /* Setting up the initialisation object */ 2644 _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) ); 2645 2646 2647 2648 /* Check to see if we are re-initialising a table */ 2649 var allSettings = DataTable.settings; 2650 for ( i=0, iLen=allSettings.length ; i<iLen ; i++ ) 2651 { 2652 var s = allSettings[i]; 2653 2654 /* Base check on table node */ 2655 if ( 2656 s.nTable == this || 2657 (s.nTHead && s.nTHead.parentNode == this) || 2658 (s.nTFoot && s.nTFoot.parentNode == this) 2659 ) { 2660 var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve; 2661 var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy; 2662 2663 if ( emptyInit || bRetrieve ) 2664 { 2665 return s.oInstance; 2666 } 2667 else if ( bDestroy ) 2668 { 2669 s.oInstance.fnDestroy(); 2670 break; 2671 } 2672 else 2673 { 2674 _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 ); 2675 return; 2676 } 2677 } 2678 2679 /* If the element we are initialising has the same ID as a table which was previously 2680 * initialised, but the table nodes don't match (from before) then we destroy the old 2681 * instance by simply deleting it. This is under the assumption that the table has been 2682 * destroyed by other methods. Anyone using non-id selectors will need to do this manually 2683 */ 2684 if ( s.sTableId == this.id ) 2685 { 2686 allSettings.splice( i, 1 ); 2687 break; 2688 } 2689 } 2690 2691 /* Ensure the table has an ID - required for accessibility */ 2692 if ( sId === null || sId === "" ) 2693 { 2694 sId = "DataTables_Table_"+(DataTable.ext._unique++); 2695 this.id = sId; 2696 } 2697 2698 /* Create the settings object for this table and set some of the default parameters */ 2699 var oSettings = $.extend( true, {}, DataTable.models.oSettings, { 2700 "sDestroyWidth": $this[0].style.width, 2701 "sInstance": sId, 2702 "sTableId": sId 2703 } ); 2704 oSettings.nTable = this; 2705 oSettings.oApi = _that.internal; 2706 oSettings.oInit = oInit; 2707 2708 allSettings.push( oSettings ); 2709 2710 // Need to add the instance after the instance after the settings object has been added 2711 // to the settings array, so we can self reference the table instance if more than one 2712 oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable(); 2713 2714 // Backwards compatibility, before we apply all the defaults 2715 _fnCompatOpts( oInit ); 2716 _fnLanguageCompat( oInit.oLanguage ); 2717 2718 // If the length menu is given, but the init display length is not, use the length menu 2719 if ( oInit.aLengthMenu && ! oInit.iDisplayLength ) 2720 { 2721 oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ? 2722 oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0]; 2723 } 2724 2725 // Apply the defaults and init options to make a single init object will all 2726 // options defined from defaults and instance options. 2727 oInit = _fnExtend( $.extend( true, {}, defaults ), oInit ); 2728 2729 2730 // Map the initialisation options onto the settings object 2731 _fnMap( oSettings.oFeatures, oInit, [ 2732 "bPaginate", 2733 "bLengthChange", 2734 "bFilter", 2735 "bSort", 2736 "bSortMulti", 2737 "bInfo", 2738 "bProcessing", 2739 "bAutoWidth", 2740 "bSortClasses", 2741 "bServerSide", 2742 "bDeferRender" 2743 ] ); 2744 _fnMap( oSettings, oInit, [ 2745 "asStripeClasses", 2746 "ajax", 2747 "fnServerData", 2748 "fnFormatNumber", 2749 "sServerMethod", 2750 "aaSorting", 2751 "aaSortingFixed", 2752 "aLengthMenu", 2753 "sPaginationType", 2754 "sAjaxSource", 2755 "sAjaxDataProp", 2756 "iStateDuration", 2757 "sDom", 2758 "bSortCellsTop", 2759 "iTabIndex", 2760 "fnStateLoadCallback", 2761 "fnStateSaveCallback", 2762 "renderer", 2763 "searchDelay", 2764 "rowId", 2765 [ "iCookieDuration", "iStateDuration" ], // backwards compat 2766 [ "oSearch", "oPreviousSearch" ], 2767 [ "aoSearchCols", "aoPreSearchCols" ], 2768 [ "iDisplayLength", "_iDisplayLength" ] 2769 ] ); 2770 _fnMap( oSettings.oScroll, oInit, [ 2771 [ "sScrollX", "sX" ], 2772 [ "sScrollXInner", "sXInner" ], 2773 [ "sScrollY", "sY" ],
2774 [ "bScrollCollapse", "bCollapse" ] 2775 ] ); 2776 _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); 2777 2778 /* Callback functions which are array driven */ 2779 _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' ); 2780 _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' ); 2781 _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' ); 2782 _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' ); 2783 _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' ); 2784 _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' ); 2785 _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' ); 2786 _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' ); 2787 _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' ); 2788 _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' ); 2789 _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' ); 2790 2791 oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId ); 2792 2793 /* Browser support detection */ 2794 _fnBrowserDetect( oSettings ); 2795 2796 var oClasses = oSettings.oClasses; 2797 2798 $.extend( oClasses, DataTable.ext.classes, oInit.oClasses ); 2799 $this.addClass( oClasses.sTable ); 2800 2801 2802 if ( oSettings.iInitDisplayStart === undefined ) 2803 { 2804 /* Display start point, taking into account the save saving */ 2805 oSettings.iInitDisplayStart = oInit.iDisplayStart; 2806 oSettings._iDisplayStart = oInit.iDisplayStart; 2807 } 2808 2809 if ( oInit.iDeferLoading !== null ) 2810 { 2811 oSettings.bDeferLoading = true; 2812 var tmp = $.isArray( oInit.iDeferLoading ); 2813 oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading; 2814 oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading; 2815 } 2816 2817 /* Language definitions */ 2818 var oLanguage = oSettings.oLanguage; 2819 $.extend( true, oLanguage, oInit.oLanguage ); 2820 2821 if ( oLanguage.sUrl ) 2822 { 2823 /* Get the language definitions from a file - because this Ajax call makes the language 2824 * get async to the remainder of this function we use bInitHandedOff to indicate that 2825 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor 2826 */ 2827 $.ajax( { 2828 dataType: 'json', 2829 url: oLanguage.sUrl, 2830 success: function ( json ) { 2831 _fnLanguageCompat( json ); 2832 _fnCamelToHungarian( defaults.oLanguage, json ); 2833 $.extend( true, oLanguage, json ); 2834 _fnInitialise( oSettings ); 2835 }, 2836 error: function () { 2837 // Error occurred loading language file, continue on as best we can 2838 _fnInitialise( oSettings ); 2839 } 2840 } ); 2841 bInitHandedOff = true; 2842 } 2843 2844 /* 2845 * Stripes 2846 */ 2847 if ( oInit.asStripeClasses === null ) 2848 { 2849 oSettings.asStripeClasses =[ 2850 oClasses.sStripeOdd, 2851 oClasses.sStripeEven 2852 ]; 2853 } 2854 2855 /* Remove row stripe classes if they are already on the table row */ 2856 var stripeClasses = oSettings.asStripeClasses; 2857 var rowOne = $this.children('tbody').find('tr').eq(0); 2858 if ( $.inArray( true, $.map( stripeClasses, function(el, i) { 2859 return rowOne.hasClass(el); 2860 } ) ) !== -1 ) { 2861 $('tbody tr', this).removeClass( stripeClasses.join(' ') ); 2862 oSettings.asDestroyStripes = stripeClasses.slice(); 2863 } 2864 2865 /* 2866 * Columns 2867 * See if we should load columns automatically or use defined ones 2868 */ 2869 var anThs = []; 2870 var aoColumnsInit; 2871 var nThead = this.getElementsByTagName('thead'); 2872 if ( nThead.length !== 0 ) 2873 { 2874 _fnDetectHeader( oSettings.aoHeader, nThead[0] ); 2875 anThs = _fnGetUniqueThs( oSettings ); 2876 } 2877 2878 /* If not given a column array, generate one with nulls */ 2879 if ( oInit.aoColumns === null ) 2880 { 2881 aoColumnsInit = []; 2882 for ( i=0, iLen=anThs.length ; i<iLen ; i++ ) 2883 { 2884 aoColumnsInit.push( null ); 2885 } 2886 } 2887 else 2888 { 2889 aoColumnsInit = oInit.aoColumns; 2890 } 2891 2892 /* Add the columns */ 2893 for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ ) 2894 { 2895 _fnAddColumn( oSettings, anThs ? anThs[i] : null ); 2896 } 2897 2898 /* Apply the column definitions */ 2899 _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) { 2900 _fnColumnOptions( oSettings, iCol, oDef ); 2901 } ); 2902 2903 /* HTML5 attribute detection - build an mData object automatically if the 2904 * attributes are found 2905 */ 2906 if ( rowOne.length ) { 2907 var a = function ( cell, name ) { 2908 return cell.getAttribute( 'data-'+name ) !== null ? name : null; 2909 }; 2910 2911 $( rowOne[0] ).children('th, td').each( function (i, cell) { 2912 var col = oSettings.aoColumns[i]; 2913 2914 if ( col.mData === i ) { 2915 var sort = a( cell, 'sort' ) || a( cell, 'order' ); 2916 var filter = a( cell, 'filter' ) || a( cell, 'search' ); 2917 2918 if ( sort !== null || filter !== null ) { 2919 col.mData = { 2920 _: i+'.display', 2921 sort: sort !== null ? i+'.@data-'+sort : undefined, 2922 type: sort !== null ? i+'.@data-'+sort : undefined, 2923 filter: filter !== null ? i+'.@data-'+filter : undefined 2924 }; 2925 2926 _fnColumnOptions( oSettings, i ); 2927 } 2928 } 2929 } ); 2930 } 2931 2932 var features = oSettings.oFeatures; 2933 var loadedInit = function () { 2934 /* 2935 * Sorting 2936 * @todo For modularisation (1.11) this needs to do into a sort start up handler 2937 */ 2938 2939 // If aaSorting is not defined, then we use the first indicator in asSorting 2940 // in case that has been altered, so the default sort reflects that option 2941 if ( oInit.aaSorting === undefined ) { 2942 var sorting = oSettings.aaSorting; 2943 for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) { 2944 sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0]; 2945 } 2946 } 2947 2948 /* Do a first pass on the sorting classes (allows any size changes to be taken into 2949 * account, and also will apply sorting disabled classes if disabled 2950 */ 2951 _fnSortingClasses( oSettings ); 2952 2953 if ( features.bSort ) { 2954 _fnCallbackReg( oSettings, 'aoDrawCallback', function () { 2955 if ( oSettings.bSorted ) { 2956 var aSort = _fnSortFlatten( oSettings ); 2957 var sortedColumns = {}; 2958 2959 $.each( aSort, function (i, val) { 2960 sortedColumns[ val.src ] = val.dir; 2961 } ); 2962 2963 _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] ); 2964 _fnSortAria( oSettings ); 2965 } 2966 } ); 2967 } 2968 2969 _fnCallbackReg( oSettings, 'aoDrawCallback', function () { 2970 if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) { 2971 _fnSortingClasses( oSettings ); 2972 } 2973 }, 'sc' ); 2974 2975 2976 /* 2977 * Final init 2978 * Cache the header, body and footer as required, creating them if needed 2979 */ 2980 2981 // Work around for Webkit bug 83867 - store the caption-side before removing from doc 2982 var captions = $this.children('caption').each( function () { 2983 this._captionSide = $(this).css('caption-side'); 2984 } ); 2985 2986 var thead = $this.children('thead'); 2987 if ( thead.length === 0 ) { 2988 thead = $('<thead/>').appendTo($this); 2989 } 2990 oSettings.nTHead = thead[0]; 2991 2992 var tbody = $this.children('tbody'); 2993 if ( tbody.length === 0 ) { 2994 tbody = $('<tbody/>').appendTo($this); 2995 } 2996 oSettings.nTBody = tbody[0]; 2997 2998 var tfoot = $this.children('tfoot'); 2999 if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) { 3000 // If we are a scrolling table, and no footer has been given, then we need to create 3001 // a tfoot element for the caption element to be appended to 3002 tfoot = $('<tfoot/>').appendTo($this); 3003 } 3004 3005 if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
3006 $this.addClass( oClasses.sNoFooter ); 3007 } 3008 else if ( tfoot.length > 0 ) { 3009 oSettings.nTFoot = tfoot[0]; 3010 _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot ); 3011 } 3012 3013 /* Check if there is data passing into the constructor */ 3014 if ( oInit.aaData ) { 3015 for ( i=0 ; i<oInit.aaData.length ; i++ ) { 3016 _fnAddData( oSettings, oInit.aaData[ i ] ); 3017 } 3018 } 3019 else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) { 3020 /* Grab the data from the page - only do this when deferred loading or no Ajax 3021 * source since there is no point in reading the DOM data if we are then going 3022 * to replace it with Ajax data 3023 */ 3024 _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') ); 3025 } 3026 3027 /* Copy the data index array */ 3028 oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); 3029 3030 /* Initialisation complete - table can be drawn */ 3031 oSettings.bInitialised = true; 3032 3033 /* Check if we need to initialise the table (it might not have been handed off to the 3034 * language processor) 3035 */ 3036 if ( bInitHandedOff === false ) { 3037 _fnInitialise( oSettings ); 3038 } 3039 }; 3040 3041 /* Must be done after everything which can be overridden by the state saving! */ 3042 if ( oInit.bStateSave ) 3043 { 3044 features.bStateSave = true; 3045 _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' ); 3046 _fnLoadState( oSettings, oInit, loadedInit ); 3047 } 3048 else { 3049 loadedInit(); 3050 } 3051 3052 } ); 3053 _that = null; 3054 return this; 3055 }; 3056 3057 3058 /*
3059 * It is useful to have variables which are scoped locally so only the 3060 * DataTables functions can access them and they don't leak into global space. 3061 * At the same time these functions are often useful over multiple files in the 3062 * core and API, so we list, or at least document, all variables which are used 3063 * by DataTables as private variables here. This also ensures that there is no 3064 * clashing of variable names and that they can easily referenced for reuse. 3065 */ 3066 3067 3068 // Defined else where 3069 // _selector_run 3070 // _selector_opts 3071 // _selector_first 3072 // _selector_row_indexes 3073 3074 var _ext; // DataTable.ext 3075 var _Api; // DataTable.Api 3076 var _api_register; // DataTable.Api.register 3077 var _api_registerPlural; // DataTable.Api.registerPlural 3078 3079 var _re_dic = {}; 3080 var _re_new_lines = /[\r\n]/g; 3081 var _re_html = /<.*?>/g; 3082 3083 // This is not strict ISO8601 - Date.parse() is quite lax, although 3084 // implementations differ between browsers. 3085 var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/; 3086 3087 // Escape regular expression special characters 3088 var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); 3089 3090 // http://en.wikipedia.org/wiki/Foreign_exchange_market 3091 // - \u20BD - Russian ruble. 3092 // - \u20a9 - South Korean Won 3093 // - \u20BA - Turkish Lira 3094 // - \u20B9 - Indian Rupee 3095 // - R - Brazil (R$) and South Africa 3096 // - fr - Swiss Franc 3097 // - kr - Swedish krona, Norwegian krone and Danish krone 3098 // - \u2009 is thin space and \u202F is narrow no-break space, both used in many 3099 // - Ƀ - Bitcoin 3100 // - Ξ - Ethereum 3101 // standards as thousands separators. 3102 var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi; 3103 3104 3105 var _empty = function ( d ) { 3106 return !d || d === true || d === '-' ? true : false; 3107 }; 3108 3109 3110 var _intVal = function ( s ) { 3111 var integer = parseInt( s, 10 ); 3112 return !isNaN(integer) && isFinite(s) ? integer : null; 3113 }; 3114 3115 // Convert from a formatted number with characters other than `.` as the 3116 // decimal place, to a Javascript number 3117 var _numToDecimal = function ( num, decimalPoint ) { 3118 // Cache created regular expressions for speed as this function is called often 3119 if ( ! _re_dic[ decimalPoint ] ) { 3120 _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' ); 3121 } 3122 return typeof num === 'string' && decimalPoint !== '.' ? 3123 num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) : 3124 num; 3125 }; 3126 3127 3128 var _isNumber = function ( d, decimalPoint, formatted ) { 3129 var strType = typeof d === 'string'; 3130 3131 // If empty return immediately so there must be a number if it is a 3132 // formatted string (this stops the string "k", or "kr", etc being detected 3133 // as a formatted number for currency 3134 if ( _empty( d ) ) { 3135 return true; 3136 } 3137 3138 if ( decimalPoint && strType ) { 3139 d = _numToDecimal( d, decimalPoint ); 3140 } 3141 3142 if ( formatted && strType ) { 3143 d = d.replace( _re_formatted_numeric, '' ); 3144 } 3145 3146 return !isNaN( parseFloat(d) ) && isFinite( d ); 3147 }; 3148 3149 3150 // A string without HTML in it can be considered to be HTML still 3151 var _isHtml = function ( d ) { 3152 return _empty( d ) || typeof d === 'string'; 3153 }; 3154 3155 3156 var _htmlNumeric = function ( d, decimalPoint, formatted ) { 3157 if ( _empty( d ) ) { 3158 return true; 3159 } 3160 3161 var html = _isHtml( d ); 3162 return ! html ? 3163 null : 3164 _isNumber( _stripHtml( d ), decimalPoint, formatted ) ? 3165 true : 3166 null; 3167 }; 3168 3169 3170 var _pluck = function ( a, prop, prop2 ) { 3171 var out = []; 3172 var i=0, ien=a.length; 3173 3174 // Could have the test in the loop for slightly smaller code, but speed 3175 // is essential here 3176 if ( prop2 !== undefined ) { 3177 for ( ; i<ien ; i++ ) { 3178 if ( a[i] && a[i][ prop ] ) { 3179 out.push( a[i][ prop ][ prop2 ] ); 3180 } 3181 } 3182 } 3183 else { 3184 for ( ; i<ien ; i++ ) { 3185 if ( a[i] ) { 3186 out.push( a[i][ prop ] ); 3187 } 3188 } 3189 } 3190 3191 return out; 3192 }; 3193 3194 3195 // Basically the same as _pluck, but rather than looping over `a` we use `order` 3196 // as the indexes to pick from `a` 3197 var _pluck_order = function ( a, order, prop, prop2 ) 3198 { 3199 var out = []; 3200 var i=0, ien=order.length; 3201 3202 // Could have the test in the loop for slightly smaller code, but speed 3203 // is essential here 3204 if ( prop2 !== undefined ) { 3205 for ( ; i<ien ; i++ ) { 3206 if ( a[ order[i] ][ prop ] ) { 3207 out.push( a[ order[i] ][ prop ][ prop2 ] ); 3208 } 3209 } 3210 } 3211 else { 3212 for ( ; i<ien ; i++ ) { 3213 out.push( a[ order[i] ][ prop ] ); 3214 } 3215 } 3216 3217 return out; 3218 }; 3219 3220 3221 var _range = function ( len, start ) 3222 { 3223 var out = []; 3224 var end; 3225 3226 if ( start === undefined ) { 3227 start = 0; 3228 end = len; 3229 } 3230 else { 3231 end = start; 3232 start = len; 3233 } 3234 3235 for ( var i=start ; i<end ; i++ ) { 3236 out.push( i ); 3237 } 3238 3239 return out; 3240 }; 3241 3242 3243 var _removeEmpty = function ( a ) 3244 { 3245 var out = []; 3246 3247 for ( var i=0, ien=a.length ; i<ien ; i++ ) { 3248 if ( a[i] ) { // careful - will remove all falsy values! 3249 out.push( a[i] ); 3250 } 3251 } 3252 3253 return out; 3254 }; 3255 3256 3257 var _stripHtml = function ( d ) { 3258 return d.replace( _re_html, '' ); 3259 }; 3260 3261 3262 /** 3263 * Determine if all values in the array are unique. This means we can short 3264 * cut the _unique method at the cost of a single loop. A sorted array is used 3265 * to easily check the values. 3266 * 3267 * @param {array} src Source array 3268 * @return {boolean} true if all unique, false otherwise 3269 * @ignore 3270 */ 3271 var _areAllUnique = function ( src ) { 3272 if ( src.length < 2 ) { 3273 return true; 3274 } 3275 3276 var sorted = src.slice().sort(); 3277 var last = sorted[0]; 3278 3279 for ( var i=1, ien=sorted.length ; i<ien ; i++ ) { 3280 if ( sorted[i] === last ) { 3281 return false;
3282 } 3283 3284 last = sorted[i]; 3285 } 3286 3287 return true; 3288 }; 3289 3290 3291 /** 3292 * Find the unique elements in a source array. 3293 * 3294 * @param {array} src Source array 3295 * @return {array} Array of unique items 3296 * @ignore 3297 */ 3298 var _unique = function ( src ) 3299 { 3300 if ( _areAllUnique( src ) ) { 3301 return src.slice(); 3302 } 3303 3304 // A faster unique method is to use object keys to identify used values, 3305 // but this doesn't work with arrays or objects, which we must also 3306 // consider. See jsperf.com/compare-array-unique-versions/4 for more 3307 // information. 3308 var 3309 out = [], 3310 val, 3311 i, ien=src.length, 3312 j, k=0; 3313 3314 again: for ( i=0 ; i<ien ; i++ ) { 3315 val = src[i]; 3316 3317 for ( j=0 ; j<k ; j++ ) { 3318 if ( out[j] === val ) { 3319 continue again; 3320 } 3321 } 3322 3323 out.push( val ); 3324 k++; 3325 } 3326 3327 return out; 3328 }; 3329 3330 3331 /** 3332 * DataTables utility methods 3333 * 3334 * This namespace provides helper methods that DataTables uses internally to 3335 * create a DataTable, but which are not exclusively used only for DataTables. 3336 * These methods can be used by extension authors to save the duplication of 3337 * code. 3338 * 3339 * @namespace 3340 */ 3341 DataTable.util = { 3342 /** 3343 * Throttle the calls to a function. Arguments and context are maintained 3344 * for the throttled function. 3345 * 3346 * @param {function} fn Function to be called 3347 * @param {integer} freq Call frequency in mS 3348 * @return {function} Wrapped function 3349 */ 3350 throttle: function ( fn, freq ) { 3351 var 3352 frequency = freq !== undefined ? freq : 200, 3353 last, 3354 timer; 3355 3356 return function () { 3357 var 3358 that = this, 3359 now = +new Date(), 3360 args = arguments; 3361 3362 if ( last && now < last + frequency ) { 3363 clearTimeout( timer ); 3364 3365 timer = setTimeout( function () { 3366 last = undefined; 3367 fn.apply( that, args ); 3368 }, frequency ); 3369 } 3370 else { 3371 last = now; 3372 fn.apply( that, args ); 3373 } 3374 }; 3375 }, 3376 3377 3378 /** 3379 * Escape a string such that it can be used in a regular expression 3380 * 3381 * @param {string} val string to escape 3382 * @returns {string} escaped string 3383 */ 3384 escapeRegex: function ( val ) { 3385 return val.replace( _re_escape_regex, '\\$1' ); 3386 } 3387 }; 3388 3389 3390 3391 /** 3392 * Create a mapping object that allows camel case parameters to be looked up 3393 * for their Hungarian counterparts. The mapping is stored in a private 3394 * parameter called `_hungarianMap` which can be accessed on the source object. 3395 * @param {object} o 3396 * @memberof DataTable#oApi 3397 */ 3398 function _fnHungarianMap ( o ) 3399 { 3400 var 3401 hungarian = 'a aa ai ao as b fn i m o s ', 3402 match, 3403 newKey, 3404 map = {}; 3405 3406 $.each( o, function (key, val) { 3407 match = key.match(/^([^A-Z]+?)([A-Z])/); 3408 3409 if ( match && hungarian.indexOf(match[1]+' ') !== -1 ) 3410 { 3411 newKey = key.replace( match[0], match[2].toLowerCase() ); 3412 map[ newKey ] = key; 3413 3414 if ( match[1] === 'o' ) 3415 { 3416 _fnHungarianMap( o[key] ); 3417 } 3418 } 3419 } ); 3420 3421 o._hungarianMap = map; 3422 } 3423 3424 3425 /** 3426 * Convert from camel case parameters to Hungarian, based on a Hungarian map 3427 * created by _fnHungarianMap. 3428 * @param {object} src The model object which holds all parameters that can be 3429 * mapped. 3430 * @param {object} user The object to convert from camel case to Hungarian. 3431 * @param {boolean} force When set to `true`, properties which already have a 3432 * Hungarian value in the `user` object will be overwritten. Otherwise they 3433 * won't be. 3434 * @memberof DataTable#oApi 3435 */ 3436 function _fnCamelToHungarian ( src, user, force ) 3437 { 3438 if ( ! src._hungarianMap ) { 3439 _fnHungarianMap( src ); 3440 } 3441 3442 var hungarianKey; 3443 3444 $.each( user, function (key, val) { 3445 hungarianKey = src._hungarianMap[ key ]; 3446 3447 if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) ) 3448 { 3449 // For objects, we need to buzz down into the object to copy parameters 3450 if ( hungarianKey.charAt(0) === 'o' ) 3451 { 3452 // Copy the camelCase options over to the hungarian 3453 if ( ! user[ hungarianKey ] ) { 3454 user[ hungarianKey ] = {}; 3455 } 3456 $.extend( true, user[hungarianKey], user[key] ); 3457 3458 _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force ); 3459 } 3460 else { 3461 user[hungarianKey] = user[ key ]; 3462 } 3463 } 3464 } ); 3465 } 3466 3467 3468 /** 3469 * Language compatibility - when certain options are given, and others aren't, we 3470 * need to duplicate the values over, in order to provide backwards compatibility 3471 * with older language files. 3472 * @param {object} oSettings dataTables settings object 3473 * @memberof DataTable#oApi 3474 */ 3475 function _fnLanguageCompat( lang ) 3476 { 3477 // Note the use of the Hungarian notation for the parameters in this method as 3478 // this is called after the mapping of camelCase to Hungarian 3479 var defaults = DataTable.defaults.oLanguage; 3480 3481 // Default mapping 3482 var defaultDecimal = defaults.sDecimal; 3483 if ( defaultDecimal ) { 3484 _addNumericSort( defaultDecimal ); 3485 } 3486 3487 if ( lang ) { 3488 var zeroRecords = lang.sZeroRecords; 3489 3490 // Backwards compatibility - if there is no sEmptyTable given, then use the same as 3491 // sZeroRecords - assuming that is given. 3492 if ( ! lang.sEmptyTable && zeroRecords && 3493 defaults.sEmptyTable === "No data available in table" ) 3494 { 3495 _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' ); 3496 } 3497 3498 // Likewise with loading records 3499 if ( ! lang.sLoadingRecords && zeroRecords && 3500 defaults.sLoadingRecords === "Loading..." ) 3501 { 3502 _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' ); 3503 } 3504 3505 // Old parameter name of the thousands separator mapped onto the new 3506 if ( lang.sInfoThousands ) { 3507 lang.sThousands = lang.sInfoThousands; 3508 } 3509 3510 var decimal = lang.sDecimal; 3511 if ( decimal && defaultDecimal !== decimal ) { 3512 _addNumericSort( decimal ); 3513 } 3514 } 3515 } 3516 3517 3518 /** 3519 * Map one parameter onto another 3520 * @param {object} o Object to map 3521 * @param {*} knew The new parameter name 3522 * @param {*} old The old parameter name 3523 */ 3524 var _fnCompatMap = function ( o, knew, old ) { 3525 if ( o[ knew ] !== undefined ) { 3526 o[ old ] = o[ knew ]; 3527 } 3528 }; 3529 3530 3531 /** 3532 * Provide backwards compatibility for the main DT options. Note that the new 3533 * options are mapped onto the old parameters, so this is an external interface 3534 * change only. 3535 * @param {object} init Object to map 3536 */ 3537 function _fnCompatOpts ( init ) 3538 { 3539 _fnCompatMap( init, 'ordering', 'bSort' ); 3540 _fnCompatMap( init, 'orderMulti', 'bSortMulti' ); 3541 _fnCompatMap( init, 'orderClasses', 'bSortClasses' ); 3542 _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' ); 3543 _fnCompatMap( init, 'order', 'aaSorting' ); 3544 _fnCompatMap( init, 'orderFixed', 'aaSortingFixed' ); 3545 _fnCompatMap( init, 'paging', 'bPaginate' ); 3546 _fnCompatMap( init, 'pagingType', 'sPaginationType' ); 3547 _fnCompatMap( init, 'pageLength', 'iDisplayLength' ); 3548 _fnCompatMap( init, 'searching', 'bFilter' ); 3549 3550 // Boolean initialisation of x-scrolling 3551 if ( typeof init.sScrollX === 'boolean' ) { 3552 init.sScrollX = init.sScrollX ? '100%' : ''; 3553 } 3554 if ( typeof init.scrollX === 'boolean' ) { 3555 init.scrollX = init.scrollX ? '100%' : ''; 3556 } 3557 3558 // Column search objects are in an array, so it needs to be converted 3559 // element by element 3560 var searchCols = init.aoSearchCols; 3561 3562 if ( searchCols ) { 3563 for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) { 3564 if ( searchCols[i] ) { 3565 _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] ); 3566 } 3567 } 3568 } 3569 } 3570 3571 3572 /** 3573 * Provide backwards compatibility for column options. Note that the new options 3574 * are mapped onto the old parameters, so this is an external interface change 3575 * only. 3576 * @param {object} init Object to map 3577 */ 3578 function _fnCompatCols ( init ) 3579 { 3580 _fnCompatMap( init, 'orderable', 'bSortable' ); 3581 _fnCompatMap( init, 'orderData', 'aDataSort' ); 3582 _fnCompatMap( init, 'orderSequence', 'asSorting' ); 3583 _fnCompatMap( init, 'orderDataType', 'sortDataType' ); 3584 3585 // orderData can be given as an integer 3586 var dataSort = init.aDataSort; 3587 if ( typeof dataSort === 'number' && ! $.isArray( dataSort ) ) { 3588 init.aDataSort = [ dataSort ]; 3589 } 3590 } 3591 3592 3593 /** 3594 * Browser feature detection for capabilities, quirks 3595 * @param {object} settings dataTables settings object 3596 * @memberof DataTable#oApi 3597 */ 3598 function _fnBrowserDetect( settings ) 3599 { 3600 // We don't need to do this every time DataTables is constructed, the values 3601 // calculated are specific to the browser and OS configuration which we 3602 // don't expect to change between initialisations 3603 if ( ! DataTable.__browser ) { 3604 var browser = {}; 3605 DataTable.__browser = browser; 3606 3607 // Scrolling feature / quirks detection 3608 var n = $('<div/>') 3609 .css( { 3610 position: 'fixed', 3611 top: 0, 3612 left: $(window).scrollLeft()*-1, // allow for scrolling 3613 height: 1, 3614 width: 1, 3615 overflow: 'hidden' 3616 } ) 3617 .append( 3618 $('<div/>') 3619 .css( { 3620 position: 'absolute', 3621 top: 1, 3622 left: 1, 3623 width: 100, 3624 overflow: 'scroll' 3625 } ) 3626 .append( 3627 $('<div/>') 3628 .css( { 3629 width: '100%', 3630 height: 10 3631 } ) 3632 ) 3633 ) 3634 .appendTo( 'body' ); 3635 3636 var outer = n.children(); 3637 var inner = outer.children(); 3638 3639 // Numbers below, in order, are: 3640 // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth 3641 // 3642 // IE6 XP: 100 100 100 83 3643 // IE7 Vista: 100 100 100 83 3644 // IE 8+ Windows: 83 83 100 83 3645 // Evergreen Windows: 83 83 100 83 3646 // Evergreen Mac with scrollbars: 85 85 100 85 3647 // Evergreen Mac without scrollbars: 100 100 100 100 3648 3649 // Get scrollbar width 3650 browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth; 3651 3652 // IE6/7 will oversize a width 100% element inside a scrolling element, to 3653 // include the width of the scrollbar, while other browsers ensure the inner 3654 // element is contained without forcing scrolling 3655 browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100; 3656 3657 // In rtl text layout, some browsers (most, but not all) will place the 3658 // scrollbar on the left, rather than the right. 3659 browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1; 3660 3661 // IE8- don't provide height and width for getBoundingClientRect 3662 browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
3663 3664 n.remove(); 3665 } 3666 3667 $.extend( settings.oBrowser, DataTable.__browser ); 3668 settings.oScroll.iBarWidth = DataTable.__browser.barWidth; 3669 } 3670 3671 3672 /** 3673 * Array.prototype reduce[Right] method, used for browsers which don't support 3674 * JS 1.6. Done this way to reduce code size, since we iterate either way 3675 * @param {object} settings dataTables settings object 3676 * @memberof DataTable#oApi 3677 */ 3678 function _fnReduce ( that, fn, init, start, end, inc ) 3679 { 3680 var 3681 i = start, 3682 value, 3683 isSet = false; 3684 3685 if ( init !== undefined ) { 3686 value = init; 3687 isSet = true; 3688 } 3689 3690 while ( i !== end ) { 3691 if ( ! that.hasOwnProperty(i) ) { 3692 continue; 3693 } 3694 3695 value = isSet ? 3696 fn( value, that[i], i, that ) : 3697 that[i]; 3698 3699 isSet = true; 3700 i += inc; 3701 } 3702 3703 return value; 3704 } 3705 3706 /** 3707 * Add a column to the list used for the table with default values 3708 * @param {object} oSettings dataTables settings object 3709 * @param {node} nTh The th element for this column 3710 * @memberof DataTable#oApi 3711 */ 3712 function _fnAddColumn( oSettings, nTh ) 3713 { 3714 // Add column to aoColumns array 3715 var oDefaults = DataTable.defaults.column; 3716 var iCol = oSettings.aoColumns.length; 3717 var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { 3718 "nTh": nTh ? nTh : document.createElement('th'), 3719 "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', 3720 "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], 3721 "mData": oDefaults.mData ? oDefaults.mData : iCol, 3722 idx: iCol 3723 } ); 3724 oSettings.aoColumns.push( oCol ); 3725 3726 // Add search object for column specific search. Note that the `searchCols[ iCol ]` 3727 // passed into extend can be undefined. This allows the user to give a default 3728 // with only some of the parameters defined, and also not give a default 3729 var searchCols = oSettings.aoPreSearchCols; 3730 searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] ); 3731 3732 // Use the default column options function to initialise classes etc 3733 _fnColumnOptions( oSettings, iCol, $(nTh).data() ); 3734 } 3735 3736 3737 /** 3738 * Apply options for a column 3739 * @param {object} oSettings dataTables settings object 3740 * @param {int} iCol column index to consider 3741 * @param {object} oOptions object with sType, bVisible and bSearchable etc 3742 * @memberof DataTable#oApi 3743 */ 3744 function _fnColumnOptions( oSettings, iCol, oOptions ) 3745 { 3746 var oCol = oSettings.aoColumns[ iCol ]; 3747 var oClasses = oSettings.oClasses; 3748 var th = $(oCol.nTh); 3749 3750 // Try to get width information from the DOM. We can't get it from CSS 3751 // as we'd need to parse the CSS stylesheet. `width` option can override 3752 if ( ! oCol.sWidthOrig ) { 3753 // Width attribute 3754 oCol.sWidthOrig = th.attr('width') || null; 3755 3756 // Style attribute 3757 var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/); 3758 if ( t ) { 3759 oCol.sWidthOrig = t[1]; 3760 } 3761 } 3762 3763 /* User specified column options */ 3764 if ( oOptions !== undefined && oOptions !== null ) 3765 { 3766 // Backwards compatibility 3767 _fnCompatCols( oOptions ); 3768 3769 // Map camel case parameters to their Hungarian counterparts 3770 _fnCamelToHungarian( DataTable.defaults.column, oOptions ); 3771 3772 /* Backwards compatibility for mDataProp */ 3773 if ( oOptions.mDataProp !== undefined && !oOptions.mData ) 3774 { 3775 oOptions.mData = oOptions.mDataProp; 3776 } 3777 3778 if ( oOptions.sType ) 3779 { 3780 oCol._sManualType = oOptions.sType; 3781 } 3782 3783 // `class` is a reserved word in Javascript, so we need to provide 3784 // the ability to use a valid name for the camel case input 3785 if ( oOptions.className && ! oOptions.sClass ) 3786 { 3787 oOptions.sClass = oOptions.className; 3788 } 3789 if ( oOptions.sClass ) { 3790 th.addClass( oOptions.sClass ); 3791 } 3792 3793 $.extend( oCol, oOptions ); 3794 _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); 3795 3796 /* iDataSort to be applied (backwards compatibility), but aDataSort will take 3797 * priority if defined 3798 */ 3799 if ( oOptions.iDataSort !== undefined ) 3800 { 3801 oCol.aDataSort = [ oOptions.iDataSort ]; 3802 } 3803 _fnMap( oCol, oOptions, "aDataSort" ); 3804 } 3805 3806 /* Cache the data get and set functions for speed */ 3807 var mDataSrc = oCol.mData; 3808 var mData = _fnGetObjectDataFn( mDataSrc ); 3809 var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; 3810 3811 var attrTest = function( src ) { 3812 return typeof src === 'string' && src.indexOf('@') !== -1; 3813 }; 3814 oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && ( 3815 attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter) 3816 ); 3817 oCol._setter = null; 3818 3819 oCol.fnGetData = function (rowData, type, meta) { 3820 var innerData = mData( rowData, type, undefined, meta ); 3821
3822 return mRender && type ? 3823 mRender( innerData, type, rowData, meta ) : 3824 innerData; 3825 }; 3826 oCol.fnSetData = function ( rowData, val, meta ) { 3827 return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta ); 3828 }; 3829 3830 // Indicate if DataTables should read DOM data as an object or array 3831 // Used in _fnGetRowElements 3832 if ( typeof mDataSrc !== 'number' ) { 3833 oSettings._rowReadObject = true; 3834 } 3835 3836 /* Feature sorting overrides column specific when off */ 3837 if ( !oSettings.oFeatures.bSort ) 3838 { 3839 oCol.bSortable = false; 3840 th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called 3841 } 3842 3843 /* Check that the class assignment is correct for sorting */ 3844 var bAsc = $.inArray('asc', oCol.asSorting) !== -1; 3845 var bDesc = $.inArray('desc', oCol.asSorting) !== -1; 3846 if ( !oCol.bSortable || (!bAsc && !bDesc) ) 3847 { 3848 oCol.sSortingClass = oClasses.sSortableNone; 3849 oCol.sSortingClassJUI = ""; 3850 } 3851 else if ( bAsc && !bDesc ) 3852 { 3853 oCol.sSortingClass = oClasses.sSortableAsc; 3854 oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed; 3855 } 3856 else if ( !bAsc && bDesc ) 3857 { 3858 oCol.sSortingClass = oClasses.sSortableDesc; 3859 oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed; 3860 } 3861 else 3862 { 3863 oCol.sSortingClass = oClasses.sSortable; 3864 oCol.sSortingClassJUI = oClasses.sSortJUI; 3865 } 3866 } 3867 3868 3869 /** 3870 * Adjust the table column widths for new data. Note: you would probably want to 3871 * do a redraw after calling this function! 3872 * @param {object} settings dataTables settings object 3873 * @memberof DataTable#oApi 3874 */ 3875 function _fnAdjustColumnSizing ( settings ) 3876 { 3877 /* Not interested in doing column width calculation if auto-width is disabled */ 3878 if ( settings.oFeatures.bAutoWidth !== false ) 3879 { 3880 var columns = settings.aoColumns; 3881 3882 _fnCalculateColumnWidths( settings ); 3883 for ( var i=0 , iLen=columns.length ; i<iLen ; i++ ) 3884 { 3885 columns[i].nTh.style.width = columns[i].sWidth; 3886 } 3887 } 3888 3889 var scroll = settings.oScroll; 3890 if ( scroll.sY !== '' || scroll.sX !== '') 3891 { 3892 _fnScrollDraw( settings ); 3893 } 3894 3895 _fnCallbackFire( settings, null, 'column-sizing', [settings] ); 3896 } 3897 3898 3899 /** 3900 * Covert the index of a visible column to the index in the data array (take account 3901 * of hidden columns) 3902 * @param {object} oSettings dataTables settings object 3903 * @param {int} iMatch Visible column index to lookup 3904 * @returns {int} i the data index 3905 * @memberof DataTable#oApi 3906 */ 3907 function _fnVisibleToColumnIndex( oSettings, iMatch ) 3908 { 3909 var aiVis = _fnGetColumns( oSettings, 'bVisible' ); 3910 3911 return typeof aiVis[iMatch] === 'number' ? 3912 aiVis[iMatch] : 3913 null; 3914 } 3915 3916 3917 /** 3918 * Covert the index of an index in the data array and convert it to the visible 3919 * column index (take account of hidden columns) 3920 * @param {int} iMatch Column index to lookup 3921 * @param {object} oSettings dataTables settings object 3922 * @returns {int} i the data index 3923 * @memberof DataTable#oApi 3924 */ 3925 function _fnColumnIndexToVisible( oSettings, iMatch ) 3926 { 3927 var aiVis = _fnGetColumns( oSettings, 'bVisible' ); 3928 var iPos = $.inArray( iMatch, aiVis ); 3929 3930 return iPos !== -1 ? iPos : null; 3931 } 3932 3933 3934 /** 3935 * Get the number of visible columns 3936 * @param {object} oSettings dataTables settings object 3937 * @returns {int} i the number of visible columns 3938 * @memberof DataTable#oApi 3939 */ 3940 function _fnVisbleColumns( oSettings ) 3941 { 3942 var vis = 0; 3943 3944 // No reduce in IE8, use a loop for now 3945 $.each( oSettings.aoColumns, function ( i, col ) { 3946 if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) { 3947 vis++; 3948 } 3949 } ); 3950 3951 return vis; 3952 } 3953 3954 3955 /** 3956 * Get an array of column indexes that match a given property 3957 * @param {object} oSettings dataTables settings object 3958 * @param {string} sParam Parameter in aoColumns to look for - typically 3959 * bVisible or bSearchable 3960 * @returns {array} Array of indexes with matched properties 3961 * @memberof DataTable#oApi 3962 */ 3963 function _fnGetColumns( oSettings, sParam ) 3964 { 3965 var a = []; 3966 3967 $.map( oSettings.aoColumns, function(val, i) { 3968 if ( val[sParam] ) { 3969 a.push( i ); 3970 } 3971 } ); 3972 3973 return a; 3974 } 3975 3976 3977 /** 3978 * Calculate the 'type' of a column 3979 * @param {object} settings dataTables settings object 3980 * @memberof DataTable#oApi 3981 */ 3982 function _fnColumnTypes ( settings ) 3983 { 3984 var columns = settings.aoColumns; 3985 var data = settings.aoData; 3986 var types = DataTable.ext.type.detect; 3987 var i, ien, j, jen, k, ken; 3988 var col, cell, detectedType, cache; 3989 3990 // For each column, spin over the 3991 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 3992 col = columns[i]; 3993 cache = []; 3994 3995 if ( ! col.sType && col._sManualType ) {
3996 col.sType = col._sManualType; 3997 } 3998 else if ( ! col.sType ) { 3999 for ( j=0, jen=types.length ; j<jen ; j++ ) { 4000 for ( k=0, ken=data.length ; k<ken ; k++ ) { 4001 // Use a cache array so we only need to get the type data 4002 // from the formatter once (when using multiple detectors) 4003 if ( cache[k] === undefined ) { 4004 cache[k] = _fnGetCellData( settings, k, i, 'type' ); 4005 } 4006 4007 detectedType = types[j]( cache[k], settings ); 4008 4009 // If null, then this type can't apply to this column, so 4010 // rather than testing all cells, break out. There is an 4011 // exception for the last type which is `html`. We need to 4012 // scan all rows since it is possible to mix string and HTML 4013 // types 4014 if ( ! detectedType && j !== types.length-1 ) { 4015 break; 4016 } 4017 4018 // Only a single match is needed for html type since it is 4019 // bottom of the pile and very similar to string 4020 if ( detectedType === 'html' ) { 4021 break; 4022 } 4023 } 4024 4025 // Type is valid for all data points in the column - use this 4026 // type 4027 if ( detectedType ) { 4028 col.sType = detectedType; 4029 break; 4030 } 4031 } 4032 4033 // Fall back - if no type was detected, always use string 4034 if ( ! col.sType ) { 4035 col.sType = 'string'; 4036 } 4037 } 4038 } 4039 } 4040 4041 4042 /** 4043 * Take the column definitions and static columns arrays and calculate how 4044 * they relate to column indexes. The callback function will then apply the 4045 * definition found for a column to a suitable configuration object. 4046 * @param {object} oSettings dataTables settings object 4047 * @param {array} aoColDefs The aoColumnDefs array that is to be applied 4048 * @param {array} aoCols The aoColumns array that defines columns individually 4049 * @param {function} fn Callback function - takes two parameters, the calculated 4050 * column index and the definition for that column. 4051 * @memberof DataTable#oApi 4052 */ 4053 function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn ) 4054 { 4055 var i, iLen, j, jLen, k, kLen, def; 4056 var columns = oSettings.aoColumns; 4057 4058 // Column definitions with aTargets 4059 if ( aoColDefs ) 4060 { 4061 /* Loop over the definitions array - loop in reverse so first instance has priority */ 4062 for ( i=aoColDefs.length-1 ; i>=0 ; i-- ) 4063 { 4064 def = aoColDefs[i]; 4065 4066 /* Each definition can target multiple columns, as it is an array */ 4067 var aTargets = def.targets !== undefined ? 4068 def.targets : 4069 def.aTargets; 4070 4071 if ( ! $.isArray( aTargets ) ) 4072 { 4073 aTargets = [ aTargets ]; 4074 } 4075 4076 for ( j=0, jLen=aTargets.length ; j<jLen ; j++ ) 4077 { 4078 if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 ) 4079 { 4080 /* Add columns that we don't yet know about */ 4081 while( columns.length <= aTargets[j] ) 4082 { 4083 _fnAddColumn( oSettings ); 4084 } 4085 4086 /* Integer, basic index */ 4087 fn( aTargets[j], def ); 4088 } 4089 else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 ) 4090 { 4091 /* Negative integer, right to left column counting */ 4092 fn( columns.length+aTargets[j], def ); 4093 } 4094 else if ( typeof aTargets[j] === 'string' ) 4095 { 4096 /* Class name matching on TH element */ 4097 for ( k=0, kLen=columns.length ; k<kLen ; k++ ) 4098 { 4099 if ( aTargets[j] == "_all" || 4100 $(columns[k].nTh).hasClass( aTargets[j] ) ) 4101 { 4102 fn( k, def ); 4103 } 4104 } 4105 } 4106 } 4107 } 4108 } 4109 4110 // Statically defined columns array 4111 if ( aoCols ) 4112 { 4113 for ( i=0, iLen=aoCols.length ; i<iLen ; i++ ) 4114 { 4115 fn( i, aoCols[i] ); 4116 } 4117 } 4118 } 4119 4120 /** 4121 * Add a data array to the table, creating DOM node etc. This is the parallel to 4122 * _fnGatherData, but for adding rows from a Javascript source, rather than a 4123 * DOM source. 4124 * @param {object} oSettings dataTables settings object 4125 * @param {array} aData data array to be added 4126 * @param {node} [nTr] TR element to add to the table - optional. If not given, 4127 * DataTables will create a row automatically 4128 * @param {array} [anTds] Array of TD|TH elements for the row - must be given 4129 * if nTr is. 4130 * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed 4131 * @memberof DataTable#oApi 4132 */ 4133 function _fnAddData ( oSettings, aDataIn, nTr, anTds ) 4134 { 4135 /* Create the object for storing information about this new row */ 4136 var iRow = oSettings.aoData.length; 4137 var oData = $.extend( true, {}, DataTable.models.oRow, { 4138 src: nTr ? 'dom' : 'data', 4139 idx: iRow 4140 } ); 4141 4142 oData._aData = aDataIn; 4143 oSettings.aoData.push( oData ); 4144 4145 /* Create the cells */ 4146 var nTd, sThisType; 4147 var columns = oSettings.aoColumns; 4148 4149 // Invalidate the column types as the new data needs to be revalidated 4150 for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) 4151 {
4152 columns[i].sType = null; 4153 } 4154 4155 /* Add to the display array */ 4156 oSettings.aiDisplayMaster.push( iRow ); 4157 4158 var id = oSettings.rowIdFn( aDataIn ); 4159 if ( id !== undefined ) { 4160 oSettings.aIds[ id ] = oData; 4161 } 4162 4163 /* Create the DOM information, or register it if already present */ 4164 if ( nTr || ! oSettings.oFeatures.bDeferRender ) 4165 { 4166 _fnCreateTr( oSettings, iRow, nTr, anTds ); 4167 } 4168 4169 return iRow; 4170 } 4171 4172 4173 /** 4174 * Add one or more TR elements to the table. Generally we'd expect to 4175 * use this for reading data from a DOM sourced table, but it could be 4176 * used for an TR element. Note that if a TR is given, it is used (i.e. 4177 * it is not cloned). 4178 * @param {object} settings dataTables settings object 4179 * @param {array|node|jQuery} trs The TR element(s) to add to the table 4180 * @returns {array} Array of indexes for the added rows 4181 * @memberof DataTable#oApi 4182 */ 4183 function _fnAddTr( settings, trs ) 4184 { 4185 var row; 4186 4187 // Allow an individual node to be passed in 4188 if ( ! (trs instanceof $) ) { 4189 trs = $(trs); 4190 } 4191 4192 return trs.map( function (i, el) { 4193 row = _fnGetRowElements( settings, el ); 4194 return _fnAddData( settings, row.data, el, row.cells ); 4195 } ); 4196 } 4197 4198 4199 /** 4200 * Take a TR element and convert it to an index in aoData 4201 * @param {object} oSettings dataTables settings object 4202 * @param {node} n the TR element to find 4203 * @returns {int} index if the node is found, null if not 4204 * @memberof DataTable#oApi 4205 */ 4206 function _fnNodeToDataIndex( oSettings, n ) 4207 { 4208 return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null; 4209 } 4210 4211 4212 /** 4213 * Take a TD element and convert it into a column data index (not the visible index) 4214 * @param {object} oSettings dataTables settings object 4215 * @param {int} iRow The row number the TD/TH can be found in 4216 * @param {node} n The TD/TH element to find 4217 * @returns {int} index if the node is found, -1 if not 4218 * @memberof DataTable#oApi 4219 */ 4220 function _fnNodeToColumnIndex( oSettings, iRow, n ) 4221 { 4222 return $.inArray( n, oSettings.aoData[ iRow ].anCells ); 4223 } 4224 4225 4226 /** 4227 * Get the data for a given cell from the internal cache, taking into account data mapping 4228 * @param {object} settings dataTables settings object 4229 * @param {int} rowIdx aoData row id 4230 * @param {int} colIdx Column index 4231 * @param {string} type data get type ('display', 'type' 'filter' 'sort') 4232 * @returns {*} Cell data 4233 * @memberof DataTable#oApi 4234 */ 4235 function _fnGetCellData( settings, rowIdx, colIdx, type ) 4236 { 4237 var draw = settings.iDraw; 4238 var col = settings.aoColumns[colIdx]; 4239 var rowData = settings.aoData[rowIdx]._aData; 4240 var defaultContent = col.sDefaultContent; 4241 var cellData = col.fnGetData( rowData, type, { 4242 settings: settings, 4243 row: rowIdx, 4244 col: colIdx 4245 } ); 4246 4247 if ( cellData === undefined ) { 4248 if ( settings.iDrawError != draw && defaultContent === null ) { 4249 _fnLog( settings, 0, "Requested unknown parameter "+ 4250 (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+ 4251 " for row "+rowIdx+", column "+colIdx, 4 ); 4252 settings.iDrawError = draw; 4253 } 4254 return defaultContent; 4255 } 4256 4257 // When the data source is null and a specific data type is requested (i.e. 4258 // not the original data), we can use default column data 4259 if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) { 4260 cellData = defaultContent; 4261 } 4262 else if ( typeof cellData === 'function' ) { 4263 // If the data source is a function, then we run it and use the return, 4264 // executing in the scope of the data object (for instances) 4265 return cellData.call( rowData ); 4266 } 4267 4268 if ( cellData === null && type == 'display' ) { 4269 return ''; 4270 } 4271 return cellData; 4272 } 4273 4274 4275 /** 4276 * Set the value for a specific cell, into the internal data cache 4277 * @param {object} settings dataTables settings object 4278 * @param {int} rowIdx aoData row id 4279 * @param {int} colIdx Column index 4280 * @param {*} val Value to set 4281 * @memberof DataTable#oApi 4282 */ 4283 function _fnSetCellData( settings, rowIdx, colIdx, val ) 4284 { 4285 var col = settings.aoColumns[colIdx]; 4286 var rowData = settings.aoData[rowIdx]._aData; 4287 4288 col.fnSetData( rowData, val, { 4289 settings: settings, 4290 row: rowIdx, 4291 col: colIdx 4292 } ); 4293 } 4294 4295 4296 // Private variable that is used to match action syntax in the data property object 4297 var __reArray = /\[.*?\]$/; 4298 var __reFn = /\(\)$/; 4299 4300 /** 4301 * Split string on periods, taking into account escaped periods 4302 * @param {string} str String to split 4303 * @return {array} Split string 4304 */ 4305 function _fnSplitObjNotation( str ) 4306 { 4307 return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) { 4308 return s.replace(/\\\./g, '.'); 4309 } ); 4310 } 4311 4312 4313 /** 4314 * Return a function that can be used to get data from a source object, taking 4315 * into account the ability to use nested objects as a source 4316 * @param {string|int|function} mSource The data source for the object 4317 * @returns {function} Data get function 4318 * @memberof DataTable#oApi 4319 */ 4320 function _fnGetObjectDataFn( mSource ) 4321 { 4322 if ( $.isPlainObject( mSource ) ) 4323 { 4324 /* Build an object of get functions, and wrap them in a single call */ 4325 var o = {}; 4326 $.each( mSource, function (key, val) { 4327 if ( val ) { 4328 o[key] = _fnGetObjectDataFn( val ); 4329 } 4330 } ); 4331 4332 return function (data, type, row, meta) { 4333 var t = o[type] || o._; 4334 return t !== undefined ? 4335 t(data, type, row, meta) : 4336 data; 4337 }; 4338 } 4339 else if ( mSource === null ) 4340 { 4341 /* Give an empty string for rendering / sorting etc */ 4342 return function (data) { // type, row and meta also passed, but not used 4343 return data; 4344 }; 4345 } 4346 else if ( typeof mSource === 'function' ) 4347 { 4348 return function (data, type, row, meta) { 4349 return mSource( data, type, row, meta ); 4350 }; 4351 } 4352 else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || 4353 mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) ) 4354 { 4355 /* If there is a . in the source string then the data source is in a 4356 * nested object so we loop over the data for each level to get the next 4357 * level down. On each loop we test for undefined, and if found immediately 4358 * return. This allows entire objects to be missing and sDefaultContent to 4359 * be used if defined, rather than throwing an error 4360 */
4361 var fetchData = function (data, type, src) { 4362 var arrayNotation, funcNotation, out, innerSrc; 4363 4364 if ( src !== "" ) 4365 { 4366 var a = _fnSplitObjNotation( src ); 4367 4368 for ( var i=0, iLen=a.length ; i<iLen ; i++ ) 4369 { 4370 // Check if we are dealing with special notation 4371 arrayNotation = a[i].match(__reArray); 4372 funcNotation = a[i].match(__reFn); 4373 4374 if ( arrayNotation ) 4375 { 4376 // Array notation 4377 a[i] = a[i].replace(__reArray, ''); 4378 4379 // Condition allows simply [] to be passed in 4380 if ( a[i] !== "" ) { 4381 data = data[ a[i] ]; 4382 } 4383 out = []; 4384 4385 // Get the remainder of the nested object to get 4386 a.splice( 0, i+1 ); 4387 innerSrc = a.join('.'); 4388 4389 // Traverse each entry in the array getting the properties requested 4390 if ( $.isArray( data ) ) { 4391 for ( var j=0, jLen=data.length ; j<jLen ; j++ ) { 4392 out.push( fetchData( data[j], type, innerSrc ) ); 4393 } 4394 } 4395 4396 // If a string is given in between the array notation indicators, that 4397 // is used to join the strings together, otherwise an array is returned 4398 var join = arrayNotation[0].substring(1, arrayNotation[0].length-1); 4399 data = (join==="") ? out : out.join(join); 4400 4401 // The inner call to fetchData has already traversed through the remainder 4402 // of the source requested, so we exit from the loop 4403 break; 4404 } 4405 else if ( funcNotation ) 4406 { 4407 // Function call 4408 a[i] = a[i].replace(__reFn, ''); 4409 data = data[ a[i] ](); 4410 continue; 4411 } 4412 4413 if ( data === null || data[ a[i] ] === undefined ) 4414 { 4415 return undefined; 4416 } 4417 data = data[ a[i] ]; 4418 } 4419 } 4420 4421 return data; 4422 }; 4423 4424 return function (data, type) { // row and meta also passed, but not used 4425 return fetchData( data, type, mSource ); 4426 }; 4427 } 4428 else 4429 { 4430 /* Array or flat object mapping */ 4431 return function (data, type) { // row and meta also passed, but not used 4432 return data[mSource]; 4433 }; 4434 } 4435 } 4436 4437 4438 /** 4439 * Return a function that can be used to set data from a source object, taking 4440 * into account the ability to use nested objects as a source 4441 * @param {string|int|function} mSource The data source for the object 4442 * @returns {function} Data set function 4443 * @memberof DataTable#oApi 4444 */ 4445 function _fnSetObjectDataFn( mSource ) 4446 { 4447 if ( $.isPlainObject( mSource ) ) 4448 { 4449 /* Unlike get, only the underscore (global) option is used for for 4450 * setting data since we don't know the type here. This is why an object 4451 * option is not documented for `mData` (which is read/write), but it is 4452 * for `mRender` which is read only. 4453 */ 4454 return _fnSetObjectDataFn( mSource._ ); 4455 } 4456 else if ( mSource === null ) 4457 { 4458 /* Nothing to do when the data source is null */ 4459 return function () {}; 4460 } 4461 else if ( typeof mSource === 'function' ) 4462 { 4463 return function (data, val, meta) { 4464 mSource( data, 'set', val, meta ); 4465 }; 4466 } 4467 else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || 4468 mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) ) 4469 { 4470 /* Like the get, we need to get data from a nested object */ 4471 var setData = function (data, val, src) { 4472 var a = _fnSplitObjNotation( src ), b; 4473 var aLast = a[a.length-1]; 4474 var arrayNotation, funcNotation, o, innerSrc; 4475 4476 for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ ) 4477 { 4478 // Check if we are dealing with an array notation request 4479 arrayNotation = a[i].match(__reArray); 4480 funcNotation = a[i].match(__reFn); 4481 4482 if ( arrayNotation ) 4483 { 4484 a[i] = a[i].replace(__reArray, ''); 4485 data[ a[i] ] = []; 4486 4487 // Get the remainder of the nested object to set so we can recurse 4488 b = a.slice(); 4489 b.splice( 0, i+1 ); 4490 innerSrc = b.join('.'); 4491 4492 // Traverse each entry in the array setting the properties requested 4493 if ( $.isArray( val ) ) 4494 { 4495 for ( var j=0, jLen=val.length ; j<jLen ; j++ ) 4496 { 4497 o = {}; 4498 setData( o, val[j], innerSrc ); 4499 data[ a[i] ].push( o ); 4500 } 4501 } 4502 else 4503 { 4504 // We've been asked to save data to an array, but it 4505 // isn't array data to be saved. Best that can be done 4506 // is to just save the value. 4507 data[ a[i] ] = val; 4508 } 4509 4510 // The inner call to setData has already traversed through the remainder 4511 // of the source and has set the data, thus we can exit here 4512 return; 4513 } 4514 else if ( funcNotation ) 4515 { 4516 // Function call 4517 a[i] = a[i].replace(__reFn, ''); 4518 data = data[ a[i] ]( val ); 4519 } 4520 4521 // If the nested object doesn't currently exist - since we are 4522 // trying to set the value - create it 4523 if ( data[ a[i] ] === null || data[ a[i] ] === undefined ) 4524 { 4525 data[ a[i] ] = {}; 4526 } 4527 data = data[ a[i] ]; 4528 } 4529 4530 // Last item in the input - i.e, the actual set 4531 if ( aLast.match(__reFn ) ) 4532 { 4533 // Function call 4534 data = data[ aLast.replace(__reFn, '') ]( val ); 4535 } 4536 else 4537 { 4538 // If array notation is used, we just want to strip it and use the property name 4539 // and assign the value. If it isn't used, then we get the result we want anyway 4540 data[ aLast.replace(__reArray, '') ] = val; 4541 } 4542 }; 4543 4544 return function (data, val) { // meta is also passed in, but not used 4545 return setData( data, val, mSource ); 4546 }; 4547 } 4548 else 4549 { 4550 /* Array or flat object mapping */ 4551 return function (data, val) { // meta is also passed in, but not used 4552 data[mSource] = val; 4553 }; 4554 } 4555 } 4556 4557 4558 /** 4559 * Return an array with the full table data 4560 * @param {object} oSettings dataTables settings object 4561 * @returns array {array} aData Master data array 4562 * @memberof DataTable#oApi 4563 */ 4564 function _fnGetDataMaster ( settings ) 4565 { 4566 return _pluck( settings.aoData, '_aData' ); 4567 } 4568 4569 4570 /** 4571 * Nuke the table 4572 * @param {object} oSettings dataTables settings object 4573 * @memberof DataTable#oApi 4574 */ 4575 function _fnClearTable( settings ) 4576 { 4577 settings.aoData.length = 0; 4578 settings.aiDisplayMaster.length = 0; 4579 settings.aiDisplay.length = 0; 4580 settings.aIds = {}; 4581 } 4582 4583 4584 /** 4585 * Take an array of integers (index array) and remove a target integer (value - not 4586 * the key!) 4587 * @param {array} a Index array to target 4588 * @param {int} iTarget value to find 4589 * @memberof DataTable#oApi 4590 */ 4591 function _fnDeleteIndex( a, iTarget, splice ) 4592 { 4593 var iTargetIndex = -1; 4594 4595 for ( var i=0, iLen=a.length ; i<iLen ; i++ ) 4596 { 4597 if ( a[i] == iTarget ) 4598 { 4599 iTargetIndex = i; 4600 } 4601 else if ( a[i] > iTarget ) 4602 { 4603 a[i]--; 4604 } 4605 } 4606 4607 if ( iTargetIndex != -1 && splice === undefined ) 4608 { 4609 a.splice( iTargetIndex, 1 ); 4610 } 4611 } 4612 4613 4614 /**
4615 * Mark cached data as invalid such that a re-read of the data will occur when 4616 * the cached data is next requested. Also update from the data source object. 4617 * 4618 * @param {object} settings DataTables settings object 4619 * @param {int} rowIdx Row index to invalidate 4620 * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom' 4621 * or 'data' 4622 * @param {int} [colIdx] Column index to invalidate. If undefined the whole 4623 * row will be invalidated 4624 * @memberof DataTable#oApi 4625 * 4626 * @todo For the modularisation of v1.11 this will need to become a callback, so 4627 * the sort and filter methods can subscribe to it. That will required 4628 * initialisation options for sorting, which is why it is not already baked in 4629 */ 4630 function _fnInvalidate( settings, rowIdx, src, colIdx ) 4631 { 4632 var row = settings.aoData[ rowIdx ]; 4633 var i, ien; 4634 var cellWrite = function ( cell, col ) { 4635 // This is very frustrating, but in IE if you just write directly 4636 // to innerHTML, and elements that are overwritten are GC'ed, 4637 // even if there is a reference to them elsewhere 4638 while ( cell.childNodes.length ) { 4639 cell.removeChild( cell.firstChild ); 4640 } 4641 4642 cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' ); 4643 }; 4644 4645 // Are we reading last data from DOM or the data object? 4646 if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) { 4647 // Read the data from the DOM 4648 row._aData = _fnGetRowElements( 4649 settings, row, colIdx, colIdx === undefined ? undefined : row._aData 4650 ) 4651 .data; 4652 } 4653 else { 4654 // Reading from data object, update the DOM 4655 var cells = row.anCells; 4656 4657 if ( cells ) { 4658 if ( colIdx !== undefined ) { 4659 cellWrite( cells[colIdx], colIdx ); 4660 } 4661 else { 4662 for ( i=0, ien=cells.length ; i<ien ; i++ ) { 4663 cellWrite( cells[i], i ); 4664 } 4665 } 4666 } 4667 } 4668 4669 // For both row and cell invalidation, the cached data for sorting and 4670 // filtering is nulled out 4671 row._aSortData = null; 4672 row._aFilterData = null; 4673 4674 // Invalidate the type for a specific column (if given) or all columns since 4675 // the data might have changed 4676 var cols = settings.aoColumns; 4677 if ( colIdx !== undefined ) { 4678 cols[ colIdx ].sType = null; 4679 } 4680 else { 4681 for ( i=0, ien=cols.length ; i<ien ; i++ ) { 4682 cols[i].sType = null; 4683 } 4684 4685 // Update DataTables special `DT_*` attributes for the row 4686 _fnRowAttributes( settings, row ); 4687 } 4688 } 4689 4690 4691 /** 4692 * Build a data source object from an HTML row, reading the contents of the 4693 * cells that are in the row. 4694 * 4695 * @param {object} settings DataTables settings object 4696 * @param {node|object} TR element from which to read data or existing row 4697 * object from which to re-read the data from the cells 4698 * @param {int} [colIdx] Optional column index 4699 * @param {array|object} [d] Data source object. If `colIdx` is given then this 4700 * parameter should also be given and will be used to write the data into. 4701 * Only the column in question will be written 4702 * @returns {object} Object with two parameters: `data` the data read, in 4703 * document order, and `cells` and array of nodes (they can be useful to the 4704 * caller, so rather than needing a second traversal to get them, just return 4705 * them from here). 4706 * @memberof DataTable#oApi 4707 */ 4708 function _fnGetRowElements( settings, row, colIdx, d ) 4709 { 4710 var 4711 tds = [], 4712 td = row.firstChild, 4713 name, col, o, i=0, contents, 4714 columns = settings.aoColumns, 4715 objectRead = settings._rowReadObject; 4716 4717 // Allow the data object to be passed in, or construct 4718 d = d !== undefined ? 4719 d : 4720 objectRead ? 4721 {} : 4722 []; 4723 4724 var attr = function ( str, td ) { 4725 if ( typeof str === 'string' ) { 4726 var idx = str.indexOf('@'); 4727 4728 if ( idx !== -1 ) { 4729 var attr = str.substring( idx+1 ); 4730 var setter = _fnSetObjectDataFn( str ); 4731 setter( d, td.getAttribute( attr ) ); 4732 } 4733 } 4734 }; 4735 4736 // Read data from a cell and store into the data object 4737 var cellProcess = function ( cell ) { 4738 if ( colIdx === undefined || colIdx === i ) { 4739 col = columns[i]; 4740 contents = $.trim(cell.innerHTML); 4741 4742 if ( col && col._bAttrSrc ) { 4743 var setter = _fnSetObjectDataFn( col.mData._ ); 4744 setter( d, contents ); 4745 4746 attr( col.mData.sort, cell ); 4747 attr( col.mData.type, cell ); 4748 attr( col.mData.filter, cell ); 4749 } 4750 else { 4751 // Depending on the `data` option for the columns the data can 4752 // be read to either an object or an array.
4753 if ( objectRead ) { 4754 if ( ! col._setter ) { 4755 // Cache the setter function 4756 col._setter = _fnSetObjectDataFn( col.mData ); 4757 } 4758 col._setter( d, contents ); 4759 } 4760 else { 4761 d[i] = contents; 4762 } 4763 } 4764 } 4765 4766 i++; 4767 }; 4768 4769 if ( td ) { 4770 // `tr` element was passed in 4771 while ( td ) { 4772 name = td.nodeName.toUpperCase(); 4773 4774 if ( name == "TD" || name == "TH" ) { 4775 cellProcess( td ); 4776 tds.push( td ); 4777 } 4778 4779 td = td.nextSibling; 4780 } 4781 } 4782 else { 4783 // Existing row object passed in 4784 tds = row.anCells; 4785 4786 for ( var j=0, jen=tds.length ; j<jen ; j++ ) { 4787 cellProcess( tds[j] ); 4788 } 4789 } 4790 4791 // Read the ID from the DOM if present 4792 var rowNode = row.firstChild ? row : row.nTr; 4793 4794 if ( rowNode ) { 4795 var id = rowNode.getAttribute( 'id' ); 4796 4797 if ( id ) { 4798 _fnSetObjectDataFn( settings.rowId )( d, id ); 4799 } 4800 } 4801 4802 return { 4803 data: d, 4804 cells: tds 4805 }; 4806 } 4807 /** 4808 * Create a new TR element (and it's TD children) for a row 4809 * @param {object} oSettings dataTables settings object 4810 * @param {int} iRow Row to consider 4811 * @param {node} [nTrIn] TR element to add to the table - optional. If not given, 4812 * DataTables will create a row automatically 4813 * @param {array} [anTds] Array of TD|TH elements for the row - must be given 4814 * if nTr is. 4815 * @memberof DataTable#oApi 4816 */ 4817 function _fnCreateTr ( oSettings, iRow, nTrIn, anTds ) 4818 { 4819 var 4820 row = oSettings.aoData[iRow], 4821 rowData = row._aData, 4822 cells = [], 4823 nTr, nTd, oCol, 4824 i, iLen; 4825 4826 if ( row.nTr === null ) 4827 { 4828 nTr = nTrIn || document.createElement('tr'); 4829 4830 row.nTr = nTr; 4831 row.anCells = cells; 4832 4833 /* Use a private property on the node to allow reserve mapping from the node 4834 * to the aoData array for fast look up 4835 */ 4836 nTr._DT_RowIndex = iRow; 4837 4838 /* Special parameters can be given by the data source to be used on the row */ 4839 _fnRowAttributes( oSettings, row ); 4840 4841 /* Process each column */ 4842 for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) 4843 { 4844 oCol = oSettings.aoColumns[i]; 4845 4846 nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType ); 4847 nTd._DT_CellIndex = { 4848 row: iRow, 4849 column: i 4850 }; 4851 4852 cells.push( nTd ); 4853 4854 // Need to create the HTML if new, or if a rendering function is defined 4855 if ( (!nTrIn || oCol.mRender || oCol.mData !== i) && 4856 (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display') 4857 ) { 4858 nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' ); 4859 } 4860 4861 /* Add user defined class */ 4862 if ( oCol.sClass ) 4863 { 4864 nTd.className += ' '+oCol.sClass; 4865 } 4866 4867 // Visibility - add or remove as required 4868 if ( oCol.bVisible && ! nTrIn ) 4869 { 4870 nTr.appendChild( nTd ); 4871 } 4872 else if ( ! oCol.bVisible && nTrIn ) 4873 { 4874 nTd.parentNode.removeChild( nTd ); 4875 } 4876 4877 if ( oCol.fnCreatedCell ) 4878 { 4879 oCol.fnCreatedCell.call( oSettings.oInstance, 4880 nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i 4881 ); 4882 } 4883 } 4884 4885 _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] ); 4886 } 4887 4888 // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved 4889 // and deployed 4890 row.nTr.setAttribute( 'role', 'row' ); 4891 } 4892 4893 4894 /** 4895 * Add attributes to a row based on the special `DT_*` parameters in a data 4896 * source object. 4897 * @param {object} settings DataTables settings object 4898 * @param {object} DataTables row object for the row to be modified 4899 * @memberof DataTable#oApi 4900 */ 4901 function _fnRowAttributes( settings, row ) 4902 { 4903 var tr = row.nTr; 4904 var data = row._aData; 4905 4906 if ( tr ) { 4907 var id = settings.rowIdFn( data ); 4908 4909 if ( id ) { 4910 tr.id = id; 4911 } 4912 4913 if ( data.DT_RowClass ) { 4914 // Remove any classes added by DT_RowClass before 4915 var a = data.DT_RowClass.split(' '); 4916 row.__rowc = row.__rowc ? 4917 _unique( row.__rowc.concat( a ) ) : 4918 a; 4919 4920 $(tr) 4921 .removeClass( row.__rowc.join(' ') ) 4922 .addClass( data.DT_RowClass ); 4923 } 4924 4925 if ( data.DT_RowAttr ) { 4926 $(tr).attr( data.DT_RowAttr ); 4927 } 4928 4929 if ( data.DT_RowData ) { 4930 $(tr).data( data.DT_RowData ); 4931 } 4932 } 4933 } 4934 4935 4936 /** 4937 * Create the HTML header for the table 4938 * @param {object} oSettings dataTables settings object 4939 * @memberof DataTable#oApi 4940 */ 4941 function _fnBuildHead( oSettings ) 4942 { 4943 var i, ien, cell, row, column; 4944 var thead = oSettings.nTHead; 4945 var tfoot = oSettings.nTFoot; 4946 var createHeader = $('th, td', thead).length === 0; 4947 var classes = oSettings.oClasses; 4948 var columns = oSettings.aoColumns; 4949 4950 if ( createHeader ) { 4951 row = $('<tr/>').appendTo( thead ); 4952 } 4953 4954 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 4955 column = columns[i]; 4956 cell = $( column.nTh ).addClass( column.sClass ); 4957 4958 if ( createHeader ) { 4959 cell.appendTo( row ); 4960 } 4961 4962 // 1.11 move into sorting 4963 if ( oSettings.oFeatures.bSort ) { 4964 cell.addClass( column.sSortingClass ); 4965 4966 if ( column.bSortable !== false ) { 4967 cell 4968 .attr( 'tabindex', oSettings.iTabIndex ) 4969 .attr( 'aria-controls', oSettings.sTableId ); 4970 4971 _fnSortAttachListener( oSettings, column.nTh, i ); 4972 } 4973 } 4974 4975 if ( column.sTitle != cell[0].innerHTML ) { 4976 cell.html( column.sTitle ); 4977 } 4978 4979 _fnRenderer( oSettings, 'header' )( 4980 oSettings, cell, column, classes 4981 ); 4982 } 4983 4984 if ( createHeader ) { 4985 _fnDetectHeader( oSettings.aoHeader, thead ); 4986 } 4987 4988 /* ARIA role for the rows */ 4989 $(thead).find('>tr').attr('role', 'row'); 4990 4991 /* Deal with the footer - add classes if required */ 4992 $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH ); 4993 $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH ); 4994 4995 // Cache the footer cells. Note that we only take the cells from the first 4996 // row in the footer. If there is more than one row the user wants to 4997 // interact with, they need to use the table().foot() method. Note also this 4998 // allows cells to be used for multiple columns using colspan 4999 if ( tfoot !== null ) { 5000 var cells = oSettings.aoFooter[0]; 5001 5002 for ( i=0, ien=cells.length ; i<ien ; i++ ) { 5003 column = columns[i]; 5004 column.nTf = cells[i].cell; 5005 5006 if ( column.sClass ) { 5007 $(column.nTf).addClass( column.sClass ); 5008 } 5009 } 5010 } 5011 } 5012 5013 5014 /** 5015 * Draw the header (or footer) element based on the column visibility states. The 5016 * methodology here is to use the layout array from _fnDetectHeader, modified for 5017 * the instantaneous column visibility, to construct the new layout. The grid is 5018 * traversed over cell at a time in a rows x columns grid fashion, although each 5019 * cell insert can cover multiple elements in the grid - which is tracks using the 5020 * aApplied array. Cell inserts in the grid will only occur where there isn't 5021 * already a cell in that position. 5022 * @param {object} oSettings dataTables settings object 5023 * @param array {objects} aoSource Layout array from _fnDetectHeader 5024 * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc, 5025 * @memberof DataTable#oApi 5026 */ 5027 function _fnDrawHead( oSettings, aoSource, bIncludeHidden ) 5028 { 5029 var i, iLen, j, jLen, k, kLen, n, nLocalTr; 5030 var aoLocal = []; 5031 var aApplied = []; 5032 var iColumns = oSettings.aoColumns.length; 5033 var iRowspan, iColspan; 5034 5035 if ( ! aoSource ) 5036 { 5037 return; 5038 } 5039 5040 if ( bIncludeHidden === undefined ) 5041 { 5042 bIncludeHidden = false;
5043 } 5044 5045 /* Make a copy of the master layout array, but without the visible columns in it */ 5046 for ( i=0, iLen=aoSource.length ; i<iLen ; i++ ) 5047 { 5048 aoLocal[i] = aoSource[i].slice(); 5049 aoLocal[i].nTr = aoSource[i].nTr; 5050 5051 /* Remove any columns which are currently hidden */ 5052 for ( j=iColumns-1 ; j>=0 ; j-- ) 5053 { 5054 if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden ) 5055 { 5056 aoLocal[i].splice( j, 1 ); 5057 } 5058 } 5059 5060 /* Prep the applied array - it needs an element for each row */ 5061 aApplied.push( [] ); 5062 } 5063 5064 for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ ) 5065 { 5066 nLocalTr = aoLocal[i].nTr; 5067 5068 /* All cells are going to be replaced, so empty out the row */ 5069 if ( nLocalTr ) 5070 { 5071 while( (n = nLocalTr.firstChild) ) 5072 { 5073 nLocalTr.removeChild( n ); 5074 } 5075 } 5076 5077 for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ ) 5078 { 5079 iRowspan = 1; 5080 iColspan = 1; 5081 5082 /* Check to see if there is already a cell (row/colspan) covering our target 5083 * insert point. If there is, then there is nothing to do. 5084 */ 5085 if ( aApplied[i][j] === undefined ) 5086 { 5087 nLocalTr.appendChild( aoLocal[i][j].cell ); 5088 aApplied[i][j] = 1; 5089 5090 /* Expand the cell to cover as many rows as needed */ 5091 while ( aoLocal[i+iRowspan] !== undefined && 5092 aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell ) 5093 { 5094 aApplied[i+iRowspan][j] = 1; 5095 iRowspan++; 5096 } 5097 5098 /* Expand the cell to cover as many columns as needed */ 5099 while ( aoLocal[i][j+iColspan] !== undefined && 5100 aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell ) 5101 { 5102 /* Must update the applied array over the rows for the columns */ 5103 for ( k=0 ; k<iRowspan ; k++ ) 5104 { 5105 aApplied[i+k][j+iColspan] = 1; 5106 } 5107 iColspan++; 5108 } 5109 5110 /* Do the actual expansion in the DOM */ 5111 $(aoLocal[i][j].cell) 5112 .attr('rowspan', iRowspan) 5113 .attr('colspan', iColspan); 5114 } 5115 } 5116 } 5117 } 5118 5119 5120 /** 5121 * Insert the required TR nodes into the table for display 5122 * @param {object} oSettings dataTables settings object 5123 * @memberof DataTable#oApi 5124 */ 5125 function _fnDraw( oSettings ) 5126 { 5127 /* Provide a pre-callback function which can be used to cancel the draw is false is returned */ 5128 var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] ); 5129 if ( $.inArray( false, aPreDraw ) !== -1 ) 5130 { 5131 _fnProcessingDisplay( oSettings, false ); 5132 return; 5133 } 5134 5135 var i, iLen, n; 5136 var anRows = []; 5137 var iRowCount = 0; 5138 var asStripeClasses = oSettings.asStripeClasses; 5139 var iStripes = asStripeClasses.length; 5140 var iOpenRows = oSettings.aoOpenRows.length; 5141 var oLang = oSettings.oLanguage; 5142 var iInitDisplayStart = oSettings.iInitDisplayStart; 5143 var bServerSide = _fnDataSource( oSettings ) == 'ssp'; 5144 var aiDisplay = oSettings.aiDisplay; 5145 5146 oSettings.bDrawing = true; 5147 5148 /* Check and see if we have an initial draw position from state saving */ 5149 if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 ) 5150 { 5151 oSettings._iDisplayStart = bServerSide ? 5152 iInitDisplayStart : 5153 iInitDisplayStart >= oSettings.fnRecordsDisplay() ? 5154 0 : 5155 iInitDisplayStart; 5156 5157 oSettings.iInitDisplayStart = -1; 5158 } 5159 5160 var iDisplayStart = oSettings._iDisplayStart; 5161 var iDisplayEnd = oSettings.fnDisplayEnd(); 5162 5163 /* Server-side processing draw intercept */ 5164 if ( oSettings.bDeferLoading ) 5165 { 5166 oSettings.bDeferLoading = false; 5167 oSettings.iDraw++; 5168 _fnProcessingDisplay( oSettings, false ); 5169 } 5170 else if ( !bServerSide ) 5171 { 5172 oSettings.iDraw++; 5173 } 5174 else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) ) 5175 { 5176 return; 5177 } 5178 5179 if ( aiDisplay.length !== 0 ) 5180 { 5181 var iStart = bServerSide ? 0 : iDisplayStart; 5182 var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd; 5183 5184 for ( var j=iStart ; j<iEnd ; j++ ) 5185 { 5186 var iDataIndex = aiDisplay[j]; 5187 var aoData = oSettings.aoData[ iDataIndex ]; 5188 if ( aoData.nTr === null ) 5189 { 5190 _fnCreateTr( oSettings, iDataIndex ); 5191 } 5192 5193 var nRow = aoData.nTr; 5194 5195 /* Remove the old striping classes and then add the new one */ 5196 if ( iStripes !== 0 ) 5197 { 5198 var sStripe = asStripeClasses[ iRowCount % iStripes ]; 5199 if ( aoData._sRowStripe != sStripe ) 5200 { 5201 $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe ); 5202 aoData._sRowStripe = sStripe; 5203 } 5204 } 5205 5206 // Row callback functions - might want to manipulate the row 5207 // iRowCount and j are not currently documented. Are they at all 5208 // useful? 5209 _fnCallbackFire( oSettings, 'aoRowCallback', null, 5210 [nRow, aoData._aData, iRowCount, j, iDataIndex] ); 5211 5212 anRows.push( nRow ); 5213 iRowCount++; 5214 } 5215 } 5216 else 5217 { 5218 /* Table is empty - create a row with an empty message in it */ 5219 var sZero = oLang.sZeroRecords; 5220 if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' ) 5221 { 5222 sZero = oLang.sLoadingRecords; 5223 } 5224 else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 ) 5225 { 5226 sZero = oLang.sEmptyTable; 5227 } 5228 5229 anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } ) 5230 .append( $('<td />', { 5231 'valign': 'top', 5232 'colSpan': _fnVisbleColumns( oSettings ), 5233 'class': oSettings.oClasses.sRowEmpty 5234 } ).html( sZero ) )[0]; 5235 } 5236 5237 /* Header and footer callbacks */ 5238 _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0], 5239 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); 5240 5241 _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0], 5242 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); 5243 5244 var body = $(oSettings.nTBody); 5245 5246 body.children().detach(); 5247 body.append( $(anRows) ); 5248 5249 /* Call all required callback functions for the end of a draw */ 5250 _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] ); 5251 5252 /* Draw is complete, sorting and filtering must be as well */ 5253 oSettings.bSorted = false;
5254 oSettings.bFiltered = false; 5255 oSettings.bDrawing = false; 5256 } 5257 5258 5259 /** 5260 * Redraw the table - taking account of the various features which are enabled 5261 * @param {object} oSettings dataTables settings object 5262 * @param {boolean} [holdPosition] Keep the current paging position. By default 5263 * the paging is reset to the first page 5264 * @memberof DataTable#oApi 5265 */ 5266 function _fnReDraw( settings, holdPosition ) 5267 { 5268 var 5269 features = settings.oFeatures, 5270 sort = features.bSort, 5271 filter = features.bFilter; 5272 5273 if ( sort ) { 5274 _fnSort( settings ); 5275 } 5276 5277 if ( filter ) { 5278 _fnFilterComplete( settings, settings.oPreviousSearch ); 5279 } 5280 else { 5281 // No filtering, so we want to just use the display master 5282 settings.aiDisplay = settings.aiDisplayMaster.slice(); 5283 } 5284 5285 if ( holdPosition !== true ) { 5286 settings._iDisplayStart = 0; 5287 } 5288 5289 // Let any modules know about the draw hold position state (used by 5290 // scrolling internally) 5291 settings._drawHold = holdPosition; 5292 5293 _fnDraw( settings ); 5294 5295 settings._drawHold = false; 5296 } 5297 5298 5299 /** 5300 * Add the options to the page HTML for the table 5301 * @param {object} oSettings dataTables settings object 5302 * @memberof DataTable#oApi 5303 */ 5304 function _fnAddOptionsHtml ( oSettings ) 5305 { 5306 var classes = oSettings.oClasses; 5307 var table = $(oSettings.nTable); 5308 var holding = $('<div/>').insertBefore( table ); // Holding element for speed 5309 var features = oSettings.oFeatures; 5310 5311 // All DataTables are wrapped in a div 5312 var insert = $('<div/>', { 5313 id: oSettings.sTableId+'_wrapper', 5314 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter) 5315 } ); 5316 5317 oSettings.nHolding = holding[0]; 5318 oSettings.nTableWrapper = insert[0]; 5319 oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; 5320
5321 /* Loop over the user set positioning and place the elements as needed */ 5322 var aDom = oSettings.sDom.split(''); 5323 var featureNode, cOption, nNewNode, cNext, sAttr, j; 5324 for ( var i=0 ; i<aDom.length ; i++ ) 5325 { 5326 featureNode = null; 5327 cOption = aDom[i]; 5328 5329 if ( cOption == '<' ) 5330 { 5331 /* New container div */ 5332 nNewNode = $('<div/>')[0]; 5333 5334 /* Check to see if we should append an id and/or a class name to the container */ 5335 cNext = aDom[i+1]; 5336 if ( cNext == "'" || cNext == '"' ) 5337 { 5338 sAttr = ""; 5339 j = 2; 5340 while ( aDom[i+j] != cNext ) 5341 { 5342 sAttr += aDom[i+j]; 5343 j++; 5344 } 5345 5346 /* Replace jQuery UI constants @todo depreciated */ 5347 if ( sAttr == "H" ) 5348 { 5349 sAttr = classes.sJUIHeader; 5350 } 5351 else if ( sAttr == "F" ) 5352 { 5353 sAttr = classes.sJUIFooter; 5354 } 5355 5356 /* The attribute can be in the format of "#id.class", "#id" or "class" This logic 5357 * breaks the string into parts and applies them as needed 5358 */ 5359 if ( sAttr.indexOf('.') != -1 ) 5360 { 5361 var aSplit = sAttr.split('.'); 5362 nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); 5363 nNewNode.className = aSplit[1]; 5364 } 5365 else if ( sAttr.charAt(0) == "#" ) 5366 { 5367 nNewNode.id = sAttr.substr(1, sAttr.length-1); 5368 } 5369 else 5370 { 5371 nNewNode.className = sAttr; 5372 } 5373 5374 i += j; /* Move along the position array */ 5375 } 5376 5377 insert.append( nNewNode ); 5378 insert = $(nNewNode); 5379 } 5380 else if ( cOption == '>' ) 5381 { 5382 /* End container div */ 5383 insert = insert.parent(); 5384 } 5385 // @todo Move options into their own plugins? 5386 else if ( cOption == 'l' && features.bPaginate && features.bLengthChange ) 5387 { 5388 /* Length */ 5389 featureNode = _fnFeatureHtmlLength( oSettings ); 5390 } 5391 else if ( cOption == 'f' && features.bFilter ) 5392 { 5393 /* Filter */ 5394 featureNode = _fnFeatureHtmlFilter( oSettings ); 5395 } 5396 else if ( cOption == 'r' && features.bProcessing ) 5397 { 5398 /* pRocessing */ 5399 featureNode = _fnFeatureHtmlProcessing( oSettings ); 5400 } 5401 else if ( cOption == 't' ) 5402 { 5403 /* Table */ 5404 featureNode = _fnFeatureHtmlTable( oSettings ); 5405 } 5406 else if ( cOption == 'i' && features.bInfo ) 5407 { 5408 /* Info */ 5409 featureNode = _fnFeatureHtmlInfo( oSettings ); 5410 } 5411 else if ( cOption == 'p' && features.bPaginate ) 5412 { 5413 /* Pagination */ 5414 featureNode = _fnFeatureHtmlPaginate( oSettings ); 5415 } 5416 else if ( DataTable.ext.feature.length !== 0 ) 5417 { 5418 /* Plug-in features */ 5419 var aoFeatures = DataTable.ext.feature; 5420 for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ ) 5421 { 5422 if ( cOption == aoFeatures[k].cFeature ) 5423 { 5424 featureNode = aoFeatures[k].fnInit( oSettings ); 5425 break; 5426 } 5427 } 5428 } 5429 5430 /* Add to the 2D features array */ 5431 if ( featureNode ) 5432 { 5433 var aanFeatures = oSettings.aanFeatures; 5434 5435 if ( ! aanFeatures[cOption] ) 5436 { 5437 aanFeatures[cOption] = []; 5438 } 5439 5440 aanFeatures[cOption].push( featureNode ); 5441 insert.append( featureNode ); 5442 } 5443 } 5444 5445 /* Built our DOM structure - replace the holding div with what we want */ 5446 holding.replaceWith( insert ); 5447 oSettings.nHolding = null; 5448 } 5449 5450 5451 /** 5452 * Use the DOM source to create up an array of header cells. The idea here is to 5453 * create a layout grid (array) of rows x columns, which contains a reference 5454 * to the cell that that point in the grid (regardless of col/rowspan), such that 5455 * any column / row could be removed and the new grid constructed 5456 * @param array {object} aLayout Array to store the calculated layout in 5457 * @param {node} nThead The header/footer element for the table 5458 * @memberof DataTable#oApi 5459 */ 5460 function _fnDetectHeader ( aLayout, nThead ) 5461 { 5462 var nTrs = $(nThead).children('tr'); 5463 var nTr, nCell; 5464 var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan; 5465 var bUnique; 5466 var fnShiftCol = function ( a, i, j ) { 5467 var k = a[i]; 5468 while ( k[j] ) { 5469 j++; 5470 } 5471 return j; 5472 }; 5473 5474 aLayout.splice( 0, aLayout.length ); 5475 5476 /* We know how many rows there are in the layout - so prep it */ 5477 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ ) 5478 { 5479 aLayout.push( [] ); 5480 } 5481 5482 /* Calculate a layout array */ 5483 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ ) 5484 { 5485 nTr = nTrs[i]; 5486 iColumn = 0; 5487 5488 /* For every cell in the row... */ 5489 nCell = nTr.firstChild; 5490 while ( nCell ) { 5491 if ( nCell.nodeName.toUpperCase() == "TD" || 5492 nCell.nodeName.toUpperCase() == "TH" ) 5493 { 5494 /* Get the col and rowspan attributes from the DOM and sanitise them */ 5495 iColspan = nCell.getAttribute('colspan') * 1;
5496 iRowspan = nCell.getAttribute('rowspan') * 1; 5497 iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan; 5498 iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan; 5499 5500 /* There might be colspan cells already in this row, so shift our target 5501 * accordingly 5502 */ 5503 iColShifted = fnShiftCol( aLayout, i, iColumn ); 5504 5505 /* Cache calculation for unique columns */ 5506 bUnique = iColspan === 1 ? true : false; 5507 5508 /* If there is col / rowspan, copy the information into the layout grid */ 5509 for ( l=0 ; l<iColspan ; l++ ) 5510 { 5511 for ( k=0 ; k<iRowspan ; k++ ) 5512 { 5513 aLayout[i+k][iColShifted+l] = { 5514 "cell": nCell, 5515 "unique": bUnique 5516 }; 5517 aLayout[i+k].nTr = nTr; 5518 } 5519 } 5520 } 5521 nCell = nCell.nextSibling; 5522 } 5523 } 5524 } 5525 5526 5527 /** 5528 * Get an array of unique th elements, one for each column 5529 * @param {object} oSettings dataTables settings object 5530 * @param {node} nHeader automatically detect the layout from this node - optional 5531 * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional 5532 * @returns array {node} aReturn list of unique th's 5533 * @memberof DataTable#oApi 5534 */ 5535 function _fnGetUniqueThs ( oSettings, nHeader, aLayout ) 5536 { 5537 var aReturn = []; 5538 if ( !aLayout ) 5539 { 5540 aLayout = oSettings.aoHeader; 5541 if ( nHeader ) 5542 { 5543 aLayout = []; 5544 _fnDetectHeader( aLayout, nHeader ); 5545 } 5546 } 5547 5548 for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ ) 5549 { 5550 for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ ) 5551 { 5552 if ( aLayout[i][j].unique && 5553 (!aReturn[j] || !oSettings.bSortCellsTop) ) 5554 { 5555 aReturn[j] = aLayout[i][j].cell; 5556 } 5557 } 5558 } 5559 5560 return aReturn; 5561 } 5562 5563 /** 5564 * Create an Ajax call based on the table's settings, taking into account that 5565 * parameters can have multiple forms, and backwards compatibility. 5566 * 5567 * @param {object} oSettings dataTables settings object 5568 * @param {array} data Data to send to the server, required by 5569 * DataTables - may be augmented by developer callbacks 5570 * @param {function} fn Callback function to run when data is obtained 5571 */ 5572 function _fnBuildAjax( oSettings, data, fn ) 5573 { 5574 // Compatibility with 1.9-, allow fnServerData and event to manipulate 5575 _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] ); 5576 5577 // Convert to object based for 1.10+ if using the old array scheme which can 5578 // come from server-side processing or serverParams 5579 if ( data && $.isArray(data) ) { 5580 var tmp = {}; 5581 var rbracket = /(.*?)\[\]$/; 5582 5583 $.each( data, function (key, val) { 5584 var match = val.name.match(rbracket); 5585 5586 if ( match ) { 5587 // Support for arrays 5588 var name = match[0]; 5589 5590 if ( ! tmp[ name ] ) { 5591 tmp[ name ] = []; 5592 } 5593 tmp[ name ].push( val.value ); 5594 } 5595 else { 5596 tmp[val.name] = val.value; 5597 } 5598 } ); 5599 data = tmp; 5600 } 5601 5602 var ajaxData; 5603 var ajax = oSettings.ajax; 5604 var instance = oSettings.oInstance; 5605 var callback = function ( json ) { 5606 _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] ); 5607 fn( json ); 5608 }; 5609 5610 if ( $.isPlainObject( ajax ) && ajax.data ) 5611 { 5612 ajaxData = ajax.data; 5613 5614 var newData = typeof ajaxData === 'function' ? 5615 ajaxData( data, oSettings ) : // fn can manipulate data or return 5616 ajaxData; // an object object or array to merge 5617 5618 // If the function returned something, use that alone 5619 data = typeof ajaxData === 'function' && newData ? 5620 newData : 5621 $.extend( true, data, newData ); 5622 5623 // Remove the data property as we've resolved it already and don't want 5624 // jQuery to do it again (it is restored at the end of the function) 5625 delete ajax.data; 5626 } 5627 5628 var baseAjax = { 5629 "data": data, 5630 "success": function (json) { 5631 var error = json.error || json.sError; 5632 if ( error ) { 5633 _fnLog( oSettings, 0, error ); 5634 } 5635 5636 oSettings.json = json; 5637 callback( json ); 5638 }, 5639 "dataType": "json", 5640 "cache": false, 5641 "type": oSettings.sServerMethod, 5642 "error": function (xhr, error, thrown) { 5643 var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] ); 5644 5645 if ( $.inArray( true, ret ) === -1 ) { 5646 if ( error == "parsererror" ) { 5647 _fnLog( oSettings, 0, 'Invalid JSON response', 1 ); 5648 } 5649 else if ( xhr.readyState === 4 ) { 5650 _fnLog( oSettings, 0, 'Ajax error', 7 ); 5651 } 5652 } 5653 5654 _fnProcessingDisplay( oSettings, false ); 5655 } 5656 }; 5657 5658 // Store the data submitted for the API 5659 oSettings.oAjaxData = data; 5660 5661 // Allow plug-ins and external processes to modify the data 5662 _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] ); 5663 5664 if ( oSettings.fnServerData ) 5665 { 5666 // DataTables 1.9- compatibility 5667 oSettings.fnServerData.call( instance, 5668 oSettings.sAjaxSource, 5669 $.map( data, function (val, key) { // Need to convert back to 1.9 trad format 5670 return { name: key, value: val }; 5671 } ), 5672 callback, 5673 oSettings 5674 ); 5675 } 5676 else if ( oSettings.sAjaxSource || typeof ajax === 'string' ) 5677 { 5678 // DataTables 1.9- compatibility 5679 oSettings.jqXHR = $.ajax( $.extend( baseAjax, { 5680 url: ajax || oSettings.sAjaxSource 5681 } ) ); 5682 } 5683 else if ( typeof ajax === 'function' ) 5684 { 5685 // Is a function - let the caller define what needs to be done 5686 oSettings.jqXHR = ajax.call( instance, data, callback, oSettings ); 5687 } 5688 else 5689 { 5690 // Object to extend the base settings 5691 oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) ); 5692 5693 // Restore for next time around 5694 ajax.data = ajaxData; 5695 } 5696 } 5697 5698 5699 /** 5700 * Update the table using an Ajax call 5701 * @param {object} settings dataTables settings object 5702 * @returns {boolean} Block the table drawing or not 5703 * @memberof DataTable#oApi 5704 */ 5705 function _fnAjaxUpdate( settings ) 5706 { 5707 if ( settings.bAjaxDataGet ) { 5708 settings.iDraw++; 5709 _fnProcessingDisplay( settings, true ); 5710 5711 _fnBuildAjax( 5712 settings, 5713 _fnAjaxParameters( settings ), 5714 function(json) { 5715 _fnAjaxUpdateDraw( settings, json ); 5716 } 5717 ); 5718 5719 return false;
5720 } 5721 return true; 5722 } 5723 5724 5725 /** 5726 * Build up the parameters in an object needed for a server-side processing 5727 * request. Note that this is basically done twice, is different ways - a modern 5728 * method which is used by default in DataTables 1.10 which uses objects and 5729 * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if 5730 * the sAjaxSource option is used in the initialisation, or the legacyAjax 5731 * option is set. 5732 * @param {object} oSettings dataTables settings object 5733 * @returns {bool} block the table drawing or not 5734 * @memberof DataTable#oApi 5735 */ 5736 function _fnAjaxParameters( settings ) 5737 { 5738 var 5739 columns = settings.aoColumns, 5740 columnCount = columns.length, 5741 features = settings.oFeatures, 5742 preSearch = settings.oPreviousSearch, 5743 preColSearch = settings.aoPreSearchCols, 5744 i, data = [], dataProp, column, columnSearch, 5745 sort = _fnSortFlatten( settings ), 5746 displayStart = settings._iDisplayStart, 5747 displayLength = features.bPaginate !== false ? 5748 settings._iDisplayLength : 5749 -1; 5750 5751 var param = function ( name, value ) { 5752 data.push( { 'name': name, 'value': value } ); 5753 }; 5754 5755 // DataTables 1.9- compatible method 5756 param( 'sEcho', settings.iDraw ); 5757 param( 'iColumns', columnCount ); 5758 param( 'sColumns', _pluck( columns, 'sName' ).join(',') ); 5759 param( 'iDisplayStart', displayStart ); 5760 param( 'iDisplayLength', displayLength ); 5761 5762 // DataTables 1.10+ method 5763 var d = { 5764 draw: settings.iDraw, 5765 columns: [], 5766 order: [], 5767 start: displayStart, 5768 length: displayLength, 5769 search: { 5770 value: preSearch.sSearch, 5771 regex: preSearch.bRegex 5772 } 5773 }; 5774 5775 for ( i=0 ; i<columnCount ; i++ ) { 5776 column = columns[i]; 5777 columnSearch = preColSearch[i]; 5778 dataProp = typeof column.mData=="function" ? 'function' : column.mData ; 5779 5780 d.columns.push( { 5781 data: dataProp, 5782 name: column.sName, 5783 searchable: column.bSearchable, 5784 orderable: column.bSortable, 5785 search: { 5786 value: columnSearch.sSearch, 5787 regex: columnSearch.bRegex 5788 } 5789 } ); 5790 5791 param( "mDataProp_"+i, dataProp ); 5792 5793 if ( features.bFilter ) { 5794 param( 'sSearch_'+i, columnSearch.sSearch ); 5795 param( 'bRegex_'+i, columnSearch.bRegex ); 5796 param( 'bSearchable_'+i, column.bSearchable ); 5797 } 5798 5799 if ( features.bSort ) { 5800 param( 'bSortable_'+i, column.bSortable ); 5801 } 5802 } 5803 5804 if ( features.bFilter ) { 5805 param( 'sSearch', preSearch.sSearch ); 5806 param( 'bRegex', preSearch.bRegex ); 5807 } 5808 5809 if ( features.bSort ) { 5810 $.each( sort, function ( i, val ) { 5811 d.order.push( { column: val.col, dir: val.dir } ); 5812 5813 param( 'iSortCol_'+i, val.col ); 5814 param( 'sSortDir_'+i, val.dir ); 5815 } ); 5816 5817 param( 'iSortingCols', sort.length ); 5818 } 5819 5820 // If the legacy.ajax parameter is null, then we automatically decide which 5821 // form to use, based on sAjaxSource 5822 var legacy = DataTable.ext.legacy.ajax; 5823 if ( legacy === null ) { 5824 return settings.sAjaxSource ? data : d; 5825 } 5826 5827 // Otherwise, if legacy has been specified then we use that to decide on the 5828 // form 5829 return legacy ? data : d; 5830 } 5831 5832 5833 /** 5834 * Data the data from the server (nuking the old) and redraw the table 5835 * @param {object} oSettings dataTables settings object 5836 * @param {object} json json data return from the server. 5837 * @param {string} json.sEcho Tracking flag for DataTables to match requests 5838 * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering 5839 * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering 5840 * @param {array} json.aaData The data to display on this page 5841 * @param {string} [json.sColumns] Column ordering (sName, comma separated) 5842 * @memberof DataTable#oApi 5843 */ 5844 function _fnAjaxUpdateDraw ( settings, json ) 5845 { 5846 // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
5847 // Support both 5848 var compat = function ( old, modern ) { 5849 return json[old] !== undefined ? json[old] : json[modern]; 5850 }; 5851 5852 var data = _fnAjaxDataSrc( settings, json ); 5853 var draw = compat( 'sEcho', 'draw' ); 5854 var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' ); 5855 var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' ); 5856 5857 if ( draw ) { 5858 // Protect against out of sequence returns 5859 if ( draw*1 < settings.iDraw ) { 5860 return; 5861 } 5862 settings.iDraw = draw * 1; 5863 } 5864 5865 _fnClearTable( settings ); 5866 settings._iRecordsTotal = parseInt(recordsTotal, 10); 5867 settings._iRecordsDisplay = parseInt(recordsFiltered, 10); 5868 5869 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 5870 _fnAddData( settings, data[i] ); 5871 } 5872 settings.aiDisplay = settings.aiDisplayMaster.slice(); 5873 5874 settings.bAjaxDataGet = false; 5875 _fnDraw( settings ); 5876 5877 if ( ! settings._bInitComplete ) { 5878 _fnInitComplete( settings, json ); 5879 } 5880 5881 settings.bAjaxDataGet = true; 5882 _fnProcessingDisplay( settings, false ); 5883 } 5884 5885 5886 /** 5887 * Get the data from the JSON data source to use for drawing a table. Using 5888 * `_fnGetObjectDataFn` allows the data to be sourced from a property of the 5889 * source object, or from a processing function. 5890 * @param {object} oSettings dataTables settings object 5891 * @param {object} json Data source object / array from the server 5892 * @return {array} Array of data to use 5893 */ 5894 function _fnAjaxDataSrc ( oSettings, json ) 5895 { 5896 var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ? 5897 oSettings.ajax.dataSrc : 5898 oSettings.sAjaxDataProp; // Compatibility with 1.9-. 5899 5900 // Compatibility with 1.9-. In order to read from aaData, check if the 5901 // default has been changed, if not, check for aaData 5902 if ( dataSrc === 'data' ) { 5903 return json.aaData || json[dataSrc]; 5904 } 5905 5906 return dataSrc !== "" ? 5907 _fnGetObjectDataFn( dataSrc )( json ) : 5908 json; 5909 } 5910 5911 /** 5912 * Generate the node required for filtering text 5913 * @returns {node} Filter control element 5914 * @param {object} oSettings dataTables settings object 5915 * @memberof DataTable#oApi 5916 */ 5917 function _fnFeatureHtmlFilter ( settings ) 5918 { 5919 var classes = settings.oClasses; 5920 var tableId = settings.sTableId; 5921 var language = settings.oLanguage; 5922 var previousSearch = settings.oPreviousSearch; 5923 var features = settings.aanFeatures; 5924 var input = '<input type="search" class="'+classes.sFilterInput+'"/>'; 5925 5926 var str = language.sSearch; 5927 str = str.match(/_INPUT_/) ? 5928 str.replace('_INPUT_', input) : 5929 str+input; 5930 5931 var filter = $('<div/>', { 5932 'id': ! features.f ? tableId+'_filter' : null, 5933 'class': classes.sFilter 5934 } ) 5935 .append( $('<label/>' ).append( str ) ); 5936 5937 var searchFn = function() { 5938 /* Update all other filter input elements for the new display */ 5939 var n = features.f; 5940 var val = !this.value ? "" : this.value; // mental IE8 fix :-( 5941 5942 /* Now do the filter */ 5943 if ( val != previousSearch.sSearch ) { 5944 _fnFilterComplete( settings, { 5945 "sSearch": val, 5946 "bRegex": previousSearch.bRegex, 5947 "bSmart": previousSearch.bSmart , 5948 "bCaseInsensitive": previousSearch.bCaseInsensitive 5949 } ); 5950 5951 // Need to redraw, without resorting 5952 settings._iDisplayStart = 0; 5953 _fnDraw( settings ); 5954 } 5955 }; 5956 5957 var searchDelay = settings.searchDelay !== null ? 5958 settings.searchDelay : 5959 _fnDataSource( settings ) === 'ssp' ? 5960 400 : 5961 0; 5962 5963 var jqFilter = $('input', filter) 5964 .val( previousSearch.sSearch ) 5965 .attr( 'placeholder', language.sSearchPlaceholder ) 5966 .on( 5967 'keyup.DT search.DT input.DT paste.DT cut.DT', 5968 searchDelay ? 5969 _fnThrottle( searchFn, searchDelay ) : 5970 searchFn 5971 ) 5972 .on( 'keypress.DT', function(e) { 5973 /* Prevent form submission */ 5974 if ( e.keyCode == 13 ) { 5975 return false; 5976 } 5977 } ) 5978 .attr('aria-controls', tableId); 5979 5980 // Update the input elements whenever the table is filtered 5981 $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) { 5982 if ( settings === s ) { 5983 // IE9 throws an 'unknown error' if document.activeElement is used 5984 // inside an iframe or frame...
5985 try { 5986 if ( jqFilter[0] !== document.activeElement ) { 5987 jqFilter.val( previousSearch.sSearch ); 5988 } 5989 } 5990 catch ( e ) {} 5991 } 5992 } ); 5993 5994 return filter[0]; 5995 } 5996 5997 5998 /** 5999 * Filter the table using both the global filter and column based filtering 6000 * @param {object} oSettings dataTables settings object 6001 * @param {object} oSearch search information 6002 * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0) 6003 * @memberof DataTable#oApi 6004 */ 6005 function _fnFilterComplete ( oSettings, oInput, iForce ) 6006 { 6007 var oPrevSearch = oSettings.oPreviousSearch; 6008 var aoPrevSearch = oSettings.aoPreSearchCols; 6009 var fnSaveFilter = function ( oFilter ) { 6010 /* Save the filtering values */ 6011 oPrevSearch.sSearch = oFilter.sSearch; 6012 oPrevSearch.bRegex = oFilter.bRegex; 6013 oPrevSearch.bSmart = oFilter.bSmart; 6014 oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive; 6015 }; 6016 var fnRegex = function ( o ) { 6017 // Backwards compatibility with the bEscapeRegex option 6018 return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex; 6019 }; 6020 6021 // Resolve any column types that are unknown due to addition or invalidation 6022 // @todo As per sort - can this be moved into an event handler? 6023 _fnColumnTypes( oSettings ); 6024 6025 /* In server-side processing all filtering is done by the server, so no point hanging around here */ 6026 if ( _fnDataSource( oSettings ) != 'ssp' ) 6027 { 6028 /* Global filter */ 6029 _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive ); 6030 fnSaveFilter( oInput ); 6031 6032 /* Now do the individual column filter */ 6033 for ( var i=0 ; i<aoPrevSearch.length ; i++ ) 6034 { 6035 _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]), 6036 aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive ); 6037 } 6038 6039 /* Custom filtering */ 6040 _fnFilterCustom( oSettings ); 6041 } 6042 else 6043 { 6044 fnSaveFilter( oInput ); 6045 } 6046 6047 /* Tell the draw function we have been filtering */ 6048 oSettings.bFiltered = true; 6049 _fnCallbackFire( oSettings, null, 'search', [oSettings] ); 6050 } 6051 6052 6053 /** 6054 * Apply custom filtering functions 6055 * @param {object} oSettings dataTables settings object 6056 * @memberof DataTable#oApi 6057 */ 6058 function _fnFilterCustom( settings ) 6059 { 6060 var filters = DataTable.ext.search; 6061 var displayRows = settings.aiDisplay; 6062 var row, rowIdx; 6063 6064 for ( var i=0, ien=filters.length ; i<ien ; i++ ) { 6065 var rows = []; 6066 6067 // Loop over each row and see if it should be included 6068 for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) { 6069 rowIdx = displayRows[ j ]; 6070 row = settings.aoData[ rowIdx ]; 6071 6072 if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) { 6073 rows.push( rowIdx ); 6074 } 6075 } 6076 6077 // So the array reference doesn't break set the results into the 6078 // existing array 6079 displayRows.length = 0; 6080 $.merge( displayRows, rows ); 6081 } 6082 } 6083 6084 6085 /** 6086 * Filter the table on a per-column basis 6087 * @param {object} oSettings dataTables settings object 6088 * @param {string} sInput string to filter on 6089 * @param {int} iColumn column to filter 6090 * @param {bool} bRegex treat search string as a regular expression or not 6091 * @param {bool} bSmart use smart filtering or not 6092 * @param {bool} bCaseInsensitive Do case insenstive matching or not 6093 * @memberof DataTable#oApi 6094 */ 6095 function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive ) 6096 { 6097 if ( searchStr === '' ) { 6098 return; 6099 } 6100 6101 var data; 6102 var out = []; 6103 var display = settings.aiDisplay; 6104 var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive ); 6105 6106 for ( var i=0 ; i<display.length ; i++ ) { 6107 data = settings.aoData[ display[i] ]._aFilterData[ colIdx ]; 6108 6109 if ( rpSearch.test( data ) ) { 6110 out.push( display[i] ); 6111 } 6112 } 6113 6114 settings.aiDisplay = out; 6115 } 6116 6117 6118 /** 6119 * Filter the data table based on user input and draw the table 6120 * @param {object} settings dataTables settings object 6121 * @param {string} input string to filter on 6122 * @param {int} force optional - force a research of the master array (1) or not (undefined or 0) 6123 * @param {bool} regex treat as a regular expression or not 6124 * @param {bool} smart perform smart filtering or not 6125 * @param {bool} caseInsensitive Do case insenstive matching or not 6126 * @memberof DataTable#oApi 6127 */ 6128 function _fnFilter( settings, input, force, regex, smart, caseInsensitive ) 6129 { 6130 var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive ); 6131 var prevSearch = settings.oPreviousSearch.sSearch; 6132 var displayMaster = settings.aiDisplayMaster; 6133 var display, invalidated, i; 6134 var filtered = []; 6135 6136 // Need to take account of custom filtering functions - always filter 6137 if ( DataTable.ext.search.length !== 0 ) { 6138 force = true; 6139 } 6140 6141 // Check if any of the rows were invalidated 6142 invalidated = _fnFilterData( settings ); 6143 6144 // If the input is blank - we just want the full data set 6145 if ( input.length <= 0 ) { 6146 settings.aiDisplay = displayMaster.slice(); 6147 } 6148 else { 6149 // New search - start from the master array 6150 if ( invalidated || 6151 force || 6152 prevSearch.length > input.length || 6153 input.indexOf(prevSearch) !== 0 || 6154 settings.bSorted // On resort, the display master needs to be 6155 // re-filtered since indexes will have changed 6156 ) { 6157 settings.aiDisplay = displayMaster.slice(); 6158 } 6159 6160 // Search the display array 6161 display = settings.aiDisplay; 6162 6163 for ( i=0 ; i<display.length ; i++ ) { 6164 if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) { 6165 filtered.push( display[i] ); 6166 } 6167 } 6168 6169 settings.aiDisplay = filtered; 6170 } 6171 } 6172 6173 6174 /** 6175 * Build a regular expression object suitable for searching a table 6176 * @param {string} sSearch string to search for 6177 * @param {bool} bRegex treat as a regular expression or not 6178 * @param {bool} bSmart perform smart filtering or not 6179 * @param {bool} bCaseInsensitive Do case insensitive matching or not 6180 * @returns {RegExp} constructed object 6181 * @memberof DataTable#oApi 6182 */ 6183 function _fnFilterCreateSearch( search, regex, smart, caseInsensitive ) 6184 { 6185 search = regex ? 6186 search : 6187 _fnEscapeRegex( search ); 6188 6189 if ( smart ) { 6190 /* For smart filtering we want to allow the search to work regardless of 6191 * word order. We also want double quoted text to be preserved, so word 6192 * order is important - a la google. So this is what we want to 6193 * generate: 6194 * 6195 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$ 6196 */ 6197 var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) { 6198 if ( word.charAt(0) === '"' ) { 6199 var m = word.match( /^"(.*)"$/ ); 6200 word = m ? m[1] : word; 6201 } 6202 6203 return word.replace('"', ''); 6204 } ); 6205 6206 search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$'; 6207 } 6208 6209 return new RegExp( search, caseInsensitive ? 'i' : '' ); 6210 } 6211 6212 6213 /** 6214 * Escape a string such that it can be used in a regular expression 6215 * @param {string} sVal string to escape 6216 * @returns {string} escaped string 6217 * @memberof DataTable#oApi 6218 */ 6219 var _fnEscapeRegex = DataTable.util.escapeRegex; 6220
6221 var __filter_div = $('<div>')[0]; 6222 var __filter_div_textContent = __filter_div.textContent !== undefined; 6223 6224 // Update the filtering data for each row if needed (by invalidation or first run) 6225 function _fnFilterData ( settings ) 6226 { 6227 var columns = settings.aoColumns; 6228 var column; 6229 var i, j, ien, jen, filterData, cellData, row; 6230 var fomatters = DataTable.ext.type.search; 6231 var wasInvalidated = false; 6232 6233 for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 6234 row = settings.aoData[i]; 6235 6236 if ( ! row._aFilterData ) { 6237 filterData = []; 6238 6239 for ( j=0, jen=columns.length ; j<jen ; j++ ) { 6240 column = columns[j]; 6241 6242 if ( column.bSearchable ) { 6243 cellData = _fnGetCellData( settings, i, j, 'filter' ); 6244 6245 if ( fomatters[ column.sType ] ) { 6246 cellData = fomatters[ column.sType ]( cellData ); 6247 } 6248 6249 // Search in DataTables 1.10 is string based. In 1.11 this 6250 // should be altered to also allow strict type checking. 6251 if ( cellData === null ) { 6252 cellData = ''; 6253 } 6254 6255 if ( typeof cellData !== 'string' && cellData.toString ) { 6256 cellData = cellData.toString(); 6257 } 6258 } 6259 else { 6260 cellData = ''; 6261 } 6262 6263 // If it looks like there is an HTML entity in the string, 6264 // attempt to decode it so sorting works as expected. Note that 6265 // we could use a single line of jQuery to do this, but the DOM 6266 // method used here is much faster http://jsperf.com/html-decode 6267 if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) { 6268 __filter_div.innerHTML = cellData; 6269 cellData = __filter_div_textContent ? 6270 __filter_div.textContent : 6271 __filter_div.innerText; 6272 } 6273 6274 if ( cellData.replace ) { 6275 cellData = cellData.replace(/[\r\n]/g, ''); 6276 } 6277 6278 filterData.push( cellData ); 6279 } 6280 6281 row._aFilterData = filterData; 6282 row._sFilterRow = filterData.join(' '); 6283 wasInvalidated = true; 6284 } 6285 } 6286 6287 return wasInvalidated; 6288 } 6289 6290 6291 /** 6292 * Convert from the internal Hungarian notation to camelCase for external 6293 * interaction 6294 * @param {object} obj Object to convert 6295 * @returns {object} Inverted object 6296 * @memberof DataTable#oApi 6297 */ 6298 function _fnSearchToCamel ( obj ) 6299 { 6300 return { 6301 search: obj.sSearch, 6302 smart: obj.bSmart, 6303 regex: obj.bRegex, 6304 caseInsensitive: obj.bCaseInsensitive 6305 }; 6306 } 6307 6308 6309 6310 /** 6311 * Convert from camelCase notation to the internal Hungarian. We could use the 6312 * Hungarian convert function here, but this is cleaner 6313 * @param {object} obj Object to convert 6314 * @returns {object} Inverted object 6315 * @memberof DataTable#oApi 6316 */ 6317 function _fnSearchToHung ( obj ) 6318 { 6319 return { 6320 sSearch: obj.search, 6321 bSmart: obj.smart, 6322 bRegex: obj.regex, 6323 bCaseInsensitive: obj.caseInsensitive 6324 }; 6325 } 6326 6327 /** 6328 * Generate the node required for the info display 6329 * @param {object} oSettings dataTables settings object 6330 * @returns {node} Information element 6331 * @memberof DataTable#oApi 6332 */ 6333 function _fnFeatureHtmlInfo ( settings ) 6334 { 6335 var 6336 tid = settings.sTableId, 6337 nodes = settings.aanFeatures.i, 6338 n = $('<div/>', { 6339 'class': settings.oClasses.sInfo, 6340 'id': ! nodes ? tid+'_info' : null 6341 } ); 6342 6343 if ( ! nodes ) { 6344 // Update display on each draw 6345 settings.aoDrawCallback.push( { 6346 "fn": _fnUpdateInfo, 6347 "sName": "information" 6348 } ); 6349 6350 n 6351 .attr( 'role', 'status' ) 6352 .attr( 'aria-live', 'polite' ); 6353 6354 // Table is described by our info div 6355 $(settings.nTable).attr( 'aria-describedby', tid+'_info' ); 6356 } 6357 6358 return n[0]; 6359 } 6360 6361 6362 /** 6363 * Update the information elements in the display 6364 * @param {object} settings dataTables settings object 6365 * @memberof DataTable#oApi 6366 */ 6367 function _fnUpdateInfo ( settings ) 6368 { 6369 /* Show information about the table */ 6370 var nodes = settings.aanFeatures.i; 6371 if ( nodes.length === 0 ) { 6372 return; 6373 } 6374 6375 var 6376 lang = settings.oLanguage, 6377 start = settings._iDisplayStart+1, 6378 end = settings.fnDisplayEnd(), 6379 max = settings.fnRecordsTotal(), 6380 total = settings.fnRecordsDisplay(), 6381 out = total ? 6382 lang.sInfo : 6383 lang.sInfoEmpty; 6384 6385 if ( total !== max ) { 6386 /* Record set after filtering */ 6387 out += ' ' + lang.sInfoFiltered; 6388 } 6389 6390 // Convert the macros 6391 out += lang.sInfoPostFix; 6392 out = _fnInfoMacros( settings, out ); 6393 6394 var callback = lang.fnInfoCallback; 6395 if ( callback !== null ) { 6396 out = callback.call( settings.oInstance, 6397 settings, start, end, max, total, out 6398 ); 6399 } 6400 6401 $(nodes).html( out ); 6402 } 6403 6404 6405 function _fnInfoMacros ( settings, str ) 6406 { 6407 // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only 6408 // internally 6409 var
6410 formatter = settings.fnFormatNumber, 6411 start = settings._iDisplayStart+1, 6412 len = settings._iDisplayLength, 6413 vis = settings.fnRecordsDisplay(), 6414 all = len === -1; 6415 6416 return str. 6417 replace(/_START_/g, formatter.call( settings, start ) ). 6418 replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ). 6419 replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ). 6420 replace(/_TOTAL_/g, formatter.call( settings, vis ) ). 6421 replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ). 6422 replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) ); 6423 } 6424 6425 6426 6427 /** 6428 * Draw the table for the first time, adding all required features 6429 * @param {object} settings dataTables settings object 6430 * @memberof DataTable#oApi 6431 */ 6432 function _fnInitialise ( settings ) 6433 { 6434 var i, iLen, iAjaxStart=settings.iInitDisplayStart; 6435 var columns = settings.aoColumns, column; 6436 var features = settings.oFeatures; 6437 var deferLoading = settings.bDeferLoading; // value modified by the draw 6438 6439 /* Ensure that the table data is fully initialised */ 6440 if ( ! settings.bInitialised ) { 6441 setTimeout( function(){ _fnInitialise( settings ); }, 200 ); 6442 return; 6443 } 6444 6445 /* Show the display HTML options */ 6446 _fnAddOptionsHtml( settings ); 6447 6448 /* Build and draw the header / footer for the table */ 6449 _fnBuildHead( settings ); 6450 _fnDrawHead( settings, settings.aoHeader ); 6451 _fnDrawHead( settings, settings.aoFooter ); 6452 6453 /* Okay to show that something is going on now */ 6454 _fnProcessingDisplay( settings, true ); 6455 6456 /* Calculate sizes for columns */ 6457 if ( features.bAutoWidth ) { 6458 _fnCalculateColumnWidths( settings ); 6459 } 6460 6461 for ( i=0, iLen=columns.length ; i<iLen ; i++ ) { 6462 column = columns[i]; 6463 6464 if ( column.sWidth ) { 6465 column.nTh.style.width = _fnStringToCss( column.sWidth ); 6466 } 6467 } 6468 6469 _fnCallbackFire( settings, null, 'preInit', [settings] ); 6470 6471 // If there is default sorting required - let's do it. The sort function 6472 // will do the drawing for us. Otherwise we draw the table regardless of the 6473 // Ajax source - this allows the table to look initialised for Ajax sourcing 6474 // data (show 'loading' message possibly) 6475 _fnReDraw( settings ); 6476 6477 // Server-side processing init complete is done by _fnAjaxUpdateDraw 6478 var dataSrc = _fnDataSource( settings ); 6479 if ( dataSrc != 'ssp' || deferLoading ) { 6480 // if there is an ajax source load the data 6481 if ( dataSrc == 'ajax' ) { 6482 _fnBuildAjax( settings, [], function(json) { 6483 var aData = _fnAjaxDataSrc( settings, json ); 6484 6485 // Got the data - add it to the table 6486 for ( i=0 ; i<aData.length ; i++ ) { 6487 _fnAddData( settings, aData[i] ); 6488 } 6489 6490 // Reset the init display for cookie saving. We've already done 6491 // a filter, and therefore cleared it before. So we need to make 6492 // it appear 'fresh' 6493 settings.iInitDisplayStart = iAjaxStart; 6494 6495 _fnReDraw( settings ); 6496 6497 _fnProcessingDisplay( settings, false ); 6498 _fnInitComplete( settings, json ); 6499 }, settings ); 6500 } 6501 else { 6502 _fnProcessingDisplay( settings, false ); 6503 _fnInitComplete( settings ); 6504 } 6505 } 6506 } 6507 6508 6509 /** 6510 * Draw the table for the first time, adding all required features 6511 * @param {object} oSettings dataTables settings object 6512 * @param {object} [json] JSON from the server that completed the table, if using Ajax source 6513 * with client-side processing (optional) 6514 * @memberof DataTable#oApi 6515 */ 6516 function _fnInitComplete ( settings, json ) 6517 { 6518 settings._bInitComplete = true; 6519 6520 // When data was added after the initialisation (data or Ajax) we need to 6521 // calculate the column sizing 6522 if ( json || settings.oInit.aaData ) { 6523 _fnAdjustColumnSizing( settings ); 6524 } 6525 6526 _fnCallbackFire( settings, null, 'plugin-init', [settings, json] ); 6527 _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] ); 6528 } 6529 6530 6531 function _fnLengthChange ( settings, val ) 6532 { 6533 var len = parseInt( val, 10 ); 6534 settings._iDisplayLength = len; 6535 6536 _fnLengthOverflow( settings ); 6537 6538 // Fire length change event 6539 _fnCallbackFire( settings, null, 'length', [settings, len] ); 6540 } 6541 6542 6543 /** 6544 * Generate the node required for user display length changing 6545 * @param {object} settings dataTables settings object 6546 * @returns {node} Display length feature node 6547 * @memberof DataTable#oApi 6548 */ 6549 function _fnFeatureHtmlLength ( settings ) 6550 { 6551 var 6552 classes = settings.oClasses, 6553 tableId = settings.sTableId, 6554 menu = settings.aLengthMenu, 6555 d2 = $.isArray( menu[0] ), 6556 lengths = d2 ? menu[0] : menu, 6557 language = d2 ? menu[1] : menu; 6558 6559 var select = $('<select/>', { 6560 'name': tableId+'_length', 6561 'aria-controls': tableId, 6562 'class': classes.sLengthSelect 6563 } ); 6564 6565 for ( var i=0, ien=lengths.length ; i<ien ; i++ ) { 6566 select[0][ i ] = new Option( 6567 typeof language[i] === 'number' ? 6568 settings.fnFormatNumber( language[i] ) : 6569 language[i], 6570 lengths[i] 6571 ); 6572 } 6573
6574 var div = $('<div><label/></div>').addClass( classes.sLength ); 6575 if ( ! settings.aanFeatures.l ) { 6576 div[0].id = tableId+'_length'; 6577 } 6578 6579 div.children().append( 6580 settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML ) 6581 ); 6582 6583 // Can't use `select` variable as user might provide their own and the 6584 // reference is broken by the use of outerHTML 6585 $('select', div) 6586 .val( settings._iDisplayLength ) 6587 .on( 'change.DT', function(e) { 6588 _fnLengthChange( settings, $(this).val() ); 6589 _fnDraw( settings ); 6590 } ); 6591 6592 // Update node value whenever anything changes the table's length 6593 $(settings.nTable).on( 'length.dt.DT', function (e, s, len) { 6594 if ( settings === s ) { 6595 $('select', div).val( len ); 6596 } 6597 } ); 6598 6599 return div[0]; 6600 } 6601 6602 6603 6604 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 6605 * Note that most of the paging logic is done in 6606 * DataTable.ext.pager 6607 */ 6608 6609 /** 6610 * Generate the node required for default pagination 6611 * @param {object} oSettings dataTables settings object 6612 * @returns {node} Pagination feature node 6613 * @memberof DataTable#oApi 6614 */ 6615 function _fnFeatureHtmlPaginate ( settings ) 6616 { 6617 var 6618 type = settings.sPaginationType, 6619 plugin = DataTable.ext.pager[ type ], 6620 modern = typeof plugin === 'function', 6621 redraw = function( settings ) { 6622 _fnDraw( settings ); 6623 }, 6624 node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0], 6625 features = settings.aanFeatures; 6626 6627 if ( ! modern ) { 6628 plugin.fnInit( settings, node, redraw ); 6629 } 6630 6631 /* Add a draw callback for the pagination on first instance, to update the paging display */ 6632 if ( ! features.p ) 6633 { 6634 node.id = settings.sTableId+'_paginate'; 6635 6636 settings.aoDrawCallback.push( { 6637 "fn": function( settings ) { 6638 if ( modern ) { 6639 var 6640 start = settings._iDisplayStart, 6641 len = settings._iDisplayLength, 6642 visRecords = settings.fnRecordsDisplay(), 6643 all = len === -1, 6644 page = all ? 0 : Math.ceil( start / len ), 6645 pages = all ? 1 : Math.ceil( visRecords / len ), 6646 buttons = plugin(page, pages), 6647 i, ien; 6648 6649 for ( i=0, ien=features.p.length ; i<ien ; i++ ) { 6650 _fnRenderer( settings, 'pageButton' )( 6651 settings, features.p[i], i, buttons, page, pages 6652 ); 6653 } 6654 } 6655 else { 6656 plugin.fnUpdate( settings, redraw ); 6657 } 6658 }, 6659 "sName": "pagination" 6660 } ); 6661 } 6662 6663 return node; 6664 } 6665 6666 6667 /** 6668 * Alter the display settings to change the page 6669 * @param {object} settings DataTables settings object 6670 * @param {string|int} action Paging action to take: "first", "previous", 6671 * "next" or "last" or page number to jump to (integer) 6672 * @param [bool] redraw Automatically draw the update or not 6673 * @returns {bool} true page has changed, false - no change 6674 * @memberof DataTable#oApi 6675 */ 6676 function _fnPageChange ( settings, action, redraw ) 6677 { 6678 var 6679 start = settings._iDisplayStart, 6680 len = settings._iDisplayLength, 6681 records = settings.fnRecordsDisplay(); 6682 6683 if ( records === 0 || len === -1 ) 6684 { 6685 start = 0; 6686 } 6687 else if ( typeof action === "number" ) 6688 { 6689 start = action * len; 6690 6691 if ( start > records ) 6692 { 6693 start = 0; 6694 } 6695 } 6696 else if ( action == "first" ) 6697 { 6698 start = 0; 6699 } 6700 else if ( action == "previous" ) 6701 { 6702 start = len >= 0 ? 6703 start - len : 6704 0; 6705 6706 if ( start < 0 ) 6707 { 6708 start = 0; 6709 } 6710 } 6711 else if ( action == "next" ) 6712 { 6713 if ( start + len < records ) 6714 { 6715 start += len; 6716 } 6717 } 6718 else if ( action == "last" ) 6719 { 6720 start = Math.floor( (records-1) / len) * len; 6721 } 6722 else 6723 { 6724 _fnLog( settings, 0, "Unknown paging action: "+action, 5 ); 6725 } 6726 6727 var changed = settings._iDisplayStart !== start; 6728 settings._iDisplayStart = start; 6729 6730 if ( changed ) { 6731 _fnCallbackFire( settings, null, 'page', [settings] ); 6732 6733 if ( redraw ) { 6734 _fnDraw( settings ); 6735 } 6736 } 6737 6738 return changed; 6739 } 6740 6741 6742 6743 /** 6744 * Generate the node required for the processing node 6745 * @param {object} settings dataTables settings object 6746 * @returns {node} Processing element 6747 * @memberof DataTable#oApi 6748 */ 6749 function _fnFeatureHtmlProcessing ( settings ) 6750 { 6751 return $('<div/>', { 6752 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null, 6753 'class': settings.oClasses.sProcessing 6754 } ) 6755 .html( settings.oLanguage.sProcessing ) 6756 .insertBefore( settings.nTable )[0]; 6757 } 6758 6759 6760 /** 6761 * Display or hide the processing indicator 6762 * @param {object} settings dataTables settings object 6763 * @param {bool} show Show the processing indicator (true) or not (false) 6764 * @memberof DataTable#oApi 6765 */ 6766 function _fnProcessingDisplay ( settings, show ) 6767 { 6768 if ( settings.oFeatures.bProcessing ) { 6769 $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' ); 6770 } 6771 6772 _fnCallbackFire( settings, null, 'processing', [settings, show] ); 6773 } 6774 6775 /** 6776 * Add any control elements for the table - specifically scrolling 6777 * @param {object} settings dataTables settings object 6778 * @returns {node} Node to add to the DOM 6779 * @memberof DataTable#oApi 6780 */ 6781 function _fnFeatureHtmlTable ( settings ) 6782 { 6783 var table = $(settings.nTable); 6784 6785 // Add the ARIA grid role to the table 6786 table.attr( 'role', 'grid' ); 6787 6788 // Scrolling from here on in 6789 var scroll = settings.oScroll; 6790
6791 if ( scroll.sX === '' && scroll.sY === '' ) { 6792 return settings.nTable; 6793 } 6794 6795 var scrollX = scroll.sX; 6796 var scrollY = scroll.sY; 6797 var classes = settings.oClasses; 6798 var caption = table.children('caption'); 6799 var captionSide = caption.length ? caption[0]._captionSide : null; 6800 var headerClone = $( table[0].cloneNode(false) ); 6801 var footerClone = $( table[0].cloneNode(false) ); 6802 var footer = table.children('tfoot'); 6803 var _div = '<div/>'; 6804 var size = function ( s ) { 6805 return !s ? null : _fnStringToCss( s ); 6806 }; 6807 6808 if ( ! footer.length ) { 6809 footer = null; 6810 } 6811 6812 /* 6813 * The HTML structure that we want to generate in this function is: 6814 * div - scroller 6815 * div - scroll head 6816 * div - scroll head inner 6817 * table - scroll head table 6818 * thead - thead 6819 * div - scroll body 6820 * table - table (master table) 6821 * thead - thead clone for sizing 6822 * tbody - tbody 6823 * div - scroll foot 6824 * div - scroll foot inner 6825 * table - scroll foot table 6826 * tfoot - tfoot 6827 */ 6828 var scroller = $( _div, { 'class': classes.sScrollWrapper } ) 6829 .append( 6830 $(_div, { 'class': classes.sScrollHead } ) 6831 .css( { 6832 overflow: 'hidden', 6833 position: 'relative', 6834 border: 0, 6835 width: scrollX ? size(scrollX) : '100%' 6836 } ) 6837 .append( 6838 $(_div, { 'class': classes.sScrollHeadInner } ) 6839 .css( { 6840 'box-sizing': 'content-box', 6841 width: scroll.sXInner || '100%' 6842 } ) 6843 .append( 6844 headerClone 6845 .removeAttr('id') 6846 .css( 'margin-left', 0 ) 6847 .append( captionSide === 'top' ? caption : null ) 6848 .append( 6849 table.children('thead') 6850 ) 6851 ) 6852 ) 6853 ) 6854 .append( 6855 $(_div, { 'class': classes.sScrollBody } ) 6856 .css( { 6857 position: 'relative', 6858 overflow: 'auto', 6859 width: size( scrollX ) 6860 } ) 6861 .append( table ) 6862 ); 6863 6864 if ( footer ) { 6865 scroller.append( 6866 $(_div, { 'class': classes.sScrollFoot } ) 6867 .css( { 6868 overflow: 'hidden', 6869 border: 0, 6870 width: scrollX ? size(scrollX) : '100%' 6871 } ) 6872 .append( 6873 $(_div, { 'class': classes.sScrollFootInner } ) 6874 .append( 6875 footerClone 6876 .removeAttr('id') 6877 .css( 'margin-left', 0 ) 6878 .append( captionSide === 'bottom' ? caption : null ) 6879 .append( 6880 table.children('tfoot') 6881 ) 6882 ) 6883 ) 6884 ); 6885 } 6886 6887 var children = scroller.children(); 6888 var scrollHead = children[0]; 6889 var scrollBody = children[1]; 6890 var scrollFoot = footer ? children[2] : null; 6891 6892 // When the body is scrolled, then we also want to scroll the headers 6893 if ( scrollX ) { 6894 $(scrollBody).on( 'scroll.DT', function (e) { 6895 var scrollLeft = this.scrollLeft; 6896 6897 scrollHead.scrollLeft = scrollLeft; 6898 6899 if ( footer ) { 6900 scrollFoot.scrollLeft = scrollLeft; 6901 } 6902 } ); 6903 } 6904 6905 $(scrollBody).css( 6906 scrollY && scroll.bCollapse ? 'max-height' : 'height', 6907 scrollY 6908 ); 6909 6910 settings.nScrollHead = scrollHead; 6911 settings.nScrollBody = scrollBody; 6912 settings.nScrollFoot = scrollFoot; 6913 6914 // On redraw - align columns 6915 settings.aoDrawCallback.push( { 6916 "fn": _fnScrollDraw, 6917 "sName": "scrolling" 6918 } ); 6919 6920 return scroller[0]; 6921 } 6922 6923 6924 6925 /** 6926 * Update the header, footer and body tables for resizing - i.e. column 6927 * alignment. 6928 * 6929 * Welcome to the most horrible function DataTables. The process that this 6930 * function follows is basically: 6931 * 1. Re-create the table inside the scrolling div 6932 * 2. Take live measurements from the DOM 6933 * 3. Apply the measurements to align the columns 6934 * 4. Clean up 6935 * 6936 * @param {object} settings dataTables settings object 6937 * @memberof DataTable#oApi 6938 */ 6939 function _fnScrollDraw ( settings ) 6940 { 6941 // Given that this is such a monster function, a lot of variables are use 6942 // to try and keep the minimised size as small as possible 6943 var 6944 scroll = settings.oScroll, 6945 scrollX = scroll.sX, 6946 scrollXInner = scroll.sXInner, 6947 scrollY = scroll.sY, 6948 barWidth = scroll.iBarWidth, 6949 divHeader = $(settings.nScrollHead), 6950 divHeaderStyle = divHeader[0].style, 6951 divHeaderInner = divHeader.children('div'), 6952 divHeaderInnerStyle = divHeaderInner[0].style, 6953 divHeaderTable = divHeaderInner.children('table'), 6954 divBodyEl = settings.nScrollBody,
6955 divBody = $(divBodyEl), 6956 divBodyStyle = divBodyEl.style, 6957 divFooter = $(settings.nScrollFoot), 6958 divFooterInner = divFooter.children('div'), 6959 divFooterTable = divFooterInner.children('table'), 6960 header = $(settings.nTHead), 6961 table = $(settings.nTable), 6962 tableEl = table[0], 6963 tableStyle = tableEl.style, 6964 footer = settings.nTFoot ? $(settings.nTFoot) : null, 6965 browser = settings.oBrowser, 6966 ie67 = browser.bScrollOversize, 6967 dtHeaderCells = _pluck( settings.aoColumns, 'nTh' ), 6968 headerTrgEls, footerTrgEls, 6969 headerSrcEls, footerSrcEls, 6970 headerCopy, footerCopy, 6971 headerWidths=[], footerWidths=[], 6972 headerContent=[], footerContent=[], 6973 idx, correction, sanityWidth, 6974 zeroOut = function(nSizer) { 6975 var style = nSizer.style; 6976 style.paddingTop = "0"; 6977 style.paddingBottom = "0"; 6978 style.borderTopWidth = "0"; 6979 style.borderBottomWidth = "0"; 6980 style.height = 0; 6981 }; 6982 6983 // If the scrollbar visibility has changed from the last draw, we need to 6984 // adjust the column sizes as the table width will have changed to account 6985 // for the scrollbar 6986 var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight; 6987 6988 if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) { 6989 settings.scrollBarVis = scrollBarVis; 6990 _fnAdjustColumnSizing( settings ); 6991 return; // adjust column sizing will call this function again 6992 } 6993 else { 6994 settings.scrollBarVis = scrollBarVis; 6995 } 6996 6997 /* 6998 * 1. Re-create the table inside the scrolling div 6999 */ 7000 7001 // Remove the old minimised thead and tfoot elements in the inner table 7002 table.children('thead, tfoot').remove(); 7003 7004 if ( footer ) { 7005 footerCopy = footer.clone().prependTo( table ); 7006 footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized 7007 footerSrcEls = footerCopy.find('tr'); 7008 } 7009 7010 // Clone the current header and footer elements and then place it into the inner table 7011 headerCopy = header.clone().prependTo( table ); 7012 headerTrgEls = header.find('tr'); // original header is in its own table 7013 headerSrcEls = headerCopy.find('tr'); 7014 headerCopy.find('th, td').removeAttr('tabindex'); 7015 7016 7017 /* 7018 * 2. Take live measurements from the DOM - do not alter the DOM itself! 7019 */ 7020 7021 // Remove old sizing and apply the calculated column widths 7022 // Get the unique column headers in the newly created (cloned) header. We want to apply the 7023 // calculated sizes to this header 7024 if ( ! scrollX ) 7025 { 7026 divBodyStyle.width = '100%'; 7027 divHeader[0].style.width = '100%'; 7028 } 7029 7030 $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) { 7031 idx = _fnVisibleToColumnIndex( settings, i ); 7032 el.style.width = settings.aoColumns[idx].sWidth; 7033 } ); 7034 7035 if ( footer ) { 7036 _fnApplyToChildren( function(n) { 7037 n.style.width = ""; 7038 }, footerSrcEls ); 7039 } 7040 7041 // Size the table as a whole 7042 sanityWidth = table.outerWidth(); 7043 if ( scrollX === "" ) { 7044 // No x scrolling 7045 tableStyle.width = "100%"; 7046 7047 // IE7 will make the width of the table when 100% include the scrollbar 7048 // - which is shouldn't. When there is a scrollbar we need to take this 7049 // into account. 7050 if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight || 7051 divBody.css('overflow-y') == "scroll") 7052 ) { 7053 tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth); 7054 } 7055 7056 // Recalculate the sanity width 7057 sanityWidth = table.outerWidth(); 7058 } 7059 else if ( scrollXInner !== "" ) { 7060 // legacy x scroll inner has been given - use it 7061 tableStyle.width = _fnStringToCss(scrollXInner); 7062 7063 // Recalculate the sanity width 7064 sanityWidth = table.outerWidth(); 7065 } 7066 7067 // Hidden header should have zero height, so remove padding and borders. Then 7068 // set the width based on the real headers 7069 7070 // Apply all styles in one pass 7071 _fnApplyToChildren( zeroOut, headerSrcEls ); 7072 7073 // Read all widths in next pass 7074 _fnApplyToChildren( function(nSizer) { 7075 headerContent.push( nSizer.innerHTML ); 7076 headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) ); 7077 }, headerSrcEls ); 7078 7079 // Apply all widths in final pass 7080 _fnApplyToChildren( function(nToSize, i) { 7081 // Only apply widths to the DataTables detected header cells - this 7082 // prevents complex headers from having contradictory sizes applied 7083 if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) { 7084 nToSize.style.width = headerWidths[i]; 7085 } 7086 }, headerTrgEls ); 7087 7088 $(headerSrcEls).height(0); 7089 7090 /* Same again with the footer if we have one */ 7091 if ( footer ) 7092 { 7093 _fnApplyToChildren( zeroOut, footerSrcEls ); 7094 7095 _fnApplyToChildren( function(nSizer) { 7096 footerContent.push( nSizer.innerHTML );
7097 footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) ); 7098 }, footerSrcEls ); 7099 7100 _fnApplyToChildren( function(nToSize, i) { 7101 nToSize.style.width = footerWidths[i]; 7102 }, footerTrgEls ); 7103 7104 $(footerSrcEls).height(0); 7105 } 7106 7107 7108 /* 7109 * 3. Apply the measurements 7110 */ 7111 7112 // "Hide" the header and footer that we used for the sizing. We need to keep 7113 // the content of the cell so that the width applied to the header and body 7114 // both match, but we want to hide it completely. We want to also fix their 7115 // width to what they currently are 7116 _fnApplyToChildren( function(nSizer, i) { 7117 nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>'; 7118 nSizer.childNodes[0].style.height = "0"; 7119 nSizer.childNodes[0].style.overflow = "hidden"; 7120 nSizer.style.width = headerWidths[i]; 7121 }, headerSrcEls ); 7122 7123 if ( footer ) 7124 { 7125 _fnApplyToChildren( function(nSizer, i) { 7126 nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>'; 7127 nSizer.childNodes[0].style.height = "0"; 7128 nSizer.childNodes[0].style.overflow = "hidden"; 7129 nSizer.style.width = footerWidths[i]; 7130 }, footerSrcEls ); 7131 } 7132 7133 // Sanity check that the table is of a sensible width. If not then we are going to get 7134 // misalignment - try to prevent this by not allowing the table to shrink below its min width 7135 if ( table.outerWidth() < sanityWidth ) 7136 { 7137 // The min width depends upon if we have a vertical scrollbar visible or not */ 7138 correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight || 7139 divBody.css('overflow-y') == "scroll")) ? 7140 sanityWidth+barWidth : 7141 sanityWidth; 7142 7143 // IE6/7 are a law unto themselves... 7144 if ( ie67 && (divBodyEl.scrollHeight > 7145 divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll") 7146 ) { 7147 tableStyle.width = _fnStringToCss( correction-barWidth ); 7148 } 7149 7150 // And give the user a warning that we've stopped the table getting too small 7151 if ( scrollX === "" || scrollXInner !== "" ) { 7152 _fnLog( settings, 1, 'Possible column misalignment', 6 ); 7153 } 7154 } 7155 else 7156 { 7157 correction = '100%'; 7158 } 7159 7160 // Apply to the container elements 7161 divBodyStyle.width = _fnStringToCss( correction ); 7162 divHeaderStyle.width = _fnStringToCss( correction ); 7163 7164 if ( footer ) { 7165 settings.nScrollFoot.style.width = _fnStringToCss( correction ); 7166 } 7167 7168 7169 /* 7170 * 4. Clean up 7171 */ 7172 if ( ! scrollY ) { 7173 /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting 7174 * the scrollbar height from the visible display, rather than adding it on. We need to 7175 * set the height in order to sort this. Don't want to do it in any other browsers. 7176 */ 7177 if ( ie67 ) { 7178 divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth ); 7179 } 7180 } 7181 7182 /* Finally set the width's of the header and footer tables */ 7183 var iOuterWidth = table.outerWidth(); 7184 divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth ); 7185 divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth ); 7186 7187 // Figure out if there are scrollbar present - if so then we need a the header and footer to 7188 // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar) 7189 var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll"; 7190 var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' ); 7191 divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px"; 7192 7193 if ( footer ) { 7194 divFooterTable[0].style.width = _fnStringToCss( iOuterWidth ); 7195 divFooterInner[0].style.width = _fnStringToCss( iOuterWidth ); 7196 divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px"; 7197 } 7198 7199 // Correct DOM ordering for colgroup - comes before the thead 7200 table.children('colgroup').insertBefore( table.children('thead') ); 7201 7202 /* Adjust the position of the header in case we loose the y-scrollbar */ 7203 divBody.scroll(); 7204 7205 // If sorting or filtering has occurred, jump the scrolling back to the top 7206 // only if we aren't holding the position 7207 if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) { 7208 divBodyEl.scrollTop = 0; 7209 } 7210 } 7211 7212 7213 7214 /** 7215 * Apply a given function to the display child nodes of an element array (typically 7216 * TD children of TR rows 7217 * @param {function} fn Method to apply to the objects 7218 * @param array {nodes} an1 List of elements to look through for display children 7219 * @param array {nodes} an2 Another list (identical structure to the first) - optional 7220 * @memberof DataTable#oApi 7221 */ 7222 function _fnApplyToChildren( fn, an1, an2 ) 7223 { 7224 var index=0, i=0, iLen=an1.length; 7225 var nNode1, nNode2; 7226 7227 while ( i < iLen ) { 7228 nNode1 = an1[i].firstChild; 7229 nNode2 = an2 ? an2[i].firstChild : null; 7230 7231 while ( nNode1 ) { 7232 if ( nNode1.nodeType === 1 ) { 7233 if ( an2 ) { 7234 fn( nNode1, nNode2, index ); 7235 } 7236 else { 7237 fn( nNode1, index ); 7238 } 7239 7240 index++; 7241 } 7242 7243 nNode1 = nNode1.nextSibling; 7244 nNode2 = an2 ? nNode2.nextSibling : null; 7245 } 7246 7247 i++; 7248 } 7249 } 7250 7251 7252 7253 var __re_html_remove = /<.*?>/g; 7254 7255 7256 /** 7257 * Calculate the width of columns for the table 7258 * @param {object} oSettings dataTables settings object 7259 * @memberof DataTable#oApi 7260 */ 7261 function _fnCalculateColumnWidths ( oSettings ) 7262 { 7263 var 7264 table = oSettings.nTable, 7265 columns = oSettings.aoColumns, 7266 scroll = oSettings.oScroll, 7267 scrollY = scroll.sY, 7268 scrollX = scroll.sX, 7269 scrollXInner = scroll.sXInner, 7270 columnCount = columns.length, 7271 visibleColumns = _fnGetColumns( oSettings, 'bVisible' ), 7272 headerCells = $('th', oSettings.nTHead), 7273 tableWidthAttr = table.getAttribute('width'), // from DOM element 7274 tableContainer = table.parentNode, 7275 userInputs = false, 7276 i, column, columnIdx, width, outerWidth, 7277 browser = oSettings.oBrowser, 7278 ie67 = browser.bScrollOversize; 7279 7280 var styleWidth = table.style.width; 7281 if ( styleWidth && styleWidth.indexOf('%') !== -1 ) { 7282 tableWidthAttr = styleWidth; 7283 } 7284 7285 /* Convert any user input sizes into pixel sizes */ 7286 for ( i=0 ; i<visibleColumns.length ; i++ ) { 7287 column = columns[ visibleColumns[i] ]; 7288 7289 if ( column.sWidth !== null ) { 7290 column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer ); 7291 7292 userInputs = true; 7293 } 7294 } 7295 7296 /* If the number of columns in the DOM equals the number that we have to 7297 * process in DataTables, then we can use the offsets that are created by 7298 * the web- browser. No custom sizes can be set in order for this to happen, 7299 * nor scrolling used 7300 */ 7301 if ( ie67 || ! userInputs && ! scrollX && ! scrollY && 7302 columnCount == _fnVisbleColumns( oSettings ) && 7303 columnCount == headerCells.length 7304 ) { 7305 for ( i=0 ; i<columnCount ; i++ ) { 7306 var colIdx = _fnVisibleToColumnIndex( oSettings, i ); 7307 7308 if ( colIdx !== null ) { 7309 columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() ); 7310 } 7311 } 7312 } 7313 else 7314 { 7315 // Otherwise construct a single row, worst case, table with the widest 7316 // node in the data, assign any user defined widths, then insert it into
7317 // the DOM and allow the browser to do all the hard work of calculating 7318 // table widths 7319 var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table 7320 .css( 'visibility', 'hidden' ) 7321 .removeAttr( 'id' ); 7322 7323 // Clean up the table body 7324 tmpTable.find('tbody tr').remove(); 7325 var tr = $('<tr/>').appendTo( tmpTable.find('tbody') ); 7326 7327 // Clone the table header and footer - we can't use the header / footer 7328 // from the cloned table, since if scrolling is active, the table's 7329 // real header and footer are contained in different table tags 7330 tmpTable.find('thead, tfoot').remove(); 7331 tmpTable 7332 .append( $(oSettings.nTHead).clone() ) 7333 .append( $(oSettings.nTFoot).clone() ); 7334 7335 // Remove any assigned widths from the footer (from scrolling) 7336 tmpTable.find('tfoot th, tfoot td').css('width', ''); 7337 7338 // Apply custom sizing to the cloned header 7339 headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] ); 7340 7341 for ( i=0 ; i<visibleColumns.length ; i++ ) { 7342 column = columns[ visibleColumns[i] ]; 7343 7344 headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ? 7345 _fnStringToCss( column.sWidthOrig ) : 7346 ''; 7347 7348 // For scrollX we need to force the column width otherwise the 7349 // browser will collapse it. If this width is smaller than the 7350 // width the column requires, then it will have no effect 7351 if ( column.sWidthOrig && scrollX ) { 7352 $( headerCells[i] ).append( $('<div/>').css( { 7353 width: column.sWidthOrig, 7354 margin: 0, 7355 padding: 0, 7356 border: 0, 7357 height: 1 7358 } ) ); 7359 } 7360 } 7361 7362 // Find the widest cell for each column and put it into the table 7363 if ( oSettings.aoData.length ) { 7364 for ( i=0 ; i<visibleColumns.length ; i++ ) { 7365 columnIdx = visibleColumns[i]; 7366 column = columns[ columnIdx ]; 7367 7368 $( _fnGetWidestNode( oSettings, columnIdx ) ) 7369 .clone( false ) 7370 .append( column.sContentPadding ) 7371 .appendTo( tr ); 7372 } 7373 } 7374 7375 // Tidy the temporary table - remove name attributes so there aren't 7376 // duplicated in the dom (radio elements for example) 7377 $('[name]', tmpTable).removeAttr('name'); 7378 7379 // Table has been built, attach to the document so we can work with it. 7380 // A holding element is used, positioned at the top of the container 7381 // with minimal height, so it has no effect on if the container scrolls 7382 // or not. Otherwise it might trigger scrolling when it actually isn't 7383 // needed 7384 var holder = $('<div/>').css( scrollX || scrollY ? 7385 { 7386 position: 'absolute', 7387 top: 0, 7388 left: 0, 7389 height: 1, 7390 right: 0, 7391 overflow: 'hidden' 7392 } : 7393 {} 7394 ) 7395 .append( tmpTable ) 7396 .appendTo( tableContainer ); 7397 7398 // When scrolling (X or Y) we want to set the width of the table as 7399 // appropriate. However, when not scrolling leave the table width as it 7400 // is. This results in slightly different, but I think correct behaviour 7401 if ( scrollX && scrollXInner ) { 7402 tmpTable.width( scrollXInner ); 7403 } 7404 else if ( scrollX ) { 7405 tmpTable.css( 'width', 'auto' ); 7406 tmpTable.removeAttr('width'); 7407 7408 // If there is no width attribute or style, then allow the table to 7409 // collapse 7410 if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) { 7411 tmpTable.width( tableContainer.clientWidth ); 7412 } 7413 } 7414 else if ( scrollY ) { 7415 tmpTable.width( tableContainer.clientWidth ); 7416 } 7417 else if ( tableWidthAttr ) { 7418 tmpTable.width( tableWidthAttr ); 7419 } 7420 7421 // Get the width of each column in the constructed table - we need to 7422 // know the inner width (so it can be assigned to the other table's 7423 // cells) and the outer width so we can calculate the full width of the 7424 // table. This is safe since DataTables requires a unique cell for each 7425 // column, but if ever a header can span multiple columns, this will 7426 // need to be modified. 7427 var total = 0; 7428 for ( i=0 ; i<visibleColumns.length ; i++ ) { 7429 var cell = $(headerCells[i]); 7430 var border = cell.outerWidth() - cell.width(); 7431 7432 // Use getBounding... where possible (not IE8-) because it can give 7433 // sub-pixel accuracy, which we then want to round up! 7434 var bounding = browser.bBounding ? 7435 Math.ceil( headerCells[i].getBoundingClientRect().width ) : 7436 cell.outerWidth(); 7437 7438 // Total is tracked to remove any sub-pixel errors as the outerWidth 7439 // of the table might not equal the total given here (IE!). 7440 total += bounding; 7441
7442 // Width for each column to use 7443 columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border ); 7444 } 7445 7446 table.style.width = _fnStringToCss( total ); 7447 7448 // Finished with the table - ditch it 7449 holder.remove(); 7450 } 7451 7452 // If there is a width attr, we want to attach an event listener which 7453 // allows the table sizing to automatically adjust when the window is 7454 // resized. Use the width attr rather than CSS, since we can't know if the 7455 // CSS is a relative value or absolute - DOM read is always px. 7456 if ( tableWidthAttr ) { 7457 table.style.width = _fnStringToCss( tableWidthAttr ); 7458 } 7459 7460 if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) { 7461 var bindResize = function () { 7462 $(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () { 7463 _fnAdjustColumnSizing( oSettings ); 7464 } ) ); 7465 }; 7466 7467 // IE6/7 will crash if we bind a resize event handler on page load. 7468 // To be removed in 1.11 which drops IE6/7 support 7469 if ( ie67 ) { 7470 setTimeout( bindResize, 1000 ); 7471 } 7472 else { 7473 bindResize(); 7474 } 7475 7476 oSettings._reszEvt = true; 7477 } 7478 } 7479 7480 7481 /** 7482 * Throttle the calls to a function. Arguments and context are maintained for 7483 * the throttled function 7484 * @param {function} fn Function to be called 7485 * @param {int} [freq=200] call frequency in mS 7486 * @returns {function} wrapped function 7487 * @memberof DataTable#oApi 7488 */ 7489 var _fnThrottle = DataTable.util.throttle; 7490 7491 7492 /** 7493 * Convert a CSS unit width to pixels (e.g. 2em) 7494 * @param {string} width width to be converted 7495 * @param {node} parent parent to get the with for (required for relative widths) - optional 7496 * @returns {int} width in pixels 7497 * @memberof DataTable#oApi 7498 */ 7499 function _fnConvertToWidth ( width, parent ) 7500 { 7501 if ( ! width ) { 7502 return 0; 7503 } 7504 7505 var n = $('<div/>') 7506 .css( 'width', _fnStringToCss( width ) ) 7507 .appendTo( parent || document.body ); 7508 7509 var val = n[0].offsetWidth; 7510 n.remove(); 7511 7512 return val; 7513 } 7514 7515 7516 /** 7517 * Get the widest node 7518 * @param {object} settings dataTables settings object 7519 * @param {int} colIdx column of interest 7520 * @returns {node} widest table node 7521 * @memberof DataTable#oApi 7522 */ 7523 function _fnGetWidestNode( settings, colIdx ) 7524 { 7525 var idx = _fnGetMaxLenString( settings, colIdx ); 7526 if ( idx < 0 ) { 7527 return null; 7528 } 7529 7530 var data = settings.aoData[ idx ]; 7531 return ! data.nTr ? // Might not have been created when deferred rendering 7532 $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] : 7533 data.anCells[ colIdx ]; 7534 } 7535 7536 7537 /** 7538 * Get the maximum strlen for each data column 7539 * @param {object} settings dataTables settings object 7540 * @param {int} colIdx column of interest 7541 * @returns {string} max string length for each column 7542 * @memberof DataTable#oApi 7543 */ 7544 function _fnGetMaxLenString( settings, colIdx ) 7545 { 7546 var s, max=-1, maxIdx = -1; 7547 7548 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 7549 s = _fnGetCellData( settings, i, colIdx, 'display' )+''; 7550 s = s.replace( __re_html_remove, '' ); 7551 s = s.replace( / /g, ' ' ); 7552 7553 if ( s.length > max ) { 7554 max = s.length; 7555 maxIdx = i; 7556 } 7557 } 7558 7559 return maxIdx; 7560 } 7561 7562 7563 /** 7564 * Append a CSS unit (only if required) to a string 7565 * @param {string} value to css-ify 7566 * @returns {string} value with css unit 7567 * @memberof DataTable#oApi 7568 */ 7569 function _fnStringToCss( s ) 7570 { 7571 if ( s === null ) { 7572 return '0px'; 7573 } 7574 7575 if ( typeof s == 'number' ) { 7576 return s < 0 ? 7577 '0px' : 7578 s+'px'; 7579 } 7580 7581 // Check it has a unit character already 7582 return s.match(/\d$/) ? 7583 s+'px' : 7584 s; 7585 } 7586 7587 7588 7589 function _fnSortFlatten ( settings ) 7590 { 7591 var 7592 i, iLen, k, kLen, 7593 aSort = [], 7594 aiOrig = [], 7595 aoColumns = settings.aoColumns, 7596 aDataSort, iCol, sType, srcCol, 7597 fixed = settings.aaSortingFixed, 7598 fixedObj = $.isPlainObject( fixed ), 7599 nestedSort = [], 7600 add = function ( a ) { 7601 if ( a.length && ! $.isArray( a[0] ) ) { 7602 // 1D array 7603 nestedSort.push( a ); 7604 } 7605 else { 7606 // 2D array 7607 $.merge( nestedSort, a ); 7608 } 7609 }; 7610 7611 // Build the sort array, with pre-fix and post-fix options if they have been 7612 // specified 7613 if ( $.isArray( fixed ) ) { 7614 add( fixed ); 7615 } 7616 7617 if ( fixedObj && fixed.pre ) { 7618 add( fixed.pre ); 7619 } 7620 7621 add( settings.aaSorting ); 7622 7623 if (fixedObj && fixed.post ) { 7624 add( fixed.post ); 7625 } 7626 7627 for ( i=0 ; i<nestedSort.length ; i++ ) 7628 { 7629 srcCol = nestedSort[i][0]; 7630 aDataSort = aoColumns[ srcCol ].aDataSort; 7631 7632 for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ ) 7633 { 7634 iCol = aDataSort[k]; 7635 sType = aoColumns[ iCol ].sType || 'string'; 7636 7637 if ( nestedSort[i]._idx === undefined ) { 7638 nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting ); 7639 } 7640 7641 aSort.push( { 7642 src: srcCol, 7643 col: iCol, 7644 dir: nestedSort[i][1], 7645 index: nestedSort[i]._idx, 7646 type: sType, 7647 formatter: DataTable.ext.type.order[ sType+"-pre" ] 7648 } ); 7649 } 7650 } 7651 7652 return aSort; 7653 } 7654 7655 /** 7656 * Change the order of the table 7657 * @param {object} oSettings dataTables settings object 7658 * @memberof DataTable#oApi 7659 * @todo This really needs split up! 7660 */ 7661 function _fnSort ( oSettings ) 7662 { 7663 var 7664 i, ien, iLen, j, jLen, k, kLen, 7665 sDataType, nTh, 7666 aiOrig = [], 7667 oExtSort = DataTable.ext.type.order, 7668 aoData = oSettings.aoData, 7669 aoColumns = oSettings.aoColumns, 7670 aDataSort, data, iCol, sType, oSort, 7671 formatters = 0, 7672 sortCol, 7673 displayMaster = oSettings.aiDisplayMaster, 7674 aSort; 7675 7676 // Resolve any column types that are unknown due to addition or invalidation 7677 // @todo Can this be moved into a 'data-ready' handler which is called when 7678 // data is going to be used in the table? 7679 _fnColumnTypes( oSettings ); 7680 7681 aSort = _fnSortFlatten( oSettings ); 7682 7683 for ( i=0, ien=aSort.length ; i<ien ; i++ ) { 7684 sortCol = aSort[i]; 7685 7686 // Track if we can use the fast sort algorithm 7687 if ( sortCol.formatter ) { 7688 formatters++; 7689 } 7690 7691 // Load the data needed for the sort, for each cell 7692 _fnSortData( oSettings, sortCol.col ); 7693 } 7694 7695 /* No sorting required if server-side or no sorting array */ 7696 if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 ) 7697 { 7698 // Create a value - key array of the current row positions such that we can use their 7699 // current position during the sort, if values match, in order to perform stable sorting 7700 for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) { 7701 aiOrig[ displayMaster[i] ] = i; 7702 } 7703
7704 /* Do the sort - here we want multi-column sorting based on a given data source (column) 7705 * and sorting function (from oSort) in a certain direction. It's reasonably complex to 7706 * follow on it's own, but this is what we want (example two column sorting): 7707 * fnLocalSorting = function(a,b){ 7708 * var iTest; 7709 * iTest = oSort['string-asc']('data11', 'data12'); 7710 * if (iTest !== 0) 7711 * return iTest; 7712 * iTest = oSort['numeric-desc']('data21', 'data22'); 7713 * if (iTest !== 0) 7714 * return iTest; 7715 * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] ); 7716 * } 7717 * Basically we have a test for each sorting column, if the data in that column is equal, 7718 * test the next column. If all columns match, then we use a numeric sort on the row 7719 * positions in the original data array to provide a stable sort. 7720 * 7721 * Note - I know it seems excessive to have two sorting methods, but the first is around 7722 * 15% faster, so the second is only maintained for backwards compatibility with sorting 7723 * methods which do not have a pre-sort formatting function. 7724 */ 7725 if ( formatters === aSort.length ) { 7726 // All sort types have formatting functions 7727 displayMaster.sort( function ( a, b ) { 7728 var 7729 x, y, k, test, sort, 7730 len=aSort.length, 7731 dataA = aoData[a]._aSortData, 7732 dataB = aoData[b]._aSortData; 7733 7734 for ( k=0 ; k<len ; k++ ) { 7735 sort = aSort[k]; 7736 7737 x = dataA[ sort.col ]; 7738 y = dataB[ sort.col ]; 7739 7740 test = x<y ? -1 : x>y ? 1 : 0; 7741 if ( test !== 0 ) { 7742 return sort.dir === 'asc' ? test : -test; 7743 } 7744 } 7745 7746 x = aiOrig[a]; 7747 y = aiOrig[b]; 7748 return x<y ? -1 : x>y ? 1 : 0; 7749 } ); 7750 } 7751 else { 7752 // Depreciated - remove in 1.11 (providing a plug-in option) 7753 // Not all sort types have formatting methods, so we have to call their sorting 7754 // methods. 7755 displayMaster.sort( function ( a, b ) { 7756 var 7757 x, y, k, l, test, sort, fn, 7758 len=aSort.length, 7759 dataA = aoData[a]._aSortData, 7760 dataB = aoData[b]._aSortData; 7761 7762 for ( k=0 ; k<len ; k++ ) { 7763 sort = aSort[k]; 7764 7765 x = dataA[ sort.col ]; 7766 y = dataB[ sort.col ]; 7767 7768 fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ]; 7769 test = fn( x, y ); 7770 if ( test !== 0 ) { 7771 return test; 7772 } 7773 } 7774 7775 x = aiOrig[a]; 7776 y = aiOrig[b]; 7777 return x<y ? -1 : x>y ? 1 : 0; 7778 } ); 7779 } 7780 } 7781 7782 /* Tell the draw function that we have sorted the data */ 7783 oSettings.bSorted = true; 7784 } 7785 7786 7787 function _fnSortAria ( settings ) 7788 { 7789 var label; 7790 var nextSort; 7791 var columns = settings.aoColumns; 7792 var aSort = _fnSortFlatten( settings ); 7793 var oAria = settings.oLanguage.oAria; 7794 7795 // ARIA attributes - need to loop all columns, to update all (removing old 7796 // attributes as needed) 7797 for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) 7798 { 7799 var col = columns[i]; 7800 var asSorting = col.asSorting; 7801 var sTitle = col.sTitle.replace( /<.*?>/g, "" ); 7802 var th = col.nTh; 7803 7804 // IE7 is throwing an error when setting these properties with jQuery's 7805 // attr() and removeAttr() methods... 7806 th.removeAttribute('aria-sort'); 7807 7808 /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ 7809 if ( col.bSortable ) { 7810 if ( aSort.length > 0 && aSort[0].col == i ) { 7811 th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" ); 7812 nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0]; 7813 } 7814 else { 7815 nextSort = asSorting[0]; 7816 } 7817 7818 label = sTitle + ( nextSort === "asc" ? 7819 oAria.sSortAscending : 7820 oAria.sSortDescending 7821 ); 7822 } 7823 else { 7824 label = sTitle; 7825 } 7826 7827 th.setAttribute('aria-label', label); 7828 } 7829 } 7830 7831 7832 /** 7833 * Function to run on user sort request 7834 * @param {object} settings dataTables settings object 7835 * @param {node} attachTo node to attach the handler to 7836 * @param {int} colIdx column sorting index 7837 * @param {boolean} [append=false] Append the requested sort to the existing
7838 * sort if true (i.e. multi-column sort) 7839 * @param {function} [callback] callback function 7840 * @memberof DataTable#oApi 7841 */ 7842 function _fnSortListener ( settings, colIdx, append, callback ) 7843 { 7844 var col = settings.aoColumns[ colIdx ]; 7845 var sorting = settings.aaSorting; 7846 var asSorting = col.asSorting; 7847 var nextSortIdx; 7848 var next = function ( a, overflow ) { 7849 var idx = a._idx; 7850 if ( idx === undefined ) { 7851 idx = $.inArray( a[1], asSorting ); 7852 } 7853 7854 return idx+1 < asSorting.length ? 7855 idx+1 : 7856 overflow ? 7857 null : 7858 0; 7859 }; 7860 7861 // Convert to 2D array if needed 7862 if ( typeof sorting[0] === 'number' ) { 7863 sorting = settings.aaSorting = [ sorting ]; 7864 } 7865 7866 // If appending the sort then we are multi-column sorting 7867 if ( append && settings.oFeatures.bSortMulti ) { 7868 // Are we already doing some kind of sort on this column? 7869 var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') ); 7870 7871 if ( sortIdx !== -1 ) { 7872 // Yes, modify the sort 7873 nextSortIdx = next( sorting[sortIdx], true ); 7874 7875 if ( nextSortIdx === null && sorting.length === 1 ) { 7876 nextSortIdx = 0; // can't remove sorting completely 7877 } 7878 7879 if ( nextSortIdx === null ) { 7880 sorting.splice( sortIdx, 1 ); 7881 } 7882 else { 7883 sorting[sortIdx][1] = asSorting[ nextSortIdx ]; 7884 sorting[sortIdx]._idx = nextSortIdx; 7885 } 7886 } 7887 else { 7888 // No sort on this column yet 7889 sorting.push( [ colIdx, asSorting[0], 0 ] ); 7890 sorting[sorting.length-1]._idx = 0; 7891 } 7892 } 7893 else if ( sorting.length && sorting[0][0] == colIdx ) { 7894 // Single column - already sorting on this column, modify the sort 7895 nextSortIdx = next( sorting[0] ); 7896 7897 sorting.length = 1; 7898 sorting[0][1] = asSorting[ nextSortIdx ]; 7899 sorting[0]._idx = nextSortIdx; 7900 } 7901 else { 7902 // Single column - sort only on this column 7903 sorting.length = 0; 7904 sorting.push( [ colIdx, asSorting[0] ] ); 7905 sorting[0]._idx = 0; 7906 } 7907 7908 // Run the sort by calling a full redraw 7909 _fnReDraw( settings ); 7910 7911 // callback used for async user interaction 7912 if ( typeof callback == 'function' ) { 7913 callback( settings ); 7914 } 7915 } 7916 7917 7918 /** 7919 * Attach a sort handler (click) to a node 7920 * @param {object} settings dataTables settings object 7921 * @param {node} attachTo node to attach the handler to 7922 * @param {int} colIdx column sorting index 7923 * @param {function} [callback] callback function 7924 * @memberof DataTable#oApi 7925 */ 7926 function _fnSortAttachListener ( settings, attachTo, colIdx, callback ) 7927 { 7928 var col = settings.aoColumns[ colIdx ]; 7929 7930 _fnBindAction( attachTo, {}, function (e) { 7931 /* If the column is not sortable - don't to anything */ 7932 if ( col.bSortable === false ) { 7933 return; 7934 } 7935 7936 // If processing is enabled use a timeout to allow the processing 7937 // display to be shown - otherwise to it synchronously 7938 if ( settings.oFeatures.bProcessing ) { 7939 _fnProcessingDisplay( settings, true ); 7940 7941 setTimeout( function() { 7942 _fnSortListener( settings, colIdx, e.shiftKey, callback ); 7943 7944 // In server-side processing, the draw callback will remove the 7945 // processing display 7946 if ( _fnDataSource( settings ) !== 'ssp' ) { 7947 _fnProcessingDisplay( settings, false ); 7948 } 7949 }, 0 ); 7950 } 7951 else { 7952 _fnSortListener( settings, colIdx, e.shiftKey, callback ); 7953 } 7954 } ); 7955 } 7956 7957 7958 /** 7959 * Set the sorting classes on table's body, Note: it is safe to call this function 7960 * when bSort and bSortClasses are false 7961 * @param {object} oSettings dataTables settings object 7962 * @memberof DataTable#oApi 7963 */ 7964 function _fnSortingClasses( settings ) 7965 { 7966 var oldSort = settings.aLastSort; 7967 var sortClass = settings.oClasses.sSortColumn; 7968 var sort = _fnSortFlatten( settings ); 7969 var features = settings.oFeatures; 7970 var i, ien, colIdx; 7971 7972 if ( features.bSort && features.bSortClasses ) { 7973 // Remove old sorting classes 7974 for ( i=0, ien=oldSort.length ; i<ien ; i++ ) { 7975 colIdx = oldSort[i].src; 7976 7977 // Remove column sorting 7978 $( _pluck( settings.aoData, 'anCells', colIdx ) ) 7979 .removeClass( sortClass + (i<2 ? i+1 : 3) ); 7980 } 7981 7982 // Add new column sorting 7983 for ( i=0, ien=sort.length ; i<ien ; i++ ) { 7984 colIdx = sort[i].src; 7985 7986 $( _pluck( settings.aoData, 'anCells', colIdx ) ) 7987 .addClass( sortClass + (i<2 ? i+1 : 3) ); 7988 } 7989 } 7990 7991 settings.aLastSort = sort; 7992 } 7993 7994 7995 // Get the data to sort a column, be it from cache, fresh (populating the 7996 // cache), or from a sort formatter 7997 function _fnSortData( settings, idx ) 7998 { 7999 // Custom sorting function - provided by the sort data type 8000 var column = settings.aoColumns[ idx ]; 8001 var customSort = DataTable.ext.order[ column.sSortDataType ]; 8002 var customData; 8003 8004 if ( customSort ) { 8005 customData = customSort.call( settings.oInstance, settings, idx, 8006 _fnColumnIndexToVisible( settings, idx ) 8007 ); 8008 } 8009 8010 // Use / populate cache 8011 var row, cellData; 8012 var formatter = DataTable.ext.type.order[ column.sType+"-pre" ]; 8013 8014 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 8015 row = settings.aoData[i]; 8016 8017 if ( ! row._aSortData ) { 8018 row._aSortData = []; 8019 } 8020 8021 if ( ! row._aSortData[idx] || customSort ) { 8022 cellData = customSort ? 8023 customData[i] : // If there was a custom sort function, use data from there 8024 _fnGetCellData( settings, i, idx, 'sort' ); 8025 8026 row._aSortData[ idx ] = formatter ? 8027 formatter( cellData ) : 8028 cellData; 8029 } 8030 } 8031 } 8032 8033 8034 8035 /** 8036 * Save the state of a table 8037 * @param {object} oSettings dataTables settings object 8038 * @memberof DataTable#oApi 8039 */ 8040 function _fnSaveState ( settings ) 8041 { 8042 if ( !settings.oFeatures.bStateSave || settings.bDestroying ) 8043 { 8044 return; 8045 } 8046 8047 /* Store the interesting variables */ 8048 var state = { 8049 time: +new Date(), 8050 start: settings._iDisplayStart, 8051 length: settings._iDisplayLength, 8052 order: $.extend( true, [], settings.aaSorting ), 8053 search: _fnSearchToCamel( settings.oPreviousSearch ),
8054 columns: $.map( settings.aoColumns, function ( col, i ) { 8055 return { 8056 visible: col.bVisible, 8057 search: _fnSearchToCamel( settings.aoPreSearchCols[i] ) 8058 }; 8059 } ) 8060 }; 8061 8062 _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] ); 8063 8064 settings.oSavedState = state; 8065 settings.fnStateSaveCallback.call( settings.oInstance, settings, state ); 8066 } 8067 8068 8069 /** 8070 * Attempt to load a saved table state 8071 * @param {object} oSettings dataTables settings object 8072 * @param {object} oInit DataTables init object so we can override settings 8073 * @param {function} callback Callback to execute when the state has been loaded 8074 * @memberof DataTable#oApi 8075 */ 8076 function _fnLoadState ( settings, oInit, callback ) 8077 { 8078 var i, ien; 8079 var columns = settings.aoColumns; 8080 var loaded = function ( s ) { 8081 if ( ! s || ! s.time ) { 8082 callback(); 8083 return; 8084 } 8085 8086 // Allow custom and plug-in manipulation functions to alter the saved data set and 8087 // cancelling of loading by returning false 8088 var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] ); 8089 if ( $.inArray( false, abStateLoad ) !== -1 ) { 8090 callback(); 8091 return; 8092 } 8093 8094 // Reject old data 8095 var duration = settings.iStateDuration; 8096 if ( duration > 0 && s.time < +new Date() - (duration*1000) ) { 8097 callback(); 8098 return; 8099 } 8100 8101 // Number of columns have changed - all bets are off, no restore of settings 8102 if ( s.columns && columns.length !== s.columns.length ) { 8103 callback(); 8104 return; 8105 } 8106 8107 // Store the saved state so it might be accessed at any time 8108 settings.oLoadedState = $.extend( true, {}, s ); 8109 8110 // Restore key features - todo - for 1.11 this needs to be done by 8111 // subscribed events 8112 if ( s.start !== undefined ) { 8113 settings._iDisplayStart = s.start; 8114 settings.iInitDisplayStart = s.start; 8115 } 8116 if ( s.length !== undefined ) { 8117 settings._iDisplayLength = s.length; 8118 } 8119 8120 // Order 8121 if ( s.order !== undefined ) { 8122 settings.aaSorting = []; 8123 $.each( s.order, function ( i, col ) { 8124 settings.aaSorting.push( col[0] >= columns.length ? 8125 [ 0, col[1] ] : 8126 col 8127 ); 8128 } ); 8129 } 8130 8131 // Search 8132 if ( s.search !== undefined ) { 8133 $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) ); 8134 } 8135 8136 // Columns 8137 // 8138 if ( s.columns ) { 8139 for ( i=0, ien=s.columns.length ; i<ien ; i++ ) { 8140 var col = s.columns[i]; 8141 8142 // Visibility 8143 if ( col.visible !== undefined ) { 8144 columns[i].bVisible = col.visible; 8145 } 8146 8147 // Search 8148 if ( col.search !== undefined ) { 8149 $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) ); 8150 } 8151 } 8152 } 8153 8154 _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] ); 8155 callback(); 8156 } 8157 8158 if ( ! settings.oFeatures.bStateSave ) { 8159 callback(); 8160 return; 8161 } 8162 8163 var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded ); 8164 8165 if ( state !== undefined ) { 8166 loaded( state ); 8167 } 8168 // otherwise, wait for the loaded callback to be executed 8169 } 8170 8171 8172 /** 8173 * Return the settings object for a particular table 8174 * @param {node} table table we are using as a dataTable 8175 * @returns {object} Settings object - or null if not found 8176 * @memberof DataTable#oApi 8177 */ 8178 function _fnSettingsFromNode ( table ) 8179 { 8180 var settings = DataTable.settings; 8181 var idx = $.inArray( table, _pluck( settings, 'nTable' ) ); 8182 8183 return idx !== -1 ? 8184 settings[ idx ] : 8185 null; 8186 } 8187 8188 8189 /** 8190 * Log an error message 8191 * @param {object} settings dataTables settings object 8192 * @param {int} level log error messages, or display them to the user 8193 * @param {string} msg error message 8194 * @param {int} tn Technical note id to get more information about the error. 8195 * @memberof DataTable#oApi 8196 */ 8197 function _fnLog( settings, level, msg, tn ) 8198 { 8199 msg = 'DataTables warning: '+ 8200 (settings ? 'table id='+settings.sTableId+' - ' : '')+msg; 8201 8202 if ( tn ) { 8203 msg += '. For more information about this error, please see '+ 8204 'http://datatables.net/tn/'+tn; 8205 } 8206 8207 if ( ! level ) { 8208 // Backwards compatibility pre 1.10 8209 var ext = DataTable.ext; 8210 var type = ext.sErrMode || ext.errMode; 8211 8212 if ( settings ) { 8213 _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] ); 8214 } 8215 8216 if ( type == 'alert' ) { 8217 alert( msg ); 8218 } 8219 else if ( type == 'throw' ) { 8220 throw new Error(msg); 8221 } 8222 else if ( typeof type == 'function' ) { 8223 type( settings, tn, msg ); 8224 } 8225 } 8226 else if ( window.console && console.log ) { 8227 console.log( msg ); 8228 } 8229 } 8230 8231 8232 /** 8233 * See if a property is defined on one object, if so assign it to the other object 8234 * @param {object} ret target object 8235 * @param {object} src source object 8236 * @param {string} name property 8237 * @param {string} [mappedName] name to map too - optional, name used if not given 8238 * @memberof DataTable#oApi 8239 */ 8240 function _fnMap( ret, src, name, mappedName ) 8241 { 8242 if ( $.isArray( name ) ) { 8243 $.each( name, function (i, val) { 8244 if ( $.isArray( val ) ) { 8245 _fnMap( ret, src, val[0], val[1] ); 8246 } 8247 else { 8248 _fnMap( ret, src, val ); 8249 } 8250 } ); 8251 8252 return; 8253 } 8254 8255 if ( mappedName === undefined ) { 8256 mappedName = name; 8257 } 8258 8259 if ( src[name] !== undefined ) { 8260 ret[mappedName] = src[name]; 8261 } 8262 } 8263 8264 8265 /** 8266 * Extend objects - very similar to jQuery.extend, but deep copy objects, and 8267 * shallow copy arrays. The reason we need to do this, is that we don't want to 8268 * deep copy array init values (such as aaSorting) since the dev wouldn't be 8269 * able to override them, but we do want to deep copy arrays. 8270 * @param {object} out Object to extend 8271 * @param {object} extender Object from which the properties will be applied to 8272 * out 8273 * @param {boolean} breakRefs If true, then arrays will be sliced to take an 8274 * independent copy with the exception of the `data` or `aaData` parameters 8275 * if they are present. This is so you can pass in a collection to 8276 * DataTables and have that used as your data source without breaking the 8277 * references 8278 * @returns {object} out Reference, just for convenience - out === the return. 8279 * @memberof DataTable#oApi 8280 * @todo This doesn't take account of arrays inside the deep copied objects. 8281 */ 8282 function _fnExtend( out, extender, breakRefs ) 8283 { 8284 var val; 8285 8286 for ( var prop in extender ) { 8287 if ( extender.hasOwnProperty(prop) ) { 8288 val = extender[prop]; 8289 8290 if ( $.isPlainObject( val ) ) { 8291 if ( ! $.isPlainObject( out[prop] ) ) { 8292 out[prop] = {}; 8293 } 8294 $.extend( true, out[prop], val ); 8295 } 8296 else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) { 8297 out[prop] = val.slice(); 8298 } 8299 else { 8300 out[prop] = val; 8301 } 8302 } 8303 } 8304 8305 return out; 8306 } 8307 8308 8309 /** 8310 * Bind an event handers to allow a click or return key to activate the callback. 8311 * This is good for accessibility since a return on the keyboard will have the 8312 * same effect as a click, if the element has focus. 8313 * @param {element} n Element to bind the action to 8314 * @param {object} oData Data object to pass to the triggered function 8315 * @param {function} fn Callback function for when the event is triggered 8316 * @memberof DataTable#oApi 8317 */ 8318 function _fnBindAction( n, oData, fn ) 8319 { 8320 $(n) 8321 .on( 'click.DT', oData, function (e) { 8322 $(n).blur(); // Remove focus outline for mouse users 8323 fn(e); 8324 } ) 8325 .on( 'keypress.DT', oData, function (e){ 8326 if ( e.which === 13 ) { 8327 e.preventDefault(); 8328 fn(e); 8329 } 8330 } ) 8331 .on( 'selectstart.DT', function () { 8332 /* Take the brutal approach to cancelling text selection */ 8333 return false;
8334 } ); 8335 } 8336 8337 8338 /** 8339 * Register a callback function. Easily allows a callback function to be added to 8340 * an array store of callback functions that can then all be called together. 8341 * @param {object} oSettings dataTables settings object 8342 * @param {string} sStore Name of the array storage for the callbacks in oSettings 8343 * @param {function} fn Function to be called back 8344 * @param {string} sName Identifying name for the callback (i.e. a label) 8345 * @memberof DataTable#oApi 8346 */ 8347 function _fnCallbackReg( oSettings, sStore, fn, sName ) 8348 { 8349 if ( fn ) 8350 { 8351 oSettings[sStore].push( { 8352 "fn": fn, 8353 "sName": sName 8354 } ); 8355 } 8356 } 8357 8358 8359 /** 8360 * Fire callback functions and trigger events. Note that the loop over the 8361 * callback array store is done backwards! Further note that you do not want to 8362 * fire off triggers in time sensitive applications (for example cell creation) 8363 * as its slow. 8364 * @param {object} settings dataTables settings object 8365 * @param {string} callbackArr Name of the array storage for the callbacks in 8366 * oSettings 8367 * @param {string} eventName Name of the jQuery custom event to trigger. If 8368 * null no trigger is fired 8369 * @param {array} args Array of arguments to pass to the callback function / 8370 * trigger 8371 * @memberof DataTable#oApi 8372 */ 8373 function _fnCallbackFire( settings, callbackArr, eventName, args ) 8374 { 8375 var ret = []; 8376 8377 if ( callbackArr ) { 8378 ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) { 8379 return val.fn.apply( settings.oInstance, args ); 8380 } ); 8381 } 8382 8383 if ( eventName !== null ) { 8384 var e = $.Event( eventName+'.dt' ); 8385 8386 $(settings.nTable).trigger( e, args ); 8387 8388 ret.push( e.result ); 8389 } 8390 8391 return ret; 8392 } 8393 8394 8395 function _fnLengthOverflow ( settings ) 8396 { 8397 var 8398 start = settings._iDisplayStart, 8399 end = settings.fnDisplayEnd(), 8400 len = settings._iDisplayLength; 8401 8402 /* If we have space to show extra rows (backing up from the end point - then do so */ 8403 if ( start >= end ) 8404 { 8405 start = end - len; 8406 } 8407 8408 // Keep the start record on the current page 8409 start -= (start % len); 8410 8411 if ( len === -1 || start < 0 ) 8412 { 8413 start = 0; 8414 } 8415 8416 settings._iDisplayStart = start; 8417 } 8418 8419 8420 function _fnRenderer( settings, type ) 8421 { 8422 var renderer = settings.renderer; 8423 var host = DataTable.ext.renderer[type]; 8424 8425 if ( $.isPlainObject( renderer ) && renderer[type] ) { 8426 // Specific renderer for this type. If available use it, otherwise use 8427 // the default. 8428 return host[renderer[type]] || host._; 8429 } 8430 else if ( typeof renderer === 'string' ) { 8431 // Common renderer - if there is one available for this type use it, 8432 // otherwise use the default 8433 return host[renderer] || host._; 8434 } 8435 8436 // Use the default 8437 return host._; 8438 } 8439 8440 8441 /** 8442 * Detect the data source being used for the table. Used to simplify the code 8443 * a little (ajax) and to make it compress a little smaller. 8444 * 8445 * @param {object} settings dataTables settings object 8446 * @returns {string} Data source 8447 * @memberof DataTable#oApi 8448 */ 8449 function _fnDataSource ( settings ) 8450 { 8451 if ( settings.oFeatures.bServerSide ) { 8452 return 'ssp'; 8453 } 8454 else if ( settings.ajax || settings.sAjaxSource ) { 8455 return 'ajax'; 8456 } 8457 return 'dom'; 8458 } 8459 8460 8461 8462 8463 /** 8464 * Computed structure of the DataTables API, defined by the options passed to 8465 * `DataTable.Api.register()` when building the API. 8466 * 8467 * The structure is built in order to speed creation and extension of the Api 8468 * objects since the extensions are effectively pre-parsed. 8469 * 8470 * The array is an array of objects with the following structure, where this 8471 * base array represents the Api prototype base: 8472 * 8473 * [ 8474 * { 8475 * name: 'data' -- string - Property name 8476 * val: function () {}, -- function - Api method (or undefined if just an object 8477 * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result 8478 * propExt: [ ... ] -- array - Array of Api object definitions to extend the property 8479 * }, 8480 * { 8481 * name: 'row' 8482 * val: {}, 8483 * methodExt: [ ... ], 8484 * propExt: [ 8485 * { 8486 * name: 'data' 8487 * val: function () {}, 8488 * methodExt: [ ... ], 8489 * propExt: [ ... ] 8490 * }, 8491 * ... 8492 * ] 8493 * } 8494 * ] 8495 * 8496 * @type {Array} 8497 * @ignore 8498 */ 8499 var __apiStruct = []; 8500 8501 8502 /** 8503 * `Array.prototype` reference. 8504 * 8505 * @type object 8506 * @ignore 8507 */ 8508 var __arrayProto = Array.prototype; 8509 8510 8511 /** 8512 * Abstraction for `context` parameter of the `Api` constructor to allow it to 8513 * take several different forms for ease of use. 8514 * 8515 * Each of the input parameter types will be converted to a DataTables settings 8516 * object where possible. 8517 * 8518 * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one 8519 * of: 8520 * 8521 * * `string` - jQuery selector. Any DataTables' matching the given selector 8522 * with be found and used. 8523 * * `node` - `TABLE` node which has already been formed into a DataTable. 8524 * * `jQuery` - A jQuery object of `TABLE` nodes. 8525 * * `object` - DataTables settings object 8526 * * `DataTables.Api` - API instance 8527 * @return {array|null} Matching DataTables settings objects. `null` or 8528 * `undefined` is returned if no matching DataTable is found. 8529 * @ignore 8530 */ 8531 var _toSettings = function ( mixed ) 8532 { 8533 var idx, jq; 8534 var settings = DataTable.settings; 8535 var tables = $.map( settings, function (el, i) { 8536 return el.nTable; 8537 } ); 8538 8539 if ( ! mixed ) { 8540 return []; 8541 } 8542 else if ( mixed.nTable && mixed.oApi ) { 8543 // DataTables settings object 8544 return [ mixed ]; 8545 } 8546 else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) { 8547 // Table node 8548 idx = $.inArray( mixed, tables ); 8549 return idx !== -1 ? [ settings[idx] ] : null; 8550 } 8551 else if ( mixed && typeof mixed.settings === 'function' ) { 8552 return mixed.settings().toArray(); 8553 } 8554 else if ( typeof mixed === 'string' ) { 8555 // jQuery selector 8556 jq = $(mixed); 8557 } 8558 else if ( mixed instanceof $ ) { 8559 // jQuery object (also DataTables instance) 8560 jq = mixed; 8561 } 8562 8563 if ( jq ) { 8564 return jq.map( function(i) { 8565 idx = $.inArray( this, tables ); 8566 return idx !== -1 ? settings[idx] : null; 8567 } ).toArray(); 8568 } 8569 }; 8570 8571 8572 /** 8573 * DataTables API class - used to control and interface with one or more 8574 * DataTables enhanced tables. 8575 * 8576 * The API class is heavily based on jQuery, presenting a chainable interface 8577 * that you can use to interact with tables. Each instance of the API class has 8578 * a "context" - i.e. the tables that it will operate on. This could be a single 8579 * table, all tables on a page or a sub-set thereof. 8580 * 8581 * Additionally the API is designed to allow you to easily work with the data in 8582 * the tables, retrieving and manipulating it as required. This is done by 8583 * presenting the API class as an array like interface. The contents of the 8584 * array depend upon the actions requested by each method (for example 8585 * `rows().nodes()` will return an array of nodes, while `rows().data()` will
8586 * return an array of objects or arrays depending upon your table's 8587 * configuration). The API object has a number of array like methods (`push`, 8588 * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`, 8589 * `unique` etc) to assist your working with the data held in a table. 8590 * 8591 * Most methods (those which return an Api instance) are chainable, which means 8592 * the return from a method call also has all of the methods available that the 8593 * top level object had. For example, these two calls are equivalent: 8594 * 8595 * // Not chained 8596 * api.row.add( {...} ); 8597 * api.draw(); 8598 * 8599 * // Chained 8600 * api.row.add( {...} ).draw(); 8601 * 8602 * @class DataTable.Api 8603 * @param {array|object|string|jQuery} context DataTable identifier. This is 8604 * used to define which DataTables enhanced tables this API will operate on. 8605 * Can be one of: 8606 * 8607 * * `string` - jQuery selector. Any DataTables' matching the given selector 8608 * with be found and used. 8609 * * `node` - `TABLE` node which has already been formed into a DataTable. 8610 * * `jQuery` - A jQuery object of `TABLE` nodes. 8611 * * `object` - DataTables settings object 8612 * @param {array} [data] Data to initialise the Api instance with. 8613 * 8614 * @example 8615 * // Direct initialisation during DataTables construction 8616 * var api = $('#example').DataTable(); 8617 * 8618 * @example 8619 * // Initialisation using a DataTables jQuery object 8620 * var api = $('#example').dataTable().api(); 8621 * 8622 * @example 8623 * // Initialisation as a constructor 8624 * var api = new $.fn.DataTable.Api( 'table.dataTable' ); 8625 */ 8626 _Api = function ( context, data ) 8627 { 8628 if ( ! (this instanceof _Api) ) { 8629 return new _Api( context, data ); 8630 } 8631 8632 var settings = []; 8633 var ctxSettings = function ( o ) { 8634 var a = _toSettings( o ); 8635 if ( a ) { 8636 settings = settings.concat( a ); 8637 } 8638 }; 8639 8640 if ( $.isArray( context ) ) { 8641 for ( var i=0, ien=context.length ; i<ien ; i++ ) { 8642 ctxSettings( context[i] ); 8643 } 8644 } 8645 else { 8646 ctxSettings( context ); 8647 } 8648 8649 // Remove duplicates 8650 this.context = _unique( settings ); 8651 8652 // Initial data 8653 if ( data ) { 8654 $.merge( this, data ); 8655 } 8656 8657 // selector 8658 this.selector = { 8659 rows: null, 8660 cols: null, 8661 opts: null 8662 }; 8663 8664 _Api.extend( this, this, __apiStruct ); 8665 }; 8666 8667 DataTable.Api = _Api; 8668 8669 // Don't destroy the existing prototype, just extend it. Required for jQuery 2's 8670 // isPlainObject. 8671 $.extend( _Api.prototype, { 8672 any: function () 8673 { 8674 return this.count() !== 0; 8675 }, 8676 8677 8678 concat: __arrayProto.concat, 8679 8680 8681 context: [], // array of table settings objects 8682 8683 8684 count: function () 8685 { 8686 return this.flatten().length; 8687 }, 8688 8689 8690 each: function ( fn ) 8691 { 8692 for ( var i=0, ien=this.length ; i<ien; i++ ) { 8693 fn.call( this, this[i], i, this ); 8694 } 8695 8696 return this; 8697 }, 8698 8699 8700 eq: function ( idx ) 8701 { 8702 var ctx = this.context; 8703 8704 return ctx.length > idx ? 8705 new _Api( ctx[idx], this[idx] ) : 8706 null; 8707 }, 8708 8709 8710 filter: function ( fn ) 8711 { 8712 var a = []; 8713 8714 if ( __arrayProto.filter ) { 8715 a = __arrayProto.filter.call( this, fn, this ); 8716 } 8717 else { 8718 // Compatibility for browsers without EMCA-252-5 (JS 1.6) 8719 for ( var i=0, ien=this.length ; i<ien ; i++ ) { 8720 if ( fn.call( this, this[i], i, this ) ) { 8721 a.push( this[i] ); 8722 } 8723 } 8724 } 8725 8726 return new _Api( this.context, a ); 8727 }, 8728 8729 8730 flatten: function () 8731 { 8732 var a = []; 8733 return new _Api( this.context, a.concat.apply( a, this.toArray() ) ); 8734 }, 8735 8736 8737 join: __arrayProto.join, 8738 8739 8740 indexOf: __arrayProto.indexOf || function (obj, start) 8741 { 8742 for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) { 8743 if ( this[i] === obj ) { 8744 return i; 8745 } 8746 } 8747 return -1; 8748 }, 8749 8750 iterator: function ( flatten, type, fn, alwaysNew ) { 8751 var 8752 a = [], ret, 8753 i, ien, j, jen, 8754 context = this.context, 8755 rows, items, item, 8756 selector = this.selector; 8757 8758 // Argument shifting 8759 if ( typeof flatten === 'string' ) { 8760 alwaysNew = fn; 8761 fn = type; 8762 type = flatten; 8763 flatten = false; 8764 } 8765 8766 for ( i=0, ien=context.length ; i<ien ; i++ ) { 8767 var apiInst = new _Api( context[i] ); 8768 8769 if ( type === 'table' ) { 8770 ret = fn.call( apiInst, context[i], i ); 8771 8772 if ( ret !== undefined ) { 8773 a.push( ret ); 8774 } 8775 } 8776 else if ( type === 'columns' || type === 'rows' ) { 8777 // this has same length as context - one entry for each table 8778 ret = fn.call( apiInst, context[i], this[i], i ); 8779 8780 if ( ret !== undefined ) { 8781 a.push( ret ); 8782 } 8783 } 8784 else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) { 8785 // columns and rows share the same structure. 8786 // 'this' is an array of column indexes for each context 8787 items = this[i]; 8788 8789 if ( type === 'column-rows' ) { 8790 rows = _selector_row_indexes( context[i], selector.opts ); 8791 } 8792 8793 for ( j=0, jen=items.length ; j<jen ; j++ ) { 8794 item = items[j]; 8795 8796 if ( type === 'cell' ) { 8797 ret = fn.call( apiInst, context[i], item.row, item.column, i, j ); 8798 } 8799 else { 8800 ret = fn.call( apiInst, context[i], item, i, j, rows ); 8801 } 8802 8803 if ( ret !== undefined ) { 8804 a.push( ret ); 8805 } 8806 } 8807 } 8808 } 8809 8810 if ( a.length || alwaysNew ) { 8811 var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a ); 8812 var apiSelector = api.selector; 8813 apiSelector.rows = selector.rows; 8814 apiSelector.cols = selector.cols; 8815 apiSelector.opts = selector.opts; 8816 return api; 8817 } 8818 return this; 8819 }, 8820 8821 8822 lastIndexOf: __arrayProto.lastIndexOf || function (obj, start) 8823 { 8824 // Bit cheeky... 8825 return this.indexOf.apply( this.toArray.reverse(), arguments ); 8826 }, 8827 8828 8829 length: 0, 8830 8831 8832 map: function ( fn ) 8833 { 8834 var a = []; 8835 8836 if ( __arrayProto.map ) { 8837 a = __arrayProto.map.call( this, fn, this ); 8838 } 8839 else { 8840 // Compatibility for browsers without EMCA-252-5 (JS 1.6) 8841 for ( var i=0, ien=this.length ; i<ien ; i++ ) { 8842 a.push( fn.call( this, this[i], i ) ); 8843 } 8844 } 8845 8846 return new _Api( this.context, a ); 8847 }, 8848 8849 8850 pluck: function ( prop ) 8851 { 8852 return this.map( function ( el ) { 8853 return el[ prop ]; 8854 } ); 8855 }, 8856 8857 pop: __arrayProto.pop, 8858 8859 8860 push: __arrayProto.push, 8861 8862 8863 // Does not return an API instance 8864 reduce: __arrayProto.reduce || function ( fn, init ) 8865 { 8866 return _fnReduce( this, fn, init, 0, this.length, 1 ); 8867 }, 8868 8869 8870 reduceRight: __arrayProto.reduceRight || function ( fn, init ) 8871 { 8872 return _fnReduce( this, fn, init, this.length-1, -1, -1 ); 8873 }, 8874 8875 8876 reverse: __arrayProto.reverse, 8877 8878 8879 // Object with rows, columns and opts 8880 selector: null, 8881 8882 8883 shift: __arrayProto.shift, 8884 8885 8886 slice: function () { 8887 return new _Api( this.context, this ); 8888 }, 8889 8890 8891 sort: __arrayProto.sort, // ? name - order? 8892 8893 8894 splice: __arrayProto.splice, 8895 8896 8897 toArray: function () 8898 { 8899 return __arrayProto.slice.call( this ); 8900 }, 8901 8902 8903 to$: function () 8904 { 8905 return $( this ); 8906 }, 8907 8908 8909 toJQuery: function () 8910 { 8911 return $( this ); 8912 }, 8913 8914 8915 unique: function () 8916 { 8917 return new _Api( this.context, _unique(this) ); 8918 }, 8919 8920 8921 unshift: __arrayProto.unshift 8922 } ); 8923 8924 8925 _Api.extend = function ( scope, obj, ext ) 8926 { 8927 // Only extend API instances and static properties of the API 8928 if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) { 8929 return; 8930 } 8931 8932 var 8933 i, ien, 8934 j, jen, 8935 struct, inner, 8936 methodScoping = function ( scope, fn, struc ) { 8937 return function () { 8938 var ret = fn.apply( scope, arguments ); 8939 8940 // Method extension 8941 _Api.extend( ret, ret, struc.methodExt ); 8942 return ret; 8943 }; 8944 }; 8945 8946 for ( i=0, ien=ext.length ; i<ien ; i++ ) { 8947 struct = ext[i]; 8948 8949 // Value 8950 obj[ struct.name ] = typeof struct.val === 'function' ? 8951 methodScoping( scope, struct.val, struct ) : 8952 $.isPlainObject( struct.val ) ? 8953 {} : 8954 struct.val; 8955 8956 obj[ struct.name ].__dt_wrapper = true; 8957 8958 // Property extension 8959 _Api.extend( scope, obj[ struct.name ], struct.propExt ); 8960 } 8961 }; 8962 8963 8964 // @todo - Is there need for an augment function? 8965 // _Api.augment = function ( inst, name ) 8966 // { 8967 // // Find src object in the structure from the name 8968 // var parts = name.split('.'); 8969 8970 // _Api.extend( inst, obj ); 8971 // }; 8972 8973 8974 // [ 8975 // { 8976 // name: 'data' -- string - Property name 8977 // val: function () {}, -- function - Api method (or undefined if just an object 8978 // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result 8979 // propExt: [ ... ] -- array - Array of Api object definitions to extend the property 8980 // }, 8981 // { 8982 // name: 'row' 8983 // val: {}, 8984 // methodExt: [ ... ], 8985 // propExt: [ 8986 // { 8987 // name: 'data' 8988 // val: function () {}, 8989 // methodExt: [ ... ], 8990 // propExt: [ ... ] 8991 // }, 8992 // ... 8993 // ] 8994 // } 8995 // ] 8996 8997 _Api.register = _api_register = function ( name, val ) 8998 { 8999 if ( $.isArray( name ) ) { 9000 for ( var j=0, jen=name.length ; j<jen ; j++ ) { 9001 _Api.register( name[j], val ); 9002 } 9003 return; 9004 } 9005 9006 var 9007 i, ien, 9008 heir = name.split('.'), 9009 struct = __apiStruct, 9010 key, method; 9011 9012 var find = function ( src, name ) { 9013 for ( var i=0, ien=src.length ; i<ien ; i++ ) { 9014 if ( src[i].name === name ) { 9015 return src[i]; 9016 } 9017 } 9018 return null; 9019 }; 9020 9021 for ( i=0, ien=heir.length ; i<ien ; i++ ) { 9022 method = heir[i].indexOf('()') !== -1; 9023 key = method ?
9024 heir[i].replace('()', '') : 9025 heir[i]; 9026 9027 var src = find( struct, key ); 9028 if ( ! src ) { 9029 src = { 9030 name: key, 9031 val: {}, 9032 methodExt: [], 9033 propExt: [] 9034 }; 9035 struct.push( src ); 9036 } 9037 9038 if ( i === ien-1 ) { 9039 src.val = val; 9040 } 9041 else { 9042 struct = method ? 9043 src.methodExt : 9044 src.propExt; 9045 } 9046 } 9047 }; 9048 9049 9050 _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) { 9051 _Api.register( pluralName, val ); 9052 9053 _Api.register( singularName, function () { 9054 var ret = val.apply( this, arguments ); 9055 9056 if ( ret === this ) { 9057 // Returned item is the API instance that was passed in, return it 9058 return this; 9059 } 9060 else if ( ret instanceof _Api ) { 9061 // New API instance returned, want the value from the first item 9062 // in the returned array for the singular result. 9063 return ret.length ? 9064 $.isArray( ret[0] ) ? 9065 new _Api( ret.context, ret[0] ) : // Array results are 'enhanced' 9066 ret[0] : 9067 undefined; 9068 } 9069 9070 // Non-API return - just fire it back 9071 return ret; 9072 } ); 9073 }; 9074 9075 9076 /** 9077 * Selector for HTML tables. Apply the given selector to the give array of 9078 * DataTables settings objects. 9079 * 9080 * @param {string|integer} [selector] jQuery selector string or integer 9081 * @param {array} Array of DataTables settings objects to be filtered 9082 * @return {array} 9083 * @ignore 9084 */ 9085 var __table_selector = function ( selector, a ) 9086 { 9087 // Integer is used to pick out a table by index 9088 if ( typeof selector === 'number' ) { 9089 return [ a[ selector ] ]; 9090 } 9091 9092 // Perform a jQuery selector on the table nodes 9093 var nodes = $.map( a, function (el, i) { 9094 return el.nTable; 9095 } ); 9096 9097 return $(nodes) 9098 .filter( selector ) 9099 .map( function (i) { 9100 // Need to translate back from the table node to the settings 9101 var idx = $.inArray( this, nodes ); 9102 return a[ idx ]; 9103 } ) 9104 .toArray(); 9105 }; 9106 9107 9108 9109 /** 9110 * Context selector for the API's context (i.e. the tables the API instance 9111 * refers to. 9112 * 9113 * @name DataTable.Api#tables 9114 * @param {string|integer} [selector] Selector to pick which tables the iterator 9115 * should operate on. If not given, all tables in the current context are 9116 * used. This can be given as a jQuery selector (for example `':gt(0)'`) to 9117 * select multiple tables or as an integer to select a single table. 9118 * @returns {DataTable.Api} Returns a new API instance if a selector is given. 9119 */ 9120 _api_register( 'tables()', function ( selector ) { 9121 // A new instance is created if there was a selector specified 9122 return selector ? 9123 new _Api( __table_selector( selector, this.context ) ) : 9124 this; 9125 } ); 9126 9127 9128 _api_register( 'table()', function ( selector ) { 9129 var tables = this.tables( selector ); 9130 var ctx = tables.context; 9131 9132 // Truncate to the first matched table 9133 return ctx.length ? 9134 new _Api( ctx[0] ) : 9135 tables; 9136 } ); 9137 9138 9139 _api_registerPlural( 'tables().nodes()', 'table().node()' , function () { 9140 return this.iterator( 'table', function ( ctx ) { 9141 return ctx.nTable; 9142 }, 1 ); 9143 } ); 9144 9145 9146 _api_registerPlural( 'tables().body()', 'table().body()' , function () { 9147 return this.iterator( 'table', function ( ctx ) { 9148 return ctx.nTBody; 9149 }, 1 ); 9150 } ); 9151 9152 9153 _api_registerPlural( 'tables().header()', 'table().header()' , function () { 9154 return this.iterator( 'table', function ( ctx ) { 9155 return ctx.nTHead; 9156 }, 1 ); 9157 } ); 9158 9159 9160 _api_registerPlural( 'tables().footer()', 'table().footer()' , function () { 9161 return this.iterator( 'table', function ( ctx ) { 9162 return ctx.nTFoot; 9163 }, 1 ); 9164 } ); 9165 9166 9167 _api_registerPlural( 'tables().containers()', 'table().container()' , function () { 9168 return this.iterator( 'table', function ( ctx ) { 9169 return ctx.nTableWrapper; 9170 }, 1 ); 9171 } ); 9172 9173 9174 9175 /** 9176 * Redraw the tables in the current context. 9177 */ 9178 _api_register( 'draw()', function ( paging ) { 9179 return this.iterator( 'table', function ( settings ) { 9180 if ( paging === 'page' ) { 9181 _fnDraw( settings ); 9182 } 9183 else { 9184 if ( typeof paging === 'string' ) { 9185 paging = paging === 'full-hold' ? 9186 false : 9187 true; 9188 } 9189 9190 _fnReDraw( settings, paging===false ); 9191 } 9192 } ); 9193 } ); 9194 9195 9196 9197 /** 9198 * Get the current page index. 9199 * 9200 * @return {integer} Current page index (zero based) 9201 *//** 9202 * Set the current page. 9203 * 9204 * Note that if you attempt to show a page which does not exist, DataTables will 9205 * not throw an error, but rather reset the paging. 9206 * 9207 * @param {integer|string} action The paging action to take. This can be one of:
9208 * * `integer` - The page index to jump to 9209 * * `string` - An action to take: 9210 * * `first` - Jump to first page. 9211 * * `next` - Jump to the next page 9212 * * `previous` - Jump to previous page 9213 * * `last` - Jump to the last page. 9214 * @returns {DataTables.Api} this 9215 */ 9216 _api_register( 'page()', function ( action ) { 9217 if ( action === undefined ) { 9218 return this.page.info().page; // not an expensive call 9219 } 9220 9221 // else, have an action to take on all tables 9222 return this.iterator( 'table', function ( settings ) { 9223 _fnPageChange( settings, action ); 9224 } ); 9225 } ); 9226 9227 9228 /** 9229 * Paging information for the first table in the current context. 9230 * 9231 * If you require paging information for another table, use the `table()` method 9232 * with a suitable selector. 9233 * 9234 * @return {object} Object with the following properties set: 9235 * * `page` - Current page index (zero based - i.e. the first page is `0`) 9236 * * `pages` - Total number of pages 9237 * * `start` - Display index for the first record shown on the current page 9238 * * `end` - Display index for the last record shown on the current page 9239 * * `length` - Display length (number of records). Note that generally `start 9240 * + length = end`, but this is not always true, for example if there are 9241 * only 2 records to show on the final page, with a length of 10. 9242 * * `recordsTotal` - Full data set length 9243 * * `recordsDisplay` - Data set length once the current filtering criterion 9244 * are applied. 9245 */ 9246 _api_register( 'page.info()', function ( action ) { 9247 if ( this.context.length === 0 ) { 9248 return undefined; 9249 } 9250 9251 var 9252 settings = this.context[0], 9253 start = settings._iDisplayStart, 9254 len = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1, 9255 visRecords = settings.fnRecordsDisplay(), 9256 all = len === -1; 9257 9258 return { 9259 "page": all ? 0 : Math.floor( start / len ), 9260 "pages": all ? 1 : Math.ceil( visRecords / len ), 9261 "start": start, 9262 "end": settings.fnDisplayEnd(), 9263 "length": len, 9264 "recordsTotal": settings.fnRecordsTotal(), 9265 "recordsDisplay": visRecords, 9266 "serverSide": _fnDataSource( settings ) === 'ssp' 9267 }; 9268 } ); 9269 9270 9271 /** 9272 * Get the current page length. 9273 * 9274 * @return {integer} Current page length. Note `-1` indicates that all records 9275 * are to be shown. 9276 *//** 9277 * Set the current page length. 9278 * 9279 * @param {integer} Page length to set. Use `-1` to show all records. 9280 * @returns {DataTables.Api} this 9281 */ 9282 _api_register( 'page.len()', function ( len ) { 9283 // Note that we can't call this function 'length()' because `length` 9284 // is a Javascript property of functions which defines how many arguments 9285 // the function expects. 9286 if ( len === undefined ) { 9287 return this.context.length !== 0 ? 9288 this.context[0]._iDisplayLength : 9289 undefined; 9290 } 9291 9292 // else, set the page length 9293 return this.iterator( 'table', function ( settings ) { 9294 _fnLengthChange( settings, len ); 9295 } ); 9296 } ); 9297 9298 9299 9300 var __reload = function ( settings, holdPosition, callback ) { 9301 // Use the draw event to trigger a callback 9302 if ( callback ) { 9303 var api = new _Api( settings ); 9304 9305 api.one( 'draw', function () { 9306 callback( api.ajax.json() ); 9307 } ); 9308 } 9309 9310 if ( _fnDataSource( settings ) == 'ssp' ) { 9311 _fnReDraw( settings, holdPosition ); 9312 } 9313 else { 9314 _fnProcessingDisplay( settings, true ); 9315 9316 // Cancel an existing request 9317 var xhr = settings.jqXHR; 9318 if ( xhr && xhr.readyState !== 4 ) { 9319 xhr.abort(); 9320 } 9321 9322 // Trigger xhr 9323 _fnBuildAjax( settings, [], function( json ) { 9324 _fnClearTable( settings ); 9325 9326 var data = _fnAjaxDataSrc( settings, json ); 9327 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 9328 _fnAddData( settings, data[i] ); 9329 } 9330 9331 _fnReDraw( settings, holdPosition ); 9332 _fnProcessingDisplay( settings, false ); 9333 } ); 9334 } 9335 }; 9336 9337 9338 /** 9339 * Get the JSON response from the last Ajax request that DataTables made to the 9340 * server. Note that this returns the JSON from the first table in the current 9341 * context. 9342 * 9343 * @return {object} JSON received from the server. 9344 */ 9345 _api_register( 'ajax.json()', function () { 9346 var ctx = this.context; 9347 9348 if ( ctx.length > 0 ) { 9349 return ctx[0].json; 9350 } 9351 9352 // else return undefined; 9353 } ); 9354 9355 9356 /** 9357 * Get the data submitted in the last Ajax request 9358 */ 9359 _api_register( 'ajax.params()', function () { 9360 var ctx = this.context; 9361 9362 if ( ctx.length > 0 ) { 9363 return ctx[0].oAjaxData; 9364 } 9365 9366 // else return undefined; 9367 } ); 9368 9369 9370 /** 9371 * Reload tables from the Ajax data source. Note that this function will 9372 * automatically re-draw the table when the remote data has been loaded. 9373 * 9374 * @param {boolean} [reset=true] Reset (default) or hold the current paging 9375 * position. A full re-sort and re-filter is performed when this method is 9376 * called, which is why the pagination reset is the default action. 9377 * @returns {DataTables.Api} this 9378 */ 9379 _api_register( 'ajax.reload()', function ( callback, resetPaging ) { 9380 return this.iterator( 'table', function (settings) { 9381 __reload( settings, resetPaging===false, callback ); 9382 } ); 9383 } ); 9384 9385 9386 /** 9387 * Get the current Ajax URL. Note that this returns the URL from the first 9388 * table in the current context. 9389 * 9390 * @return {string} Current Ajax source URL 9391 *//** 9392 * Set the Ajax URL. Note that this will set the URL for all tables in the 9393 * current context. 9394 * 9395 * @param {string} url URL to set. 9396 * @returns {DataTables.Api} this 9397 */ 9398 _api_register( 'ajax.url()', function ( url ) { 9399 var ctx = this.context; 9400 9401 if ( url === undefined ) { 9402 // get 9403 if ( ctx.length === 0 ) { 9404 return undefined; 9405 } 9406 ctx = ctx[0]; 9407
9408 return ctx.ajax ? 9409 $.isPlainObject( ctx.ajax ) ? 9410 ctx.ajax.url : 9411 ctx.ajax : 9412 ctx.sAjaxSource; 9413 } 9414 9415 // set 9416 return this.iterator( 'table', function ( settings ) { 9417 if ( $.isPlainObject( settings.ajax ) ) { 9418 settings.ajax.url = url; 9419 } 9420 else { 9421 settings.ajax = url; 9422 } 9423 // No need to consider sAjaxSource here since DataTables gives priority 9424 // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any 9425 // value of `sAjaxSource` redundant. 9426 } ); 9427 } ); 9428 9429 9430 /** 9431 * Load data from the newly set Ajax URL. Note that this method is only 9432 * available when `ajax.url()` is used to set a URL. Additionally, this method 9433 * has the same effect as calling `ajax.reload()` but is provided for 9434 * convenience when setting a new URL. Like `ajax.reload()` it will 9435 * automatically redraw the table once the remote data has been loaded. 9436 * 9437 * @returns {DataTables.Api} this 9438 */ 9439 _api_register( 'ajax.url().load()', function ( callback, resetPaging ) { 9440 // Same as a reload, but makes sense to present it for easy access after a 9441 // url change 9442 return this.iterator( 'table', function ( ctx ) { 9443 __reload( ctx, resetPaging===false, callback ); 9444 } ); 9445 } ); 9446 9447 9448 9449 9450 var _selector_run = function ( type, selector, selectFn, settings, opts ) 9451 { 9452 var 9453 out = [], res, 9454 a, i, ien, j, jen, 9455 selectorType = typeof selector; 9456 9457 // Can't just check for isArray here, as an API or jQuery instance might be 9458 // given with their array like look 9459 if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) { 9460 selector = [ selector ]; 9461 } 9462 9463 for ( i=0, ien=selector.length ; i<ien ; i++ ) { 9464 // Only split on simple strings - complex expressions will be jQuery selectors 9465 a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ? 9466 selector[i].split(',') : 9467 [ selector[i] ]; 9468 9469 for ( j=0, jen=a.length ; j<jen ; j++ ) { 9470 res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] ); 9471 9472 if ( res && res.length ) { 9473 out = out.concat( res ); 9474 } 9475 } 9476 } 9477 9478 // selector extensions 9479 var ext = _ext.selector[ type ]; 9480 if ( ext.length ) { 9481 for ( i=0, ien=ext.length ; i<ien ; i++ ) { 9482 out = ext[i]( settings, opts, out ); 9483 } 9484 } 9485 9486 return _unique( out ); 9487 }; 9488 9489 9490 var _selector_opts = function ( opts ) 9491 { 9492 if ( ! opts ) { 9493 opts = {}; 9494 } 9495 9496 // Backwards compatibility for 1.9- which used the terminology filter rather 9497 // than search 9498 if ( opts.filter && opts.search === undefined ) { 9499 opts.search = opts.filter; 9500 } 9501 9502 return $.extend( { 9503 search: 'none', 9504 order: 'current', 9505 page: 'all' 9506 }, opts ); 9507 }; 9508 9509 9510 var _selector_first = function ( inst ) 9511 { 9512 // Reduce the API instance to the first item found 9513 for ( var i=0, ien=inst.length ; i<ien ; i++ ) { 9514 if ( inst[i].length > 0 ) { 9515 // Assign the first element to the first item in the instance 9516 // and truncate the instance and context 9517 inst[0] = inst[i]; 9518 inst[0].length = 1; 9519 inst.length = 1; 9520 inst.context = [ inst.context[i] ]; 9521 9522 return inst; 9523 } 9524 } 9525 9526 // Not found - return an empty instance 9527 inst.length = 0; 9528 return inst; 9529 }; 9530 9531 9532 var _selector_row_indexes = function ( settings, opts ) 9533 { 9534 var 9535 i, ien, tmp, a=[], 9536 displayFiltered = settings.aiDisplay, 9537 displayMaster = settings.aiDisplayMaster; 9538 9539 var 9540 search = opts.search, // none, applied, removed 9541 order = opts.order, // applied, current, index (original - compatibility with 1.9) 9542 page = opts.page; // all, current 9543 9544 if ( _fnDataSource( settings ) == 'ssp' ) { 9545 // In server-side processing mode, most options are irrelevant since 9546 // rows not shown don't exist and the index order is the applied order 9547 // Removed is a special case - for consistency just return an empty 9548 // array 9549 return search === 'removed' ? 9550 [] : 9551 _range( 0, displayMaster.length ); 9552 } 9553 else if ( page == 'current' ) { 9554 // Current page implies that order=current and fitler=applied, since it is 9555 // fairly senseless otherwise, regardless of what order and search actually 9556 // are 9557 for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) { 9558 a.push( displayFiltered[i] ); 9559 } 9560 } 9561 else if ( order == 'current' || order == 'applied' ) { 9562 if ( search == 'none') {
9563 a = displayMaster.slice(); 9564 } 9565 else if ( search == 'applied' ) { 9566 a = displayFiltered.slice(); 9567 } 9568 else if ( search == 'removed' ) { 9569 // O(n+m) solution by creating a hash map 9570 var displayFilteredMap = {}; 9571 9572 for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) { 9573 displayFilteredMap[displayFiltered[i]] = null; 9574 } 9575 9576 a = $.map( displayMaster, function (el) { 9577 return ! displayFilteredMap.hasOwnProperty(el) ? 9578 el : 9579 null; 9580 } ); 9581 } 9582 } 9583 else if ( order == 'index' || order == 'original' ) { 9584 for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 9585 if ( search == 'none' ) { 9586 a.push( i ); 9587 } 9588 else { // applied | removed 9589 tmp = $.inArray( i, displayFiltered ); 9590 9591 if ((tmp === -1 && search == 'removed') || 9592 (tmp >= 0 && search == 'applied') ) 9593 { 9594 a.push( i ); 9595 } 9596 } 9597 } 9598 } 9599 9600 return a; 9601 }; 9602 9603 9604 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 9605 * Rows 9606 * 9607 * {} - no selector - use all available rows 9608 * {integer} - row aoData index 9609 * {node} - TR node 9610 * {string} - jQuery selector to apply to the TR elements 9611 * {array} - jQuery array of nodes, or simply an array of TR nodes 9612 * 9613 */ 9614 var __row_selector = function ( settings, selector, opts ) 9615 { 9616 var rows; 9617 var run = function ( sel ) { 9618 var selInt = _intVal( sel ); 9619 var i, ien; 9620 var aoData = settings.aoData; 9621 9622 // Short cut - selector is a number and no options provided (default is 9623 // all records, so no need to check if the index is in there, since it 9624 // must be - dev error if the index doesn't exist). 9625 if ( selInt !== null && ! opts ) { 9626 return [ selInt ]; 9627 } 9628 9629 if ( ! rows ) { 9630 rows = _selector_row_indexes( settings, opts ); 9631 } 9632 9633 if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) { 9634 // Selector - integer 9635 return [ selInt ]; 9636 } 9637 else if ( sel === null || sel === undefined || sel === '' ) { 9638 // Selector - none 9639 return rows; 9640 } 9641 9642 // Selector - function 9643 if ( typeof sel === 'function' ) { 9644 return $.map( rows, function (idx) { 9645 var row = aoData[ idx ]; 9646 return sel( idx, row._aData, row.nTr ) ? idx : null; 9647 } ); 9648 } 9649 9650 // Selector - node 9651 if ( sel.nodeName ) { 9652 var rowIdx = sel._DT_RowIndex; // Property added by DT for fast lookup 9653 var cellIdx = sel._DT_CellIndex; 9654 9655 if ( rowIdx !== undefined ) { 9656 // Make sure that the row is actually still present in the table 9657 return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ? 9658 [ rowIdx ] : 9659 []; 9660 } 9661 else if ( cellIdx ) { 9662 return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel ? 9663 [ cellIdx.row ] : 9664 []; 9665 } 9666 else { 9667 var host = $(sel).closest('*[data-dt-row]'); 9668 return host.length ? 9669 [ host.data('dt-row') ] : 9670 []; 9671 } 9672 } 9673 9674 // ID selector. Want to always be able to select rows by id, regardless 9675 // of if the tr element has been created or not, so can't rely upon 9676 // jQuery here - hence a custom implementation. This does not match 9677 // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything, 9678 // but to select it using a CSS selector engine (like Sizzle or 9679 // querySelect) it would need to need to be escaped for some characters. 9680 // DataTables simplifies this for row selectors since you can select 9681 // only a row. A # indicates an id any anything that follows is the id - 9682 // unescaped. 9683 if ( typeof sel === 'string' && sel.charAt(0) === '#' ) { 9684 // get row index from id 9685 var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ]; 9686 if ( rowObj !== undefined ) { 9687 return [ rowObj.idx ]; 9688 } 9689 9690 // need to fall through to jQuery in case there is DOM id that 9691 // matches 9692 } 9693 9694 // Get nodes in the order from the `rows` array with null values removed 9695 var nodes = _removeEmpty( 9696 _pluck_order( settings.aoData, rows, 'nTr' ) 9697 ); 9698 9699 // Selector - jQuery selector string, array of nodes or jQuery object/ 9700 // As jQuery's .filter() allows jQuery objects to be passed in filter, 9701 // it also allows arrays, so this will cope with all three options 9702 return $(nodes) 9703 .filter( sel ) 9704 .map( function () { 9705 return this._DT_RowIndex; 9706 } ) 9707 .toArray(); 9708 }; 9709 9710 return _selector_run( 'row', selector, run, settings, opts ); 9711 }; 9712 9713 9714 _api_register( 'rows()', function ( selector, opts ) { 9715 // argument shifting 9716 if ( selector === undefined ) { 9717 selector = ''; 9718 } 9719 else if ( $.isPlainObject( selector ) ) { 9720 opts = selector; 9721 selector = ''; 9722 } 9723 9724 opts = _selector_opts( opts ); 9725 9726 var inst = this.iterator( 'table', function ( settings ) { 9727 return __row_selector( settings, selector, opts ); 9728 }, 1 ); 9729 9730 // Want argument shifting here and in __row_selector? 9731 inst.selector.rows = selector; 9732 inst.selector.opts = opts; 9733 9734 return inst; 9735 } ); 9736 9737 _api_register( 'rows().nodes()', function () { 9738 return this.iterator( 'row', function ( settings, row ) { 9739 return settings.aoData[ row ].nTr || undefined; 9740 }, 1 ); 9741 } ); 9742 9743 _api_register( 'rows().data()', function () { 9744 return this.iterator( true, 'rows', function ( settings, rows ) { 9745 return _pluck_order( settings.aoData, rows, '_aData' ); 9746 }, 1 ); 9747 } ); 9748 9749 _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) { 9750 return this.iterator( 'row', function ( settings, row ) { 9751 var r = settings.aoData[ row ]; 9752 return type === 'search' ? r._aFilterData : r._aSortData; 9753 }, 1 ); 9754 } ); 9755 9756 _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) { 9757 return this.iterator( 'row', function ( settings, row ) { 9758 _fnInvalidate( settings, row, src ); 9759 } ); 9760 } ); 9761 9762 _api_registerPlural( 'rows().indexes()', 'row().index()', function () { 9763 return this.iterator( 'row', function ( settings, row ) { 9764 return row; 9765 }, 1 ); 9766 } ); 9767 9768 _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) { 9769 var a = []; 9770 var context = this.context; 9771 9772 // `iterator` will drop undefined values, but in this case we want them 9773 for ( var i=0, ien=context.length ; i<ien ; i++ ) { 9774 for ( var j=0, jen=this[i].length ; j<jen ; j++ ) { 9775 var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData ); 9776 a.push( (hash === true ? '#' : '' )+ id ); 9777 } 9778 } 9779 9780 return new _Api( context, a ); 9781 } ); 9782 9783 _api_registerPlural( 'rows().remove()', 'row().remove()', function () { 9784 var that = this; 9785 9786 this.iterator( 'row', function ( settings, row, thatIdx ) { 9787 var data = settings.aoData; 9788 var rowData = data[ row ]; 9789 var i, ien, j, jen; 9790 var loopRow, loopCells; 9791 9792 data.splice( row, 1 ); 9793 9794 // Update the cached indexes 9795 for ( i=0, ien=data.length ; i<ien ; i++ ) { 9796 loopRow = data[i]; 9797 loopCells = loopRow.anCells; 9798 9799 // Rows 9800 if ( loopRow.nTr !== null ) { 9801 loopRow.nTr._DT_RowIndex = i; 9802 } 9803 9804 // Cells 9805 if ( loopCells !== null ) { 9806 for ( j=0, jen=loopCells.length ; j<jen ; j++ ) { 9807 loopCells[j]._DT_CellIndex.row = i; 9808 } 9809 } 9810 } 9811 9812 // Delete from the display arrays 9813 _fnDeleteIndex( settings.aiDisplayMaster, row ); 9814 _fnDeleteIndex( settings.aiDisplay, row ); 9815 _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes 9816 9817 // For server-side processing tables - subtract the deleted row from the count 9818 if ( settings._iRecordsDisplay > 0 ) { 9819 settings._iRecordsDisplay--; 9820 } 9821 9822 // Check for an 'overflow' they case for displaying the table 9823 _fnLengthOverflow( settings ); 9824 9825 // Remove the row's ID reference if there is one 9826 var id = settings.rowIdFn( rowData._aData ); 9827 if ( id !== undefined ) { 9828 delete settings.aIds[ id ]; 9829 } 9830 } ); 9831 9832 this.iterator( 'table', function ( settings ) { 9833 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 9834 settings.aoData[i].idx = i; 9835 } 9836 } ); 9837 9838 return this; 9839 } ); 9840 9841 9842 _api_register( 'rows.add()', function ( rows ) { 9843 var newRows = this.iterator( 'table', function ( settings ) { 9844 var row, i, ien; 9845 var out = []; 9846 9847 for ( i=0, ien=rows.length ; i<ien ; i++ ) {
9848 row = rows[i]; 9849 9850 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) { 9851 out.push( _fnAddTr( settings, row )[0] ); 9852 } 9853 else { 9854 out.push( _fnAddData( settings, row ) ); 9855 } 9856 } 9857 9858 return out; 9859 }, 1 ); 9860 9861 // Return an Api.rows() extended instance, so rows().nodes() etc can be used 9862 var modRows = this.rows( -1 ); 9863 modRows.pop(); 9864 $.merge( modRows, newRows ); 9865 9866 return modRows; 9867 } ); 9868 9869 9870 9871 9872 9873 /** 9874 * 9875 */ 9876 _api_register( 'row()', function ( selector, opts ) { 9877 return _selector_first( this.rows( selector, opts ) ); 9878 } ); 9879 9880 9881 _api_register( 'row().data()', function ( data ) { 9882 var ctx = this.context; 9883 9884 if ( data === undefined ) { 9885 // Get 9886 return ctx.length && this.length ? 9887 ctx[0].aoData[ this[0] ]._aData : 9888 undefined; 9889 } 9890 9891 // Set 9892 var row = ctx[0].aoData[ this[0] ]; 9893 row._aData = data; 9894 9895 // If the DOM has an id, and the data source is an array 9896 if ( $.isArray( data ) && row.nTr.id ) { 9897 _fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id ); 9898 } 9899 9900 // Automatically invalidate 9901 _fnInvalidate( ctx[0], this[0], 'data' ); 9902 9903 return this; 9904 } ); 9905 9906 9907 _api_register( 'row().node()', function () { 9908 var ctx = this.context; 9909 9910 return ctx.length && this.length ? 9911 ctx[0].aoData[ this[0] ].nTr || null : 9912 null; 9913 } ); 9914 9915 9916 _api_register( 'row.add()', function ( row ) { 9917 // Allow a jQuery object to be passed in - only a single row is added from 9918 // it though - the first element in the set 9919 if ( row instanceof $ && row.length ) { 9920 row = row[0]; 9921 } 9922 9923 var rows = this.iterator( 'table', function ( settings ) { 9924 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) { 9925 return _fnAddTr( settings, row )[0]; 9926 } 9927 return _fnAddData( settings, row ); 9928 } ); 9929 9930 // Return an Api.rows() extended instance, with the newly added row selected 9931 return this.row( rows[0] ); 9932 } ); 9933 9934 9935 9936 var __details_add = function ( ctx, row, data, klass ) 9937 { 9938 // Convert to array of TR elements 9939 var rows = []; 9940 var addRow = function ( r, k ) { 9941 // Recursion to allow for arrays of jQuery objects 9942 if ( $.isArray( r ) || r instanceof $ ) { 9943 for ( var i=0, ien=r.length ; i<ien ; i++ ) { 9944 addRow( r[i], k ); 9945 } 9946 return; 9947 } 9948 9949 // If we get a TR element, then just add it directly - up to the dev 9950 // to add the correct number of columns etc 9951 if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) { 9952 rows.push( r ); 9953 } 9954 else { 9955 // Otherwise create a row with a wrapper 9956 var created = $('<tr><td/></tr>').addClass( k ); 9957 $('td', created) 9958 .addClass( k ) 9959 .html( r ) 9960 [0].colSpan = _fnVisbleColumns( ctx ); 9961 9962 rows.push( created[0] ); 9963 } 9964 }; 9965 9966 addRow( data, klass ); 9967 9968 if ( row._details ) { 9969 row._details.detach(); 9970 } 9971 9972 row._details = $(rows); 9973 9974 // If the children were already shown, that state should be retained 9975 if ( row._detailsShow ) { 9976 row._details.insertAfter( row.nTr ); 9977 } 9978 }; 9979 9980 9981 var __details_remove = function ( api, idx ) 9982 { 9983 var ctx = api.context; 9984 9985 if ( ctx.length ) { 9986 var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ]; 9987 9988 if ( row && row._details ) { 9989 row._details.remove(); 9990 9991 row._detailsShow = undefined; 9992 row._details = undefined; 9993 } 9994 } 9995 }; 9996 9997 9998 var __details_display = function ( api, show ) { 9999 var ctx = api.context; 10000 10001 if ( ctx.length && api.length ) { 10002 var row = ctx[0].aoData[ api[0] ]; 10003 10004 if ( row._details ) { 10005 row._detailsShow = show; 10006 10007 if ( show ) { 10008 row._details.insertAfter( row.nTr ); 10009 } 10010 else { 10011 row._details.detach(); 10012 } 10013 10014 __details_events( ctx[0] ); 10015 } 10016 } 10017 }; 10018 10019 10020 var __details_events = function ( settings ) 10021 { 10022 var api = new _Api( settings ); 10023 var namespace = '.dt.DT_details'; 10024 var drawEvent = 'draw'+namespace; 10025 var colvisEvent = 'column-visibility'+namespace; 10026 var destroyEvent = 'destroy'+namespace; 10027 var data = settings.aoData; 10028 10029 api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent ); 10030 10031 if ( _pluck( data, '_details' ).length > 0 ) { 10032 // On each draw, insert the required elements into the document 10033 api.on( drawEvent, function ( e, ctx ) { 10034 if ( settings !== ctx ) { 10035 return; 10036 } 10037 10038 api.rows( {page:'current'} ).eq(0).each( function (idx) { 10039 // Internal data grab 10040 var row = data[ idx ]; 10041 10042 if ( row._detailsShow ) { 10043 row._details.insertAfter( row.nTr ); 10044 } 10045 } ); 10046 } ); 10047 10048 // Column visibility change - update the colspan 10049 api.on( colvisEvent, function ( e, ctx, idx, vis ) { 10050 if ( settings !== ctx ) { 10051 return; 10052 } 10053 10054 // Update the colspan for the details rows (note, only if it already has 10055 // a colspan) 10056 var row, visible = _fnVisbleColumns( ctx ); 10057 10058 for ( var i=0, ien=data.length ; i<ien ; i++ ) {
10059 row = data[i]; 10060 10061 if ( row._details ) { 10062 row._details.children('td[colspan]').attr('colspan', visible ); 10063 } 10064 } 10065 } ); 10066 10067 // Table destroyed - nuke any child rows 10068 api.on( destroyEvent, function ( e, ctx ) { 10069 if ( settings !== ctx ) { 10070 return; 10071 } 10072 10073 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 10074 if ( data[i]._details ) { 10075 __details_remove( api, i ); 10076 } 10077 } 10078 } ); 10079 } 10080 }; 10081 10082 // Strings for the method names to help minification 10083 var _emp = ''; 10084 var _child_obj = _emp+'row().child'; 10085 var _child_mth = _child_obj+'()'; 10086 10087 // data can be: 10088 // tr 10089 // string 10090 // jQuery or array of any of the above 10091 _api_register( _child_mth, function ( data, klass ) { 10092 var ctx = this.context; 10093 10094 if ( data === undefined ) { 10095 // get 10096 return ctx.length && this.length ? 10097 ctx[0].aoData[ this[0] ]._details : 10098 undefined; 10099 } 10100 else if ( data === true ) { 10101 // show 10102 this.child.show(); 10103 } 10104 else if ( data === false ) { 10105 // remove 10106 __details_remove( this ); 10107 } 10108 else if ( ctx.length && this.length ) { 10109 // set 10110 __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass ); 10111 } 10112 10113 return this; 10114 } ); 10115 10116 10117 _api_register( [ 10118 _child_obj+'.show()', 10119 _child_mth+'.show()' // only when `child()` was called with parameters (without 10120 ], function ( show ) { // it returns an object and this method is not executed) 10121 __details_display( this, true ); 10122 return this; 10123 } ); 10124 10125 10126 _api_register( [ 10127 _child_obj+'.hide()', 10128 _child_mth+'.hide()' // only when `child()` was called with parameters (without 10129 ], function () { // it returns an object and this method is not executed) 10130 __details_display( this, false ); 10131 return this; 10132 } ); 10133 10134 10135 _api_register( [ 10136 _child_obj+'.remove()', 10137 _child_mth+'.remove()' // only when `child()` was called with parameters (without 10138 ], function () { // it returns an object and this method is not executed) 10139 __details_remove( this ); 10140 return this; 10141 } ); 10142 10143 10144 _api_register( _child_obj+'.isShown()', function () { 10145 var ctx = this.context; 10146 10147 if ( ctx.length && this.length ) { 10148 // _detailsShown as false or undefined will fall through to return false 10149 return ctx[0].aoData[ this[0] ]._detailsShow || false; 10150 } 10151 return false; 10152 } ); 10153 10154 10155 10156 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10157 * Columns 10158 * 10159 * {integer} - column index (>=0 count from left, <0 count from right) 10160 * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right) 10161 * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right) 10162 * "{string}:name" - column name 10163 * "{string}" - jQuery selector on column header nodes 10164 * 10165 */ 10166 10167 // can be an array of these items, comma separated list, or an array of comma 10168 // separated lists 10169 10170 var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/; 10171 10172 10173 // r1 and r2 are redundant - but it means that the parameters match for the 10174 // iterator callback in columns().data() 10175 var __columnData = function ( settings, column, r1, r2, rows ) { 10176 var a = []; 10177 for ( var row=0, ien=rows.length ; row<ien ; row++ ) { 10178 a.push( _fnGetCellData( settings, rows[row], column ) ); 10179 } 10180 return a; 10181 }; 10182 10183 10184 var __column_selector = function ( settings, selector, opts ) 10185 { 10186 var 10187 columns = settings.aoColumns, 10188 names = _pluck( columns, 'sName' ), 10189 nodes = _pluck( columns, 'nTh' ); 10190 10191 var run = function ( s ) { 10192 var selInt = _intVal( s ); 10193 10194 // Selector - all 10195 if ( s === '' ) { 10196 return _range( columns.length ); 10197 } 10198 10199 // Selector - index 10200 if ( selInt !== null ) { 10201 return [ selInt >= 0 ? 10202 selInt : // Count from left 10203 columns.length + selInt // Count from right (+ because its a negative value) 10204 ]; 10205 } 10206 10207 // Selector = function 10208 if ( typeof s === 'function' ) { 10209 var rows = _selector_row_indexes( settings, opts ); 10210 10211 return $.map( columns, function (col, idx) { 10212 return s( 10213 idx, 10214 __columnData( settings, idx, 0, 0, rows ), 10215 nodes[ idx ] 10216 ) ? idx : null; 10217 } ); 10218 } 10219 10220 // jQuery or string selector 10221 var match = typeof s === 'string' ? 10222 s.match( __re_column_selector ) : 10223 ''; 10224 10225 if ( match ) { 10226 switch( match[2] ) { 10227 case 'visIdx': 10228 case 'visible': 10229 var idx = parseInt( match[1], 10 ); 10230 // Visible index given, convert to column index 10231 if ( idx < 0 ) { 10232 // Counting from the right 10233 var visColumns = $.map( columns, function (col,i) { 10234 return col.bVisible ? i : null; 10235 } ); 10236 return [ visColumns[ visColumns.length + idx ] ]; 10237 } 10238 // Counting from the left 10239 return [ _fnVisibleToColumnIndex( settings, idx ) ]; 10240 10241 case 'name': 10242 // match by name. `names` is column index complete and in order 10243 return $.map( names, function (name, i) { 10244 return name === match[1] ? i : null; 10245 } ); 10246 10247 default: 10248 return []; 10249 } 10250 } 10251 10252 // Cell in the table body 10253 if ( s.nodeName && s._DT_CellIndex ) { 10254 return [ s._DT_CellIndex.column ]; 10255 } 10256 10257 // jQuery selector on the TH elements for the columns 10258 var jqResult = $( nodes ) 10259 .filter( s ) 10260 .map( function () { 10261 return $.inArray( this, nodes ); // `nodes` is column index complete and in order 10262 } ) 10263 .toArray(); 10264 10265 if ( jqResult.length || ! s.nodeName ) {
10266 return jqResult; 10267 } 10268 10269 // Otherwise a node which might have a `dt-column` data attribute, or be 10270 // a child or such an element 10271 var host = $(s).closest('*[data-dt-column]'); 10272 return host.length ? 10273 [ host.data('dt-column') ] : 10274 []; 10275 }; 10276 10277 return _selector_run( 'column', selector, run, settings, opts ); 10278 }; 10279 10280 10281 var __setColumnVis = function ( settings, column, vis ) { 10282 var 10283 cols = settings.aoColumns, 10284 col = cols[ column ], 10285 data = settings.aoData, 10286 row, cells, i, ien, tr; 10287 10288 // Get 10289 if ( vis === undefined ) { 10290 return col.bVisible; 10291 } 10292 10293 // Set 10294 // No change 10295 if ( col.bVisible === vis ) { 10296 return; 10297 } 10298 10299 if ( vis ) { 10300 // Insert column 10301 // Need to decide if we should use appendChild or insertBefore 10302 var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 ); 10303 10304 for ( i=0, ien=data.length ; i<ien ; i++ ) { 10305 tr = data[i].nTr; 10306 cells = data[i].anCells; 10307 10308 if ( tr ) { 10309 // insertBefore can act like appendChild if 2nd arg is null 10310 tr.insertBefore( cells[ column ], cells[ insertBefore ] || null ); 10311 } 10312 } 10313 } 10314 else { 10315 // Remove column 10316 $( _pluck( settings.aoData, 'anCells', column ) ).detach(); 10317 } 10318 10319 // Common actions 10320 col.bVisible = vis; 10321 _fnDrawHead( settings, settings.aoHeader ); 10322 _fnDrawHead( settings, settings.aoFooter ); 10323 10324 // Update colspan for no records display. Child rows and extensions will use their own 10325 // listeners to do this - only need to update the empty table item here 10326 if ( ! settings.aiDisplay.length ) { 10327 $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings)); 10328 } 10329 10330 _fnSaveState( settings ); 10331 }; 10332 10333 10334 _api_register( 'columns()', function ( selector, opts ) { 10335 // argument shifting 10336 if ( selector === undefined ) { 10337 selector = ''; 10338 } 10339 else if ( $.isPlainObject( selector ) ) { 10340 opts = selector; 10341 selector = ''; 10342 } 10343 10344 opts = _selector_opts( opts ); 10345 10346 var inst = this.iterator( 'table', function ( settings ) { 10347 return __column_selector( settings, selector, opts ); 10348 }, 1 ); 10349 10350 // Want argument shifting here and in _row_selector? 10351 inst.selector.cols = selector; 10352 inst.selector.opts = opts; 10353 10354 return inst; 10355 } ); 10356 10357 _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) { 10358 return this.iterator( 'column', function ( settings, column ) { 10359 return settings.aoColumns[column].nTh; 10360 }, 1 ); 10361 } ); 10362 10363 _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) { 10364 return this.iterator( 'column', function ( settings, column ) { 10365 return settings.aoColumns[column].nTf; 10366 }, 1 ); 10367 } ); 10368 10369 _api_registerPlural( 'columns().data()', 'column().data()', function () { 10370 return this.iterator( 'column-rows', __columnData, 1 ); 10371 } ); 10372 10373 _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () { 10374 return this.iterator( 'column', function ( settings, column ) { 10375 return settings.aoColumns[column].mData; 10376 }, 1 ); 10377 } ); 10378 10379 _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) { 10380 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) { 10381 return _pluck_order( settings.aoData, rows, 10382 type === 'search' ? '_aFilterData' : '_aSortData', column 10383 ); 10384 }, 1 ); 10385 } ); 10386 10387 _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () { 10388 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) { 10389 return _pluck_order( settings.aoData, rows, 'anCells', column ) ; 10390 }, 1 ); 10391 } ); 10392 10393 _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) { 10394 var ret = this.iterator( 'column', function ( settings, column ) { 10395 if ( vis === undefined ) { 10396 return settings.aoColumns[ column ].bVisible; 10397 } // else 10398 __setColumnVis( settings, column, vis ); 10399 } ); 10400 10401 // Group the column visibility changes 10402 if ( vis !== undefined ) { 10403 // Second loop once the first is done for events 10404 this.iterator( 'column', function ( settings, column ) { 10405 _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] ); 10406 } ); 10407 10408 if ( calc === undefined || calc ) { 10409 this.columns.adjust(); 10410 } 10411 } 10412 10413 return ret; 10414 } ); 10415 10416 _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) { 10417 return this.iterator( 'column', function ( settings, column ) { 10418 return type === 'visible' ? 10419 _fnColumnIndexToVisible( settings, column ) : 10420 column; 10421 }, 1 ); 10422 } ); 10423 10424 _api_register( 'columns.adjust()', function () { 10425 return this.iterator( 'table', function ( settings ) { 10426 _fnAdjustColumnSizing( settings ); 10427 }, 1 ); 10428 } ); 10429 10430 _api_register( 'column.index()', function ( type, idx ) { 10431 if ( this.context.length !== 0 ) { 10432 var ctx = this.context[0]; 10433 10434 if ( type === 'fromVisible' || type === 'toData' ) { 10435 return _fnVisibleToColumnIndex( ctx, idx ); 10436 } 10437 else if ( type === 'fromData' || type === 'toVisible' ) { 10438 return _fnColumnIndexToVisible( ctx, idx ); 10439 } 10440 } 10441 } ); 10442 10443 _api_register( 'column()', function ( selector, opts ) { 10444 return _selector_first( this.columns( selector, opts ) ); 10445 } ); 10446 10447 10448 10449 var __cell_selector = function ( settings, selector, opts ) 10450 { 10451 var data = settings.aoData; 10452 var rows = _selector_row_indexes( settings, opts ); 10453 var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) ); 10454 var allCells = $( [].concat.apply([], cells) ); 10455 var row; 10456 var columns = settings.aoColumns.length; 10457 var a, i, ien, j, o, host; 10458 10459 var run = function ( s ) { 10460 var fnSelector = typeof s === 'function'; 10461 10462 if ( s === null || s === undefined || fnSelector ) { 10463 // All cells and function selectors 10464 a = []; 10465 10466 for ( i=0, ien=rows.length ; i<ien ; i++ ) {
10467 row = rows[i]; 10468 10469 for ( j=0 ; j<columns ; j++ ) { 10470 o = { 10471 row: row, 10472 column: j 10473 }; 10474 10475 if ( fnSelector ) { 10476 // Selector - function 10477 host = data[ row ]; 10478 10479 if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) { 10480 a.push( o ); 10481 } 10482 } 10483 else { 10484 // Selector - all 10485 a.push( o ); 10486 } 10487 } 10488 } 10489 10490 return a; 10491 } 10492 10493 // Selector - index 10494 if ( $.isPlainObject( s ) ) { 10495 // Valid cell index and its in the array of selectable rows 10496 return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ? 10497 [s] : 10498 []; 10499 } 10500 10501 // Selector - jQuery filtered cells 10502 var jqResult = allCells 10503 .filter( s ) 10504 .map( function (i, el) { 10505 return { // use a new object, in case someone changes the values 10506 row: el._DT_CellIndex.row, 10507 column: el._DT_CellIndex.column 10508 }; 10509 } ) 10510 .toArray(); 10511 10512 if ( jqResult.length || ! s.nodeName ) { 10513 return jqResult; 10514 } 10515 10516 // Otherwise the selector is a node, and there is one last option - the 10517 // element might be a child of an element which has dt-row and dt-column 10518 // data attributes 10519 host = $(s).closest('*[data-dt-row]'); 10520 return host.length ? 10521 [ { 10522 row: host.data('dt-row'), 10523 column: host.data('dt-column') 10524 } ] : 10525 []; 10526 }; 10527 10528 return _selector_run( 'cell', selector, run, settings, opts ); 10529 }; 10530 10531 10532 10533 10534 _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) { 10535 // Argument shifting 10536 if ( $.isPlainObject( rowSelector ) ) { 10537 // Indexes 10538 if ( rowSelector.row === undefined ) { 10539 // Selector options in first parameter 10540 opts = rowSelector; 10541 rowSelector = null; 10542 } 10543 else { 10544 // Cell index objects in first parameter 10545 opts = columnSelector; 10546 columnSelector = null; 10547 } 10548 } 10549 if ( $.isPlainObject( columnSelector ) ) { 10550 opts = columnSelector; 10551 columnSelector = null; 10552 } 10553 10554 // Cell selector 10555 if ( columnSelector === null || columnSelector === undefined ) { 10556 return this.iterator( 'table', function ( settings ) { 10557 return __cell_selector( settings, rowSelector, _selector_opts( opts ) ); 10558 } ); 10559 } 10560 10561 // Row + column selector 10562 var columns = this.columns( columnSelector ); 10563 var rows = this.rows( rowSelector ); 10564 var a, i, ien, j, jen; 10565 10566 this.iterator( 'table', function ( settings, idx ) { 10567 a = []; 10568 10569 for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) { 10570 for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) { 10571 a.push( { 10572 row: rows[idx][i], 10573 column: columns[idx][j] 10574 } ); 10575 } 10576 } 10577 }, 1 ); 10578 10579 // Now pass through the cell selector for options 10580 var cells = this.cells( a, opts ); 10581 10582 $.extend( cells.selector, { 10583 cols: columnSelector, 10584 rows: rowSelector, 10585 opts: opts 10586 } ); 10587 10588 return cells; 10589 } ); 10590 10591 10592 _api_registerPlural( 'cells().nodes()', 'cell().node()', function () { 10593 return this.iterator( 'cell', function ( settings, row, column ) { 10594 var data = settings.aoData[ row ]; 10595 10596 return data && data.anCells ? 10597 data.anCells[ column ] : 10598 undefined; 10599 }, 1 ); 10600 } ); 10601 10602 10603 _api_register( 'cells().data()', function () { 10604 return this.iterator( 'cell', function ( settings, row, column ) { 10605 return _fnGetCellData( settings, row, column ); 10606 }, 1 ); 10607 } ); 10608 10609 10610 _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) { 10611 type = type === 'search' ? '_aFilterData' : '_aSortData'; 10612 10613 return this.iterator( 'cell', function ( settings, row, column ) { 10614 return settings.aoData[ row ][ type ][ column ]; 10615 }, 1 ); 10616 } ); 10617 10618 10619 _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) { 10620 return this.iterator( 'cell', function ( settings, row, column ) { 10621 return _fnGetCellData( settings, row, column, type ); 10622 }, 1 ); 10623 } ); 10624 10625 10626 _api_registerPlural( 'cells().indexes()', 'cell().index()', function () { 10627 return this.iterator( 'cell', function ( settings, row, column ) { 10628 return { 10629 row: row, 10630 column: column, 10631 columnVisible: _fnColumnIndexToVisible( settings, column ) 10632 }; 10633 }, 1 ); 10634 } ); 10635 10636 10637 _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
10638 return this.iterator( 'cell', function ( settings, row, column ) { 10639 _fnInvalidate( settings, row, src, column ); 10640 } ); 10641 } ); 10642 10643 10644 10645 _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) { 10646 return _selector_first( this.cells( rowSelector, columnSelector, opts ) ); 10647 } ); 10648 10649 10650 _api_register( 'cell().data()', function ( data ) { 10651 var ctx = this.context; 10652 var cell = this[0]; 10653 10654 if ( data === undefined ) { 10655 // Get 10656 return ctx.length && cell.length ? 10657 _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) : 10658 undefined; 10659 } 10660 10661 // Set 10662 _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data ); 10663 _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column ); 10664 10665 return this; 10666 } ); 10667 10668 10669 10670 /** 10671 * Get current ordering (sorting) that has been applied to the table. 10672 * 10673 * @returns {array} 2D array containing the sorting information for the first 10674 * table in the current context. Each element in the parent array represents 10675 * a column being sorted upon (i.e. multi-sorting with two columns would have 10676 * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is 10677 * the column index that the sorting condition applies to, the second is the 10678 * direction of the sort (`desc` or `asc`) and, optionally, the third is the 10679 * index of the sorting order from the `column.sorting` initialisation array. 10680 *//** 10681 * Set the ordering for the table. 10682 * 10683 * @param {integer} order Column index to sort upon. 10684 * @param {string} direction Direction of the sort to be applied (`asc` or `desc`) 10685 * @returns {DataTables.Api} this 10686 *//** 10687 * Set the ordering for the table. 10688 * 10689 * @param {array} order 1D array of sorting information to be applied. 10690 * @param {array} [...] Optional additional sorting conditions 10691 * @returns {DataTables.Api} this 10692 *//** 10693 * Set the ordering for the table. 10694 * 10695 * @param {array} order 2D array of sorting information to be applied. 10696 * @returns {DataTables.Api} this 10697 */ 10698 _api_register( 'order()', function ( order, dir ) { 10699 var ctx = this.context; 10700 10701 if ( order === undefined ) { 10702 // get 10703 return ctx.length !== 0 ? 10704 ctx[0].aaSorting : 10705 undefined; 10706 } 10707 10708 // set 10709 if ( typeof order === 'number' ) { 10710 // Simple column / direction passed in 10711 order = [ [ order, dir ] ]; 10712 } 10713 else if ( order.length && ! $.isArray( order[0] ) ) { 10714 // Arguments passed in (list of 1D arrays) 10715 order = Array.prototype.slice.call( arguments ); 10716 } 10717 // otherwise a 2D array was passed in 10718 10719 return this.iterator( 'table', function ( settings ) { 10720 settings.aaSorting = order.slice(); 10721 } ); 10722 } ); 10723 10724 10725 /** 10726 * Attach a sort listener to an element for a given column 10727 * 10728 * @param {node|jQuery|string} node Identifier for the element(s) to attach the 10729 * listener to. This can take the form of a single DOM node, a jQuery 10730 * collection of nodes or a jQuery selector which will identify the node(s). 10731 * @param {integer} column the column that a click on this node will sort on 10732 * @param {function} [callback] callback function when sort is run 10733 * @returns {DataTables.Api} this 10734 */ 10735 _api_register( 'order.listener()', function ( node, column, callback ) { 10736 return this.iterator( 'table', function ( settings ) { 10737 _fnSortAttachListener( settings, node, column, callback ); 10738 } ); 10739 } ); 10740 10741 10742 _api_register( 'order.fixed()', function ( set ) { 10743 if ( ! set ) { 10744 var ctx = this.context; 10745 var fixed = ctx.length ? 10746 ctx[0].aaSortingFixed : 10747 undefined; 10748 10749 return $.isArray( fixed ) ? 10750 { pre: fixed } : 10751 fixed; 10752 } 10753 10754 return this.iterator( 'table', function ( settings ) { 10755 settings.aaSortingFixed = $.extend( true, {}, set ); 10756 } ); 10757 } ); 10758 10759 10760 // Order by the selected column(s) 10761 _api_register( [ 10762 'columns().order()', 10763 'column().order()' 10764 ], function ( dir ) { 10765 var that = this; 10766 10767 return this.iterator( 'table', function ( settings, i ) { 10768 var sort = []; 10769 10770 $.each( that[i], function (j, col) { 10771 sort.push( [ col, dir ] ); 10772 } ); 10773 10774 settings.aaSorting = sort; 10775 } ); 10776 } ); 10777 10778 10779 10780 _api_register( 'search()', function ( input, regex, smart, caseInsen ) { 10781 var ctx = this.context; 10782 10783 if ( input === undefined ) { 10784 // get 10785 return ctx.length !== 0 ? 10786 ctx[0].oPreviousSearch.sSearch : 10787 undefined; 10788 } 10789 10790 // set 10791 return this.iterator( 'table', function ( settings ) { 10792 if ( ! settings.oFeatures.bFilter ) { 10793 return; 10794 } 10795 10796 _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, { 10797 "sSearch": input+"", 10798 "bRegex": regex === null ? false : regex,
10799 "bSmart": smart === null ? true : smart, 10800 "bCaseInsensitive": caseInsen === null ? true : caseInsen 10801 } ), 1 ); 10802 } ); 10803 } ); 10804 10805 10806 _api_registerPlural( 10807 'columns().search()', 10808 'column().search()', 10809 function ( input, regex, smart, caseInsen ) { 10810 return this.iterator( 'column', function ( settings, column ) { 10811 var preSearch = settings.aoPreSearchCols; 10812 10813 if ( input === undefined ) { 10814 // get 10815 return preSearch[ column ].sSearch; 10816 } 10817 10818 // set 10819 if ( ! settings.oFeatures.bFilter ) { 10820 return; 10821 } 10822 10823 $.extend( preSearch[ column ], { 10824 "sSearch": input+"", 10825 "bRegex": regex === null ? false : regex, 10826 "bSmart": smart === null ? true : smart, 10827 "bCaseInsensitive": caseInsen === null ? true : caseInsen 10828 } ); 10829 10830 _fnFilterComplete( settings, settings.oPreviousSearch, 1 ); 10831 } ); 10832 } 10833 ); 10834 10835 /* 10836 * State API methods 10837 */ 10838 10839 _api_register( 'state()', function () { 10840 return this.context.length ? 10841 this.context[0].oSavedState : 10842 null; 10843 } ); 10844 10845 10846 _api_register( 'state.clear()', function () { 10847 return this.iterator( 'table', function ( settings ) { 10848 // Save an empty object 10849 settings.fnStateSaveCallback.call( settings.oInstance, settings, {} ); 10850 } ); 10851 } ); 10852 10853 10854 _api_register( 'state.loaded()', function () { 10855 return this.context.length ? 10856 this.context[0].oLoadedState : 10857 null; 10858 } ); 10859 10860 10861 _api_register( 'state.save()', function () { 10862 return this.iterator( 'table', function ( settings ) { 10863 _fnSaveState( settings ); 10864 } ); 10865 } ); 10866 10867 10868 10869 /** 10870 * Provide a common method for plug-ins to check the version of DataTables being 10871 * used, in order to ensure compatibility. 10872 * 10873 * @param {string} version Version string to check for, in the format "X.Y.Z". 10874 * Note that the formats "X" and "X.Y" are also acceptable. 10875 * @returns {boolean} true if this version of DataTables is greater or equal to 10876 * the required version, or false if this version of DataTales is not 10877 * suitable 10878 * @static 10879 * @dtopt API-Static 10880 * 10881 * @example 10882 * alert( $.fn.dataTable.versionCheck( '1.9.0' ) ); 10883 */ 10884 DataTable.versionCheck = DataTable.fnVersionCheck = function( version ) 10885 { 10886 var aThis = DataTable.version.split('.'); 10887 var aThat = version.split('.'); 10888 var iThis, iThat; 10889 10890 for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) { 10891 iThis = parseInt( aThis[i], 10 ) || 0; 10892 iThat = parseInt( aThat[i], 10 ) || 0; 10893 10894 // Parts are the same, keep comparing 10895 if (iThis === iThat) { 10896 continue; 10897 } 10898 10899 // Parts are different, return immediately 10900 return iThis > iThat; 10901 } 10902 10903 return true; 10904 }; 10905 10906 10907 /** 10908 * Check if a `<table>` node is a DataTable table already or not. 10909 * 10910 * @param {node|jquery|string} table Table node, jQuery object or jQuery 10911 * selector for the table to test. Note that if more than more than one 10912 * table is passed on, only the first will be checked 10913 * @returns {boolean} true the table given is a DataTable, or false otherwise 10914 * @static 10915 * @dtopt API-Static 10916 * 10917 * @example 10918 * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) { 10919 * $('#example').dataTable(); 10920 * } 10921 */ 10922 DataTable.isDataTable = DataTable.fnIsDataTable = function ( table ) 10923 { 10924 var t = $(table).get(0); 10925 var is = false; 10926 10927 if ( table instanceof DataTable.Api ) { 10928 return true; 10929 } 10930 10931 $.each( DataTable.settings, function (i, o) { 10932 var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null; 10933 var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null; 10934 10935 if ( o.nTable === t || head === t || foot === t ) { 10936 is = true; 10937 } 10938 } ); 10939 10940 return is; 10941 }; 10942 10943 10944 /** 10945 * Get all DataTable tables that have been initialised - optionally you can 10946 * select to get only currently visible tables. 10947 * 10948 * @param {boolean} [visible=false] Flag to indicate if you want all (default) 10949 * or visible tables only. 10950 * @returns {array} Array of `table` nodes (not DataTable instances) which are 10951 * DataTables 10952 * @static 10953 * @dtopt API-Static 10954 * 10955 * @example 10956 * $.each( $.fn.dataTable.tables(true), function () { 10957 * $(table).DataTable().columns.adjust(); 10958 * } ); 10959 */ 10960 DataTable.tables = DataTable.fnTables = function ( visible ) 10961 { 10962 var api = false;
10963 10964 if ( $.isPlainObject( visible ) ) { 10965 api = visible.api; 10966 visible = visible.visible; 10967 } 10968 10969 var a = $.map( DataTable.settings, function (o) { 10970 if ( !visible || (visible && $(o.nTable).is(':visible')) ) { 10971 return o.nTable; 10972 } 10973 } ); 10974 10975 return api ? 10976 new _Api( a ) : 10977 a; 10978 }; 10979 10980 10981 /** 10982 * Convert from camel case parameters to Hungarian notation. This is made public 10983 * for the extensions to provide the same ability as DataTables core to accept 10984 * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase 10985 * parameters. 10986 * 10987 * @param {object} src The model object which holds all parameters that can be 10988 * mapped. 10989 * @param {object} user The object to convert from camel case to Hungarian. 10990 * @param {boolean} force When set to `true`, properties which already have a 10991 * Hungarian value in the `user` object will be overwritten. Otherwise they 10992 * won't be. 10993 */ 10994 DataTable.camelToHungarian = _fnCamelToHungarian; 10995 10996 10997 10998 /** 10999 * 11000 */ 11001 _api_register( '$()', function ( selector, opts ) { 11002 var 11003 rows = this.rows( opts ).nodes(), // Get all rows 11004 jqRows = $(rows); 11005 11006 return $( [].concat( 11007 jqRows.filter( selector ).toArray(), 11008 jqRows.find( selector ).toArray() 11009 ) ); 11010 } ); 11011 11012 11013 // jQuery functions to operate on the tables 11014 $.each( [ 'on', 'one', 'off' ], function (i, key) { 11015 _api_register( key+'()', function ( /* event, handler */ ) { 11016 var args = Array.prototype.slice.call(arguments); 11017 11018 // Add the `dt` namespace automatically if it isn't already present 11019 args[0] = $.map( args[0].split( /\s/ ), function ( e ) { 11020 return ! e.match(/\.dt\b/) ? 11021 e+'.dt' : 11022 e; 11023 } ).join( ' ' ); 11024 11025 var inst = $( this.tables().nodes() ); 11026 inst[key].apply( inst, args ); 11027 return this; 11028 } ); 11029 } ); 11030 11031 11032 _api_register( 'clear()', function () { 11033 return this.iterator( 'table', function ( settings ) { 11034 _fnClearTable( settings ); 11035 } ); 11036 } ); 11037 11038 11039 _api_register( 'settings()', function () { 11040 return new _Api( this.context, this.context ); 11041 } ); 11042 11043 11044 _api_register( 'init()', function () { 11045 var ctx = this.context; 11046 return ctx.length ? ctx[0].oInit : null; 11047 } ); 11048 11049 11050 _api_register( 'data()', function () { 11051 return this.iterator( 'table', function ( settings ) { 11052 return _pluck( settings.aoData, '_aData' ); 11053 } ).flatten(); 11054 } ); 11055 11056 11057 _api_register( 'destroy()', function ( remove ) { 11058 remove = remove || false; 11059 11060 return this.iterator( 'table', function ( settings ) { 11061 var orig = settings.nTableWrapper.parentNode; 11062 var classes = settings.oClasses; 11063 var table = settings.nTable; 11064 var tbody = settings.nTBody; 11065 var thead = settings.nTHead; 11066 var tfoot = settings.nTFoot; 11067 var jqTable = $(table); 11068 var jqTbody = $(tbody); 11069 var jqWrapper = $(settings.nTableWrapper); 11070 var rows = $.map( settings.aoData, function (r) { return r.nTr; } ); 11071 var i, ien; 11072 11073 // Flag to note that the table is currently being destroyed - no action 11074 // should be taken 11075 settings.bDestroying = true; 11076 11077 // Fire off the destroy callbacks for plug-ins etc 11078 _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] ); 11079 11080 // If not being removed from the document, make all columns visible 11081 if ( ! remove ) { 11082 new _Api( settings ).columns().visible( true ); 11083 } 11084 11085 // Blitz all `DT` namespaced events (these are internal events, the 11086 // lowercase, `dt` events are user subscribed and they are responsible 11087 // for removing them 11088 jqWrapper.off('.DT').find(':not(tbody *)').off('.DT'); 11089 $(window).off('.DT-'+settings.sInstance); 11090 11091 // When scrolling we had to break the table up - restore it 11092 if ( table != thead.parentNode ) { 11093 jqTable.children('thead').detach(); 11094 jqTable.append( thead ); 11095 } 11096 11097 if ( tfoot && table != tfoot.parentNode ) { 11098 jqTable.children('tfoot').detach(); 11099 jqTable.append( tfoot ); 11100 } 11101 11102 settings.aaSorting = []; 11103 settings.aaSortingFixed = []; 11104 _fnSortingClasses( settings ); 11105 11106 $( rows ).removeClass( settings.asStripeClasses.join(' ') ); 11107 11108 $('th, td', thead).removeClass( classes.sSortable+' '+ 11109 classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone 11110 ); 11111 11112 // Add the TR elements back into the table in their original order 11113 jqTbody.children().detach(); 11114 jqTbody.append( rows ); 11115 11116 // Remove the DataTables generated nodes, events and classes 11117 var removedMethod = remove ? 'remove' : 'detach'; 11118 jqTable[ removedMethod ](); 11119 jqWrapper[ removedMethod ](); 11120 11121 // If we need to reattach the table to the document 11122 if ( ! remove && orig ) { 11123 // insertBefore acts like appendChild if !arg[1]
11124 orig.insertBefore( table, settings.nTableReinsertBefore ); 11125 11126 // Restore the width of the original table - was read from the style property, 11127 // so we can restore directly to that 11128 jqTable 11129 .css( 'width', settings.sDestroyWidth ) 11130 .removeClass( classes.sTable ); 11131 11132 // If the were originally stripe classes - then we add them back here. 11133 // Note this is not fool proof (for example if not all rows had stripe 11134 // classes - but it's a good effort without getting carried away 11135 ien = settings.asDestroyStripes.length; 11136 11137 if ( ien ) { 11138 jqTbody.children().each( function (i) { 11139 $(this).addClass( settings.asDestroyStripes[i % ien] ); 11140 } ); 11141 } 11142 } 11143 11144 /* Remove the settings object from the settings array */ 11145 var idx = $.inArray( settings, DataTable.settings ); 11146 if ( idx !== -1 ) { 11147 DataTable.settings.splice( idx, 1 ); 11148 } 11149 } ); 11150 } ); 11151 11152 11153 // Add the `every()` method for rows, columns and cells in a compact form 11154 $.each( [ 'column', 'row', 'cell' ], function ( i, type ) { 11155 _api_register( type+'s().every()', function ( fn ) { 11156 var opts = this.selector.opts; 11157 var api = this; 11158 11159 return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) { 11160 // Rows and columns: 11161 // arg1 - index 11162 // arg2 - table counter 11163 // arg3 - loop counter 11164 // arg4 - undefined 11165 // Cells: 11166 // arg1 - row index 11167 // arg2 - column index 11168 // arg3 - table counter 11169 // arg4 - loop counter 11170 fn.call( 11171 api[ type ]( 11172 arg1, 11173 type==='cell' ? arg2 : opts, 11174 type==='cell' ? opts : undefined 11175 ), 11176 arg1, arg2, arg3, arg4 11177 ); 11178 } ); 11179 } ); 11180 } ); 11181 11182 11183 // i18n method for extensions to be able to use the language object from the 11184 // DataTable 11185 _api_register( 'i18n()', function ( token, def, plural ) { 11186 var ctx = this.context[0]; 11187 var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage ); 11188 11189 if ( resolved === undefined ) { 11190 resolved = def; 11191 } 11192 11193 if ( plural !== undefined && $.isPlainObject( resolved ) ) { 11194 resolved = resolved[ plural ] !== undefined ? 11195 resolved[ plural ] : 11196 resolved._; 11197 } 11198 11199 return resolved.replace( '%d', plural ); // nb: plural might be undefined, 11200 } ); 11201 11202 /** 11203 * Version string for plug-ins to check compatibility. Allowed format is 11204 * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used 11205 * only for non-release builds. See http://semver.org/ for more information. 11206 * @member 11207 * @type string 11208 * @default Version number 11209 */ 11210 DataTable.version = "1.10.18"; 11211 11212 /** 11213 * Private data store, containing all of the settings objects that are 11214 * created for the tables on a given page. 11215 * 11216 * Note that the `DataTable.settings` object is aliased to 11217 * `jQuery.fn.dataTableExt` through which it may be accessed and 11218 * manipulated, or `jQuery.fn.dataTable.settings`. 11219 * @member 11220 * @type array 11221 * @default [] 11222 * @private 11223 */ 11224 DataTable.settings = []; 11225 11226 /** 11227 * Object models container, for the various models that DataTables has 11228 * available to it. These models define the objects that are used to hold 11229 * the active state and configuration of the table. 11230 * @namespace 11231 */ 11232 DataTable.models = {}; 11233 11234 11235 11236 /** 11237 * Template object for the way in which DataTables holds information about 11238 * search information for the global filter and individual column filters. 11239 * @namespace 11240 */ 11241 DataTable.models.oSearch = { 11242 /** 11243 * Flag to indicate if the filtering should be case insensitive or not 11244 * @type boolean 11245 * @default true 11246 */ 11247 "bCaseInsensitive": true, 11248 11249 /** 11250 * Applied search term 11251 * @type string 11252 * @default <i>Empty string</i> 11253 */ 11254 "sSearch": "", 11255 11256 /** 11257 * Flag to indicate if the search term should be interpreted as a 11258 * regular expression (true) or not (false) and therefore and special 11259 * regex characters escaped. 11260 * @type boolean 11261 * @default false 11262 */ 11263 "bRegex": false, 11264 11265 /** 11266 * Flag to indicate if DataTables is to use its smart filtering or not. 11267 * @type boolean 11268 * @default true 11269 */ 11270 "bSmart": true 11271 }; 11272 11273 11274 11275 11276 /** 11277 * Template object for the way in which DataTables holds information about 11278 * each individual row. This is the object format used for the settings 11279 * aoData array.
11280 * @namespace 11281 */ 11282 DataTable.models.oRow = { 11283 /** 11284 * TR element for the row 11285 * @type node 11286 * @default null 11287 */ 11288 "nTr": null, 11289 11290 /** 11291 * Array of TD elements for each row. This is null until the row has been 11292 * created. 11293 * @type array nodes 11294 * @default [] 11295 */ 11296 "anCells": null, 11297 11298 /** 11299 * Data object from the original data source for the row. This is either 11300 * an array if using the traditional form of DataTables, or an object if 11301 * using mData options. The exact type will depend on the passed in 11302 * data from the data source, or will be an array if using DOM a data 11303 * source. 11304 * @type array|object 11305 * @default [] 11306 */ 11307 "_aData": [], 11308 11309 /** 11310 * Sorting data cache - this array is ostensibly the same length as the 11311 * number of columns (although each index is generated only as it is 11312 * needed), and holds the data that is used for sorting each column in the 11313 * row. We do this cache generation at the start of the sort in order that 11314 * the formatting of the sort data need be done only once for each cell 11315 * per sort. This array should not be read from or written to by anything 11316 * other than the master sorting methods. 11317 * @type array 11318 * @default null 11319 * @private 11320 */ 11321 "_aSortData": null, 11322 11323 /** 11324 * Per cell filtering data cache. As per the sort data cache, used to 11325 * increase the performance of the filtering in DataTables 11326 * @type array 11327 * @default null 11328 * @private 11329 */ 11330 "_aFilterData": null, 11331 11332 /** 11333 * Filtering data cache. This is the same as the cell filtering cache, but 11334 * in this case a string rather than an array. This is easily computed with 11335 * a join on `_aFilterData`, but is provided as a cache so the join isn't 11336 * needed on every search (memory traded for performance) 11337 * @type array 11338 * @default null 11339 * @private 11340 */ 11341 "_sFilterRow": null, 11342 11343 /** 11344 * Cache of the class name that DataTables has applied to the row, so we 11345 * can quickly look at this variable rather than needing to do a DOM check 11346 * on className for the nTr property. 11347 * @type string 11348 * @default <i>Empty string</i> 11349 * @private 11350 */ 11351 "_sRowStripe": "", 11352 11353 /** 11354 * Denote if the original data source was from the DOM, or the data source 11355 * object. This is used for invalidating data, so DataTables can 11356 * automatically read data from the original source, unless uninstructed 11357 * otherwise. 11358 * @type string 11359 * @default null 11360 * @private 11361 */ 11362 "src": null, 11363 11364 /** 11365 * Index in the aoData array. This saves an indexOf lookup when we have the 11366 * object, but want to know the index 11367 * @type integer 11368 * @default -1 11369 * @private 11370 */ 11371 "idx": -1 11372 }; 11373 11374 11375 /** 11376 * Template object for the column information object in DataTables. This object 11377 * is held in the settings aoColumns array and contains all the information that 11378 * DataTables needs about each individual column. 11379 * 11380 * Note that this object is related to {@link DataTable.defaults.column} 11381 * but this one is the internal data store for DataTables's cache of columns. 11382 * It should NOT be manipulated outside of DataTables. Any configuration should 11383 * be done through the initialisation options. 11384 * @namespace 11385 */ 11386 DataTable.models.oColumn = { 11387 /** 11388 * Column index. This could be worked out on-the-fly with $.inArray, but it 11389 * is faster to just hold it as a variable 11390 * @type integer 11391 * @default null 11392 */ 11393 "idx": null, 11394 11395 /** 11396 * A list of the columns that sorting should occur on when this column 11397 * is sorted. That this property is an array allows multi-column sorting 11398 * to be defined for a column (for example first name / last name columns 11399 * would benefit from this). The values are integers pointing to the 11400 * columns to be sorted on (typically it will be a single integer pointing 11401 * at itself, but that doesn't need to be the case). 11402 * @type array 11403 */ 11404 "aDataSort": null, 11405 11406 /** 11407 * Define the sorting directions that are applied to the column, in sequence 11408 * as the column is repeatedly sorted upon - i.e. the first value is used 11409 * as the sorting direction when the column if first sorted (clicked on). 11410 * Sort it again (click again) and it will move on to the next index. 11411 * Repeat until loop. 11412 * @type array 11413 */ 11414 "asSorting": null, 11415 11416 /** 11417 * Flag to indicate if the column is searchable, and thus should be included 11418 * in the filtering or not. 11419 * @type boolean 11420 */ 11421 "bSearchable": null, 11422 11423 /** 11424 * Flag to indicate if the column is sortable or not. 11425 * @type boolean 11426 */ 11427 "bSortable": null, 11428 11429 /** 11430 * Flag to indicate if the column is currently visible in the table or not 11431 * @type boolean 11432 */ 11433 "bVisible": null, 11434 11435 /** 11436 * Store for manual type assignment using the `column.type` option. This 11437 * is held in store so we can manipulate the column's `sType` property. 11438 * @type string 11439 * @default null 11440 * @private 11441 */ 11442 "_sManualType": null, 11443 11444 /** 11445 * Flag to indicate if HTML5 data attributes should be used as the data 11446 * source for filtering or sorting. True is either are. 11447 * @type boolean 11448 * @default false 11449 * @private 11450 */ 11451 "_bAttrSrc": false, 11452 11453 /** 11454 * Developer definable function that is called whenever a cell is created (Ajax source, 11455 * etc) or processed for input (DOM source). This can be used as a compliment to mRender 11456 * allowing you to modify the DOM element (add background colour for example) when the 11457 * element is available. 11458 * @type function 11459 * @param {element} nTd The TD node that has been created 11460 * @param {*} sData The Data for the cell 11461 * @param {array|object} oData The data for the whole row 11462 * @param {int} iRow The row index for the aoData data store 11463 * @default null 11464 */ 11465 "fnCreatedCell": null, 11466 11467 /** 11468 * Function to get data from a cell in a column. You should <b>never</b> 11469 * access data directly through _aData internally in DataTables - always use 11470 * the method attached to this property. It allows mData to function as 11471 * required. This function is automatically assigned by the column 11472 * initialisation method 11473 * @type function 11474 * @param {array|object} oData The data array/object for the array 11475 * (i.e. aoData[]._aData) 11476 * @param {string} sSpecific The specific data type you want to get - 11477 * 'display', 'type' 'filter' 'sort' 11478 * @returns {*} The data for the cell from the given row's data 11479 * @default null 11480 */ 11481 "fnGetData": null, 11482 11483 /** 11484 * Function to set data for a cell in the column. You should <b>never</b> 11485 * set the data directly to _aData internally in DataTables - always use 11486 * this method. It allows mData to function as required. This function 11487 * is automatically assigned by the column initialisation method 11488 * @type function 11489 * @param {array|object} oData The data array/object for the array 11490 * (i.e. aoData[]._aData) 11491 * @param {*} sValue Value to set 11492 * @default null 11493 */ 11494 "fnSetData": null, 11495 11496 /** 11497 * Property to read the value for the cells in the column from the data 11498 * source array / object. If null, then the default content is used, if a 11499 * function is given then the return from the function is used. 11500 * @type function|int|string|null 11501 * @default null 11502 */ 11503 "mData": null, 11504 11505 /** 11506 * Partner property to mData which is used (only when defined) to get 11507 * the data - i.e. it is basically the same as mData, but without the 11508 * 'set' option, and also the data fed to it is the result from mData. 11509 * This is the rendering method to match the data method of mData. 11510 * @type function|int|string|null 11511 * @default null 11512 */
11513 "mRender": null, 11514 11515 /** 11516 * Unique header TH/TD element for this column - this is what the sorting 11517 * listener is attached to (if sorting is enabled.) 11518 * @type node 11519 * @default null 11520 */ 11521 "nTh": null, 11522 11523 /** 11524 * Unique footer TH/TD element for this column (if there is one). Not used 11525 * in DataTables as such, but can be used for plug-ins to reference the 11526 * footer for each column. 11527 * @type node 11528 * @default null 11529 */ 11530 "nTf": null, 11531 11532 /** 11533 * The class to apply to all TD elements in the table's TBODY for the column 11534 * @type string 11535 * @default null 11536 */ 11537 "sClass": null, 11538 11539 /** 11540 * When DataTables calculates the column widths to assign to each column, 11541 * it finds the longest string in each column and then constructs a 11542 * temporary table and reads the widths from that. The problem with this 11543 * is that "mmm" is much wider then "iiii", but the latter is a longer 11544 * string - thus the calculation can go wrong (doing it properly and putting 11545 * it into an DOM object and measuring that is horribly(!) slow). Thus as 11546 * a "work around" we provide this option. It will append its value to the 11547 * text that is found to be the longest string for the column - i.e. padding. 11548 * @type string 11549 */ 11550 "sContentPadding": null, 11551 11552 /** 11553 * Allows a default value to be given for a column's data, and will be used 11554 * whenever a null data source is encountered (this can be because mData 11555 * is set to null, or because the data source itself is null). 11556 * @type string 11557 * @default null 11558 */ 11559 "sDefaultContent": null, 11560 11561 /** 11562 * Name for the column, allowing reference to the column by name as well as 11563 * by index (needs a lookup to work by name). 11564 * @type string 11565 */ 11566 "sName": null, 11567 11568 /** 11569 * Custom sorting data type - defines which of the available plug-ins in 11570 * afnSortData the custom sorting will use - if any is defined. 11571 * @type string 11572 * @default std 11573 */ 11574 "sSortDataType": 'std', 11575 11576 /** 11577 * Class to be applied to the header element when sorting on this column 11578 * @type string 11579 * @default null 11580 */ 11581 "sSortingClass": null, 11582 11583 /** 11584 * Class to be applied to the header element when sorting on this column - 11585 * when jQuery UI theming is used. 11586 * @type string 11587 * @default null 11588 */ 11589 "sSortingClassJUI": null, 11590 11591 /** 11592 * Title of the column - what is seen in the TH element (nTh). 11593 * @type string 11594 */ 11595 "sTitle": null, 11596 11597 /** 11598 * Column sorting and filtering type 11599 * @type string 11600 * @default null 11601 */ 11602 "sType": null, 11603 11604 /** 11605 * Width of the column 11606 * @type string 11607 * @default null 11608 */ 11609 "sWidth": null, 11610 11611 /** 11612 * Width of the column when it was first "encountered" 11613 * @type string 11614 * @default null 11615 */ 11616 "sWidthOrig": null 11617 }; 11618 11619 11620 /* 11621 * Developer note: The properties of the object below are given in Hungarian 11622 * notation, that was used as the interface for DataTables prior to v1.10, however 11623 * from v1.10 onwards the primary interface is camel case. In order to avoid 11624 * breaking backwards compatibility utterly with this change, the Hungarian 11625 * version is still, internally the primary interface, but is is not documented 11626 * - hence the @name tags in each doc comment. This allows a Javascript function 11627 * to create a map from Hungarian notation to camel case (going the other direction 11628 * would require each property to be listed, which would at around 3K to the size 11629 * of DataTables, while this method is about a 0.5K hit. 11630 * 11631 * Ultimately this does pave the way for Hungarian notation to be dropped 11632 * completely, but that is a massive amount of work and will break current 11633 * installs (therefore is on-hold until v2). 11634 */ 11635 11636 /** 11637 * Initialisation options that can be given to DataTables at initialisation 11638 * time. 11639 * @namespace 11640 */ 11641 DataTable.defaults = { 11642 /** 11643 * An array of data to use for the table, passed in at initialisation which 11644 * will be used in preference to any data which is already in the DOM. This is 11645 * particularly useful for constructing tables purely in Javascript, for 11646 * example with a custom Ajax call. 11647 * @type array 11648 * @default null 11649 * 11650 * @dtopt Option 11651 * @name DataTable.defaults.data 11652 * 11653 * @example 11654 * // Using a 2D array data source 11655 * $(document).ready( function () { 11656 * $('#example').dataTable( { 11657 * "data": [ 11658 * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'], 11659 * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'], 11660 * ], 11661 * "columns": [ 11662 * { "title": "Engine" }, 11663 * { "title": "Browser" }, 11664 * { "title": "Platform" }, 11665 * { "title": "Version" }, 11666 * { "title": "Grade" } 11667 * ] 11668 * } ); 11669 * } ); 11670 * 11671 * @example 11672 * // Using an array of objects as a data source (`data`) 11673 * $(document).ready( function () { 11674 * $('#example').dataTable( { 11675 * "data": [ 11676 * {
11677 * "engine": "Trident", 11678 * "browser": "Internet Explorer 4.0", 11679 * "platform": "Win 95+", 11680 * "version": 4, 11681 * "grade": "X" 11682 * }, 11683 * { 11684 * "engine": "Trident", 11685 * "browser": "Internet Explorer 5.0", 11686 * "platform": "Win 95+", 11687 * "version": 5, 11688 * "grade": "C" 11689 * } 11690 * ], 11691 * "columns": [ 11692 * { "title": "Engine", "data": "engine" }, 11693 * { "title": "Browser", "data": "browser" }, 11694 * { "title": "Platform", "data": "platform" }, 11695 * { "title": "Version", "data": "version" }, 11696 * { "title": "Grade", "data": "grade" } 11697 * ] 11698 * } ); 11699 * } ); 11700 */ 11701 "aaData": null, 11702 11703 11704 /** 11705 * If ordering is enabled, then DataTables will perform a first pass sort on 11706 * initialisation. You can define which column(s) the sort is performed 11707 * upon, and the sorting direction, with this variable. The `sorting` array 11708 * should contain an array for each column to be sorted initially containing 11709 * the column's index and a direction string ('asc' or 'desc'). 11710 * @type array 11711 * @default [[0,'asc']] 11712 * 11713 * @dtopt Option 11714 * @name DataTable.defaults.order 11715 * 11716 * @example 11717 * // Sort by 3rd column first, and then 4th column 11718 * $(document).ready( function() { 11719 * $('#example').dataTable( { 11720 * "order": [[2,'asc'], [3,'desc']] 11721 * } ); 11722 * } ); 11723 * 11724 * // No initial sorting 11725 * $(document).ready( function() { 11726 * $('#example').dataTable( { 11727 * "order": [] 11728 * } ); 11729 * } ); 11730 */ 11731 "aaSorting": [[0,'asc']], 11732 11733 11734 /** 11735 * This parameter is basically identical to the `sorting` parameter, but 11736 * cannot be overridden by user interaction with the table. What this means 11737 * is that you could have a column (visible or hidden) which the sorting 11738 * will always be forced on first - any sorting after that (from the user) 11739 * will then be performed as required. This can be useful for grouping rows 11740 * together. 11741 * @type array 11742 * @default null 11743 * 11744 * @dtopt Option 11745 * @name DataTable.defaults.orderFixed 11746 * 11747 * @example 11748 * $(document).ready( function() { 11749 * $('#example').dataTable( { 11750 * "orderFixed": [[0,'asc']] 11751 * } ); 11752 * } ) 11753 */ 11754 "aaSortingFixed": [], 11755 11756 11757 /** 11758 * DataTables can be instructed to load data to display in the table from a 11759 * Ajax source. This option defines how that Ajax call is made and where to. 11760 * 11761 * The `ajax` property has three different modes of operation, depending on 11762 * how it is defined. These are: 11763 * 11764 * * `string` - Set the URL from where the data should be loaded from. 11765 * * `object` - Define properties for `jQuery.ajax`. 11766 * * `function` - Custom data get function 11767 * 11768 * `string` 11769 * -------- 11770 * 11771 * As a string, the `ajax` property simply defines the URL from which 11772 * DataTables will load data. 11773 * 11774 * `object` 11775 * -------- 11776 * 11777 * As an object, the parameters in the object are passed to 11778 * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control 11779 * of the Ajax request. DataTables has a number of default parameters which 11780 * you can override using this option. Please refer to the jQuery 11781 * documentation for a full description of the options available, although 11782 * the following parameters provide additional options in DataTables or 11783 * require special consideration: 11784 * 11785 * * `data` - As with jQuery, `data` can be provided as an object, but it 11786 * can also be used as a function to manipulate the data DataTables sends 11787 * to the server. The function takes a single parameter, an object of 11788 * parameters with the values that DataTables has readied for sending. An 11789 * object may be returned which will be merged into the DataTables 11790 * defaults, or you can add the items to the object that was passed in and 11791 * not return anything from the function. This supersedes `fnServerParams` 11792 * from DataTables 1.9-. 11793 * 11794 * * `dataSrc` - By default DataTables will look for the property `data` (or 11795 * `aaData` for compatibility with DataTables 1.9-) when obtaining data 11796 * from an Ajax source or for server-side processing - this parameter 11797 * allows that property to be changed. You can use Javascript dotted 11798 * object notation to get a data source for multiple levels of nesting, or 11799 * it my be used as a function. As a function it takes a single parameter, 11800 * the JSON returned from the server, which can be manipulated as 11801 * required, with the returned value being that used by DataTables as the 11802 * data source for the table. This supersedes `sAjaxDataProp` from 11803 * DataTables 1.9-. 11804 * 11805 * * `success` - Should not be overridden it is used internally in 11806 * DataTables. To manipulate / transform the data returned by the server 11807 * use `ajax.dataSrc`, or use `ajax` as a function (see below). 11808 * 11809 * `function` 11810 * ---------- 11811 * 11812 * As a function, making the Ajax call is left up to yourself allowing 11813 * complete control of the Ajax request. Indeed, if desired, a method other 11814 * than Ajax could be used to obtain the required data, such as Web storage 11815 * or an AIR database. 11816 * 11817 * The function is given four parameters and no return is required. The 11818 * parameters are: 11819 * 11820 * 1. _object_ - Data to send to the server 11821 * 2. _function_ - Callback function that must be executed when the required 11822 * data has been obtained. That data should be passed into the callback 11823 * as the only parameter 11824 * 3. _object_ - DataTables settings object for the table 11825 * 11826 * Note that this supersedes `fnServerData` from DataTables 1.9-. 11827 * 11828 * @type string|object|function 11829 * @default null 11830 * 11831 * @dtopt Option 11832 * @name DataTable.defaults.ajax
11833 * @since 1.10.0 11834 * 11835 * @example 11836 * // Get JSON data from a file via Ajax. 11837 * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default). 11838 * $('#example').dataTable( { 11839 * "ajax": "data.json" 11840 * } ); 11841 * 11842 * @example 11843 * // Get JSON data from a file via Ajax, using `dataSrc` to change 11844 * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`) 11845 * $('#example').dataTable( { 11846 * "ajax": { 11847 * "url": "data.json", 11848 * "dataSrc": "tableData" 11849 * } 11850 * } ); 11851 * 11852 * @example 11853 * // Get JSON data from a file via Ajax, using `dataSrc` to read data 11854 * // from a plain array rather than an array in an object 11855 * $('#example').dataTable( { 11856 * "ajax": { 11857 * "url": "data.json", 11858 * "dataSrc": "" 11859 * } 11860 * } ); 11861 * 11862 * @example 11863 * // Manipulate the data returned from the server - add a link to data 11864 * // (note this can, should, be done using `render` for the column - this 11865 * // is just a simple example of how the data can be manipulated). 11866 * $('#example').dataTable( { 11867 * "ajax": { 11868 * "url": "data.json", 11869 * "dataSrc": function ( json ) { 11870 * for ( var i=0, ien=json.length ; i<ien ; i++ ) { 11871 * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>'; 11872 * } 11873 * return json; 11874 * } 11875 * } 11876 * } ); 11877 * 11878 * @example 11879 * // Add data to the request 11880 * $('#example').dataTable( { 11881 * "ajax": { 11882 * "url": "data.json", 11883 * "data": function ( d ) { 11884 * return { 11885 * "extra_search": $('#extra').val() 11886 * }; 11887 * } 11888 * } 11889 * } ); 11890 * 11891 * @example 11892 * // Send request as POST 11893 * $('#example').dataTable( { 11894 * "ajax": { 11895 * "url": "data.json", 11896 * "type": "POST" 11897 * } 11898 * } ); 11899 * 11900 * @example 11901 * // Get the data from localStorage (could interface with a form for 11902 * // adding, editing and removing rows). 11903 * $('#example').dataTable( { 11904 * "ajax": function (data, callback, settings) { 11905 * callback( 11906 * JSON.parse( localStorage.getItem('dataTablesData') ) 11907 * ); 11908 * } 11909 * } ); 11910 */ 11911 "ajax": null, 11912 11913 11914 /** 11915 * This parameter allows you to readily specify the entries in the length drop 11916 * down menu that DataTables shows when pagination is enabled. It can be 11917 * either a 1D array of options which will be used for both the displayed 11918 * option and the value, or a 2D array which will use the array in the first 11919 * position as the value, and the array in the second position as the 11920 * displayed options (useful for language strings such as 'All'). 11921 * 11922 * Note that the `pageLength` property will be automatically set to the 11923 * first value given in this array, unless `pageLength` is also provided. 11924 * @type array 11925 * @default [ 10, 25, 50, 100 ] 11926 * 11927 * @dtopt Option 11928 * @name DataTable.defaults.lengthMenu 11929 * 11930 * @example 11931 * $(document).ready( function() { 11932 * $('#example').dataTable( { 11933 * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] 11934 * } ); 11935 * } ); 11936 */ 11937 "aLengthMenu": [ 10, 25, 50, 100 ], 11938 11939 11940 /** 11941 * The `columns` option in the initialisation parameter allows you to define 11942 * details about the way individual columns behave. For a full list of 11943 * column options that can be set, please see 11944 * {@link DataTable.defaults.column}. Note that if you use `columns` to 11945 * define your columns, you must have an entry in the array for every single 11946 * column that you have in your table (these can be null if you don't which 11947 * to specify any options). 11948 * @member 11949 * 11950 * @name DataTable.defaults.column 11951 */ 11952 "aoColumns": null, 11953 11954 /** 11955 * Very similar to `columns`, `columnDefs` allows you to target a specific 11956 * column, multiple columns, or all columns, using the `targets` property of 11957 * each object in the array. This allows great flexibility when creating 11958 * tables, as the `columnDefs` arrays can be of any length, targeting the 11959 * columns you specifically want. `columnDefs` may use any of the column 11960 * options available: {@link DataTable.defaults.column}, but it _must_ 11961 * have `targets` defined in each object in the array. Values in the `targets` 11962 * array may be: 11963 * <ul> 11964 * <li>
11964a string - class name will be matched on the TH for the column</li> 11965 * <li>0 or a positive integer - column index counting from the left</li> 11966 * <li>a negative integer - column index counting from the right</li> 11967 * <li>the string "_all" - all columns (i.e. assign a default)</li> 11968 * </ul> 11969 * @member 11970 * 11971 * @name DataTable.defaults.columnDefs 11972 */ 11973 "aoColumnDefs": null, 11974 11975 11976 /** 11977 * Basically the same as `search`, this parameter defines the individual column 11978 * filtering state at initialisation time. The array must be of the same size 11979 * as the number of columns, and each element be an object with the parameters 11980 * `search` and `escapeRegex` (the latter is optional). 'null' is also 11981 * accepted and the default will be used. 11982 * @type array 11983 * @default [] 11984 * 11985 * @dtopt Option 11986 * @name DataTable.defaults.searchCols 11987 * 11988 * @example 11989 * $(document).ready( function() { 11990 * $('#example').dataTable( { 11991 * "searchCols": [ 11992 * null, 11993 * { "search": "My filter" }, 11994 * null, 11995 * { "search": "^[0-9]", "escapeRegex": false } 11996 * ] 11997 * } ); 11998 * } ) 11999 */ 12000 "aoSearchCols": [], 12001 12002 12003 /** 12004 * An array of CSS classes that should be applied to displayed rows. This 12005 * array may be of any length, and DataTables will apply each class 12006 * sequentially, looping when required. 12007 * @type array 12008 * @default null <i>
12008Will take the values determined by the `oClasses.stripe*` 12009 * options</i> 12010 * 12011 * @dtopt Option 12012 * @name DataTable.defaults.stripeClasses 12013 * 12014 * @example 12015 * $(document).ready( function() { 12016 * $('#example').dataTable( { 12017 * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ] 12018 * } ); 12019 * } ) 12020 */ 12021 "asStripeClasses": null, 12022 12023 12024 /** 12025 * Enable or disable automatic column width calculation. This can be disabled 12026 * as an optimisation (it takes some time to calculate the widths) if the 12027 * tables widths are passed in using `columns`. 12028 * @type boolean 12029 * @default true 12030 * 12031 * @dtopt Features 12032 * @name DataTable.defaults.autoWidth 12033 * 12034 * @example 12035 * $(document).ready( function () { 12036 * $('#example').dataTable( { 12037 * "autoWidth": false 12038 * } ); 12039 * } ); 12040 */ 12041 "bAutoWidth": true, 12042 12043 12044 /** 12045 * Deferred rendering can provide DataTables with a huge speed boost when you 12046 * are using an Ajax or JS data source for the table. This option, when set to 12047 * true, will cause DataTables to defer the creation of the table elements for 12048 * each row until they are needed for a draw - saving a significant amount of 12049 * time. 12050 * @type boolean 12051 * @default false 12052 * 12053 * @dtopt Features 12054 * @name DataTable.defaults.deferRender 12055 * 12056 * @example 12057 * $(document).ready( function() { 12058 * $('#example').dataTable( { 12059 * "ajax": "sources/arrays.txt", 12060 * "deferRender": true 12061 * } ); 12062 * } ); 12063 */ 12064 "bDeferRender": false, 12065 12066 12067 /** 12068 * Replace a DataTable which matches the given selector and replace it with 12069 * one which has the properties of the new initialisation object passed. If no 12070 * table matches the selector, then the new DataTable will be constructed as 12071 * per normal. 12072 * @type boolean 12073 * @default false 12074 * 12075 * @dtopt Options 12076 * @name DataTable.defaults.destroy 12077 * 12078 * @example 12079 * $(document).ready( function() { 12080 * $('#example').dataTable( { 12081 * "srollY": "200px", 12082 * "paginate": false 12083 * } ); 12084 * 12085 * // Some time later.... 12086 * $('#example').dataTable( { 12087 * "filter": false, 12088 * "destroy": true 12089 * } ); 12090 * } ); 12091 */ 12092 "bDestroy": false, 12093 12094 12095 /** 12096 * Enable or disable filtering of data. Filtering in DataTables is "smart" in 12097 * that it allows the end user to input multiple words (space separated) and 12098 * will match a row containing those words, even if not in the order that was 12099 * specified (this allow matching across multiple columns). Note that if you 12100 * wish to use filtering in DataTables this must remain 'true' - to remove the 12101 * default filtering input box and retain filtering abilities, please use 12102 * {@link DataTable.defaults.dom}. 12103 * @type boolean 12104 * @default true 12105 * 12106 * @dtopt Features 12107 * @name DataTable.defaults.searching 12108 * 12109 * @example 12110 * $(document).ready( function () { 12111 * $('#example').dataTable( { 12112 * "searching": false 12113 * } ); 12114 * } ); 12115 */ 12116 "bFilter": true, 12117 12118 12119 /** 12120 * Enable or disable the table information display. This shows information 12121 * about the data that is currently visible on the page, including information 12122 * about filtered data if that action is being performed. 12123 * @type boolean 12124 * @default true 12125 * 12126 * @dtopt Features 12127 * @name DataTable.defaults.info 12128 * 12129 * @example 12130 * $(document).ready( function () { 12131 * $('#example').dataTable( { 12132 * "info": false 12133 * } ); 12134 * } ); 12135 */ 12136 "bInfo": true, 12137 12138 12139 /** 12140 * Allows the end user to select the size of a formatted page from a select 12141 * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`). 12142 * @type boolean 12143 * @default true 12144 * 12145 * @dtopt Features 12146 * @name DataTable.defaults.lengthChange 12147 * 12148 * @example 12149 * $(document).ready( function () { 12150 * $('#example').dataTable( { 12151 * "lengthChange": false 12152 * } ); 12153 * } ); 12154 */ 12155 "bLengthChange": true, 12156 12157 12158 /** 12159 * Enable or disable pagination. 12160 * @type boolean 12161 * @default true 12162 * 12163 * @dtopt Features 12164 * @name DataTable.defaults.paging 12165 * 12166 * @example 12167 * $(document).ready( function () { 12168 * $('#example').dataTable( { 12169 * "paging": false 12170 * } ); 12171 * } ); 12172 */ 12173 "bPaginate": true, 12174 12175 12176 /** 12177 * Enable or disable the display of a 'processing' indicator when the table is 12178 * being processed (e.g. a sort). This is particularly useful for tables with 12179 * large amounts of data where it can take a noticeable amount of time to sort 12180 * the entries. 12181 * @type boolean 12182 * @default false 12183 * 12184 * @dtopt Features 12185 * @name DataTable.defaults.processing 12186 * 12187 * @example 12188 * $(document).ready( function () { 12189 * $('#example').dataTable( { 12190 * "processing": true 12191 * } ); 12192 * } ); 12193 */ 12194 "bProcessing": false, 12195 12196 12197 /** 12198 * Retrieve the DataTables object for the given selector. Note that if the 12199 * table has already been initialised, this parameter will cause DataTables 12200 * to simply return the object that has already been set up - it will not take 12201 * account of any changes you might have made to the initialisation object 12202 * passed to DataTables (setting this parameter to true is an acknowledgement 12203 * that you understand this). `destroy` can be used to reinitialise a table if 12204 * you need. 12205 * @type boolean 12206 * @default false 12207 * 12208 * @dtopt Options 12209 * @name DataTable.defaults.retrieve 12210 * 12211 * @example 12212 * $(document).ready( function() { 12213 * initTable(); 12214 * tableActions(); 12215 * } ); 12216 * 12217 * function initTable () 12218 * { 12219 * return $('#example').dataTable( { 12220 * "scrollY": "200px", 12221 * "paginate": false, 12222 * "retrieve": true 12223 * } ); 12224 * } 12225 * 12226 * function tableActions () 12227 * { 12228 * var table = initTable(); 12229 * // perform API operations with oTable 12230 * } 12231 */ 12232 "bRetrieve": false, 12233 12234 12235 /** 12236 * When vertical (y) scrolling is enabled, DataTables will force the height of
12237 * the table's viewport to the given height at all times (useful for layout). 12238 * However, this can look odd when filtering data down to a small data set, 12239 * and the footer is left "floating" further down. This parameter (when 12240 * enabled) will cause DataTables to collapse the table's viewport down when 12241 * the result set will fit within the given Y height. 12242 * @type boolean 12243 * @default false 12244 * 12245 * @dtopt Options 12246 * @name DataTable.defaults.scrollCollapse 12247 * 12248 * @example 12249 * $(document).ready( function() { 12250 * $('#example').dataTable( { 12251 * "scrollY": "200", 12252 * "scrollCollapse": true 12253 * } ); 12254 * } ); 12255 */ 12256 "bScrollCollapse": false, 12257 12258 12259 /** 12260 * Configure DataTables to use server-side processing. Note that the 12261 * `ajax` parameter must also be given in order to give DataTables a 12262 * source to obtain the required data for each draw. 12263 * @type boolean 12264 * @default false 12265 * 12266 * @dtopt Features 12267 * @dtopt Server-side 12268 * @name DataTable.defaults.serverSide 12269 * 12270 * @example 12271 * $(document).ready( function () { 12272 * $('#example').dataTable( { 12273 * "serverSide": true, 12274 * "ajax": "xhr.php" 12275 * } ); 12276 * } ); 12277 */ 12278 "bServerSide": false, 12279 12280 12281 /** 12282 * Enable or disable sorting of columns. Sorting of individual columns can be 12283 * disabled by the `sortable` option for each column. 12284 * @type boolean 12285 * @default true 12286 * 12287 * @dtopt Features 12288 * @name DataTable.defaults.ordering 12289 * 12290 * @example 12291 * $(document).ready( function () { 12292 * $('#example').dataTable( { 12293 * "ordering": false 12294 * } ); 12295 * } ); 12296 */ 12297 "bSort": true, 12298 12299 12300 /** 12301 * Enable or display DataTables' ability to sort multiple columns at the 12302 * same time (activated by shift-click by the user). 12303 * @type boolean 12304 * @default true 12305 * 12306 * @dtopt Options 12307 * @name DataTable.defaults.orderMulti 12308 * 12309 * @example 12310 * // Disable multiple column sorting ability 12311 * $(document).ready( function () { 12312 * $('#example').dataTable( { 12313 * "orderMulti": false 12314 * } ); 12315 * } ); 12316 */ 12317 "bSortMulti": true, 12318 12319 12320 /** 12321 * Allows control over whether DataTables should use the top (true) unique 12322 * cell that is found for a single column, or the bottom (false - default). 12323 * This is useful when using complex headers. 12324 * @type boolean 12325 * @default false 12326 * 12327 * @dtopt Options 12328 * @name DataTable.defaults.orderCellsTop 12329 * 12330 * @example 12331 * $(document).ready( function() { 12332 * $('#example').dataTable( { 12333 * "orderCellsTop": true 12334 * } ); 12335 * } ); 12336 */ 12337 "bSortCellsTop": false, 12338 12339 12340 /** 12341 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and 12342 * `sorting\_3` to the columns which are currently being sorted on. This is 12343 * presented as a feature switch as it can increase processing time (while 12344 * classes are removed and added) so for large data sets you might want to 12345 * turn this off. 12346 * @type boolean 12347 * @default true 12348 * 12349 * @dtopt Features 12350 * @name DataTable.defaults.orderClasses 12351 * 12352 * @example 12353 * $(document).ready( function () { 12354 * $('#example').dataTable( { 12355 * "orderClasses": false 12356 * } ); 12357 * } ); 12358 */ 12359 "bSortClasses": true, 12360 12361 12362 /** 12363 * Enable or disable state saving. When enabled HTML5 `localStorage` will be 12364 * used to save table display information such as pagination information, 12365 * display length, filtering and sorting. As such when the end user reloads 12366 * the page the display display will match what thy had previously set up. 12367 * 12368 * Due to the use of `localStorage` the default state saving is not supported 12369 * in IE6 or 7. If state saving is required in those browsers, use 12370 * `stateSaveCallback` to provide a storage solution such as cookies. 12371 * @type boolean 12372 * @default false 12373 * 12374 * @dtopt Features 12375 * @name DataTable.defaults.stateSave 12376 * 12377 * @example 12378 * $(document).ready( function () { 12379 * $('#example').dataTable( { 12380 * "stateSave": true 12381 * } ); 12382 * } ); 12383 */ 12384 "bStateSave": false, 12385 12386 12387 /** 12388 * This function is called when a TR element is created (and all TD child 12389 * elements have been inserted), or registered if using a DOM source, allowing 12390 * manipulation of the TR element (adding classes etc). 12391 * @type function 12392 * @param {node} row "TR" element for the current row 12393 * @param {array} data Raw data array for this row 12394 * @param {int} dataIndex The index of this row in the internal aoData array 12395 * 12396 * @dtopt Callbacks 12397 * @name DataTable.defaults.createdRow 12398 * 12399 * @example 12400 * $(document).ready( function() { 12401 * $('#example').dataTable( { 12402 * "createdRow": function( row, data, dataIndex ) { 12403 * // Bold the grade for all 'A' grade browsers 12404 * if ( data[4] == "A" ) 12405 * { 12406 * $('td:eq(4)', row).html( '<b>A</b>' ); 12407 * } 12408 * } 12409 * } ); 12410 * } ); 12411 */ 12412 "fnCreatedRow": null, 12413 12414 12415 /** 12416 * This function is called on every 'draw' event, and allows you to 12417 * dynamically modify any aspect you want about the created DOM. 12418 * @type function 12419 * @param {object} settings DataTables settings object 12420 * 12421 * @dtopt Callbacks 12422 * @name DataTable.defaults.drawCallback 12423 * 12424 * @example 12425 * $(document).ready( function() { 12426 * $('#example').dataTable( { 12427 * "drawCallback": function( settings ) { 12428 * alert( 'DataTables has redrawn the table' ); 12429 * } 12430 * } ); 12431 * } ); 12432 */ 12433 "fnDrawCallback": null, 12434 12435 12436 /** 12437 * Identical to fnHeaderCallback() but for the table footer this function 12438 * allows you to modify the table footer on every 'draw' event. 12439 * @type function 12440 * @param {node} foot "TR" element for the footer 12441 * @param {array} data Full table data (as derived from the original HTML) 12442 * @param {int} start Index for the current display starting point in the 12443 * display array 12444 * @param {int} end Index for the current display ending point in the 12445 * display array 12446 * @param {array int} display Index array to translate the visual position 12447 * to the full data array 12448 * 12449 * @dtopt Callbacks 12450 * @name DataTable.defaults.footerCallback 12451 * 12452 * @example 12453 * $(document).ready( function() { 12454 * $('#example').dataTable( { 12455 * "footerCallback": function( tfoot, data, start, end, display ) { 12456 * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start; 12457 * } 12458 * } ); 12459 * } ) 12460 */ 12461 "fnFooterCallback": null, 12462 12463 12464 /** 12465 * When rendering large numbers in the information element for the table 12466 * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers 12467 * to have a comma separator for the 'thousands' units (e.g. 1 million is 12468 * rendered as "1,000,000") to help readability for the end user. This 12469 * function will override the default method DataTables uses. 12470 * @type function 12471 * @member 12472 * @param {int} toFormat number to be formatted 12473 * @returns {string} formatted string for DataTables to show the number 12474 * 12475 * @dtopt Callbacks 12476 * @name DataTable.defaults.formatNumber 12477 * 12478 * @example 12479 * // Format a number using a single quote for the separator (note that
12480 * // this can also be done with the language.thousands option) 12481 * $(document).ready( function() { 12482 * $('#example').dataTable( { 12483 * "formatNumber": function ( toFormat ) { 12484 * return toFormat.toString().replace( 12485 * /\B(?=(\d{3})+(?!\d))/g, "'" 12486 * ); 12487 * }; 12488 * } ); 12489 * } ); 12490 */ 12491 "fnFormatNumber": function ( toFormat ) { 12492 return toFormat.toString().replace( 12493 /\B(?=(\d{3})+(?!\d))/g, 12494 this.oLanguage.sThousands 12495 ); 12496 }, 12497 12498 12499 /** 12500 * This function is called on every 'draw' event, and allows you to 12501 * dynamically modify the header row. This can be used to calculate and 12502 * display useful information about the table. 12503 * @type function 12504 * @param {node} head "TR" element for the header 12505 * @param {array} data Full table data (as derived from the original HTML) 12506 * @param {int} start Index for the current display starting point in the 12507 * display array 12508 * @param {int} end Index for the current display ending point in the 12509 * display array 12510 * @param {array int} display Index array to translate the visual position 12511 * to the full data array 12512 * 12513 * @dtopt Callbacks 12514 * @name DataTable.defaults.headerCallback 12515 * 12516 * @example 12517 * $(document).ready( function() { 12518 * $('#example').dataTable( { 12519 * "fheaderCallback": function( head, data, start, end, display ) { 12520 * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records"; 12521 * } 12522 * } ); 12523 * } ) 12524 */ 12525 "fnHeaderCallback": null, 12526 12527 12528 /** 12529 * The information element can be used to convey information about the current 12530 * state of the table. Although the internationalisation options presented by 12531 * DataTables are quite capable of dealing with most customisations, there may 12532 * be times where you wish to customise the string further. This callback 12533 * allows you to do exactly that. 12534 * @type function 12535 * @param {object} oSettings DataTables settings object 12536 * @param {int} start Starting position in data for the draw 12537 * @param {int} end End position in data for the draw 12538 * @param {int} max Total number of rows in the table (regardless of 12539 * filtering) 12540 * @param {int} total Total number of rows in the data set, after filtering 12541 * @param {string} pre The string that DataTables has formatted using it's 12542 * own rules 12543 * @returns {string} The string to be displayed in the information element. 12544 * 12545 * @dtopt Callbacks 12546 * @name DataTable.defaults.infoCallback 12547 * 12548 * @example 12549 * $('#example').dataTable( { 12550 * "infoCallback": function( settings, start, end, max, total, pre ) { 12551 * return start +" to "+ end; 12552 * } 12553 * } ); 12554 */ 12555 "fnInfoCallback": null, 12556 12557 12558 /** 12559 * Called when the table has been initialised. Normally DataTables will 12560 * initialise sequentially and there will be no need for this function, 12561 * however, this does not hold true when using external language information 12562 * since that is obtained using an async XHR call. 12563 * @type function 12564 * @param {object} settings DataTables settings object 12565 * @param {object} json The JSON object request from the server - only 12566 * present if client-side Ajax sourced data is used 12567 * 12568 * @dtopt Callbacks 12569 * @name DataTable.defaults.initComplete 12570 * 12571 * @example 12572 * $(document).ready( function() { 12573 * $('#example').dataTable( { 12574 * "initComplete": function(settings, json) { 12575 * alert( 'DataTables has finished its initialisation.' ); 12576 * } 12577 * } ); 12578 * } ) 12579 */ 12580 "fnInitComplete": null, 12581 12582 12583 /** 12584 * Called at the very start of each table draw and can be used to cancel the 12585 * draw by returning false, any other return (including undefined) results in 12586 * the full draw occurring). 12587 * @type function 12588 * @param {object} settings DataTables settings object 12589 * @returns {boolean} False will cancel the draw, anything else (including no 12590 * return) will allow it to complete. 12591 * 12592 * @dtopt Callbacks 12593 * @name DataTable.defaults.preDrawCallback 12594 * 12595 * @example 12596 * $(document).ready( function() { 12597 * $('#example').dataTable( { 12598 * "preDrawCallback": function( settings ) { 12599 * if ( $('#test').val() == 1 ) { 12600 * return false;
12601 * } 12602 * } 12603 * } ); 12604 * } ); 12605 */ 12606 "fnPreDrawCallback": null, 12607 12608 12609 /** 12610 * This function allows you to 'post process' each row after it have been 12611 * generated for each table draw, but before it is rendered on screen. This 12612 * function might be used for setting the row class name etc. 12613 * @type function 12614 * @param {node} row "TR" element for the current row 12615 * @param {array} data Raw data array for this row 12616 * @param {int} displayIndex The display index for the current table draw 12617 * @param {int} displayIndexFull The index of the data in the full list of 12618 * rows (after filtering) 12619 * 12620 * @dtopt Callbacks 12621 * @name DataTable.defaults.rowCallback 12622 * 12623 * @example 12624 * $(document).ready( function() { 12625 * $('#example').dataTable( { 12626 * "rowCallback": function( row, data, displayIndex, displayIndexFull ) { 12627 * // Bold the grade for all 'A' grade browsers 12628 * if ( data[4] == "A" ) { 12629 * $('td:eq(4)', row).html( '<b>A</b>' ); 12630 * } 12631 * } 12632 * } ); 12633 * } ); 12634 */ 12635 "fnRowCallback": null, 12636 12637 12638 /** 12639 * __Deprecated__ The functionality provided by this parameter has now been 12640 * superseded by that provided through `ajax`, which should be used instead. 12641 * 12642 * This parameter allows you to override the default function which obtains 12643 * the data from the server so something more suitable for your application. 12644 * For example you could use POST data, or pull information from a Gears or 12645 * AIR database. 12646 * @type function 12647 * @member 12648 * @param {string} source HTTP source to obtain the data from (`ajax`) 12649 * @param {array} data A key/value pair object containing the data to send 12650 * to the server 12651 * @param {function} callback to be called on completion of the data get 12652 * process that will draw the data on the page. 12653 * @param {object} settings DataTables settings object 12654 * 12655 * @dtopt Callbacks 12656 * @dtopt Server-side 12657 * @name DataTable.defaults.serverData 12658 * 12659 * @deprecated 1.10. Please use `ajax` for this functionality now. 12660 */ 12661 "fnServerData": null, 12662 12663 12664 /** 12665 * __Deprecated__ The functionality provided by this parameter has now been 12666 * superseded by that provided through `ajax`, which should be used instead. 12667 * 12668 * It is often useful to send extra data to the server when making an Ajax 12669 * request - for example custom filtering information, and this callback 12670 * function makes it trivial to send extra information to the server. The 12671 * passed in parameter is the data set that has been constructed by 12672 * DataTables, and you can add to this or modify it as you require. 12673 * @type function 12674 * @param {array} data Data array (array of objects which are name/value 12675 * pairs) that has been constructed by DataTables and will be sent to the 12676 * server. In the case of Ajax sourced data with server-side processing 12677 * this will be an empty array, for server-side processing there will be a 12678 * significant number of parameters! 12679 * @returns {undefined} Ensure that you modify the data array passed in, 12680 * as this is passed by reference. 12681 * 12682 * @dtopt Callbacks 12683 * @dtopt Server-side 12684 * @name DataTable.defaults.serverParams 12685 * 12686 * @deprecated 1.10. Please use `ajax` for this functionality now. 12687 */ 12688 "fnServerParams": null, 12689 12690 12691 /** 12692 * Load the table state. With this function you can define from where, and how, the 12693 * state of a table is loaded. By default DataTables will load from `localStorage` 12694 * but you might wish to use a server-side database or cookies. 12695 * @type function 12696 * @member 12697 * @param {object} settings DataTables settings object 12698 * @param {object} callback Callback that can be executed when done. It 12699 * should be passed the loaded state object. 12700 * @return {object} The DataTables state object to be loaded 12701 * 12702 * @dtopt Callbacks 12703 * @name DataTable.defaults.stateLoadCallback 12704 * 12705 * @example 12706 * $(document).ready( function() { 12707 * $('#example').dataTable( { 12708 * "stateSave": true,
12709 * "stateLoadCallback": function (settings, callback) { 12710 * $.ajax( { 12711 * "url": "/state_load", 12712 * "dataType": "json", 12713 * "success": function (json) { 12714 * callback( json ); 12715 * } 12716 * } ); 12717 * } 12718 * } ); 12719 * } ); 12720 */ 12721 "fnStateLoadCallback": function ( settings ) { 12722 try { 12723 return JSON.parse( 12724 (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem( 12725 'DataTables_'+settings.sInstance+'_'+location.pathname 12726 ) 12727 ); 12728 } catch (e) {} 12729 }, 12730 12731 12732 /** 12733 * Callback which allows modification of the saved state prior to loading that state. 12734 * This callback is called when the table is loading state from the stored data, but 12735 * prior to the settings object being modified by the saved state. Note that for 12736 * plug-in authors, you should use the `stateLoadParams` event to load parameters for 12737 * a plug-in. 12738 * @type function 12739 * @param {object} settings DataTables settings object 12740 * @param {object} data The state object that is to be loaded 12741 * 12742 * @dtopt Callbacks 12743 * @name DataTable.defaults.stateLoadParams 12744 * 12745 * @example 12746 * // Remove a saved filter, so filtering is never loaded 12747 * $(document).ready( function() { 12748 * $('#example').dataTable( { 12749 * "stateSave": true, 12750 * "stateLoadParams": function (settings, data) { 12751 * data.oSearch.sSearch = ""; 12752 * } 12753 * } ); 12754 * } ); 12755 * 12756 * @example 12757 * // Disallow state loading by returning false 12758 * $(document).ready( function() { 12759 * $('#example').dataTable( { 12760 * "stateSave": true, 12761 * "stateLoadParams": function (settings, data) { 12762 * return false; 12763 * } 12764 * } ); 12765 * } ); 12766 */ 12767 "fnStateLoadParams": null, 12768 12769 12770 /** 12771 * Callback that is called when the state has been loaded from the state saving method 12772 * and the DataTables settings object has been modified as a result of the loaded state. 12773 * @type function 12774 * @param {object} settings DataTables settings object 12775 * @param {object} data The state object that was loaded 12776 * 12777 * @dtopt Callbacks 12778 * @name DataTable.defaults.stateLoaded 12779 * 12780 * @example 12781 * // Show an alert with the filtering value that was saved 12782 * $(document).ready( function() { 12783 * $('#example').dataTable( { 12784 * "stateSave": true, 12785 * "stateLoaded": function (settings, data) { 12786 * alert( 'Saved filter was: '+data.oSearch.sSearch ); 12787 * } 12788 * } ); 12789 * } ); 12790 */ 12791 "fnStateLoaded": null, 12792 12793 12794 /** 12795 * Save the table state. This function allows you to define where and how the state 12796 * information for the table is stored By default DataTables will use `localStorage` 12797 * but you might wish to use a server-side database or cookies. 12798 * @type function 12799 * @member 12800 * @param {object} settings DataTables settings object 12801 * @param {object} data The state object to be saved 12802 * 12803 * @dtopt Callbacks 12804 * @name DataTable.defaults.stateSaveCallback 12805 * 12806 * @example 12807 * $(document).ready( function() { 12808 * $('#example').dataTable( { 12809 * "stateSave": true, 12810 * "stateSaveCallback": function (settings, data) { 12811 * // Send an Ajax request to the server with the state object 12812 * $.ajax( { 12813 * "url": "/state_save", 12814 * "data": data, 12815 * "dataType": "json", 12816 * "method": "POST" 12817 * "success": function () {} 12818 * } ); 12819 * } 12820 * } ); 12821 * } ); 12822 */ 12823 "fnStateSaveCallback": function ( settings, data ) { 12824 try { 12825 (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem( 12826 'DataTables_'+settings.sInstance+'_'+location.pathname, 12827 JSON.stringify( data ) 12828 ); 12829 } catch (e) {} 12830 }, 12831 12832 12833 /** 12834 * Callback which allows modification of the state to be saved. Called when the table 12835 * has changed state a new state save is required. This method allows modification of 12836 * the state saving object prior to actually doing the save, including addition or
12837 * other state properties or modification. Note that for plug-in authors, you should 12838 * use the `stateSaveParams` event to save parameters for a plug-in. 12839 * @type function 12840 * @param {object} settings DataTables settings object 12841 * @param {object} data The state object to be saved 12842 * 12843 * @dtopt Callbacks 12844 * @name DataTable.defaults.stateSaveParams 12845 * 12846 * @example 12847 * // Remove a saved filter, so filtering is never saved 12848 * $(document).ready( function() { 12849 * $('#example').dataTable( { 12850 * "stateSave": true, 12851 * "stateSaveParams": function (settings, data) { 12852 * data.oSearch.sSearch = ""; 12853 * } 12854 * } ); 12855 * } ); 12856 */ 12857 "fnStateSaveParams": null, 12858 12859 12860 /** 12861 * Duration for which the saved state information is considered valid. After this period 12862 * has elapsed the state will be returned to the default. 12863 * Value is given in seconds. 12864 * @type int 12865 * @default 7200 <i>(2 hours)</i> 12866 * 12867 * @dtopt Options 12868 * @name DataTable.defaults.stateDuration 12869 * 12870 * @example 12871 * $(document).ready( function() { 12872 * $('#example').dataTable( { 12873 * "stateDuration": 60*60*24; // 1 day 12874 * } ); 12875 * } ) 12876 */ 12877 "iStateDuration": 7200, 12878 12879 12880 /** 12881 * When enabled DataTables will not make a request to the server for the first 12882 * page draw - rather it will use the data already on the page (no sorting etc 12883 * will be applied to it), thus saving on an XHR at load time. `deferLoading` 12884 * is used to indicate that deferred loading is required, but it is also used 12885 * to tell DataTables how many records there are in the full table (allowing 12886 * the information element and pagination to be displayed correctly). In the case 12887 * where a filtering is applied to the table on initial load, this can be 12888 * indicated by giving the parameter as an array, where the first element is 12889 * the number of records available after filtering and the second element is the 12890 * number of records without filtering (allowing the table information element 12891 * to be shown correctly). 12892 * @type int | array 12893 * @default null 12894 * 12895 * @dtopt Options 12896 * @name DataTable.defaults.deferLoading 12897 * 12898 * @example 12899 * // 57 records available in the table, no filtering applied 12900 * $(document).ready( function() { 12901 * $('#example').dataTable( { 12902 * "serverSide": true, 12903 * "ajax": "scripts/server_processing.php", 12904 * "deferLoading": 57 12905 * } ); 12906 * } ); 12907 * 12908 * @example 12909 * // 57 records after filtering, 100 without filtering (an initial filter applied) 12910 * $(document).ready( function() { 12911 * $('#example').dataTable( { 12912 * "serverSide": true, 12913 * "ajax": "scripts/server_processing.php", 12914 * "deferLoading": [ 57, 100 ], 12915 * "search": { 12916 * "search": "my_filter" 12917 * } 12918 * } ); 12919 * } ); 12920 */ 12921 "iDeferLoading": null, 12922 12923 12924 /** 12925 * Number of rows to display on a single page when using pagination. If 12926 * feature enabled (`lengthChange`) then the end user will be able to override 12927 * this to a custom setting using a pop-up menu. 12928 * @type int 12929 * @default 10 12930 * 12931 * @dtopt Options 12932 * @name DataTable.defaults.pageLength 12933 * 12934 * @example 12935 * $(document).ready( function() { 12936 * $('#example').dataTable( { 12937 * "pageLength": 50 12938 * } ); 12939 * } ) 12940 */ 12941 "iDisplayLength": 10, 12942 12943 12944 /** 12945 * Define the starting point for data display when using DataTables with 12946 * pagination. Note that this parameter is the number of records, rather than 12947 * the page number, so if you have 10 records per page and want to start on 12948 * the third page, it should be "20". 12949 * @type int 12950 * @default 0 12951 * 12952 * @dtopt Options 12953 * @name DataTable.defaults.displayStart 12954 * 12955 * @example 12956 * $(document).ready( function() { 12957 * $('#example').dataTable( { 12958 * "displayStart": 20 12959 * } ); 12960 * } ) 12961 */ 12962 "iDisplayStart": 0, 12963 12964 12965 /** 12966 * By default DataTables allows keyboard navigation of the table (sorting, paging, 12967 * and filtering) by adding a `tabindex` attribute to the required elements. This 12968 * allows you to tab through the controls and press the enter key to activate them. 12969 * The tabindex is default 0, meaning that the tab follows the flow of the document. 12970 * You can overrule this using this parameter if you wish. Use a value of -1 to 12971 * disable built-in keyboard navigation. 12972 * @type int 12973 * @default 0 12974 * 12975 * @dtopt Options 12976 * @name DataTable.defaults.tabIndex 12977 * 12978 * @example 12979 * $(document).ready( function() { 12980 * $('#example').dataTable( { 12981 * "tabIndex": 1 12982 * } ); 12983 * } ); 12984 */ 12985 "iTabIndex": 0, 12986 12987 12988 /** 12989 * Classes that DataTables assigns to the various components and features 12990 * that it adds to the HTML table. This allows classes to be configured 12991 * during initialisation in addition to through the static 12992 * {@link DataTable.ext.oStdClasses} object). 12993 * @namespace 12994 * @name DataTable.defaults.classes 12995 */
12996 "oClasses": {}, 12997 12998 12999 /** 13000 * All strings that DataTables uses in the user interface that it creates 13001 * are defined in this object, allowing you to modified them individually or 13002 * completely replace them all as required. 13003 * @namespace 13004 * @name DataTable.defaults.language 13005 */ 13006 "oLanguage": { 13007 /** 13008 * Strings that are used for WAI-ARIA labels and controls only (these are not 13009 * actually visible on the page, but will be read by screenreaders, and thus 13010 * must be internationalised as well). 13011 * @namespace 13012 * @name DataTable.defaults.language.aria 13013 */ 13014 "oAria": { 13015 /** 13016 * ARIA label that is added to the table headers when the column may be 13017 * sorted ascending by activing the column (click or return when focused). 13018 * Note that the column header is prefixed to this string. 13019 * @type string 13020 * @default : activate to sort column ascending 13021 * 13022 * @dtopt Language 13023 * @name DataTable.defaults.language.aria.sortAscending 13024 * 13025 * @example 13026 * $(document).ready( function() { 13027 * $('#example').dataTable( { 13028 * "language": { 13029 * "aria": { 13030 * "sortAscending": " - click/return to sort ascending" 13031 * } 13032 * } 13033 * } ); 13034 * } ); 13035 */ 13036 "sSortAscending": ": activate to sort column ascending", 13037 13038 /** 13039 * ARIA label that is added to the table headers when the column may be 13040 * sorted descending by activing the column (click or return when focused). 13041 * Note that the column header is prefixed to this string. 13042 * @type string 13043 * @default : activate to sort column ascending 13044 * 13045 * @dtopt Language 13046 * @name DataTable.defaults.language.aria.sortDescending 13047 * 13048 * @example 13049 * $(document).ready( function() { 13050 * $('#example').dataTable( { 13051 * "language": { 13052 * "aria": { 13053 * "sortDescending": " - click/return to sort descending" 13054 * } 13055 * } 13056 * } ); 13057 * } ); 13058 */ 13059 "sSortDescending": ": activate to sort column descending" 13060 }, 13061 13062 /** 13063 * Pagination string used by DataTables for the built-in pagination 13064 * control types. 13065 * @namespace 13066 * @name DataTable.defaults.language.paginate 13067 */ 13068 "oPaginate": { 13069 /** 13070 * Text to use when using the 'full_numbers' type of pagination for the 13071 * button to take the user to the first page. 13072 * @type string 13073 * @default First 13074 * 13075 * @dtopt Language 13076 * @name DataTable.defaults.language.paginate.first 13077 * 13078 * @example 13079 * $(document).ready( function() { 13080 * $('#example').dataTable( { 13081 * "language": { 13082 * "paginate": { 13083 * "first": "First page" 13084 * } 13085 * } 13086 * } ); 13087 * } ); 13088 */ 13089 "sFirst": "First", 13090 13091 13092 /** 13093 * Text to use when using the 'full_numbers' type of pagination for the 13094 * button to take the user to the last page. 13095 * @type string 13096 * @default Last 13097 * 13098 * @dtopt Language 13099 * @name DataTable.defaults.language.paginate.last 13100 * 13101 * @example 13102 * $(document).ready( function() { 13103 * $('#example').dataTable( { 13104 * "language": { 13105 * "paginate": { 13106 * "last": "Last page" 13107 * } 13108 * } 13109 * } ); 13110 * } ); 13111 */ 13112 "sLast": "Last", 13113 13114 13115 /** 13116 * Text to use for the 'next' pagination button (to take the user to the 13117 * next page). 13118 * @type string 13119 * @default Next 13120 * 13121 * @dtopt Language 13122 * @name DataTable.defaults.language.paginate.next 13123 * 13124 * @example 13125 * $(document).ready( function() { 13126 * $('#example').dataTable( { 13127 * "language": { 13128 * "paginate": { 13129 * "next": "Next page" 13130 * } 13131 * } 13132 * } ); 13133 * } ); 13134 */ 13135 "sNext": "Next", 13136 13137 13138 /** 13139 * Text to use for the 'previous' pagination button (to take the user to 13140 * the previous page). 13141 * @type string 13142 * @default Previous 13143 * 13144 * @dtopt Language 13145 * @name DataTable.defaults.language.paginate.previous 13146 * 13147 * @example 13148 * $(document).ready( function() { 13149 * $('#example').dataTable( { 13150 * "language": { 13151 * "paginate": { 13152 * "previous": "Previous page" 13153 * } 13154 * } 13155 * } ); 13156 * } ); 13157 */ 13158 "sPrevious": "Previous" 13159 }, 13160 13161 /** 13162 * This string is shown in preference to `zeroRecords` when the table is 13163 * empty of data (regardless of filtering). Note that this is an optional 13164 * parameter - if it is not given, the value of `zeroRecords` will be used 13165 * instead (either the default or given value). 13166 * @type string 13167 * @default No data available in table 13168 * 13169 * @dtopt Language 13170 * @name DataTable.defaults.language.emptyTable 13171 * 13172 * @example 13173 * $(document).ready( function() { 13174 * $('#example').dataTable( { 13175 * "language": { 13176 * "emptyTable": "No data available in table" 13177 * } 13178 * } ); 13179 * } ); 13180 */ 13181 "sEmptyTable": "No data available in table", 13182 13183 13184 /** 13185 * This string gives information to the end user about the information 13186 * that is current on display on the page. The following tokens can be 13187 * used in the string and will be dynamically replaced as the table 13188 * display updates. This tokens can be placed anywhere in the string, or 13189 * removed as needed by the language requires: 13190 * 13191 * * `\_START\_` - Display index of the first record on the current page 13192 * * `\_END\_` - Display index of the last record on the current page 13193 * * `\_TOTAL\_` - Number of records in the table after filtering 13194 * * `\_MAX\_` - Number of records in the table without filtering 13195 * * `\_PAGE\_` - Current page number 13196 * * `\_PAGES\_` - Total number of pages of data in the table 13197 * 13198 * @type string 13199 * @default Showing _START_ to _END_ of _TOTAL_ entries 13200 * 13201 * @dtopt Language 13202 * @name DataTable.defaults.language.info 13203 * 13204 * @example 13205 * $(document).ready( function() { 13206 * $('#example').dataTable( { 13207 * "language": { 13208 * "info": "Showing page _PAGE_ of _PAGES_" 13209 * } 13210 * } ); 13211 * } ); 13212 */ 13213 "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", 13214 13215 13216 /**
13217 * Display information string for when the table is empty. Typically the 13218 * format of this string should match `info`. 13219 * @type string 13220 * @default Showing 0 to 0 of 0 entries 13221 * 13222 * @dtopt Language 13223 * @name DataTable.defaults.language.infoEmpty 13224 * 13225 * @example 13226 * $(document).ready( function() { 13227 * $('#example').dataTable( { 13228 * "language": { 13229 * "infoEmpty": "No entries to show" 13230 * } 13231 * } ); 13232 * } ); 13233 */ 13234 "sInfoEmpty": "Showing 0 to 0 of 0 entries", 13235 13236 13237 /** 13238 * When a user filters the information in a table, this string is appended 13239 * to the information (`info`) to give an idea of how strong the filtering 13240 * is. The variable _MAX_ is dynamically updated. 13241 * @type string 13242 * @default (filtered from _MAX_ total entries) 13243 * 13244 * @dtopt Language 13245 * @name DataTable.defaults.language.infoFiltered 13246 * 13247 * @example 13248 * $(document).ready( function() { 13249 * $('#example').dataTable( { 13250 * "language": { 13251 * "infoFiltered": " - filtering from _MAX_ records" 13252 * } 13253 * } ); 13254 * } ); 13255 */ 13256 "sInfoFiltered": "(filtered from _MAX_ total entries)", 13257 13258 13259 /** 13260 * If can be useful to append extra information to the info string at times, 13261 * and this variable does exactly that. This information will be appended to 13262 * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are 13263 * being used) at all times. 13264 * @type string 13265 * @default <i>Empty string</i> 13266 * 13267 * @dtopt Language 13268 * @name DataTable.defaults.language.infoPostFix 13269 * 13270 * @example 13271 * $(document).ready( function() { 13272 * $('#example').dataTable( { 13273 * "language": { 13274 * "infoPostFix": "All records shown are derived from real information." 13275 * } 13276 * } ); 13277 * } ); 13278 */ 13279 "sInfoPostFix": "", 13280 13281 13282 /** 13283 * This decimal place operator is a little different from the other 13284 * language options since DataTables doesn't output floating point 13285 * numbers, so it won't ever use this for display of a number. Rather, 13286 * what this parameter does is modify the sort methods of the table so 13287 * that numbers which are in a format which has a character other than 13288 * a period (`.`) as a decimal place will be sorted numerically. 13289 * 13290 * Note that numbers with different decimal places cannot be shown in 13291 * the same table and still be sortable, the table must be consistent. 13292 * However, multiple different tables on the page can use different 13293 * decimal place characters. 13294 * @type string 13295 * @default 13296 * 13297 * @dtopt Language 13298 * @name DataTable.defaults.language.decimal 13299 * 13300 * @example 13301 * $(document).ready( function() { 13302 * $('#example').dataTable( { 13303 * "language": { 13304 * "decimal": "," 13305 * "thousands": "." 13306 * } 13307 * } ); 13308 * } ); 13309 */ 13310 "sDecimal": "", 13311 13312 13313 /** 13314 * DataTables has a build in number formatter (`formatNumber`) which is 13315 * used to format large numbers that are used in the table information. 13316 * By default a comma is used, but this can be trivially changed to any 13317 * character you wish with this parameter. 13318 * @type string 13319 * @default , 13320 * 13321 * @dtopt Language 13322 * @name DataTable.defaults.language.thousands 13323 * 13324 * @example 13325 * $(document).ready( function() { 13326 * $('#example').dataTable( { 13327 * "language": { 13328 * "thousands": "'" 13329 * } 13330 * } ); 13331 * } ); 13332 */ 13333 "sThousands": ",", 13334 13335 13336 /** 13337 * Detail the action that will be taken when the drop down menu for the 13338 * pagination length option is changed. The '_MENU_' variable is replaced 13339 * with a default select list of 10, 25, 50 and 100, and can be replaced 13340 * with a custom select box if required. 13341 * @type string 13342 * @default Show _MENU_ entries 13343 * 13344 * @dtopt Language 13345 * @name DataTable.defaults.language.lengthMenu 13346 * 13347 * @example 13348 * // Language change only 13349 * $(document).ready( function() { 13350 * $('#example').dataTable( { 13351 * "language": {
13352 * "lengthMenu": "Display _MENU_ records" 13353 * } 13354 * } ); 13355 * } ); 13356 * 13357 * @example 13358 * // Language and options change 13359 * $(document).ready( function() { 13360 * $('#example').dataTable( { 13361 * "language": { 13362 * "lengthMenu": 'Display <select>'+ 13363 * '<option value="10">10</option>'+ 13364 * '<option value="20">20</option>'+ 13365 * '<option value="30">30</option>'+ 13366 * '<option value="40">40</option>'+ 13367 * '<option value="50">50</option>'+ 13368 * '<option value="-1">All</option>'+ 13369 * '</select> records' 13370 * } 13371 * } ); 13372 * } ); 13373 */ 13374 "sLengthMenu": "Show _MENU_ entries", 13375 13376 13377 /** 13378 * When using Ajax sourced data and during the first draw when DataTables is 13379 * gathering the data, this message is shown in an empty row in the table to 13380 * indicate to the end user the the data is being loaded. Note that this 13381 * parameter is not used when loading data by server-side processing, just 13382 * Ajax sourced data with client-side processing. 13383 * @type string 13384 * @default Loading... 13385 * 13386 * @dtopt Language 13387 * @name DataTable.defaults.language.loadingRecords 13388 * 13389 * @example 13390 * $(document).ready( function() { 13391 * $('#example').dataTable( { 13392 * "language": { 13393 * "loadingRecords": "Please wait - loading..." 13394 * } 13395 * } ); 13396 * } ); 13397 */ 13398 "sLoadingRecords": "Loading...", 13399 13400 13401 /** 13402 * Text which is displayed when the table is processing a user action 13403 * (usually a sort command or similar). 13404 * @type string 13405 * @default Processing... 13406 * 13407 * @dtopt Language 13408 * @name DataTable.defaults.language.processing 13409 * 13410 * @example 13411 * $(document).ready( function() { 13412 * $('#example').dataTable( { 13413 * "language": { 13414 * "processing": "DataTables is currently busy" 13415 * } 13416 * } ); 13417 * } ); 13418 */ 13419 "sProcessing": "Processing...", 13420 13421 13422 /** 13423 * Details the actions that will be taken when the user types into the 13424 * filtering input text box. The variable "_INPUT_", if used in the string, 13425 * is replaced with the HTML text box for the filtering input allowing 13426 * control over where it appears in the string. If "_INPUT_" is not given 13427 * then the input box is appended to the string automatically. 13428 * @type string 13429 * @default Search: 13430 * 13431 * @dtopt Language 13432 * @name DataTable.defaults.language.search 13433 * 13434 * @example 13435 * // Input text box will be appended at the end automatically 13436 * $(document).ready( function() { 13437 * $('#example').dataTable( { 13438 * "language": { 13439 * "search": "Filter records:" 13440 * } 13441 * } ); 13442 * } ); 13443 * 13444 * @example 13445 * // Specify where the filter should appear 13446 * $(document).ready( function() { 13447 * $('#example').dataTable( { 13448 * "language": { 13449 * "search": "Apply filter _INPUT_ to table" 13450 * } 13451 * } ); 13452 * } ); 13453 */ 13454 "sSearch": "Search:", 13455 13456 13457 /** 13458 * Assign a `placeholder` attribute to the search `input` element 13459 * @type string 13460 * @default 13461 * 13462 * @dtopt Language 13463 * @name DataTable.defaults.language.searchPlaceholder 13464 */ 13465 "sSearchPlaceholder": "", 13466 13467 13468 /** 13469 * All of the language information can be stored in a file on the 13470 * server-side, which DataTables will look up if this parameter is passed. 13471 * It must store the URL of the language file, which is in a JSON format, 13472 * and the object has the same properties as the oLanguage object in the 13473 * initialiser object (i.e. the above parameters). Please refer to one of 13474 * the example language files to see how this works in action. 13475 * @type string 13476 * @default <i>Empty string - i.e. disabled</i> 13477 * 13478 * @dtopt Language 13479 * @name DataTable.defaults.language.url 13480 * 13481 * @example 13482 * $(document).ready( function() { 13483 * $('#example').dataTable( { 13484 * "language": { 13485 * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt" 13486 * } 13487 * } ); 13488 * } ); 13489 */ 13490 "sUrl": "", 13491 13492 13493 /** 13494 * Text shown inside the table records when the is no information to be 13495 * displayed after filtering. `emptyTable` is shown when there is simply no 13496 * information in the table at all (regardless of filtering). 13497 * @type string
13498 * @default No matching records found 13499 * 13500 * @dtopt Language 13501 * @name DataTable.defaults.language.zeroRecords 13502 * 13503 * @example 13504 * $(document).ready( function() { 13505 * $('#example').dataTable( { 13506 * "language": { 13507 * "zeroRecords": "No records to display" 13508 * } 13509 * } ); 13510 * } ); 13511 */ 13512 "sZeroRecords": "No matching records found" 13513 }, 13514 13515 13516 /** 13517 * This parameter allows you to have define the global filtering state at 13518 * initialisation time. As an object the `search` parameter must be 13519 * defined, but all other parameters are optional. When `regex` is true, 13520 * the search string will be treated as a regular expression, when false 13521 * (default) it will be treated as a straight string. When `smart` 13522 * DataTables will use it's smart filtering methods (to word match at 13523 * any point in the data), when false this will not be done. 13524 * @namespace 13525 * @extends DataTable.models.oSearch 13526 * 13527 * @dtopt Options 13528 * @name DataTable.defaults.search 13529 * 13530 * @example 13531 * $(document).ready( function() { 13532 * $('#example').dataTable( { 13533 * "search": {"search": "Initial search"} 13534 * } ); 13535 * } ) 13536 */ 13537 "oSearch": $.extend( {}, DataTable.models.oSearch ), 13538 13539 13540 /** 13541 * __Deprecated__ The functionality provided by this parameter has now been 13542 * superseded by that provided through `ajax`, which should be used instead. 13543 * 13544 * By default DataTables will look for the property `data` (or `aaData` for 13545 * compatibility with DataTables 1.9-) when obtaining data from an Ajax 13546 * source or for server-side processing - this parameter allows that 13547 * property to be changed. You can use Javascript dotted object notation to 13548 * get a data source for multiple levels of nesting. 13549 * @type string 13550 * @default data 13551 * 13552 * @dtopt Options 13553 * @dtopt Server-side 13554 * @name DataTable.defaults.ajaxDataProp 13555 * 13556 * @deprecated 1.10. Please use `ajax` for this functionality now. 13557 */ 13558 "sAjaxDataProp": "data", 13559 13560 13561 /** 13562 * __Deprecated__ The functionality provided by this parameter has now been 13563 * superseded by that provided through `ajax`, which should be used instead. 13564 * 13565 * You can instruct DataTables to load data from an external 13566 * source using this parameter (use aData if you want to pass data in you 13567 * already have). Simply provide a url a JSON object can be obtained from. 13568 * @type string 13569 * @default null 13570 * 13571 * @dtopt Options 13572 * @dtopt Server-side 13573 * @name DataTable.defaults.ajaxSource 13574 * 13575 * @deprecated 1.10. Please use `ajax` for this functionality now. 13576 */ 13577 "sAjaxSource": null, 13578 13579 13580 /** 13581 * This initialisation variable allows you to specify exactly where in the 13582 * DOM you want DataTables to inject the various controls it adds to the page 13583 * (for example you might want the pagination controls at the top of the 13584 * table). DIV elements (with or without a custom class) can also be added to 13585 * aid styling. The follow syntax is used: 13586 * <ul> 13587 * <li>The following options are allowed: 13588 * <ul> 13589 * <li>'l' - Length changing</li> 13590 * <li>'f' - Filtering input</li> 13591 * <li>'t' - The table!</li> 13592 * <li>'i' - Information</li> 13593 * <li>'p' - Pagination</li> 13594 * <li>'r' - pRocessing</li> 13595 * </ul> 13596 * </li> 13597 * <li>The following constants are allowed: 13598 * <ul> 13599 * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li> 13600 * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li> 13601 * </ul> 13602 * </li> 13603 * <li>The following syntax is expected: 13604 * <ul> 13605 * <li>'<' and '>' - div elements</li> 13606 * <li>'<"class" and '>' - div with a class</li> 13607 * <li>'<"#id" and '>' - div with an ID</li> 13608 * </ul> 13609 * </li> 13610 * <li>Examples: 13611 * <ul> 13612 * <li>'<"wrapper"flipt>'</li> 13613 * <li>'<lf<t>ip>'</li> 13614 * </ul> 13615 * </li> 13616 * </ul> 13617 * @type string 13618 * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b> 13619 * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i> 13620 * 13621 * @dtopt Options 13622 * @name DataTable.defaults.dom 13623 * 13624 * @example 13625 * $(document).ready( function() { 13626 * $('#example').dataTable( { 13627 * "dom": '<"top"i>rt<"bottom"flp><"clear">' 13628 * } ); 13629 * } ); 13630 */ 13631 "sDom": "lfrtip", 13632 13633 13634 /** 13635 * Search delay option. This will throttle full table searches that use the 13636 * DataTables provided search input element (it does not effect calls to 13637 * `dt-api search()`, providing a delay before the search is made. 13638 * @type integer 13639 * @default 0 13640 * 13641 * @dtopt Options 13642 * @name DataTable.defaults.searchDelay 13643 * 13644 * @example 13645 * $(document).ready( function() { 13646 * $('#example').dataTable( { 13647 * "searchDelay": 200 13648 * } ); 13649 * } ) 13650 */ 13651 "searchDelay": null, 13652 13653 13654 /** 13655 * DataTables features six different built-in options for the buttons to 13656 * display for pagination control: 13657 * 13658 * * `numbers` - Page number buttons only 13659 * * `simple` - 'Previous' and 'Next' buttons only 13660 * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers 13661 * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons 13662 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers 13663 * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers 13664 * 13665 * Further methods can be added using {@link DataTable.ext.oPagination}. 13666 * @type string 13667 * @default simple_numbers 13668 * 13669 * @dtopt Options 13670 * @name DataTable.defaults.pagingType 13671 * 13672 * @example 13673 * $(document).ready( function() { 13674 * $('#example').dataTable( { 13675 * "pagingType": "full_numbers" 13676 * } ); 13677 * } ) 13678 */ 13679 "sPaginationType": "simple_numbers", 13680 13681 13682 /** 13683 * Enable horizontal scrolling. When a table is too wide to fit into a 13684 * certain layout, or you have a large number of columns in the table, you 13685 * can enable x-scrolling to show the table in a viewport, which can be 13686 * scrolled. This property can be `true` which will allow the table to 13687 * scroll horizontally when needed, or any CSS unit, or a number (in which 13688 * case it will be treated as a pixel measurement). Setting as simply `true` 13689 * is recommended.
13690 * @type boolean|string 13691 * @default <i>blank string - i.e. disabled</i> 13692 * 13693 * @dtopt Features 13694 * @name DataTable.defaults.scrollX 13695 * 13696 * @example 13697 * $(document).ready( function() { 13698 * $('#example').dataTable( { 13699 * "scrollX": true, 13700 * "scrollCollapse": true 13701 * } ); 13702 * } ); 13703 */ 13704 "sScrollX": "", 13705 13706 13707 /** 13708 * This property can be used to force a DataTable to use more width than it 13709 * might otherwise do when x-scrolling is enabled. For example if you have a 13710 * table which requires to be well spaced, this parameter is useful for 13711 * "over-sizing" the table, and thus forcing scrolling. This property can by 13712 * any CSS unit, or a number (in which case it will be treated as a pixel 13713 * measurement). 13714 * @type string 13715 * @default <i>blank string - i.e. disabled</i> 13716 * 13717 * @dtopt Options 13718 * @name DataTable.defaults.scrollXInner 13719 * 13720 * @example 13721 * $(document).ready( function() { 13722 * $('#example').dataTable( { 13723 * "scrollX": "100%", 13724 * "scrollXInner": "110%" 13725 * } ); 13726 * } ); 13727 */ 13728 "sScrollXInner": "", 13729 13730 13731 /** 13732 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable 13733 * to the given height, and enable scrolling for any data which overflows the 13734 * current viewport. This can be used as an alternative to paging to display 13735 * a lot of data in a small area (although paging and scrolling can both be 13736 * enabled at the same time). This property can be any CSS unit, or a number 13737 * (in which case it will be treated as a pixel measurement). 13738 * @type string 13739 * @default <i>blank string - i.e. disabled</i> 13740 * 13741 * @dtopt Features 13742 * @name DataTable.defaults.scrollY 13743 * 13744 * @example 13745 * $(document).ready( function() { 13746 * $('#example').dataTable( { 13747 * "scrollY": "200px", 13748 * "paginate": false 13749 * } ); 13750 * } ); 13751 */ 13752 "sScrollY": "", 13753 13754 13755 /** 13756 * __Deprecated__ The functionality provided by this parameter has now been 13757 * superseded by that provided through `ajax`, which should be used instead. 13758 * 13759 * Set the HTTP method that is used to make the Ajax call for server-side 13760 * processing or Ajax sourced data. 13761 * @type string 13762 * @default GET 13763 * 13764 * @dtopt Options 13765 * @dtopt Server-side 13766 * @name DataTable.defaults.serverMethod 13767 * 13768 * @deprecated 1.10. Please use `ajax` for this functionality now. 13769 */ 13770 "sServerMethod": "GET", 13771 13772 13773 /** 13774 * DataTables makes use of renderers when displaying HTML elements for 13775 * a table. These renderers can be added or modified by plug-ins to 13776 * generate suitable mark-up for a site. For example the Bootstrap 13777 * integration plug-in for DataTables uses a paging button renderer to 13778 * display pagination buttons in the mark-up required by Bootstrap. 13779 * 13780 * For further information about the renderers available see 13781 * DataTable.ext.renderer 13782 * @type string|object 13783 * @default null 13784 * 13785 * @name DataTable.defaults.renderer 13786 * 13787 */ 13788 "renderer": null, 13789 13790 13791 /** 13792 * Set the data property name that DataTables should use to get a row's id 13793 * to set as the `id` property in the node. 13794 * @type string 13795 * @default DT_RowId 13796 * 13797 * @name DataTable.defaults.rowId 13798 */ 13799 "rowId": "DT_RowId" 13800 }; 13801 13802 _fnHungarianMap( DataTable.defaults ); 13803 13804 13805 13806 /* 13807 * Developer note - See note in model.defaults.js about the use of Hungarian 13808 * notation and camel case. 13809 */ 13810 13811 /** 13812 * Column options that can be given to DataTables at initialisation time. 13813 * @namespace 13814 */ 13815 DataTable.defaults.column = { 13816 /** 13817 * Define which column(s) an order will occur on for this column. This 13818 * allows a column's ordering to take multiple columns into account when 13819 * doing a sort or use the data from a different column. For example first 13820 * name / last name columns make sense to do a multi-column sort over the 13821 * two columns. 13822 * @type array|int 13823 * @default null <i>Takes the value of the column index automatically</i> 13824 * 13825 * @name DataTable.defaults.column.orderData 13826 * @dtopt Columns 13827 * 13828 * @example 13829 * // Using `columnDefs` 13830 * $(document).ready( function() { 13831 * $('#example').dataTable( { 13832 * "columnDefs": [ 13833 * { "orderData": [ 0, 1 ], "targets": [ 0 ] }, 13834 * { "orderData": [ 1, 0 ], "targets": [ 1 ] }, 13835 * { "orderData": 2, "targets": [ 2 ] } 13836 * ] 13837 * } ); 13838 * } ); 13839 * 13840 * @example 13841 * // Using `columns` 13842 * $(document).ready( function() { 13843 * $('#example').dataTable( { 13844 * "columns": [ 13845 * { "orderData": [ 0, 1 ] }, 13846 * { "orderData": [ 1, 0 ] }, 13847 * { "orderData": 2 }, 13848 * null, 13849 * null 13850 * ] 13851 * } ); 13852 * } ); 13853 */ 13854 "aDataSort": null, 13855 "iDataSort": -1, 13856 13857 13858 /** 13859 * You can control the default ordering direction, and even alter the 13860 * behaviour of the sort handler (i.e. only allow ascending ordering etc) 13861 * using this parameter. 13862 * @type array 13863 * @default [ 'asc', 'desc' ] 13864 * 13865 * @name DataTable.defaults.column.orderSequence 13866 * @dtopt Columns 13867 * 13868 * @example 13869 * // Using `columnDefs` 13870 * $(document).ready( function() { 13871 * $('#example').dataTable( { 13872 * "columnDefs": [ 13873 * { "orderSequence": [ "asc" ], "targets": [ 1 ] }, 13874 * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] }, 13875 * { "orderSequence": [ "desc" ], "targets": [ 3 ] } 13876 * ] 13877 * } ); 13878 * } ); 13879 * 13880 * @example 13881 * // Using `columns` 13882 * $(document).ready( function() { 13883 * $('#example').dataTable( { 13884 * "columns": [ 13885 * null, 13886 * { "orderSequence": [ "asc" ] }, 13887 * { "orderSequence": [ "desc", "asc", "asc" ] }, 13888 * { "orderSequence": [ "desc" ] }, 13889 * null 13890 * ] 13891 * } ); 13892 * } ); 13893 */ 13894 "asSorting": [ 'asc', 'desc' ], 13895 13896 13897 /** 13898 * Enable or disable filtering on the data in this column. 13899 * @type boolean 13900 * @default true 13901 * 13902 * @name DataTable.defaults.column.searchable 13903 * @dtopt Columns 13904 * 13905 * @example 13906 * // Using `columnDefs` 13907 * $(document).ready( function() { 13908 * $('#example').dataTable( { 13909 * "columnDefs": [ 13910 * { "searchable": false, "targets": [ 0 ] } 13911 * ] } ); 13912 * } ); 13913 * 13914 * @example 13915 * // Using `columns` 13916 * $(document).ready( function() { 13917 * $('#example').dataTable( { 13918 * "columns": [ 13919 * { "searchable": false }, 13920 * null, 13921 * null, 13922 * null, 13923 * null 13924 * ] } ); 13925 * } ); 13926 */ 13927 "bSearchable": true, 13928 13929 13930 /** 13931 * Enable or disable ordering on this column. 13932 * @type boolean 13933 * @default true 13934 * 13935 * @name DataTable.defaults.column.orderable 13936 * @dtopt Columns 13937 * 13938 * @example 13939 * // Using `columnDefs` 13940 * $(document).ready( function() { 13941 * $('#example').dataTable( { 13942 * "columnDefs": [ 13943 * { "orderable": false, "targets": [ 0 ] } 13944 * ] } ); 13945 * } ); 13946 * 13947 * @example 13948 * // Using `columns` 13949 * $(document).ready( function() { 13950 * $('#example').dataTable( { 13951 * "columns": [ 13952 * { "orderable": false }, 13953 * null, 13954 * null, 13955 * null, 13956 * null 13957 * ] } ); 13958 * } ); 13959 */ 13960 "bSortable": true, 13961 13962 13963 /** 13964 * Enable or disable the display of this column. 13965 * @type boolean 13966 * @default true 13967 * 13968 * @name DataTable.defaults.column.visible 13969 * @dtopt Columns 13970 * 13971 * @example 13972 * // Using `columnDefs` 13973 * $(document).ready( function() { 13974 * $('#example').dataTable( { 13975 * "columnDefs": [ 13976 * { "visible": false, "targets": [ 0 ] } 13977 * ] } ); 13978 * } ); 13979 * 13980 * @example 13981 * // Using `columns` 13982 * $(document).ready( function() { 13983 * $('#example').dataTable( { 13984 * "columns": [ 13985 * { "visible": false }, 13986 * null, 13987 * null, 13988 * null, 13989 * null 13990 * ] } ); 13991 * } ); 13992 */ 13993 "bVisible": true, 13994 13995 13996 /** 13997 * Developer definable function that is called whenever a cell is created (Ajax source, 13998 * etc) or processed for input (DOM source). This can be used as a compliment to mRender 13999 * allowing you to modify the DOM element (add background colour for example) when the 14000 * element is available. 14001 * @type function 14002 * @param {element} td The TD node that has been created 14003 * @param {*} cellData The Data for the cell 14004 * @param {array|object} rowData The data for the whole row 14005 * @param {int} row The row index for the aoData data store 14006 * @param {int} col The column index for aoColumns 14007 * 14008 * @name DataTable.defaults.column.createdCell 14009 * @dtopt Columns 14010 * 14011 * @example 14012 * $(document).ready( function() { 14013 * $('#example').dataTable( { 14014 * "columnDefs": [ { 14015 * "targets": [3], 14016 * "createdCell": function (td, cellData, rowData, row, c
14016ol) { 14017 * if ( cellData == "1.7" ) { 14018 * $(td).css('color', 'blue') 14019 * } 14020 * } 14021 * } ] 14022 * }); 14023 * } ); 14024 */ 14025 "fnCreatedCell": null, 14026 14027 14028 /** 14029 * This parameter has been replaced by `data` in DataTables to ensure naming 14030 * consistency. `dataProp` can still be used, as there is backwards 14031 * compatibility in DataTables for this option, but it is strongly 14032 * recommended that you use `data` in preference to `dataProp`. 14033 * @name DataTable.defaults.column.dataProp 14034 */ 14035 14036 14037 /** 14038 * This property can be used to read data from any data source property, 14039 * including deeply nested objects / properties. `data` can be given in a 14040 * number of different ways which effect its behaviour: 14041 * 14042 * * `integer` - treated as an array index for the data source. This is the 14043 * default that DataTables uses (incrementally increased for each column). 14044 * * `string` - read an object property from the data source. There are 14045 * three 'special' options that can be used in the string to alter how 14046 * DataTables reads the data from the source object: 14047 * * `.` - Dotted Javascript notation. Just as you use a `.` in 14048 * Javascript to read from nested objects, so to can the options 14049 * specified in `data`. For example: `browser.version` or 14050 * `browser.name`. If your object parameter name contains a period, use 14051 * `\\` to escape it - i.e. `first\\.name`. 14052 * * `[]` - Array notation. DataTables can automatically combine data 14053 * from and array source, joining the data with the characters provided 14054 * between the two brackets. For example: `name[, ]` would provide a 14055 * comma-space separated list from the source array. If no characters 14056 * are provided between the brackets, the original array source is 14057 * returned. 14058 * * `()` - Function notation. Adding `()` to the end of a parameter will 14059 * execute a function of the name given. For example: `browser()` for a 14060 * simple function on the data source, `browser.version()` for a 14061 * function in a nested property or even `browser().version` to get an 14062 * object property if the function called returns an object. Note that 14063 * function notation is recommended for use in `render` rather than 14064 * `data` as it is much simpler to use as a renderer. 14065 * * `null` - use the original data source for the row rather than plucking 14066 * data directly from it. This action has effects on two other 14067 * initialisation options: 14068 * * `defaultContent` - When null is given as the `data` option and 14069 * `defaultContent` is specified for the column, the value defined by 14070 * `defaultContent` will be used for the cell. 14071 * * `render` - When null is used for the `data` option and the `render` 14072 * option is specified for the column, the whole data source for the 14073 * row is used for the renderer. 14074 * * `function` - the function given will be executed whenever DataTables 14075 * needs to set or get the data for a cell in the column. The function 14076 * takes three parameters: 14077 * * Parameters: 14078 * * `{array|object}` The data source for the row 14079 * * `{string}` The type call data requested - this will be 'set' when 14080 * setting data or 'filter', 'display', 'type', 'sort' or undefined 14081 * when gathering data. Note that when `undefined` is given for the 14082 * type DataTables expects to get the raw data for the object back< 14083 * * `{*}` Data to set when the second parameter is 'set'. 14084 * * Return: 14085 * * The return value from the function is not required when 'set' is 14086 * the type of call, but otherwise the return is what will be used 14087 * for the data requested. 14088 * 14089 * Note that `data` is a getter and setter option. If you just require 14090 * formatting of data for output, you will likely want to use `render` which 14091 * is simply a getter and thus simpler to use. 14092 * 14093 * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The 14094 * name change reflects the flexibility of this property and is consistent 14095 * with the naming of mRender. If 'mDataProp' is given, then it will still 14096 * be used by DataTables, as it automatically maps the old name to the new 14097 * if required. 14098 * 14099 * @type string|int|function|null 14100 * @default null <i>Use automatically calculated column index</i> 14101 * 14102 * @name DataTable.defaults.column.data 14103 * @dtopt Columns 14104 * 14105 * @example 14106 * // Read table data from objects 14107 * // JSON structure for each row: 14108 * // { 14109 * // "engine": {value}, 14110 * // "browser": {value}, 14111 * // "platform": {value}, 14112 * // "version": {value}, 14113 * // "grade": {value} 14114 * // } 14115 * $(document).ready( function() { 14116 * $('#example').dataTable( { 14117 * "ajaxSource": "sources/objects.txt", 14118 * "columns": [ 14119 * { "data": "engine" }, 14120 * { "data": "browser" }, 14121 * { "data": "platform" }, 14122 * { "data": "version" }, 14123 * { "data": "grade" } 14124 * ] 14125 * } ); 14126 * } ); 14127 * 14128 * @example 14129 * // Read information from deeply nested objects 14130 * // JSON structure for each row: 14131 * // { 14132 * // "engine": {value}, 14133 * // "browser": {value}, 14134 * // "platform": { 14135 * // "inner": {value} 14136 * // }, 14137 * // "details": [ 14138 * // {value}, {value} 14139 * // ] 14140 * // } 14141 * $(document).ready( function() { 14142 * $('#example').dataTable( { 14143 * "ajaxSource": "sources/deep.txt", 14144 * "columns": [ 14145 * { "data": "engine" }, 14146 * { "data": "browser" }, 14147 * { "data": "platform.inner" }, 14148 * { "data": "details.0" }, 14149 * { "data": "details.1" } 14150 * ] 14151 * } ); 14152 * } ); 14153 * 14154 * @example 14155 * // Using `data` as a function to provide different information for 14156 * // sorting, filtering and display. In this case, currency (price) 14157 * $(document).ready( function() { 14158 * $('#example').dataTable( { 14159 * "columnDefs": [ { 14160 * "targets": [ 0 ], 14161 * "data": function ( source, type, val ) { 14162 * if (type === 'set') { 14163 * source.price = val; 14164 * // Store the computed dislay and filter values for efficiency 14165 * source.price_display = val=="" ? "" : "$"+numberFormat(val); 14166 * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val; 14167 * return; 14168 * } 14169 * else if (type === 'display') { 14170 * return source.price_display; 14171 * } 14172 * else if (type === 'filter') { 14173 * return source.price_filter; 14174 * } 14175 * // 'sort', 'type' and undefined all just use the integer 14176 * return source.price; 14177 * } 14178 * } ] 14179 * } ); 14180 * } ); 14181 * 14182 * @example 14183 * // Using default content 14184 * $(document).ready( function() { 14185 * $('#example').dataTable( { 14186 * "columnDefs": [ { 14187 * "targets": [ 0 ], 14188 * "data": null, 14189 * "defaultContent": "Click to edit" 14190 * } ] 14191 * } ); 14192 * } ); 14193 * 14194 * @example 14195 * // Using array notation - outputting a list from an array 14196 * $(document).ready( function() { 14197 * $('#example').dataTable( { 14198 * "columnDefs": [ { 14199 * "targets": [ 0 ], 14200 * "data": "name[, ]" 14201 * } ] 14202 * } ); 14203 * } ); 14204 * 14205 */ 14206 "mData": null, 14207 14208 14209 /** 14210 * This property is the rendering partner to `data` and it is suggested that 14211 * when you want to manipulate data for display (including filtering, 14212 * sorting etc) without altering the underlying data for the table, use this 14213 * property. `render` can be considered to be the the read only companion to 14214 * `data` which is read / write (then as such more complex). Like `data` 14215 * this option can be given in a number of different ways to effect its 14216 * behaviour: 14217 * 14218 * * `integer` - treated as an array index for the data source. This is the 14219 * default that DataTables uses (incrementally increased for each column). 14220 * * `string` - read an object property from the data source. There are 14221 * three 'special' options that can be used in the string to alter how 14222 * DataTables reads the data from the source object: 14223 * * `.` - Dotted Javascript notation. Just as you use a `.` in 14224 * Javascript to read from nested objects, so to can the options 14225 * specified in `data`. For example: `browser.version` or 14226 * `browser.name`. If your object parameter name contains a period, use 14227 * `\\` to escape it - i.e. `first\\.name`. 14228 * * `[]` - Array notation. DataTables can automatically combine data 14229 * from and array source, joining the data with the characters provided 14230 * between the two brackets. For example: `name[, ]` would provide a 14231 * comma-space separated list from the source array. If no characters 14232 * are provided between the brackets, the original array source is 14233 * returned. 14234 * * `()` - Function notation. Adding `()` to the end of a parameter will 14235 * execute a function of the name given. For example: `browser()` for a 14236 * simple function on the data source, `browser.version()` for a 14237 * function in a nested property or even `browser().version` to get an 14238 * object property if the function called returns an object. 14239 * * `object` - use different data for the different data types requested by 14240 * DataTables ('filter', 'display', 'type' or 'sort'). The property names 14241 * of the object is the data type the property refers to and the value can 14242 * defined using an integer, string or function using the same rules as 14243 * `render` normally does. Note that an `_` option _must_ be specified. 14244 * This is the default value to use if you haven't specified a value for 14245 * the data type requested by DataTables. 14246 * * `function` - the function given will be executed whenever DataTables 14247 * needs to set or get the data for a cell in the column. The function 14248 * takes three parameters: 14249 * * Parameters: 14250 * * {array|object} The data source for the row (based on `data`) 14251 * * {string} The type call data requested - this will be 'filter', 14252 * 'display', 'type' or 'sort'. 14253 * * {array|object} The full data source for the row (not based on 14254 * `data`) 14255 * * Return: 14256 * * The return value from the function is what will be used for the 14257 * data requested. 14258 * 14259 * @type string|int|function|object|null 14260 * @default null Use the data source value. 14261 * 14262 * @name DataTable.defaults.column.render 14263 * @dtopt Columns 14264 * 14265 * @example 14266 * // Create a comma separated list from an array of objects 14267 * $(document).ready( function() { 14268 * $('#example').dataTable( { 14269 * "ajaxSource": "sources/deep.txt", 14270 * "columns": [ 14271 * { "data": "engine" }, 14272 * { "data": "browser" }, 14273 * { 14274 * "data": "platform", 14275 * "render": "[, ].name" 14276 * } 14277 * ] 14278 * } ); 14279 * } ); 14280 * 14281 * @example 14282 * // Execute a function to obtain data 14283 * $(document).ready( function() { 14284 * $('#example').dataTable( { 14285 * "columnDefs": [ { 14286 * "targets": [ 0 ], 14287 * "data": null, // Use the full data source object for the renderer's source 14288 * "render": "browserName()" 14289 * } ] 14290 * } ); 14291 * } ); 14292 * 14293 * @example 14294 * // As an object, extracting different data for the different types 14295 * // This would be used with a data source such as: 14296 * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" } 14297 * // Here the `phone` integer is used for sorting and type detection, while `phone_filter` 14298 * // (which has both forms) is used for filtering for if a user inputs either format, while 14299 * // the formatted phone number is the one that is shown in the table. 14300 * $(document).ready( function() { 14301 * $('#example').dataTable( { 14302 * "columnDefs": [ { 14303 * "targets": [ 0 ], 14304 * "data": null, // Use the full data source object for the renderer's source 14305 * "render": { 14306 * "_": "phone", 14307 * "filter": "phone_filter", 14308 * "display": "phone_display" 14309 * } 14310 * } ] 14311 * } ); 14312 * } ); 14313 * 14314 * @example 14315 * // Use as a function to create a link from the data source 14316 * $(document).ready( function() { 14317 * $('#example').dataTable( { 14318 * "columnDefs": [ { 14319 * "targets": [ 0 ], 14320 * "data": "download_link", 14321 * "render": function ( data, type, full ) { 14322 * return '<a href="'+data+'">Download</a>'; 14323 * } 14324 * } ] 14325 * } ); 14326 * } ); 14327 */
14328 "mRender": null, 14329 14330 14331 /** 14332 * Change the cell type created for the column - either TD cells or TH cells. This 14333 * can be useful as TH cells have semantic meaning in the table body, allowing them 14334 * to act as a header for a row (you may wish to add scope='row' to the TH elements). 14335 * @type string 14336 * @default td 14337 * 14338 * @name DataTable.defaults.column.cellType 14339 * @dtopt Columns 14340 * 14341 * @example 14342 * // Make the first column use TH cells 14343 * $(document).ready( function() { 14344 * $('#example').dataTable( { 14345 * "columnDefs": [ { 14346 * "targets": [ 0 ], 14347 * "cellType": "th" 14348 * } ] 14349 * } ); 14350 * } ); 14351 */ 14352 "sCellType": "td", 14353 14354 14355 /** 14356 * Class to give to each cell in this column. 14357 * @type string 14358 * @default <i>Empty string</i> 14359 * 14360 * @name DataTable.defaults.column.class 14361 * @dtopt Columns 14362 * 14363 * @example 14364 * // Using `columnDefs` 14365 * $(document).ready( function() { 14366 * $('#example').dataTable( { 14367 * "columnDefs": [ 14368 * { "class": "my_class", "targets": [ 0 ] } 14369 * ] 14370 * } ); 14371 * } ); 14372 * 14373 * @example 14374 * // Using `columns` 14375 * $(document).ready( function() { 14376 * $('#example').dataTable( { 14377 * "columns": [ 14378 * { "class": "my_class" }, 14379 * null, 14380 * null, 14381 * null, 14382 * null 14383 * ] 14384 * } ); 14385 * } ); 14386 */ 14387 "sClass": "", 14388 14389 /** 14390 * When DataTables calculates the column widths to assign to each column, 14391 * it finds the longest string in each column and then constructs a 14392 * temporary table and reads the widths from that. The problem with this 14393 * is that "mmm" is much wider then "iiii", but the latter is a longer 14394 * string - thus the calculation can go wrong (doing it properly and putting 14395 * it into an DOM object and measuring that is horribly(!) slow). Thus as 14396 * a "work around" we provide this option. It will append its value to the 14397 * text that is found to be the longest string for the column - i.e. padding. 14398 * Generally you shouldn't need this! 14399 * @type string 14400 * @default <i>Empty string<i> 14401 * 14402 * @name DataTable.defaults.column.contentPadding 14403 * @dtopt Columns 14404 * 14405 * @example 14406 * // Using `columns` 14407 * $(document).ready( function() { 14408 * $('#example').dataTable( { 14409 * "columns": [ 14410 * null, 14411 * null, 14412 * null, 14413 * { 14414 * "contentPadding": "mmm" 14415 * } 14416 * ] 14417 * } ); 14418 * } ); 14419 */ 14420 "sContentPadding": "", 14421 14422 14423 /** 14424 * Allows a default value to be given for a column's data, and will be used 14425 * whenever a null data source is encountered (this can be because `data` 14426 * is set to null, or because the data source itself is null). 14427 * @type string 14428 * @default null 14429 * 14430 * @name DataTable.defaults.column.defaultContent 14431 * @dtopt Columns 14432 * 14433 * @example 14434 * // Using `columnDefs` 14435 * $(document).ready( function() { 14436 * $('#example').dataTable( { 14437 * "columnDefs": [ 14438 * { 14439 * "data": null, 14440 * "defaultContent": "Edit", 14441 * "targets": [ -1 ] 14442 * } 14443 * ] 14444 * } ); 14445 * } ); 14446 * 14447 * @example 14448 * // Using `columns` 14449 * $(document).ready( function() { 14450 * $('#example').dataTable( { 14451 * "columns": [ 14452 * null, 14453 * null, 14454 * null, 14455 * { 14456 * "data": null, 14457 * "defaultContent": "Edit" 14458 * } 14459 * ] 14460 * } ); 14461 * } ); 14462 */ 14463 "sDefaultContent": null, 14464 14465 14466 /** 14467 * This parameter is only used in DataTables' server-side processing. It can 14468 * be exceptionally useful to know what columns are being displayed on the 14469 * client side, and to map these to database fields. When defined, the names 14470 * also allow DataTables to reorder information from the server if it comes 14471 * back in an unexpected order (i.e. if you switch your columns around on the 14472 * client-side, your server-side code does not also need updating). 14473 * @type string 14474 * @default <i>Empty string</i> 14475 * 14476 * @name DataTable.defaults.column.name 14477 * @dtopt Columns 14478 * 14479 * @example 14480 * // Using `columnDefs` 14481 * $(document).ready( function() { 14482 * $('#example').dataTable( { 14483 * "columnDefs": [ 14484 * { "name": "engine", "targets": [ 0 ] }, 14485 * { "name": "browser", "targets": [ 1 ] }, 14486 * { "name": "platform", "targets": [ 2 ] }, 14487 * { "name": "version", "targets": [ 3 ] }, 14488 * { "name": "grade", "targets": [ 4 ] } 14489 * ] 14490 * } ); 14491 * } ); 14492 * 14493 * @example 14494 * // Using `columns` 14495 * $(document).ready( function() { 14496 * $('#example').dataTable( { 14497 * "columns": [ 14498 * { "name": "engine" }, 14499 * { "name": "browser" }, 14500 * { "name": "platform" }, 14501 * { "name": "version" }, 14502 * { "name": "grade" } 14503 * ] 14504 * } ); 14505 * } ); 14506 */ 14507 "sName": "", 14508 14509 14510 /** 14511 * Defines a data source type for the ordering which can be used to read 14512 * real-time information from the table (updating the internally cached 14513 * version) prior to ordering. This allows ordering to occur on user 14514 * editable elements such as form inputs. 14515 * @type string 14516 * @default std 14517 * 14518 * @name DataTable.defaults.column.orderDataType 14519 * @dtopt Columns 14520 * 14521 * @example 14522 * // Using `columnDefs` 14523 * $(document).ready( function() { 14524 * $('#example').dataTable( { 14525 * "columnDefs": [ 14526 * { "orderDataType": "dom-text", "targets": [ 2, 3 ] }, 14527 * { "type": "numeric", "targets": [ 3 ] }, 14528 * { "orderDataType": "dom-select", "targets": [ 4 ] }, 14529 * { "orderDataType": "dom-checkbox", "targets": [ 5 ] } 14530 * ] 14531 * } ); 14532 * } ); 14533 * 14534 * @example 14535 * // Using `columns` 14536 * $(document).ready( function() { 14537 * $('#example').dataTable( { 14538 * "columns": [ 14539 * null, 14540 * null, 14541 * { "orderDataType": "dom-text" }, 14542 * { "orderDataType": "dom-text", "type": "numeric" }, 14543 * { "orderDataType": "dom-select" }, 14544 * { "orderDataType": "dom-checkbox" } 14545 * ] 14546 * } ); 14547 * } ); 14548 */ 14549 "sSortDataType": "std", 14550 14551 14552 /** 14553 * The title of this column. 14554 * @type string 14555 * @default null <i>Derived from the 'TH' value for this column in the 14556 * original HTML table.</i> 14557 * 14558 * @name DataTable.defaults.column.title 14559 * @dtopt Columns 14560 * 14561 * @example 14562 * // Using `columnDefs` 14563 * $(document).ready( function() { 14564 * $('#example').dataTable( { 14565 * "columnDefs": [ 14566 * { "title": "My column title", "targets": [ 0 ] } 14567 * ] 14568 * } ); 14569 * } ); 14570 * 14571 * @example 14572 * // Using `columns` 14573 * $(document).ready( function() { 14574 * $('#example').dataTable( { 14575 * "columns": [ 14576 * { "title": "My column title" }, 14577 * null, 14578 * null, 14579 * null, 14580 * null 14581 * ] 14582 * } ); 14583 * } ); 14584 */ 14585 "sTitle": null, 14586 14587 14588 /** 14589 * The type allows you to specify how the data for this column will be
14590 * ordered. Four types (string, numeric, date and html (which will strip 14591 * HTML tags before ordering)) are currently available. Note that only date 14592 * formats understood by Javascript's Date() object will be accepted as type 14593 * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 14594 * 'numeric', 'date' or 'html' (by default). Further types can be adding 14595 * through plug-ins. 14596 * @type string 14597 * @default null <i>Auto-detected from raw data</i> 14598 * 14599 * @name DataTable.defaults.column.type 14600 * @dtopt Columns 14601 * 14602 * @example 14603 * // Using `columnDefs` 14604 * $(document).ready( function() { 14605 * $('#example').dataTable( { 14606 * "columnDefs": [ 14607 * { "type": "html", "targets": [ 0 ] } 14608 * ] 14609 * } ); 14610 * } ); 14611 * 14612 * @example 14613 * // Using `columns` 14614 * $(document).ready( function() { 14615 * $('#example').dataTable( { 14616 * "columns": [ 14617 * { "type": "html" }, 14618 * null, 14619 * null, 14620 * null, 14621 * null 14622 * ] 14623 * } ); 14624 * } ); 14625 */ 14626 "sType": null, 14627 14628 14629 /** 14630 * Defining the width of the column, this parameter may take any CSS value 14631 * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not 14632 * been given a specific width through this interface ensuring that the table 14633 * remains readable. 14634 * @type string 14635 * @default null <i>Automatic</i> 14636 * 14637 * @name DataTable.defaults.column.width 14638 * @dtopt Columns 14639 * 14640 * @example 14641 * // Using `columnDefs` 14642 * $(document).ready( function() { 14643 * $('#example').dataTable( { 14644 * "columnDefs": [ 14645 * { "width": "20%", "targets": [ 0 ] } 14646 * ] 14647 * } ); 14648 * } ); 14649 * 14650 * @example 14651 * // Using `columns` 14652 * $(document).ready( function() { 14653 * $('#example').dataTable( { 14654 * "columns": [ 14655 * { "width": "20%" }, 14656 * null, 14657 * null, 14658 * null, 14659 * null 14660 * ] 14661 * } ); 14662 * } ); 14663 */ 14664 "sWidth": null 14665 }; 14666 14667 _fnHungarianMap( DataTable.defaults.column ); 14668 14669 14670 14671 /** 14672 * DataTables settings object - this holds all the information needed for a 14673 * given table, including configuration, data and current application of the 14674 * table options. DataTables does not have a single instance for each DataTable 14675 * with the settings attached to that instance, but rather instances of the 14676 * DataTable "class" are created on-the-fly as needed (typically by a 14677 * $().dataTable() call) and the settings object is then applied to that 14678 * instance. 14679 * 14680 * Note that this object is related to {@link DataTable.defaults} but this 14681 * one is the internal data store for DataTables's cache of columns. It should 14682 * NOT be manipulated outside of DataTables. Any configuration should be done 14683 * through the initialisation options. 14684 * @namespace 14685 * @todo Really should attach the settings object to individual instances so we 14686 * don't need to create new instances on each $().dataTable() call (if the 14687 * table already exists). It would also save passing oSettings around and 14688 * into every single function. However, this is a very significant 14689 * architecture change for DataTables and will almost certainly break 14690 * backwards compatibility with older installations. This is something that 14691 * will be done in 2.0. 14692 */ 14693 DataTable.models.oSettings = { 14694 /** 14695 * Primary features of DataTables and their enablement state. 14696 * @namespace 14697 */ 14698 "oFeatures": { 14699 14700 /** 14701 * Flag to say if DataTables should automatically try to calculate the 14702 * optimum table and columns widths (true) or not (false). 14703 * Note that this parameter will be set by the initialisation routine. To 14704 * set a default use {@link DataTable.defaults}. 14705 * @type boolean 14706 */ 14707 "bAutoWidth": null, 14708 14709 /** 14710 * Delay the creation of TR and TD elements until they are actually 14711 * needed by a driven page draw. This can give a significant speed 14712 * increase for Ajax source and Javascript source data, but makes no 14713 * difference at all fro DOM and server-side processing tables. 14714 * Note that this parameter will be set by the initialisation routine. To 14715 * set a default use {@link DataTable.defaults}. 14716 * @type boolean 14717 */ 14718 "bDeferRender": null, 14719 14720 /** 14721 * Enable filtering on the table or not. Note that if this is disabled 14722 * then there is no filtering at all on the table, including fnFilter. 14723 * To just remove the filtering input use sDom and remove the 'f' option. 14724 * Note that this parameter will be set by the initialisation routine. To 14725 * set a default use {@link DataTable.defaults}. 14726 * @type boolean 14727 */ 14728 "bFilter": null, 14729 14730 /** 14731 * Table information element (the 'Showing x of y records' div) enable 14732 * flag. 14733 * Note that this parameter will be set by the initialisation routine. To 14734 * set a default use {@link DataTable.defaults}. 14735 * @type boolean 14736 */ 14737 "bInfo": null, 14738 14739 /** 14740 * Present a user control allowing the end user to change the page size 14741 * when pagination is enabled. 14742 * Note that this parameter will be set by the initialisation routine. To 14743 * set a default use {@link DataTable.defaults}. 14744 * @type boolean 14745 */ 14746 "bLengthChange": null, 14747 14748 /** 14749 * Pagination enabled or not. Note that if this is disabled then length 14750 * changing must also be disabled. 14751 * Note that this parameter will be set by the initialisation routine. To 14752 * set a default use {@link DataTable.defaults}. 14753 * @type boolean 14754 */ 14755 "bPaginate": null, 14756 14757 /** 14758 * Processing indicator enable flag whenever DataTables is enacting a 14759 * user request - typically an Ajax request for server-side processing. 14760 * Note that this parameter will be set by the initialisation routine. To 14761 * set a default use {@link DataTable.defaults}. 14762 * @type boolean 14763 */ 14764 "bProcessing": null, 14765 14766 /** 14767 * Server-side processing enabled flag - when enabled DataTables will 14768 * get all data from the server for every draw - there is no filtering, 14769 * sorting or paging done on the client-side. 14770 * Note that this parameter will be set by the initialisation routine. To 14771 * set a default use {@link DataTable.defaults}. 14772 * @type boolean 14773 */ 14774 "bServerSide": null, 14775 14776 /** 14777 * Sorting enablement flag. 14778 * Note that this parameter will be set by the initialisation routine. To 14779 * set a default use {@link DataTable.defaults}. 14780 * @type boolean 14781 */ 14782 "bSort": null, 14783 14784 /**
14785 * Multi-column sorting 14786 * Note that this parameter will be set by the initialisation routine. To 14787 * set a default use {@link DataTable.defaults}. 14788 * @type boolean 14789 */ 14790 "bSortMulti": null, 14791 14792 /** 14793 * Apply a class to the columns which are being sorted to provide a 14794 * visual highlight or not. This can slow things down when enabled since 14795 * there is a lot of DOM interaction. 14796 * Note that this parameter will be set by the initialisation routine. To 14797 * set a default use {@link DataTable.defaults}. 14798 * @type boolean 14799 */ 14800 "bSortClasses": null, 14801 14802 /** 14803 * State saving enablement flag. 14804 * Note that this parameter will be set by the initialisation routine. To 14805 * set a default use {@link DataTable.defaults}. 14806 * @type boolean 14807 */ 14808 "bStateSave": null 14809 }, 14810 14811 14812 /** 14813 * Scrolling settings for a table. 14814 * @namespace 14815 */ 14816 "oScroll": { 14817 /** 14818 * When the table is shorter in height than sScrollY, collapse the 14819 * table container down to the height of the table (when true). 14820 * Note that this parameter will be set by the initialisation routine. To 14821 * set a default use {@link DataTable.defaults}. 14822 * @type boolean 14823 */ 14824 "bCollapse": null, 14825 14826 /** 14827 * Width of the scrollbar for the web-browser's platform. Calculated 14828 * during table initialisation. 14829 * @type int 14830 * @default 0 14831 */ 14832 "iBarWidth": 0, 14833 14834 /** 14835 * Viewport width for horizontal scrolling. Horizontal scrolling is 14836 * disabled if an empty string. 14837 * Note that this parameter will be set by the initialisation routine. To 14838 * set a default use {@link DataTable.defaults}. 14839 * @type string 14840 */ 14841 "sX": null, 14842 14843 /** 14844 * Width to expand the table to when using x-scrolling. Typically you 14845 * should not need to use this. 14846 * Note that this parameter will be set by the initialisation routine. To 14847 * set a default use {@link DataTable.defaults}. 14848 * @type string 14849 * @deprecated 14850 */ 14851 "sXInner": null, 14852 14853 /** 14854 * Viewport height for vertical scrolling. Vertical scrolling is disabled 14855 * if an empty string. 14856 * Note that this parameter will be set by the initialisation routine. To 14857 * set a default use {@link DataTable.defaults}. 14858 * @type string 14859 */ 14860 "sY": null 14861 }, 14862 14863 /** 14864 * Language information for the table. 14865 * @namespace 14866 * @extends DataTable.defaults.oLanguage 14867 */ 14868 "oLanguage": { 14869 /** 14870 * Information callback function. See 14871 * {@link DataTable.defaults.fnInfoCallback} 14872 * @type function 14873 * @default null 14874 */ 14875 "fnInfoCallback": null 14876 }, 14877 14878 /** 14879 * Browser support parameters 14880 * @namespace 14881 */ 14882 "oBrowser": { 14883 /** 14884 * Indicate if the browser incorrectly calculates width:100% inside a 14885 * scrolling element (IE6/7) 14886 * @type boolean 14887 * @default false 14888 */ 14889 "bScrollOversize": false, 14890 14891 /** 14892 * Determine if the vertical scrollbar is on the right or left of the 14893 * scrolling container - needed for rtl language layout, although not 14894 * all browsers move the scrollbar (Safari). 14895 * @type boolean 14896 * @default false 14897 */ 14898 "bScrollbarLeft": false, 14899 14900 /** 14901 * Flag for if `getBoundingClientRect` is fully supported or not 14902 * @type boolean 14903 * @default false 14904 */ 14905 "bBounding": false, 14906 14907 /** 14908 * Browser scrollbar width 14909 * @type integer 14910 * @default 0 14911 */ 14912 "barWidth": 0 14913 }, 14914 14915 14916 "ajax": null, 14917 14918 14919 /** 14920 * Array referencing the nodes which are used for the features. The 14921 * parameters of this object match what is allowed by sDom - i.e. 14922 * <ul> 14923 * <li>'l' - Length changing</li> 14924 * <li>'f' - Filtering input</li> 14925 * <li>'t' - The table!</li> 14926 * <li>'i' - Information</li> 14927 * <li>'p' - Pagination</li> 14928 * <li>'r' - pRocessing</li> 14929 * </ul> 14930 * @type array 14931 * @default [] 14932 */ 14933 "aanFeatures": [], 14934 14935 /** 14936 * Store data information - see {@link DataTable.models.oRow} for detailed 14937 * information. 14938 * @type array 14939 * @default [] 14940 */ 14941 "aoData": [], 14942 14943 /** 14944 * Array of indexes which are in the current display (after filtering etc) 14945 * @type array 14946 * @default [] 14947 */ 14948 "aiDisplay": [], 14949 14950 /** 14951 * Array of indexes for display - no filtering 14952 * @type array 14953 * @default [] 14954 */ 14955 "aiDisplayMaster": [], 14956 14957 /** 14958 * Map of row ids to data indexes 14959 * @type object 14960 * @default {} 14961 */ 14962 "aIds": {}, 14963 14964 /** 14965 * Store information about each column that is in use 14966 * @type array 14967 * @default [] 14968 */ 14969 "aoColumns": [], 14970 14971 /** 14972 * Store information about the table's header 14973 * @type array 14974 * @default [] 14975 */ 14976 "aoHeader": [], 14977 14978 /** 14979 * Store information about the table's footer 14980 * @type array 14981 * @default [] 14982 */ 14983 "aoFooter": [], 14984 14985 /** 14986 * Store the applied global search information in case we want to force a 14987 * research or compare the old search to a new one. 14988 * Note that this parameter will be set by the initialisation routine. To 14989 * set a default use {@link DataTable.defaults}. 14990 * @namespace 14991 * @extends DataTable.models.oSearch 14992 */ 14993 "oPreviousSearch": {}, 14994 14995 /** 14996 * Store the applied search for each column - see 14997 * {@link DataTable.models.oSearch} for the format that is used for the 14998 * filtering information for each column. 14999 * @type array 15000 * @default [] 15001 */ 15002 "aoPreSearchCols": [], 15003 15004 /** 15005 * Sorting that is applied to the table. Note that the inner arrays are 15006 * used in the following manner: 15007 * <ul> 15008 * <li>Index 0 - column number</li> 15009 * <li>Index 1 - current sorting direction</li> 15010 * </ul> 15011 * Note that this parameter will be set by the initialisation routine. To 15012 * set a default use {@link DataTable.defaults}. 15013 * @type array 15014 * @todo These inner arrays should really be objects 15015 */ 15016 "aaSorting": null, 15017 15018 /** 15019 * Sorting that is always applied to the table (i.e. prefixed in front of 15020 * aaSorting). 15021 * Note that this parameter will be set by the initialisation routine. To 15022 * set a default use {@link DataTable.defaults}. 15023 * @type array 15024 * @default [] 15025 */ 15026 "aaSortingFixed": [], 15027 15028 /** 15029 * Classes to use for the striping of a table. 15030 * Note that this parameter will be set by the initialisation routine. To 15031 * set a default use {@link DataTable.defaults}. 15032 * @type array 15033 * @default [] 15034 */ 15035 "asStripeClasses": null, 15036 15037 /** 15038 * If restoring a table - we should restore its striping classes as well 15039 * @type array 15040 * @default [] 15041 */ 15042 "asDestroyStripes": [], 15043 15044 /** 15045 * If restoring a table - we should restore its width 15046 * @type int 15047 * @default 0 15048 */ 15049 "sDestroyWidth": 0, 15050 15051 /** 15052 * Callback functions array for every time a row is inserted (i.e. on a draw). 15053 * @type array 15054 * @default [] 15055 */ 15056 "aoRowCallback": [], 15057 15058 /** 15059 * Callback functions for the header on each draw. 15060 * @type array 15061 * @default [] 15062 */ 15063 "aoHeaderCallback": [], 15064 15065 /** 15066 * Callback function for the footer on each draw. 15067 * @type array 15068 * @default [] 15069 */ 15070 "aoFooterCallback": [], 15071 15072 /** 15073 * Array of callback functions for draw callback functions 15074 * @type array 15075 * @default [] 15076 */ 15077 "aoDrawCallback": [], 15078 15079 /** 15080 * Array of callback functions for row created function 15081 * @type array 15082 * @default [] 15083 */ 15084 "aoRowCreatedCallback": [], 15085 15086 /** 15087 * Callback functions for just before the table is redrawn. A return of 15088 * false will be used to cancel the draw. 15089 * @type array 15090 * @default [] 15091 */ 15092 "aoPreDrawCallback": [], 15093 15094 /** 15095 * Callback functions for when the table has been initialised. 15096 * @type array 15097 * @default [] 15098 */ 15099 "aoInitComplete": [], 15100 15101 15102 /** 15103 * Callbacks for modifying the settings to be stored for state saving, prior to 15104 * saving state. 15105 * @type array 15106 * @default [] 15107 */ 15108 "aoStateSaveParams": [], 15109 15110 /** 15111 * Callbacks for modifying the settings that have been stored for state saving 15112 * prior to using the stored values to restore the state. 15113 * @type array 15114 * @default [] 15115 */ 15116 "aoStateLoadParams": [], 15117 15118 /** 15119 * Callbacks for operating on the settings object once the saved state has been 15120 * loaded 15121 * @type array 15122 * @default [] 15123 */ 15124 "aoStateLoaded": [], 15125 15126 /** 15127 * Cache the table ID for quick access 15128 * @type string 15129 * @default <i>Empty string</i> 15130 */ 15131 "sTableId": "", 15132 15133 /** 15134 * The TABLE node for the main table 15135 * @type node 15136 * @default null 15137 */ 15138 "nTable": null, 15139 15140 /** 15141 * Permanent ref to the thead element 15142 * @type node 15143 * @default null 15144 */ 15145 "nTHead": null, 15146 15147 /** 15148 * Permanent ref to the tfoot element - if it exists 15149 * @type node 15150 * @default null 15151 */ 15152 "nTFoot": null, 15153 15154 /** 15155 * Permanent ref to the tbody element 15156 * @type node 15157 * @default null 15158 */ 15159 "nTBody": null, 15160 15161 /** 15162 * Cache the wrapper node (contains all DataTables controlled elements) 15163 * @type node 15164 * @default null 15165 */ 15166 "nTableWrapper": null, 15167 15168 /** 15169 * Indicate if when using server-side processing the loading of data 15170 * should be deferred until the second draw. 15171 * Note that this parameter will be set by the initialisation routine. To 15172 * set a default use {@link DataTable.defaults}. 15173 * @type boolean 15174 * @default false 15175 */ 15176 "bDeferLoading": false, 15177 15178 /** 15179 * Indicate if all required information has been read in 15180 * @type boolean 15181 * @default false 15182 */ 15183 "bInitialised": false, 15184 15185 /** 15186 * Information about open rows. Each object in the array has the parameters 15187 * 'nTr' and 'nParent' 15188 * @type array 15189 * @default [] 15190 */ 15191 "aoOpenRows": [], 15192 15193 /**
15194 * Dictate the positioning of DataTables' control elements - see 15195 * {@link DataTable.model.oInit.sDom}. 15196 * Note that this parameter will be set by the initialisation routine. To 15197 * set a default use {@link DataTable.defaults}. 15198 * @type string 15199 * @default null 15200 */ 15201 "sDom": null, 15202 15203 /** 15204 * Search delay (in mS) 15205 * @type integer 15206 * @default null 15207 */ 15208 "searchDelay": null, 15209 15210 /** 15211 * Which type of pagination should be used. 15212 * Note that this parameter will be set by the initialisation routine. To 15213 * set a default use {@link DataTable.defaults}. 15214 * @type string 15215 * @default two_button 15216 */ 15217 "sPaginationType": "two_button", 15218 15219 /** 15220 * The state duration (for `stateSave`) in seconds. 15221 * Note that this parameter will be set by the initialisation routine. To 15222 * set a default use {@link DataTable.defaults}. 15223 * @type int 15224 * @default 0 15225 */ 15226 "iStateDuration": 0, 15227 15228 /** 15229 * Array of callback functions for state saving. Each array element is an 15230 * object with the following parameters: 15231 * <ul> 15232 * <li>function:fn - function to call. Takes two parameters, oSettings 15233 * and the JSON string to save that has been thus far created. Returns 15234 * a JSON string to be inserted into a json object 15235 * (i.e. '"param": [ 0, 1, 2]')</li> 15236 * <li>string:sName - name of callback</li> 15237 * </ul> 15238 * @type array 15239 * @default [] 15240 */ 15241 "aoStateSave": [], 15242 15243 /** 15244 * Array of callback functions for state loading. Each array element is an 15245 * object with the following parameters: 15246 * <ul> 15247 * <li>function:fn - function to call. Takes two parameters, oSettings 15248 * and the object stored. May return false to cancel state loading</li> 15249 * <li>string:sName - name of callback</li> 15250 * </ul> 15251 * @type array 15252 * @default [] 15253 */ 15254 "aoStateLoad": [], 15255 15256 /** 15257 * State that was saved. Useful for back reference 15258 * @type object 15259 * @default null 15260 */ 15261 "oSavedState": null, 15262 15263 /** 15264 * State that was loaded. Useful for back reference 15265 * @type object 15266 * @default null 15267 */ 15268 "oLoadedState": null, 15269 15270 /** 15271 * Source url for AJAX data for the table. 15272 * Note that this parameter will be set by the initialisation routine. To 15273 * set a default use {@link DataTable.defaults}. 15274 * @type string 15275 * @default null 15276 */ 15277 "sAjaxSource": null, 15278 15279 /** 15280 * Property from a given object from which to read the table data from. This 15281 * can be an empty string (when not server-side processing), in which case 15282 * it is assumed an an array is given directly. 15283 * Note that this parameter will be set by the initialisation routine. To 15284 * set a default use {@link DataTable.defaults}. 15285 * @type string 15286 */ 15287 "sAjaxDataProp": null, 15288 15289 /** 15290 * Note if draw should be blocked while getting data 15291 * @type boolean 15292 * @default true 15293 */ 15294 "bAjaxDataGet": true, 15295 15296 /** 15297 * The last jQuery XHR object that was used for server-side data gathering. 15298 * This can be used for working with the XHR information in one of the 15299 * callbacks 15300 * @type object 15301 * @default null 15302 */ 15303 "jqXHR": null, 15304 15305 /** 15306 * JSON returned from the server in the last Ajax request 15307 * @type object 15308 * @default undefined 15309 */ 15310 "json": undefined, 15311 15312 /** 15313 * Data submitted as part of the last Ajax request 15314 * @type object 15315 * @default undefined 15316 */ 15317 "oAjaxData": undefined, 15318 15319 /** 15320 * Function to get the server-side data. 15321 * Note that this parameter will be set by the initialisation routine. To 15322 * set a default use {@link DataTable.defaults}. 15323 * @type function 15324 */ 15325 "fnServerData": null, 15326 15327 /** 15328 * Functions which are called prior to sending an Ajax request so extra 15329 * parameters can easily be sent to the server 15330 * @type array 15331 * @default [] 15332 */ 15333 "aoServerParams": [], 15334 15335 /** 15336 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if 15337 * required). 15338 * Note that this parameter will be set by the initialisation routine. To 15339 * set a default use {@link DataTable.defaults}. 15340 * @type string 15341 */ 15342 "sServerMethod": null, 15343 15344 /** 15345 * Format numbers for display. 15346 * Note that this parameter will be set by the initialisation routine. To 15347 * set a default use {@link DataTable.defaults}. 15348 * @type function 15349 */ 15350 "fnFormatNumber": null, 15351 15352 /** 15353 * List of options that can be used for the user selectable length menu. 15354 * Note that this parameter will be set by the initialisation routine. To 15355 * set a default use {@link DataTable.defaults}. 15356 * @type array 15357 * @default [] 15358 */ 15359 "aLengthMenu": null, 15360 15361 /** 15362 * Counter for the draws that the table does. Also used as a tracker for 15363 * server-side processing 15364 * @type int 15365 * @default 0 15366 */ 15367 "iDraw": 0, 15368 15369 /** 15370 * Indicate if a redraw is being done - useful for Ajax 15371 * @type boolean 15372 * @default false 15373 */ 15374 "bDrawing": false, 15375 15376 /** 15377 * Draw index (iDraw) of the last error when parsing the returned data 15378 * @type int 15379 * @default -1 15380 */ 15381 "iDrawError": -1, 15382 15383 /** 15384 * Paging display length 15385 * @type int 15386 * @default 10 15387 */ 15388 "_iDisplayLength": 10, 15389 15390 /** 15391 * Paging start point - aiDisplay index 15392 * @type int 15393 * @default 0 15394 */ 15395 "_iDisplayStart": 0, 15396 15397 /** 15398 * Server-side processing - number of records in the result set 15399 * (i.e. before filtering), Use fnRecordsTotal rather than 15400 * this property to get the value of the number of records, regardless of 15401 * the server-side processing setting. 15402 * @type int 15403 * @default 0 15404 * @private 15405 */ 15406 "_iRecordsTotal": 0, 15407 15408 /** 15409 * Server-side processing - number of records in the current display set 15410 * (i.e. after filtering). Use fnRecordsDisplay rather than 15411 * this property to get the value of the number of records, regardless of 15412 * the server-side processing setting. 15413 * @type boolean 15414 * @default 0 15415 * @private 15416 */ 15417 "_iRecordsDisplay": 0, 15418 15419 /** 15420 * The classes to use for the table 15421 * @type object 15422 * @default {} 15423 */
15424 "oClasses": {}, 15425 15426 /** 15427 * Flag attached to the settings object so you can check in the draw 15428 * callback if filtering has been done in the draw. Deprecated in favour of 15429 * events. 15430 * @type boolean 15431 * @default false 15432 * @deprecated 15433 */ 15434 "bFiltered": false, 15435 15436 /** 15437 * Flag attached to the settings object so you can check in the draw 15438 * callback if sorting has been done in the draw. Deprecated in favour of 15439 * events. 15440 * @type boolean 15441 * @default false 15442 * @deprecated 15443 */ 15444 "bSorted": false, 15445 15446 /** 15447 * Indicate that if multiple rows are in the header and there is more than 15448 * one unique cell per column, if the top one (true) or bottom one (false) 15449 * should be used for sorting / title by DataTables. 15450 * Note that this parameter will be set by the initialisation routine. To 15451 * set a default use {@link DataTable.defaults}. 15452 * @type boolean 15453 */ 15454 "bSortCellsTop": null, 15455 15456 /** 15457 * Initialisation object that is used for the table 15458 * @type object 15459 * @default null 15460 */ 15461 "oInit": null, 15462 15463 /** 15464 * Destroy callback functions - for plug-ins to attach themselves to the 15465 * destroy so they can clean up markup and events. 15466 * @type array 15467 * @default [] 15468 */ 15469 "aoDestroyCallback": [], 15470 15471 15472 /** 15473 * Get the number of records in the current record set, before filtering 15474 * @type function 15475 */ 15476 "fnRecordsTotal": function () 15477 { 15478 return _fnDataSource( this ) == 'ssp' ? 15479 this._iRecordsTotal * 1 : 15480 this.aiDisplayMaster.length; 15481 }, 15482 15483 /** 15484 * Get the number of records in the current record set, after filtering 15485 * @type function 15486 */ 15487 "fnRecordsDisplay": function () 15488 { 15489 return _fnDataSource( this ) == 'ssp' ? 15490 this._iRecordsDisplay * 1 : 15491 this.aiDisplay.length; 15492 }, 15493 15494 /** 15495 * Get the display end point - aiDisplay index 15496 * @type function 15497 */ 15498 "fnDisplayEnd": function () 15499 { 15500 var 15501 len = this._iDisplayLength, 15502 start = this._iDisplayStart, 15503 calc = start + len, 15504 records = this.aiDisplay.length, 15505 features = this.oFeatures, 15506 paginate = features.bPaginate; 15507 15508 if ( features.bServerSide ) { 15509 return paginate === false || len === -1 ? 15510 start + records : 15511 Math.min( start+len, this._iRecordsDisplay ); 15512 } 15513 else { 15514 return ! paginate || calc>records || len===-1 ? 15515 records : 15516 calc; 15517 } 15518 }, 15519 15520 /** 15521 * The DataTables object for this table 15522 * @type object 15523 * @default null 15524 */ 15525 "oInstance": null, 15526 15527 /** 15528 * Unique identifier for each instance of the DataTables object. If there 15529 * is an ID on the table node, then it takes that value, otherwise an 15530 * incrementing internal counter is used. 15531 * @type string 15532 * @default null 15533 */ 15534 "sInstance": null, 15535 15536 /** 15537 * tabindex attribute value that is added to DataTables control elements, allowing 15538 * keyboard navigation of the table and its controls. 15539 */ 15540 "iTabIndex": 0, 15541 15542 /** 15543 * DIV container for the footer scrolling table if scrolling 15544 */ 15545 "nScrollHead": null, 15546 15547 /** 15548 * DIV container for the footer scrolling table if scrolling 15549 */ 15550 "nScrollFoot": null, 15551 15552 /** 15553 * Last applied sort 15554 * @type array 15555 * @default [] 15556 */ 15557 "aLastSort": [], 15558 15559 /** 15560 * Stored plug-in instances 15561 * @type object 15562 * @default {} 15563 */ 15564 "oPlugins": {}, 15565 15566 /** 15567 * Function used to get a row's id from the row's data 15568 * @type function 15569 * @default null 15570 */ 15571 "rowIdFn": null, 15572 15573 /** 15574 * Data location where to store a row's id 15575 * @type string 15576 * @default null 15577 */ 15578 "rowId": null 15579 }; 15580 15581 /** 15582 * Extension object for DataTables that is used to provide all extension 15583 * options. 15584 * 15585 * Note that the `DataTable.ext` object is available through 15586 * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is 15587 * also aliased to `jQuery.fn.dataTableExt` for historic reasons. 15588 * @namespace 15589 * @extends DataTable.models.ext 15590 */ 15591 15592 15593 /** 15594 * DataTables extensions 15595 * 15596 * This namespace acts as a collection area for plug-ins that can be used to 15597 * extend DataTables capabilities. Indeed many of the build in methods 15598 * use this method to provide their own capabilities (sorting methods for 15599 * example). 15600 * 15601 * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy 15602 * reasons 15603 * 15604 * @namespace 15605 */ 15606 DataTable.ext = _ext = { 15607 /** 15608 * Buttons. For use with the Buttons extension for DataTables. This is 15609 * defined here so other extensions can define buttons regardless of load 15610 * order. It is _not_ used by DataTables core. 15611 * 15612 * @type object 15613 * @default {} 15614 */ 15615 buttons: {}, 15616 15617 15618 /** 15619 * Element class names 15620 * 15621 * @type object 15622 * @default {} 15623 */ 15624 classes: {}, 15625 15626 15627 /** 15628 * DataTables build type (expanded by the download builder) 15629 * 15630 * @type string 15631 */ 15632 build:"dt/dt-1.10.18", 15633 15634 15635 /** 15636 * Error reporting. 15637 * 15638 * How should DataTables report an error. Can take the value 'alert', 15639 * 'throw', 'none' or a function. 15640 * 15641 * @type string|function 15642 * @default alert 15643 */ 15644 errMode: "alert", 15645 15646 15647 /**
15648 * Feature plug-ins. 15649 * 15650 * This is an array of objects which describe the feature plug-ins that are 15651 * available to DataTables. These feature plug-ins are then available for 15652 * use through the `dom` initialisation option. 15653 * 15654 * Each feature plug-in is described by an object which must have the 15655 * following properties: 15656 * 15657 * * `fnInit` - function that is used to initialise the plug-in, 15658 * * `cFeature` - a character so the feature can be enabled by the `dom` 15659 * instillation option. This is case sensitive. 15660 * 15661 * The `fnInit` function has the following input parameters: 15662 * 15663 * 1. `{object}` DataTables settings object: see 15664 * {@link DataTable.models.oSettings} 15665 * 15666 * And the following return is expected: 15667 * 15668 * * {node|null} The element which contains your feature. Note that the 15669 * return may also be void if your plug-in does not require to inject any 15670 * DOM elements into DataTables control (`dom`) - for example this might 15671 * be useful when developing a plug-in which allows table control via 15672 * keyboard entry 15673 * 15674 * @type array 15675 * 15676 * @example 15677 * $.fn.dataTable.ext.features.push( { 15678 * "fnInit": function( oSettings ) { 15679 * return new TableTools( { "oDTSettings": oSettings } ); 15680 * }, 15681 * "cFeature": "T" 15682 * } ); 15683 */ 15684 feature: [], 15685 15686 15687 /** 15688 * Row searching. 15689 * 15690 * This method of searching is complimentary to the default type based 15691 * searching, and a lot more comprehensive as it allows you complete control 15692 * over the searching logic. Each element in this array is a function 15693 * (parameters described below) that is called for every row in the table, 15694 * and your logic decides if it should be included in the searching data set 15695 * or not. 15696 * 15697 * Searching functions have the following input parameters: 15698 * 15699 * 1. `{object}` DataTables settings object: see 15700 * {@link DataTable.models.oSettings} 15701 * 2. `{array|object}` Data for the row to be processed (same as the 15702 * original format that was passed in as the data source, or an array 15703 * from a DOM data source 15704 * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which 15705 * can be useful to retrieve the `TR` element if you need DOM interaction. 15706 * 15707 * And the following return is expected: 15708 * 15709 * * {boolean} Include the row in the searched result set (true) or not 15710 * (false) 15711 * 15712 * Note that as with the main search ability in DataTables, technically this 15713 * is "filtering", since it is subtractive. However, for consistency in 15714 * naming we call it searching here. 15715 * 15716 * @type array 15717 * @default [] 15718 * 15719 * @example 15720 * // The following example shows custom search being applied to the 15721 * // fourth column (i.e. the data[3] index) based on two input values 15722 * // from the end-user, matching the data in a certain range. 15723 * $.fn.dataTable.ext.search.push( 15724 * function( settings, data, dataIndex ) { 15725 * var min = document.getElementById('min').value * 1; 15726 * var max = document.getElementById('max').value * 1; 15727 * var version = data[3] == "-" ? 0 : data[3]*1; 15728 * 15729 * if ( min == "" && max == "" ) { 15730 * return true; 15731 * } 15732 * else if ( min == "" && version < max ) { 15733 * return true; 15734 * } 15735 * else if ( min < version && "" == max ) { 15736 * return true; 15737 * } 15738 * else if ( min < version && version < max ) { 15739 * return true; 15740 * } 15741 * return false; 15742 * } 15743 * ); 15744 */ 15745 search: [], 15746 15747 15748 /** 15749 * Selector extensions 15750 * 15751 * The `selector` option can be used to extend the options available for the 15752 * selector modifier options (`selector-modifier` object data type) that 15753 * each of the three built in selector types offer (row, column and cell + 15754 * their plural counterparts). For example the Select extension uses this 15755 * mechanism to provide an option to select only rows, columns and cells 15756 * that have been marked as selected by the end user (`{selected: true}`), 15757 * which can be used in conjunction with the existing built in selector 15758 * options. 15759 * 15760 * Each property is an array to which functions can be pushed. The functions 15761 * take three attributes: 15762 * 15763 * * Settings object for the host table 15764 * * Options object (`selector-modifier` object type) 15765 * * Array of selected item indexes 15766 * 15767 * The return is an array of the resulting item indexes after the custom 15768 * selector has been applied. 15769 * 15770 * @type object 15771 */ 15772 selector: { 15773 cell: [], 15774 column: [], 15775 row: [] 15776 }, 15777 15778 15779 /** 15780 * Internal functions, exposed for used in plug-ins. 15781 * 15782 * Please note that you should not need to use the internal methods for 15783 * anything other than a plug-in (and even then, try to avoid if possible). 15784 * The internal function may change between releases. 15785 * 15786 * @type object 15787 * @default {} 15788 */ 15789 internal: {}, 15790 15791 15792 /** 15793 * Legacy configuration options. Enable and disable legacy options that 15794 * are available in DataTables. 15795 * 15796 * @type object 15797 */ 15798 legacy: { 15799 /** 15800 * Enable / disable DataTables 1.9 compatible server-side processing 15801 * requests 15802 * 15803 * @type boolean 15804 * @default null 15805 */ 15806 ajax: null 15807 }, 15808 15809 15810 /** 15811 * Pagination plug-in methods. 15812 * 15813 * Each entry in this object is a function and defines which buttons should 15814 * be shown by the pagination rendering method that is used for the table: 15815 * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the 15816 * buttons are displayed in the document, while the functions here tell it 15817 * what buttons to display. This is done by returning an array of button 15818 * descriptions (what each button will do). 15819 * 15820 * Pagination types (the four built in options and any additional plug-in 15821 * options defined here) can be used through the `paginationType` 15822 * initialisation parameter. 15823 * 15824 * The functions defined take two parameters: 15825 * 15826 * 1. `{int} page` The current page index 15827 * 2. `{int} pages` The number of pages in the table 15828 * 15829 * Each function is expected to return an array where each element of the 15830 * array can be one of: 15831 * 15832 * * `first` - Jump to first page when activated 15833 * * `last` - Jump to last page when activated 15834 * * `previous` - Show previous page when activated 15835 * * `next` - Show next page when activated 15836 * * `{int}` - Show page of the index given 15837 * * `{array}` - A nested array containing the above elements to add a 15838 * containing 'DIV' element (might be useful for styling). 15839 * 15840 * Note that DataTables v1.9- used this object slightly differently whereby 15841 * an object with two functions would be defined for each plug-in. That 15842 * ability is still supported by DataTables 1.10+ to provide backwards 15843 * compatibility, but this option of use is now decremented and no longer 15844 * documented in DataTables 1.10+. 15845 * 15846 * @type object 15847 * @default {} 15848 * 15849 * @example 15850 * // Show previous, next and current page buttons only 15851 * $.fn.dataTableExt.oPagination.current = function ( page, pages ) { 15852 * return [ 'previous', page, 'next' ]; 15853 * }; 15854 */ 15855 pager: {}, 15856 15857 15858 renderer: { 15859 pageButton: {}, 15860 header: {} 15861 }, 15862 15863 15864 /** 15865 * Ordering plug-ins - custom data source 15866 *
15867 * The extension options for ordering of data available here is complimentary 15868 * to the default type based ordering that DataTables typically uses. It 15869 * allows much greater control over the the data that is being used to 15870 * order a column, but is necessarily therefore more complex. 15871 * 15872 * This type of ordering is useful if you want to do ordering based on data 15873 * live from the DOM (for example the contents of an 'input' element) rather 15874 * than just the static string that DataTables knows of. 15875 * 15876 * The way these plug-ins work is that you create an array of the values you 15877 * wish to be ordering for the column in question and then return that 15878 * array. The data in the array much be in the index order of the rows in 15879 * the table (not the currently ordering order!). Which order data gathering 15880 * function is run here depends on the `dt-init columns.orderDataType` 15881 * parameter that is used for the column (if any). 15882 * 15883 * The functions defined take two parameters: 15884 * 15885 * 1. `{object}` DataTables settings object: see 15886 * {@link DataTable.models.oSettings} 15887 * 2. `{int}` Target column index 15888 * 15889 * Each function is expected to return an array: 15890 * 15891 * * `{array}` Data for the column to be ordering upon 15892 * 15893 * @type array 15894 * 15895 * @example 15896 * // Ordering using `input` node values 15897 * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col ) 15898 * { 15899 * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { 15900 * return $('input', td).val(); 15901 * } ); 15902 * } 15903 */ 15904 order: {}, 15905 15906 15907 /** 15908 * Type based plug-ins. 15909 * 15910 * Each column in DataTables has a type assigned to it, either by automatic 15911 * detection or by direct assignment using the `type` option for the column. 15912 * The type of a column will effect how it is ordering and search (plug-ins 15913 * can also make use of the column type if required). 15914 * 15915 * @namespace 15916 */ 15917 type: { 15918 /** 15919 * Type detection functions. 15920 * 15921 * The functions defined in this object are used to automatically detect 15922 * a column's type, making initialisation of DataTables super easy, even 15923 * when complex data is in the table. 15924 * 15925 * The functions defined take two parameters: 15926 * 15927 * 1. `{*}` Data from the column cell to be analysed 15928 * 2. `{settings}` DataTables settings object. This can be used to 15929 * perform context specific type detection - for example detection 15930 * based on language settings such as using a comma for a decimal 15931 * place. Generally speaking the options from the settings will not 15932 * be required 15933 * 15934 * Each function is expected to return: 15935 * 15936 * * `{string|null}` Data type detected, or null if unknown (and thus 15937 * pass it on to the other type detection functions. 15938 * 15939 * @type array 15940 * 15941 * @example 15942 * // Currency type detection plug-in: 15943 * $.fn.dataTable.ext.type.detect.push( 15944 * function ( data, settings ) { 15945 * // Check the numeric part 15946 * if ( ! data.substring(1).match(/[0-9]/) ) { 15947 * return null; 15948 * } 15949 * 15950 * // Check prefixed by currency 15951 * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) { 15952 * return 'currency'; 15953 * } 15954 * return null; 15955 * } 15956 * ); 15957 */ 15958 detect: [], 15959 15960 15961 /** 15962 * Type based search formatting. 15963 * 15964 * The type based searching functions can be used to pre-format the 15965 * data to be search on. For example, it can be used to strip HTML 15966 * tags or to de-format telephone numbers for numeric only searching. 15967 * 15968 * Note that is a search is not defined for a column of a given type, 15969 * no search formatting will be performed. 15970 * 15971 * Pre-processing of searching data plug-ins - When you assign the sType 15972 * for a column (or have it automatically detected for you by DataTables 15973 * or a type detection plug-in), you will typically be using this for 15974 * custom sorting, but it can also be used to provide custom searching 15975 * by allowing you to pre-processing the data and returning the data in 15976 * the format that should be searched upon. This is done by adding 15977 * functions this object with a parameter name which matches the sType 15978 * for that target column. This is the corollary of <i>afnSortData</i> 15979 * for searching data. 15980 * 15981 * The functions defined take a single parameter: 15982 * 15983 * 1. `{*}` Data from the column cell to be prepared for searching 15984 *
15985 * Each function is expected to return: 15986 * 15987 * * `{string|null}` Formatted string that will be used for the searching. 15988 * 15989 * @type object 15990 * @default {} 15991 * 15992 * @example 15993 * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) { 15994 * return d.replace(/\n/g," ").replace( /<.*?>/g, "" ); 15995 * } 15996 */ 15997 search: {}, 15998 15999 16000 /** 16001 * Type based ordering. 16002 * 16003 * The column type tells DataTables what ordering to apply to the table 16004 * when a column is sorted upon. The order for each type that is defined, 16005 * is defined by the functions available in this object. 16006 * 16007 * Each ordering option can be described by three properties added to 16008 * this object: 16009 * 16010 * * `{type}-pre` - Pre-formatting function 16011 * * `{type}-asc` - Ascending order function 16012 * * `{type}-desc` - Descending order function 16013 * 16014 * All three can be used together, only `{type}-pre` or only 16015 * `{type}-asc` and `{type}-desc` together. It is generally recommended 16016 * that only `{type}-pre` is used, as this provides the optimal 16017 * implementation in terms of speed, although the others are provided 16018 * for compatibility with existing Javascript sort functions. 16019 * 16020 * `{type}-pre`: Functions defined take a single parameter: 16021 * 16022 * 1. `{*}` Data from the column cell to be prepared for ordering 16023 * 16024 * And return: 16025 * 16026 * * `{*}` Data to be sorted upon 16027 * 16028 * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort 16029 * functions, taking two parameters: 16030 * 16031 * 1. `{*}` Data to compare to the second parameter 16032 * 2. `{*}` Data to compare to the first parameter 16033 * 16034 * And returning: 16035 * 16036 * * `{*}` Ordering match: <0 if first parameter should be sorted lower 16037 * than the second parameter, ===0 if the two parameters are equal and 16038 * >0 if the first parameter should be sorted height than the second 16039 * parameter. 16040 * 16041 * @type object 16042 * @default {} 16043 * 16044 * @example 16045 * // Numeric ordering of formatted numbers with a pre-formatter 16046 * $.extend( $.fn.dataTable.ext.type.order, { 16047 * "string-pre": function(x) { 16048 * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" ); 16049 * return parseFloat( a ); 16050 * } 16051 * } ); 16052 * 16053 * @example 16054 * // Case-sensitive string ordering, with no pre-formatting method 16055 * $.extend( $.fn.dataTable.ext.order, { 16056 * "string-case-asc": function(x,y) { 16057 * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 16058 * }, 16059 * "string-case-desc": function(x,y) { 16060 * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 16061 * } 16062 * } ); 16063 */ 16064 order: {} 16065 }, 16066 16067 /** 16068 * Unique DataTables instance counter 16069 * 16070 * @type int 16071 * @private 16072 */ 16073 _unique: 0, 16074 16075 16076 // 16077 // Depreciated 16078 // The following properties are retained for backwards compatiblity only. 16079 // The should not be used in new projects and will be removed in a future 16080 // version 16081 // 16082 16083 /** 16084 * Version check function. 16085 * @type function 16086 * @depreciated Since 1.10 16087 */ 16088 fnVersionCheck: DataTable.fnVersionCheck, 16089 16090 16091 /** 16092 * Index for what 'this' index API functions should use 16093 * @type int 16094 * @deprecated Since v1.10 16095 */ 16096 iApiIndex: 0, 16097 16098 16099 /** 16100 * jQuery UI class container 16101 * @type object 16102 * @deprecated Since v1.10 16103 */ 16104 oJUIClasses: {}, 16105 16106 16107 /** 16108 * Software version 16109 * @type string 16110 * @deprecated Since v1.10 16111 */ 16112 sVersion: DataTable.version 16113 }; 16114 16115 16116 // 16117 // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts 16118 // 16119 $.extend( _ext, { 16120 afnFiltering: _ext.search, 16121 aTypes: _ext.type.detect, 16122 ofnSearch: _ext.type.search, 16123 oSort: _ext.type.order, 16124 afnSortData: _ext.order, 16125 aoFeatures: _ext.feature, 16126 oApi: _ext.internal, 16127 oStdClasses: _ext.classes, 16128 oPagination: _ext.pager 16129 } ); 16130 16131 16132 $.extend( DataTable.ext.classes, { 16133 "sTable": "dataTable", 16134 "sNoFooter": "no-footer", 16135 16136 /* Paging buttons */ 16137 "sPageButton": "paginate_button", 16138 "sPageButtonActive": "current", 16139 "sPageButtonDisabled": "disabled", 16140 16141 /* Striping classes */ 16142 "sStripeOdd": "odd", 16143 "sStripeEven": "even", 16144 16145 /* Empty row */ 16146 "sRowEmpty": "dataTables_empty", 16147 16148 /* Features */ 16149 "sWrapper": "dataTables_wrapper", 16150 "sFilter": "dataTables_filter", 16151 "sInfo": "dataTables_info", 16152 "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */ 16153 "sLength": "dataTables_length", 16154 "sProcessing": "dataTables_processing", 16155 16156 /* Sorting */ 16157 "sSortAsc": "sorting_asc", 16158 "sSortDesc": "sorting_desc", 16159 "sSortable": "sorting", /* Sortable in both directions */ 16160 "sSortableAsc": "sorting_asc_disabled", 16161 "sSortableDesc": "sorting_desc_disabled", 16162 "sSortableNone": "sorting_disabled", 16163 "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ 16164 16165 /* Filtering */ 16166 "sFilterInput": "", 16167 16168 /* Page length */ 16169 "sLengthSelect": "", 16170 16171 /* Scrolling */ 16172 "sScrollWrapper": "dataTables_scroll", 16173 "sScrollHead": "dataTables_scrollHead", 16174 "sScrollHeadInner": "dataTables_scrollHeadInner", 16175 "sScrollBody": "dataTables_scrollBody", 16176 "sScrollFoot": "dataTables_scrollFoot", 16177 "sScrollFootInner": "dataTables_scrollFootInner", 16178 16179 /* Misc */ 16180 "sHeaderTH": "", 16181 "sFooterTH": "", 16182 16183 // Deprecated 16184 "sSortJUIAsc": "", 16185 "sSortJUIDesc": "", 16186 "sSortJUI": "", 16187 "sSortJUIAscAllowed": "", 16188 "sSortJUIDescAllowed": "", 16189 "sSortJUIWrapper": "", 16190 "sSortIcon": "", 16191 "sJUIHeader": "", 16192 "sJUIFooter": "" 16193 } ); 16194 16195 16196 var extPagination = DataTable.ext.pager; 16197 16198 function _numbers ( page, pages ) { 16199 var 16200 numbers = [], 16201 buttons = extPagination.numbers_length, 16202 half = Math.floor( buttons / 2 ), 16203 i = 1; 16204 16205 if ( pages <= buttons ) { 16206 numbers = _range( 0, pages ); 16207 } 16208 else if ( page <= half ) { 16209 numbers = _range( 0, buttons-2 ); 16210 numbers.push( 'ellipsis' ); 16211 numbers.push( pages-1 ); 16212 } 16213 else if ( page >= pages - 1 - half ) { 16214 numbers = _range( pages-(buttons-2), pages ); 16215 numbers.splice( 0, 0, 'ellipsis' );
16215 // no unshift in ie6 16216 numbers.splice( 0, 0, 0 ); 16217 } 16218 else { 16219 numbers = _range( page-half+2, page+half-1 ); 16220 numbers.push( 'ellipsis' ); 16221 numbers.push( pages-1 ); 16222 numbers.splice( 0, 0, 'ellipsis' ); 16223 numbers.splice( 0, 0, 0 ); 16224 } 16225 16226 numbers.DT_el = 'span'; 16227 return numbers; 16228 } 16229 16230 16231 $.extend( extPagination, { 16232 simple: function ( page, pages ) { 16233 return [ 'previous', 'next' ]; 16234 }, 16235 16236 full: function ( page, pages ) { 16237 return [ 'first', 'previous', 'next', 'last' ]; 16238 }, 16239 16240 numbers: function ( page, pages ) { 16241 return [ _numbers(page, pages) ]; 16242 }, 16243 16244 simple_numbers: function ( page, pages ) { 16245 return [ 'previous', _numbers(page, pages), 'next' ]; 16246 }, 16247 16248 full_numbers: function ( page, pages ) { 16249 return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ]; 16250 }, 16251 16252 first_last_numbers: function (page, pages) { 16253 return ['first', _numbers(page, pages), 'last']; 16254 }, 16255 16256 // For testing and plug-ins to use 16257 _numbers: _numbers, 16258 16259 // Number of number buttons (including ellipsis) to show. _Must be odd!_ 16260 numbers_length: 7 16261 } ); 16262 16263 16264 $.extend( true, DataTable.ext.renderer, { 16265 pageButton: { 16266 _: function ( settings, host, idx, buttons, page, pages ) { 16267 var classes = settings.oClasses; 16268 var lang = settings.oLanguage.oPaginate; 16269 var aria = settings.oLanguage.oAria.paginate || {}; 16270 var btnDisplay, btnClass, counter=0; 16271 16272 var attach = function( container, buttons ) { 16273 var i, ien, node, button; 16274 var clickHandler = function ( e ) { 16275 _fnPageChange( settings, e.data.action, true ); 16276 }; 16277 16278 for ( i=0, ien=buttons.length ; i<ien ; i++ ) { 16279 button = buttons[i]; 16280 16281 if ( $.isArray( button ) ) { 16282 var inner = $( '<'+(button.DT_el || 'div')+'/>' ) 16283 .appendTo( container ); 16284 attach( inner, button ); 16285 } 16286 else { 16287 btnDisplay = null; 16288 btnClass = ''; 16289 16290 switch ( button ) { 16291 case 'ellipsis': 16292 container.append('<span class="ellipsis">…</span>'); 16293 break; 16294 16295 case 'first': 16296 btnDisplay = lang.sFirst; 16297 btnClass = button + (page > 0 ? 16298 '' : ' '+classes.sPageButtonDisabled); 16299 break; 16300 16301 case 'previous': 16302 btnDisplay = lang.sPrevious; 16303 btnClass = button + (page > 0 ? 16304 '' : ' '+classes.sPageButtonDisabled); 16305 break; 16306 16307 case 'next': 16308 btnDisplay = lang.sNext; 16309 btnClass = button + (page < pages-1 ? 16310 '' : ' '+classes.sPageButtonDisabled); 16311 break; 16312 16313 case 'last': 16314 btnDisplay = lang.sLast; 16315 btnClass = button + (page < pages-1 ? 16316 '' : ' '+classes.sPageButtonDisabled); 16317 break; 16318 16319 default: 16320 btnDisplay = button + 1; 16321 btnClass = page === button ? 16322 classes.sPageButtonActive : ''; 16323 break; 16324 } 16325 16326 if ( btnDisplay !== null ) { 16327 node = $('<a>', { 16328 'class': classes.sPageButton+' '+btnClass, 16329 'aria-controls': settings.sTableId, 16330 'aria-label': aria[ button ], 16331 'data-dt-idx': counter, 16332 'tabindex': settings.iTabIndex, 16333 'id': idx === 0 && typeof button === 'string' ? 16334 settings.sTableId +'_'+ button : 16335 null 16336 } ) 16337 .html( btnDisplay ) 16338 .appendTo( container ); 16339 16340 _fnBindAction( 16341 node, {action: button}, clickHandler 16342 ); 16343 16344 counter++; 16345 } 16346 } 16347 } 16348 }; 16349 16350 // IE9 throws an 'unknown error' if document.activeElement is used 16351 // inside an iframe or frame. Try / catch the error. Not good for 16352 // accessibility, but neither are frames. 16353 var activeEl; 16354 16355 try { 16356 // Because this approach is destroying and recreating the paging 16357 // elements, focus is lost on the select button which is bad for 16358 // accessibility. So we want to restore focus once the draw has 16359 // completed 16360 activeEl = $(host).find(document.activeElement).data('dt-idx'); 16361 } 16362 catch (e) {} 16363 16364 attach( $(host).empty(), buttons ); 16365 16366 if ( activeEl !== undefined ) { 16367 $(host).find( '[data-dt-idx='+activeEl+']' ).focus(); 16368 } 16369 } 16370 } 16371 } ); 16372 16373 16374 16375 // Built in type detection. See model.ext.aTypes for information about 16376 // what is required from this methods. 16377 $.extend( DataTable.ext.type.detect, [
16378 // Plain numbers - first since V8 detects some plain numbers as dates 16379 // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...). 16380 function ( d, settings ) 16381 { 16382 var decimal = settings.oLanguage.sDecimal; 16383 return _isNumber( d, decimal ) ? 'num'+decimal : null; 16384 }, 16385 16386 // Dates (only those recognised by the browser's Date.parse) 16387 function ( d, settings ) 16388 { 16389 // V8 tries _very_ hard to make a string passed into `Date.parse()` 16390 // valid, so we need to use a regex to restrict date formats. Use a 16391 // plug-in for anything other than ISO8601 style strings 16392 if ( d && !(d instanceof Date) && ! _re_date.test(d) ) { 16393 return null; 16394 } 16395 var parsed = Date.parse(d); 16396 return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null; 16397 }, 16398 16399 // Formatted numbers 16400 function ( d, settings ) 16401 { 16402 var decimal = settings.oLanguage.sDecimal; 16403 return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null; 16404 }, 16405 16406 // HTML numeric 16407 function ( d, settings ) 16408 { 16409 var decimal = settings.oLanguage.sDecimal; 16410 return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null; 16411 }, 16412 16413 // HTML numeric, formatted 16414 function ( d, settings ) 16415 { 16416 var decimal = settings.oLanguage.sDecimal; 16417 return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null; 16418 }, 16419 16420 // HTML (this is strict checking - there must be html) 16421 function ( d, settings ) 16422 { 16423 return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ? 16424 'html' : null; 16425 } 16426 ] ); 16427 16428 16429 16430 // Filter formatting functions. See model.ext.ofnSearch for information about 16431 // what is required from these methods. 16432 // 16433 // Note that additional search methods are added for the html numbers and 16434 // html formatted numbers by `_addNumericSort()` when we know what the decimal 16435 // place is 16436 16437 16438 $.extend( DataTable.ext.type.search, { 16439 html: function ( data ) { 16440 return _empty(data) ? 16441 data : 16442 typeof data === 'string' ? 16443 data 16444 .replace( _re_new_lines, " " ) 16445 .replace( _re_html, "" ) : 16446 ''; 16447 }, 16448 16449 string: function ( data ) { 16450 return _empty(data) ? 16451 data : 16452 typeof data === 'string' ? 16453 data.replace( _re_new_lines, " " ) : 16454 data; 16455 } 16456 } ); 16457 16458 16459 16460 var __numericReplace = function ( d, decimalPlace, re1, re2 ) { 16461 if ( d !== 0 && (!d || d === '-') ) { 16462 return -Infinity; 16463 } 16464 16465 // If a decimal place other than `.` is used, it needs to be given to the 16466 // function so we can detect it and replace with a `.` which is the only 16467 // decimal place Javascript recognises - it is not locale aware. 16468 if ( decimalPlace ) { 16469 d = _numToDecimal( d, decimalPlace ); 16470 } 16471 16472 if ( d.replace ) { 16473 if ( re1 ) { 16474 d = d.replace( re1, '' ); 16475 } 16476 16477 if ( re2 ) { 16478 d = d.replace( re2, '' ); 16479 } 16480 } 16481 16482 return d * 1; 16483 }; 16484 16485 16486 // Add the numeric 'deformatting' functions for sorting and search. This is done 16487 // in a function to provide an easy ability for the language options to add 16488 // additional methods if a non-period decimal place is used. 16489 function _addNumericSort ( decimalPlace ) { 16490 $.each( 16491 { 16492 // Plain numbers 16493 "num": function ( d ) { 16494 return __numericReplace( d, decimalPlace ); 16495 }, 16496 16497 // Formatted numbers 16498 "num-fmt": function ( d ) { 16499 return __numericReplace( d, decimalPlace, _re_formatted_numeric ); 16500 }, 16501 16502 // HTML numeric 16503 "html-num": function ( d ) { 16504 return __numericReplace( d, decimalPlace, _re_html ); 16505 }, 16506 16507 // HTML numeric, formatted 16508 "html-num-fmt": function ( d ) { 16509 return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric ); 16510 } 16511 }, 16512 function ( key, fn ) { 16513 // Add the ordering method 16514 _ext.type.order[ key+decimalPlace+'-pre' ] = fn; 16515 16516 // For HTML types add a search formatter that will strip the HTML 16517 if ( key.match(/^html\-/) ) { 16518 _ext.type.search[ key+decimalPlace ] = _ext.type.search.html; 16519 } 16520 } 16521 ); 16522 } 16523 16524 16525 // Default sort methods 16526 $.extend( _ext.type.order, { 16527 // Dates 16528 "date-pre": function ( d ) { 16529 var ts = Date.parse( d ); 16530 return isNaN(ts) ? -Infinity : ts; 16531 }, 16532 16533 // html 16534 "html-pre": function ( a ) { 16535 return _empty(a) ? 16536 '' : 16537 a.replace ? 16538 a.replace( /<.*?>/g, "" ).toLowerCase() : 16539 a+''; 16540 }, 16541 16542 // string 16543 "string-pre": function ( a ) { 16544 // This is a little complex, but faster than always calling toString, 16545 // http://jsperf.com/tostring-v-check 16546 return _empty(a) ? 16547 '' : 16548 typeof a === 'string' ? 16549 a.toLowerCase() : 16550 ! a.toString ? 16551 '' : 16552 a.toString(); 16553 }, 16554 16555 // string-asc and -desc are retained only for compatibility with the old 16556 // sort methods 16557 "string-asc": function ( x, y ) { 16558 return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 16559 }, 16560 16561 "string-desc": function ( x, y ) { 16562 return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 16563 } 16564 } ); 16565 16566 16567 // Numeric sorting types - order doesn't matter here 16568 _addNumericSort( '' ); 16569 16570 16571 $.extend( true, DataTable.ext.renderer, { 16572 header: { 16573 _: function ( settings, cell, column, classes ) { 16574 // No additional mark-up required
16575 // Attach a sort listener to update on sort - note that using the 16576 // `DT` namespace will allow the event to be removed automatically 16577 // on destroy, while the `dt` namespaced event is the one we are 16578 // listening for 16579 $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) { 16580 if ( settings !== ctx ) { // need to check this this is the host 16581 return; // table, not a nested one 16582 } 16583 16584 var colIdx = column.idx; 16585 16586 cell 16587 .removeClass( 16588 column.sSortingClass +' '+ 16589 classes.sSortAsc +' '+ 16590 classes.sSortDesc 16591 ) 16592 .addClass( columns[ colIdx ] == 'asc' ? 16593 classes.sSortAsc : columns[ colIdx ] == 'desc' ? 16594 classes.sSortDesc : 16595 column.sSortingClass 16596 ); 16597 } ); 16598 }, 16599 16600 jqueryui: function ( settings, cell, column, classes ) { 16601 $('<div/>') 16602 .addClass( classes.sSortJUIWrapper ) 16603 .append( cell.contents() ) 16604 .append( $('<span/>') 16605 .addClass( classes.sSortIcon+' '+column.sSortingClassJUI ) 16606 ) 16607 .appendTo( cell ); 16608 16609 // Attach a sort listener to update on sort 16610 $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) { 16611 if ( settings !== ctx ) { 16612 return; 16613 } 16614 16615 var colIdx = column.idx; 16616 16617 cell 16618 .removeClass( classes.sSortAsc +" "+classes.sSortDesc ) 16619 .addClass( columns[ colIdx ] == 'asc' ? 16620 classes.sSortAsc : columns[ colIdx ] == 'desc' ? 16621 classes.sSortDesc : 16622 column.sSortingClass 16623 ); 16624 16625 cell 16626 .find( 'span.'+classes.sSortIcon ) 16627 .removeClass( 16628 classes.sSortJUIAsc +" "+ 16629 classes.sSortJUIDesc +" "+ 16630 classes.sSortJUI +" "+ 16631 classes.sSortJUIAscAllowed +" "+ 16632 classes.sSortJUIDescAllowed 16633 ) 16634 .addClass( columns[ colIdx ] == 'asc' ? 16635 classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ? 16636 classes.sSortJUIDesc : 16637 column.sSortingClassJUI 16638 ); 16639 } ); 16640 } 16641 } 16642 } ); 16643 16644 /* 16645 * Public helper functions. These aren't used internally by DataTables, or 16646 * called by any of the options passed into DataTables, but they can be used 16647 * externally by developers working with DataTables. They are helper functions 16648 * to make working with DataTables a little bit easier. 16649 */ 16650 16651 var __htmlEscapeEntities = function ( d ) { 16652 return typeof d === 'string' ? 16653 d.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"') : 16654 d; 16655 }; 16656 16657 /** 16658 * Helpers for `columns.render`. 16659 * 16660 * The options defined here can be used with the `columns.render` initialisation 16661 * option to provide a display renderer. The following functions are defined: 16662 * 16663 * * `number` - Will format numeric data (defined by `columns.data`) for 16664 * display, retaining the original unformatted data for sorting and filtering. 16665 * It takes 5 parameters: 16666 * * `string` - Thousands grouping separator 16667 * * `string` - Decimal point indicator 16668 * * `integer` - Number of decimal points to show 16669 * * `string` (optional) - Prefix. 16670 * * `string` (optional) - Postfix (/suffix). 16671 * * `text` - Escape HTML to help prevent XSS attacks. It has no optional 16672 * parameters. 16673 * 16674 * @example 16675 * // Column definition using the number renderer 16676 * { 16677 * data: "salary", 16678 * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' ) 16679 * } 16680 * 16681 * @namespace 16682 */ 16683 DataTable.render = { 16684 number: function ( thousands, decimal, precision, prefix, postfix ) { 16685 return { 16686 display: function ( d ) { 16687 if ( typeof d !== 'number' && typeof d !== 'string' ) { 16688 return d; 16689 } 16690 16691 var negative = d < 0 ? '-' : ''; 16692 var flo = parseFloat( d ); 16693 16694 // If NaN then there isn't much formatting that we can do - just 16695 // return immediately, escaping any HTML (this was supposed to 16696 // be a number after all) 16697 if ( isNaN( flo ) ) { 16698 return __htmlEscapeEntities( d ); 16699 } 16700 16701 flo = flo.toFixed( precision ); 16702 d = Math.abs( flo ); 16703 16704 var intPart = parseInt( d, 10 ); 16705 var floatPart = precision ? 16706 decimal+(d - intPart).toFixed( precision ).substring( 2 ): 16707 ''; 16708 16709 return negative + (prefix||'') + 16710 intPart.toString().replace( 16711 /\B(?=(\d{3})+(?!\d))/g, thousands 16712 ) + 16713 floatPart + 16714 (postfix||''); 16715 } 16716 }; 16717 }, 16718 16719 text: function () { 16720 return { 16721 display: __htmlEscapeEntities 16722 }; 16723 } 16724 }; 16725 16726 16727 /* 16728 * This is really a good bit rubbish this method of exposing the internal methods 16729 * publicly... - To be fixed in 2.0 using methods on the prototype 16730 */ 16731 16732 16733 /** 16734 * Create a wrapper function for exporting an internal functions to an external API. 16735 * @param {string} fn API function name 16736 * @returns {function} wrapped function 16737 * @memberof DataTable#internal 16738 */ 16739 function _fnExternApiFunc (fn) 16740 { 16741 return function() { 16742 var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat( 16743 Array.prototype.slice.call(arguments) 16744 ); 16745 return DataTable.ext.internal[fn].apply( this, args ); 16746 }; 16747 } 16748 16749 16750 /** 16751 * Reference to internal functions for use by plug-in developers. Note that 16752 * these methods are references to internal functions and are considered to be 16753 * private. If you use these methods, be aware that they are liable to change 16754 * between versions. 16755 * @namespace 16756 */ 16757 $.extend( DataTable.ext.internal, { 16758 _fnExternApiFunc: _fnExternApiFunc, 16759 _fnBuildAjax: _fnBuildAjax, 16760 _fnAjaxUpdate: _fnAjaxUpdate, 16761 _fnAjaxParameters: _fnAjaxParameters, 16762 _fnAjaxUpdateDraw: _fnAjaxUpdateDraw, 16763 _fnAjaxDataSrc: _fnAjaxDataSrc, 16764 _fnAddColumn: _fnAddColumn, 16765 _fnColumnOptions: _fnColumnOptions, 16766 _fnAdjustColumnSizing: _fnAdjustColumnSizing, 16767 _fnVisibleToColumnIndex: _fnVisibleToColumnIndex, 16768 _fnColumnIndexToVisible: _fnColumnIndexToVisible, 16769 _fnVisbleColumns: _fnVisbleColumns, 16770 _fnGetColumns: _fnGetColumns, 16771 _fnColumnTypes: _fnColumnTypes, 16772 _fnApplyColumnDefs: _fnApplyColumnDefs, 16773 _fnHungarianMap: _fnHungarianMap, 16774 _fnCamelToHungarian: _fnCamelToHungarian, 16775 _fnLanguageCompat: _fnLanguageCompat, 16776 _fnBrowserDetect: _fnBrowserDetect, 16777 _fnAddData: _fnAddData, 16778 _fnAddTr: _fnAddTr, 16779 _fnNodeToDataIndex: _fnNodeToDataIndex, 16780 _fnNodeToColumnIndex: _fnNodeToColumnIndex, 16781 _fnGetCellData: _fnGetCellData, 16782 _fnSetCellData: _fnSetCellData, 16783 _fnSplitObjNotation: _fnSplitObjNotation, 16784 _fnGetObjectDataFn: _fnGetObjectDataFn, 16785 _fnSetObjectDataFn: _fnSetObjectDataFn, 16786 _fnGetDataMaster: _fnGetDataMaster, 16787 _fnClearTable: _fnClearTable, 16788 _fnDeleteIndex: _fnDeleteIndex, 16789 _fnInvalidate: _fnInvalidate, 16790 _fnGetRowElements: _fnGetRowElements, 16791 _fnCreateTr: _fnCreateTr, 16792 _fnBuildHead: _fnBuildHead, 16793 _fnDrawHead: _fnDrawHead, 16794 _fnDraw: _fnDraw, 16795 _fnReDraw: _fnReDraw, 16796 _fnAddOptionsHtml: _fnAddOptionsHtml, 16797 _fnDetectHeader: _fnDetectHeader, 16798 _fnGetUniqueThs: _fnGetUniqueThs, 16799 _fnFeatureHtmlFilter: _fnFeatureHtmlFilter, 16800 _fnFilterComplete: _fnFilterComplete, 16801 _fnFilterCustom: _fnFilterCustom, 16802 _fnFilterColumn: _fnFilterColumn, 16803 _fnFilter: _fnFilter, 16804 _fnFilterCreateSearch: _fnFilterCreateSearch, 16805 _fnEscapeRegex: _fnEscapeRegex, 16806 _fnFilterData: _fnFilterData, 16807 _fnFeatureHtmlInfo: _fnFeatureHtmlInfo, 16808 _fnUpdateInfo: _fnUpdateInfo, 16809 _fnInfoMacros: _fnInfoMacros, 16810 _fnInitialise: _fnInitialise, 16811 _fnInitComplete: _fnInitComplete, 16812 _fnLengthChange: _fnLengthChange, 16813 _fnFeatureHtmlLength: _fnFeatureHtmlLength, 16814 _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate, 16815 _fnPageChange: _fnPageChange, 16816 _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing, 16817 _fnProcessingDisplay: _fnProcessingDisplay, 16818 _fnFeatureHtmlTable: _fnFeatureHtmlTable, 16819 _fnScrollDraw: _fnScrollDraw, 16820 _fnApplyToChildren: _fnApplyToChildren, 16821 _fnCalculateColumnWidths: _fnCalculateColumnWidths, 16822 _fnThrottle: _fnThrottle, 16823 _fnConvertToWidth: _fnConvertToWidth, 16824 _fnGetWidestNode: _fnGetWidestNode, 16825 _fnGetMaxLenString: _fnGetMaxLenString, 16826 _fnStringToCss: _fnStringToCss, 16827 _fnSortFlatten: _fnSortFlatten, 16828 _fnSort: _fnSort, 16829 _fnSortAria: _fnSortAria, 16830 _fnSortListener: _fnSortListener, 16831 _fnSortAttachListener: _fnSortAttachListener, 16832 _fnSortingClasses: _fnSortingClasses, 16833 _fnSortData: _fnSortData, 16834 _fnSaveState: _fnSaveState, 16835 _fnLoadState: _fnLoadState, 16836 _fnSettingsFromNode: _fnSettingsFromNode, 16837 _fnLog: _fnLog, 16838 _fnMap: _fnMap, 16839 _fnBindAction: _fnBindAction, 16840 _fnCallbackReg: _fnCallbackReg, 16841 _fnCallbackFire: _fnCallbackFire, 16842 _fnLengthOverflow: _fnLengthOverflow, 16843 _fnRenderer: _fnRenderer, 16844 _fnDataSource: _fnDataSource, 16845 _fnRowAttributes: _fnRowAttributes, 16846 _fnExtend: _fnExtend, 16847 _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant 16848 // in 1.10, so this dead-end function is 16849 // added to prevent errors 16850 } ); 16851 16852 16853 // jQuery access 16854 $.fn.dataTable = DataTable; 16855 16856 // Provide access to the host jQuery object (circular reference) 16857 DataTable.$ = $; 16858 16859 // Legacy aliases 16860 $.fn.dataTableSettings = DataTable.settings; 16861 $.fn.dataTableExt = DataTable.ext; 16862 16863 // With a capital `D` we return a DataTables API instance rather than a 16864 // jQuery object 16865 $.fn.DataTable = function ( opts ) { 16866 return $(this).dataTable( opts ).api(); 16867 }; 16868 16869 // All properties that are available to $.fn.dataTable should also be 16870 // available on $.fn.DataTable 16871 $.each( DataTable, function ( prop, val ) { 16872 $.fn.DataTable[ prop ] = val; 16873 } ); 16874 16875 16876 // Information about events fired by DataTables - for documentation. 16877 /** 16878 * Draw event, fired whenever the table is redrawn on the page, at the same 16879 * point as fnDrawCallback. This may be useful for binding events or 16880 * performing calculations when the table is altered at all. 16881 * @name DataTable#draw.dt 16882 * @event 16883 * @param {event} e jQuery event object 16884 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 16885 */ 16886 16887 /** 16888 * Search event, fired when the searching applied to the table (using the 16889 * built-in global search, or column filters) is altered. 16890 * @name DataTable#search.dt 16891 * @event 16892 * @param {event} e jQuery event object 16893 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 16894 */ 16895 16896 /** 16897 * Page change event, fired when the paging of the table is altered. 16898 * @name DataTable#page.dt 16899 * @event 16900 * @param {event} e jQuery event object 16901 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 16902 */ 16903 16904 /** 16905 * Order event, fired when the ordering applied to the table is altered. 16906 * @name DataTable#order.dt 16907 * @event 16908 * @param {event} e jQuery event object 16909 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 16910 */ 16911 16912 /** 16913 * DataTables initialisation complete event, fired when the table is fully 16914 * drawn, including Ajax data loaded, if Ajax data is required. 16915 * @name DataTable#init.dt 16916 * @event 16917 * @param {event} e jQuery event object 16918 * @param {object} oSettings DataTables settings object 16919 * @param {object} json The JSON object request from the server - only 16920 * present if client-side Ajax sourced data is used</li></ol> 16921 */ 16922 16923 /** 16924 * State save event, fired when the table has changed state a new state save 16925 * is required. This event allows modification of the state saving object 16926 * prior to actually doing the save, including addition or other state 16927 * properties (for plug-ins) or modification of a DataTables core property. 16928 * @name DataTable#stateSaveParams.dt 16929 * @event 16930 * @param {event} e jQuery event object 16931 * @param {object} oSettings DataTables settings object 16932 * @param {object} json The state information to be saved 16933 */ 16934 16935 /** 16936 * State load event, fired when the table is loading state from the stored 16937 * data, but prior to the settings object being modified by the saved state 16938 * - allowing modification of the saved state is required or loading of 16939 * state for a plug-in. 16940 * @name DataTable#stateLoadParams.dt 16941 * @event 16942 * @param {event} e jQuery event object 16943 * @param {object} oSettings DataTables settings object 16944 * @param {object} json The saved state information 16945 */ 16946 16947 /** 16948 * State loaded event, fired when state has been loaded from stored data and 16949 * the settings object has been modified by the loaded data. 16950 * @name DataTable#stateLoaded.dt 16951 * @event 16952 * @param {event} e jQuery event object 16953 * @param {object} oSettings DataTables settings object 16954 * @param {object} json The saved state information 16955 */ 16956 16957 /** 16958 * Processing event, fired when DataTables is doing some kind of processing 16959 * (be it, order, searcg or anything else). It can be used to indicate to 16960 * the end user that there is something happening, or that something has 16961 * finished. 16962 * @name DataTable#processing.dt 16963 * @event 16964 * @param {event} e jQuery event object 16965 * @param {object} oSettings DataTables settings object 16966 * @param {boolean} bShow Flag for if DataTables is doing processing or not 16967 */ 16968 16969 /** 16970 * Ajax (XHR) event, fired whenever an Ajax request is completed from a 16971 * request to made to the server for new data. This event is called before 16972 * DataTables processed the returned data, so it can also be used to pre- 16973 * process the data returned from the server, if needed. 16974 *
16975 * Note that this trigger is called in `fnServerData`, if you override 16976 * `fnServerData` and which to use this event, you need to trigger it in you 16977 * success function. 16978 * @name DataTable#xhr.dt 16979 * @event 16980 * @param {event} e jQuery event object 16981 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 16982 * @param {object} json JSON returned from the server 16983 * 16984 * @example 16985 * // Use a custom property returned from the server in another DOM element 16986 * $('#table').dataTable().on('xhr.dt', function (e, settings, json) { 16987 * $('#status').html( json.status ); 16988 * } ); 16989 * 16990 * @example 16991 * // Pre-process the data returned from the server 16992 * $('#table').dataTable().on('xhr.dt', function (e, settings, json) { 16993 * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) { 16994 * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two; 16995 * } 16996 * // Note no return - manipulate the data directly in the JSON object. 16997 * } ); 16998 */ 16999 17000 /** 17001 * Destroy event, fired when the DataTable is destroyed by calling fnDestroy 17002 * or passing the bDestroy:true parameter in the initialisation object. This 17003 * can be used to remove bound events, added DOM nodes, etc. 17004 * @name DataTable#destroy.dt 17005 * @event 17006 * @param {event} e jQuery event object 17007 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 17008 */ 17009 17010 /** 17011 * Page length change event, fired when number of records to show on each 17012 * page (the length) is changed. 17013 * @name DataTable#length.dt 17014 * @event 17015 * @param {event} e jQuery event object 17016 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 17017 * @param {integer} len New length 17018 */ 17019 17020 /** 17021 * Column sizing has changed. 17022 * @name DataTable#column-sizing.dt 17023 * @event 17024 * @param {event} e jQuery event object 17025 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 17026 */ 17027 17028 /** 17029 * Column visibility has changed. 17030 * @name DataTable#column-visibility.dt 17031 * @event 17032 * @param {event} e jQuery event object 17033 * @param {object} o DataTables settings object {@link DataTable.models.oSettings} 17034 * @param {int} column Column index 17035 * @param {bool} vis `false` if column now hidden, or `true` if visible 17036 */ 17037 17038 return $.fn.dataTable; 17039})); 17040 17041 17042; 17043/* 17044 * Copyright 2016 Small Batch, Inc. 17045 * 17046 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 17047 * use this file except in compliance with the License. You may obtain a copy of 17048 * the License at 17049 * 17050 * http://www.apache.org/licenses/LICENSE-2.0 17051 * 17052 * Unless required by applicable law or agreed to in writing, software 17053 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17054 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 17055 * License for the specific language governing permissions and limitations under 17056 * the License. 17057 */ 17058/* Web Font Loader v1.6.26 - (c) Adobe Systems, Google. License: Apache 2.0 */(function(){function aa(a,b,c){return a.call.apply(a.bind,arguments)}function ba(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}function p(a,b,c){p=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?aa:ba;return p.apply(null,arguments)}var q=Date.now||function(){return+new Date};function ca(a,b){this.a=a;this.m=b||a;this.c=this.m.document}var da=!!window.FontFace;function t(a,b,c,d){b=a.c.createElement(b);if(c)for(var e in c)c.hasOwnProperty(e)&&("style"==e?b.style.cssText=c[e]:b.setAttribute(e,c[e]));d&&b.appendChild(a.c.createTextNode(d));return b}function u(a,b,c){a=a.c.getElementsByTagName(b)[0];a||(a=document.documentElement);a.insertBefore(c,a.lastChild)}function v(a){a.parentNode&&a.parentNode.removeChild(a)} 17059function w(a,b,c){b=b||[];c=c||[];for(var d=a.className.split(/\s+/),e=0;e<b.length;e+=1){for(var f=!1,g=0;g<d.length;g+=1)if(b[e]===d[g]){f=!0;break}f||d.push(b[e])}b=[];for(e=0;e<d.length;e+=1){f=!1;for(g=0;g<c.length;g+=1)if(d[e]===c[g]){f=!0;break}f||b.push(d[e])}a.className=b.join(" ").replace(/\s+/g," ").replace(/^\s+|\s+$/,"")}function y(a,b){for(var c=a.className.split(/\s+/),d=0,e=c.length;d<e;d++)if(c[d]==b)return!0;return!1} 17060function z(a){if("string"===typeof a.f)return a.f;var b=a.m.location.protocol;"about:"==b&&(b=a.a.location.protocol);return"https:"==b?"https:":"http:"}function ea(a){return a.m.location.hostname||a.a.location.hostname} 17061function A(a,b,c){function d(){k&&e&&f&&(k(g),k=null)}b=t(a,"link",{rel:"stylesheet",href:b,media:"all"});var e=!1,f=!0,g=null,k=c||null;da?(b.onload=function(){e=!0;d()},b.onerror=function(){e=!0;g=Error("Stylesheet failed to load");d()}):setTimeout(function(){e=!0;d()},0);u(a,"head",b)} 17062function B(a,b,c,d){var e=a.c.getElementsByTagName("head")[0];if(e){var f=t(a,"script",{src:b}),g=!1;f.onload=f.onreadystatechange=function(){g||this.readyState&&"loaded"!=this.readyState&&"complete"!=this.readyState||(g=!0,
vendor: 9,292 bytes, lines 17062-17075
17062c&&c(null),f.onload=f.onreadystatechange=null,"HEAD"==f.parentNode.tagName&&e.removeChild(f))};e.appendChild(f);setTimeout(function(){g||(g=!0,c&&c(Error("Script load timeout")))},d||5E3);return f}return null};function C(){this.a=0;this.c=null}function D(a){a.a++;return function(){a.a--;E(a)}}function F(a,b){a.c=b;E(a)}function E(a){0==a.a&&a.c&&(a.c(),a.c=null)};function G(a){this.a=a||"-"}G.prototype.c=function(a){for(var b=[],c=0;c<arguments.length;c++)b.push(arguments[c].replace(/[\W_]+/g,"").toLowerCase());return b.join(this.a)};function H(a,b){this.c=a;this.f=4;this.a="n";var c=(b||"n4").match(/^([nio])([1-9])$/i);c&&(this.a=c[1],this.f=parseInt(c[2],10))}function fa(a){return I(a)+" "+(a.f+"00")+" 300px "+J(a.c)}function J(a){var b=[];a=a.split(/,\s*/);for(var c=0;c<a.length;c++){var d=a[c].replace(/['"]/g,"");-1!=d.indexOf(" ")||/^\d/.test(d)?b.push("'"+d+"'"):b.push(d)}return b.join(",")}function K(a){return a.a+a.f}function I(a){var b="normal";"o"===a.a?b="oblique":"i"===a.a&&(b="italic");return b} 17063function ga(a){var b=4,c="n",d=null;a&&((d=a.match(/(normal|oblique|italic)/i))&&d[1]&&(c=d[1].substr(0,1).toLowerCase()),(d=a.match(/([1-9]00|normal|bold)/i))&&d[1]&&(/bold/i.test(d[1])?b=7:/[1-9]00/.test(d[1])&&(b=parseInt(d[1].substr(0,1),10))));return c+b};function ha(a,b){this.c=a;this.f=a.m.document.documentElement;this.h=b;this.a=new G("-");this.j=!1!==b.events;this.g=!1!==b.classes}function ia(a){a.g&&w(a.f,[a.a.c("wf","loading")]);L(a,"loading")}function M(a){if(a.g){var b=y(a.f,a.a.c("wf","active")),c=[],d=[a.a.c("wf","loading")];b||c.push(a.a.c("wf","inactive"));w(a.f,c,d)}L(a,"inactive")}function L(a,b,c){if(a.j&&a.h[b])if(c)a.h[b](c.c,K(c));else a.h[b]()};function ja(){this.c={}}function ka(a,b,c){var d=[],e;for(e in b)if(b.hasOwnProperty(e)){var f=a.c[e];f&&d.push(f(b[e],c))}return d};function N(a,b){this.c=a;this.f=b;this.a=t(this.c,"span",{"aria-hidden":"true"},this.f)}function O(a){u(a.c,"body",a.a)}function P(a){return"display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:"+J(a.c)+";"+("font-style:"+I(a)+";font-weight:"+(a.f+"00")+";")};function Q(a,b,c,d,e,f){this.g=a;this.j=b;this.a=d;this.c=c;this.f=e||3E3;this.h=f||void 0}Q.prototype.start=function(){var a=this.c.m.document,b=this,c=q(),d=new Promise(function(d,e){function k(){q()-c>=b.f?e():a.fonts.load(fa(b.a),b.h).then(function(a){1<=a.length?d():setTimeout(k,25)},function(){e()})}k()}),e=new Promise(function(a,d){setTimeout(d,b.f)});Promise.race([e,d]).then(function(){b.g(b.a)},function(){b.j(b.a)})};function R(a,b,c,d,e,f,g){this.v=a;this.B=b;this.c=c;this.a=d;this.s=g||"BESbswy";this.f={};this.w=e||3E3;this.u=f||null;this.o=this.j=this.h=this.g=null;this.g=new N(this.c,this.s);this.h=new N(this.c,this.s);this.j=new N(this.c,this.s);this.o=new N(this.c,this.s);a=new H(this.a.c+",serif",K(this.a));a=P(a);this.g.a.style.cssText=a;a=new H(this.a.c+",sans-serif",K(this.a));a=P(a);this.h.a.style.cssText=a;a=new H("serif",K(this.a));a=P(a);this.j.a.style.cssText=a;a=new H("sans-serif",K(this.a));a= 17064P(a);this.o.a.style.cssText=a;O(this.g);O(this.h);O(this.j);O(this.o)}var S={D:"serif",C:"sans-serif"},T=null;function U(){if(null===T){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent);T=!!a&&(536>parseInt(a[1],10)||536===parseInt(a[1],10)&&11>=parseInt(a[2],10))}return T}R.prototype.start=function(){this.f.serif=this.j.a.offsetWidth;this.f["sans-serif"]=this.o.a.offsetWidth;this.A=q();la(this)}; 17065function ma(a,b,c){for(var d in S)if(S.hasOwnProperty(d)&&b===a.f[S[d]]&&c===a.f[S[d]])return!0;return!1}function la(a){var b=a.g.a.offsetWidth,c=a.h.a.offsetWidth,d;(d=b===a.f.serif&&c===a.f["sans-serif"])||(d=U()&&ma(a,b,c));d?q()-a.A>=a.w?U()&&ma(a,b,c)&&(null===a.u||a.u.hasOwnProperty(a.a.c))?V(a,a.v):V(a,a.B):na(a):V(a,a.v)}function na(a){setTimeout(p(function(){la(this)},a),50)}function V(a,b){setTimeout(p(function(){v(this.g.a);v(this.h.a);v(this.j.a);v(this.o.a);b(this.a)},a),0)};function W(a,b,c){this.c=a;this.a=b;this.f=0;this.o=this.j=!1;this.s=c}var X=null;W.prototype.g=function(a){var b=this.a;b.g&&w(b.f,[b.a.c("wf",a.c,K(a).toString(),"active")],[b.a.c("wf",a.c,K(a).toString(),"loading"),b.a.c("wf",a.c,K(a).toString(),"inactive")]);L(b,"fontactive",a);this.o=!0;oa(this)}; 17066W.prototype.h=function(a){var b=this.a;if(b.g){var c=y(b.f,b.a.c("wf",a.c,K(a).toString(),"active")),d=[],e=[b.a.c("wf",a.c,K(a).toString(),"loading")];c||d.push(b.a.c("wf",a.c,K(a).toString(),"inactive"));w(b.f,d,e)}L(b,"fontinactive",a);oa(this)};function oa(a){0==--a.f&&a.j&&(a.o?(a=a.a,a.g&&w(a.f,[a.a.c("wf","active")],[a.a.c("wf","loading"),a.a.c("wf","inactive")]),L(a,"active")):M(a.a))};function pa(a){this.j=a;this.a=new ja;this.h=0;this.f=this.g=!0}pa.prototype.load=function(a){this.c=new ca(this.j,a.context||this.j);this.g=!1!==a.events;this.f=!1!==a.classes;qa(this,new ha(this.c,a),a)}; 17067function ra(a,b,c,d,e){var f=0==--a.h;(a.f||a.g)&&setTimeout(function(){var a=e||null,k=d||null||{};if(0===c.length&&f)M(b.a);else{b.f+=c.length;f&&(b.j=f);var h,m=[];for(h=0;h<c.length;h++){var l=c[h],n=k[l.c],r=b.a,x=l;r.g&&w(r.f,[r.a.c("wf",x.c,K(x).toString(),"loading")]);L(r,"fontloading",x);r=null;null===X&&(X=window.FontFace?(x=/Gecko.*Firefox\/(\d+)/.exec(window.navigator.userAgent))?42<parseInt(x[1],10):!0:!1);X?r=new Q(p(b.g,b),p(b.h,b),b.c,l,b.s,n):r=new R(p(b.g,b),p(b.h,b),b.c,l,b.s,a, 17068n);m.push(r)}for(h=0;h<m.length;h++)m[h].start()}},0)}function qa(a,b,c){var d=[],e=c.timeout;ia(b);var d=ka(a.a,c,a.c),f=new W(a.c,b,e);a.h=d.length;b=0;for(c=d.length;b<c;b++)d[b].load(function(b,d,c){ra(a,f,b,d,c)})};function sa(a,b){this.c=a;this.a=b}function ta(a,b,c){var d=z(a.c);a=(a.a.api||"fast.fonts.net/jsapi").replace(/^.*http(s?):(\/\/)?/,"");return d+"//"+a+"/"+b+".js"+(c?"?v="+c:"")} 17069sa.prototype.load=function(a){function b(){if(f["__mti_fntLst"+d]){var c=f["__mti_fntLst"+d](),e=[],h;if(c)for(var m=0;m<c.length;m++){var l=c[m].fontfamily;void 0!=c[m].fontStyle&&void 0!=c[m].fontWeight?(h=c[m].fontStyle+c[m].fontWeight,e.push(new H(l,h))):e.push(new H(l))}a(e)}else setTimeout(function(){b()},50)}var c=this,d=c.a.projectId,e=c.a.version;if(d){var f=c.c.m;B(this.c,ta(c,d,e),function(e){e?a([]):(f["__MonotypeConfiguration__"+d]=function(){return c.a},b())}).id="__MonotypeAPIScript__"+ 17070d}else a([])};function ua(a,b){this.c=a;this.a=b}ua.prototype.load=function(a){var b,c,d=this.a.urls||[],e=this.a.families||[],f=this.a.testStrings||{},g=new C;b=0;for(c=d.length;b<c;b++)A(this.c,d[b],D(g));var k=[];b=0;for(c=e.length;b<c;b++)if(d=e[b].split(":"),d[1])for(var h=d[1].split(","),m=0;m<h.length;m+=1)k.push(new H(d[0],h[m]));else k.push(new H(d[0]));F(g,function(){a(k,f)})};function va(a,b,c){a?this.c=a:this.c=b+wa;this.a=[];this.f=[];this.g=c||""}var wa="//fonts.googleapis.com/css";function xa(a,b){for(var c=b.length,d=0;d<c;d++){var e=b[d].split(":");3==e.length&&a.f.push(e.pop());var f="";2==e.length&&""!=e[1]&&(f=":");a.a.push(e.join(f))}} 17071function ya(a){if(0==a.a.length)throw Error("No fonts to load!");if(-1!=a.c.indexOf("kit="))return a.c;for(var b=a.a.length,c=[],d=0;d<b;d++)c.push(a.a[d].replace(/ /g,"+"));b=a.c+"?family="+c.join("%7C");0<a.f.length&&(b+="&subset="+a.f.join(","));0<a.g.length&&(b+="&text="+encodeURIComponent(a.g));return b};function za(a){this.f=a;this.a=[];this.c={}} 17072var Aa={latin:"BESbswy","latin-ext":"\u00e7\u00f6\u00fc\u011f\u015f",cyrillic:"\u0439\u044f\u0416",greek:"\u03b1\u03b2\u03a3",khmer:"\u1780\u1781\u1782",Hanuman:"\u1780\u1781\u1782"},Ba={thin:"1",extralight:"2","extra-light":"2",ultralight:"2","ultra-light":"2",light:"3",regular:"4",book:"4",medium:"5","semi-bold":"6",semibold:"6","demi-bold":"6",demibold:"6",bold:"7","extra-bold":"8",extrabold:"8","ultra-bold":"8",ultrabold:"8",black:"9",heavy:"9",l:"3",r:"4",b:"7"},Ca={i:"i",italic:"i",n:"n",normal:"n"}, 17073Da=/^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i|normal|italic)?$/; 17074function Ea(a){for(var b=a.f.length,c=0;c<b;c++){var d=a.f[c].split(":"),e=d[0].replace(/\+/g," "),f=["n4"];if(2<=d.length){var g;var k=d[1];g=[];if(k)for(var k=k.split(","),h=k.length,m=0;m<h;m++){var l;l=k[m];if(l.match(/^[\w-]+$/)){var n=Da.exec(l.toLowerCase());if(null==n)l="";else{l=n[2];l=null==l||""==l?"n":Ca[l];n=n[1];if(null==n||""==n)n="4";else var r=Ba[n],n=r?r:isNaN(n)?"4":n.substr(0,1);l=[l,n].join("")}}else l="";l&&g.push(l)}0<g.length&&(f=g);3==d.length&&(d=d[2],g=[],d=d?d.split(","): 17075g,0<d.length&&(d=Aa[d[0]])&&(a.c[e]=d))}a.c[e]||(d=Aa[e])&&(a.c[e]=d);for(d=0;d<f.length;d+=1)a.a.push(new H(e,f[d]))}};function Fa(a,b){this.c=a;this.a=b}var Ga={Arimo:!0,Cousine:!0,Tinos:!0};Fa.prototype.load=function(a){var b=new C,c=this.c,d=new va(this.a.api,z(c),this.a.text),e=this.a.families;xa(d,e);var f=new za(e);Ea(f);A(c,ya(d),D(b));F(b,function(){a(f.a,f.c,Ga)})};function Ha(a,b){this.c=a;this.a=b}Ha.prototype.load=function(a){var b=this.a.id,c=this.c.m;b?B(this.c,(this.a.api||"https://use.typekit.net")+"/"+b+".js",function(b){if(b)a([]);else if(c.Typekit&&c.Typekit.config&&c.Typekit.config.fn){b=c.Typekit.config.fn;for(var e=[],f=0;f<b.length;f+=2)for(var g=b[f],k=b[f+1],h=0;h<k.length;
17075h++)e.push(new H(g,k[h]));try{c.Typekit.load({events:!1,classes:!1,async:!0})}catch(m){}a(e)}},2E3):a([])};function Ia(a,b){this.c=a;this.f=b;this.a=[]}Ia.prototype.load=function(a){var b=this.f.id,c=this.c.m,d=this;b?(c.__webfontfontdeckmodule__||(c.__webfontfontdeckmodule__={}),c.__webfontfontdeckmodule__[b]=function(b,c){for(var g=0,k=c.fonts.length;g<k;++g){var h=c.fonts[g];d.a.push(new H(h.name,ga("font-weight:"+h.weight+";font-style:"+h.style)))}a(d.a)},B(this.c,z(this.c)+(this.f.api||"//f.fontdeck.com/s/css/js/")+ea(this.c)+"/"+b+".js",function(b){b&&a([])})):a([])};var Y=new pa(window);Y.a.c.custom=function(a,b){return new ua(b,a)};Y.a.c.fontdeck=function(a,b){return new Ia(b,a)};Y.a.c.monotype=function(a,b){return new sa(b,a)};Y.a.c.typekit=function(a,b){return new Ha(b,a)};Y.a.c.google=function(a,b){return new Fa(b,a)};var Z={load:p(Y.load,Y)};"function"===typeof define&&define.amd?define(function(){return Z}):"undefined"!==typeof module&&module.exports?module.exports=Z:(window.WebFont=Z,window.WebFontConfig&&Y.load(window.WebFontConfig));}()); 17076; 17077(function (root, factory) { 17078 if (typeof define === 'function' && define.amd) { 17079 // AMD. Register as an anonymous module. 17080 define(['leaflet'], factory); 17081 } else if (typeof modules === 'object' && module.exports) { 17082 // define a Common JS module that relies on 'leaflet' 17083 module.exports = factory(require('leaflet')); 17084 } else { 17085 // Assume Leaflet is loaded into global object L already 17086 factory(L); 17087 } 17088}(this, function (L) { 17089 'use strict'; 17090 17091 L.TileLayer.Provider = L.TileLayer.extend({ 17092 initialize: function (arg, options) { 17093 var providers = L.TileLayer.Provider.providers; 17094 17095 var parts = arg.split('.'); 17096 17097 var providerName = parts[0]; 17098 var variantName = parts[1]; 17099 17100 if (!providers[providerName]) { 17101 throw 'No such provider (' + providerName + ')'; 17102 } 17103 17104 var provider = { 17105 url: providers[providerName].url, 17106 options: providers[providerName].options 17107 }; 17108 17109 // overwrite values in provider from variant. 17110 if (variantName && 'variants' in providers[providerName]) { 17111 if (!(variantName in providers[providerName].variants)) { 17112 throw 'No such variant of ' + providerName + ' (' + variantName + ')'; 17113 } 17114 var variant = providers[providerName].variants[variantName]; 17115 var variantOptions; 17116 if (typeof variant === 'string') { 17117 variantOptions = { 17118 variant: variant 17119 }; 17120 } else { 17121 variantOptions = variant.options; 17122 } 17123 provider = { 17124 url: variant.url || provider.url, 17125 options: L.Util.extend({}, provider.options, variantOptions) 17126 }; 17127 } 17128 17129 // replace attribution placeholders with their values from toplevel provider attribution, 17130 // recursively 17131 var attributionReplacer = function (attr) { 17132 if (attr.indexOf('{attribution.') === -1) { 17133 return attr; 17134 } 17135 return attr.replace(/\{attribution.(\w*)\}/g, 17136 function (match, attributionName) { 17137 return attributionReplacer(providers[attributionName].options.attribution); 17138 } 17139 ); 17140 }; 17141 provider.options.attribution = attributionReplacer(provider.options.attribution); 17142 17143 // Compute final options combining provider options with any user overrides 17144 var layerOpts = L.Util.extend({}, provider.options, options); 17145 L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts); 17146 } 17147 }); 17148 17149 /** 17150 * Definition of providers. 17151 * see http://leafletjs.com/reference.html#tilelayer for options in the options map. 17152 */ 17153 17154 L.TileLayer.Provider.providers = { 17155 OpenStreetMap: { 17156 url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 17157 options: { 17158 maxZoom: 19, 17159 attribution: 17160 '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' 17161 }, 17162 variants: { 17163 Mapnik: {}, 17164 DE: { 17165 url: 'https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', 17166 options: { 17167 maxZoom: 18 17168 } 17169 }, 17170 CH: { 17171 url: 'https://tile.osm.ch/switzerland/{z}/{x}/{y}.png', 17172 options: { 17173 maxZoom: 18, 17174 bounds: [[45, 5], [48, 11]] 17175 } 17176 }, 17177 France: { 17178 url: 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', 17179 options: { 17180 maxZoom: 20, 17181 attribution: '© Openstreetmap France | {attribution.OpenStreetMap}' 17182 } 17183 }, 17184 HOT: { 17185 url: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', 17186 options: { 17187 attribution: 17188 '{attribution.OpenStreetMap}, ' + 17189 'Tiles style by <a href="https://www.hotosm.org/" target="_blank">Humanitarian OpenStreetMap Team</a> ' + 17190 'hosted by <a href="https://openstreetmap.fr/" target="_blank">OpenStreetMap France</a>' 17191 } 17192 }, 17193 BZH: { 17194 url: 'https://tile.openstreetmap.bzh/br/{z}/{x}/{y}.png', 17195 options: { 17196 attribution: '{attribution.OpenStreetMap}, Tiles courtesy of <a href="http://www.openstreetmap.bzh/" target="_blank">Breton OpenStreetMap Team</a>', 17197 bounds: [[46.2, -5.5], [50, 0.7]] 17198 } 17199 } 17200 } 17201 }, 17202 OpenSeaMap: { 17203 url: 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 17204 options: { 17205 attribution: 'Map data: © <a href="http://www.openseamap.org">OpenSeaMap</a> contributors' 17206 } 17207 }, 17208 OpenPtMap: { 17209 url: 'http://openptmap.org/tiles/{z}/{x}/{y}.png', 17210 options: { 17211 maxZoom: 17, 17212 attribution: 'Map data: © <a href="http://www.openptmap.org">OpenPtMap</a> contributors' 17213 } 17214 }, 17215 OpenTopoMap: { 17216 url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', 17217 options: { 17218 maxZoom: 17, 17219 attribution: 'Map data: {attribution.OpenStreetMap}, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)' 17220 } 17221 }, 17222 OpenRailwayMap: { 17223 url: 'https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', 17224 options: { 17225 maxZoom: 19, 17226 attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © <a href="https://www.OpenRailwayMap.org">OpenRailwayMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)' 17227 } 17228 }, 17229 OpenFireMap: { 17230 url: 'http://openfiremap.org/hytiles/{z}/{x}/{y}.png', 17231 options: { 17232 maxZoom: 19, 17233 attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © <a href="http://www.openfiremap.org">OpenFireMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)' 17234 } 17235 }, 17236 SafeCast: { 17237 url: 'https://s3.amazonaws.com/te512.safecast.org/{z}/{x}/{y}.png', 17238 options: { 17239 maxZoom: 16, 17240 attribution: 'Map data: {attribution.OpenStreetMap} | Map style: © <a href="https://blog.safecast.org/about/">SafeCast</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)' 17241 } 17242 }, 17243 Thunderforest: { 17244 url: 'https://{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png?apikey={apikey}', 17245 options: { 17246 attribution: 17247 '© <a href="http://www.thunderforest.com/">Thunderforest</a>, {attribution.OpenStreetMap}', 17248 variant: 'cycle', 17249 apikey: '<insert your api key here>', 17250 maxZoom: 22 17251 }, 17252 variants: { 17253 OpenCycleMap: 'cycle', 17254 Transport: { 17255 options: { 17256 variant: 'transport' 17257 } 17258 }, 17259 TransportDark: { 17260 options: { 17261 variant: 'transport-dark' 17262 } 17263 }, 17264 SpinalMap: { 17265 options: { 17266 variant: 'spinal-map' 17267 } 17268 }, 17269 Landscape: 'landscape', 17270 Outdoors: 'outdoors',
17271 Pioneer: 'pioneer', 17272 MobileAtlas: 'mobile-atlas', 17273 Neighbourhood: 'neighbourhood' 17274 } 17275 }, 17276 CyclOSM: { 17277 url: 'https://dev.{s}.tile.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', 17278 options: { 17279 maxZoom: 20, 17280 attribution: '<a href="https://github.com/cyclosm/cyclosm-cartocss-style/releases" title="CyclOSM - Open Bicycle render">CyclOSM</a> | Map data: {attribution.OpenStreetMap}' 17281 } 17282 }, 17283 OpenMapSurfer: { 17284 url: 'https://maps.heigit.org/openmapsurfer/tiles/{variant}/webmercator/{z}/{x}/{y}.png', 17285 options: { 17286 maxZoom: 19, 17287 variant: 'roads', 17288 attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> | Map data ' 17289 }, 17290 variants: { 17291 Roads: { 17292 options: { 17293 variant: 'roads', 17294 attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' 17295 } 17296 }, 17297 Hybrid: { 17298 options: { 17299 variant: 'hybrid', 17300 attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' 17301 } 17302 }, 17303 AdminBounds: { 17304 options: { 17305 variant: 'adminb', 17306 maxZoom: 18, 17307 attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' 17308 } 17309 }, 17310 ContourLines: { 17311 options: { 17312 variant: 'asterc', 17313 maxZoom: 18, 17314 minZoom: 13, 17315 attribution: '{attribution.OpenMapSurfer} <a href="https://lpdaac.usgs.gov/products/aster_policies">ASTER GDEM</a>' 17316 } 17317 }, 17318 Hillshade: { 17319 options: { 17320 variant: 'asterh', 17321 maxZoom: 18, 17322 attribution: '{attribution.OpenMapSurfer} <a href="https://lpdaac.usgs.gov/products/aster_policies">ASTER GDEM</a>, <a href="http://srtm.csi.cgiar.org/">SRTM</a>' 17323 } 17324 }, 17325 ElementsAtRisk: { 17326 options: { 17327 variant: 'elements_at_risk', 17328 attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}' 17329 } 17330 } 17331 } 17332 }, 17333 Hydda: { 17334 url: 'https://{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png', 17335 options: { 17336 maxZoom: 18, 17337 variant: 'full', 17338 attribution: 'Tiles courtesy of <a href="http://openstreetmap.se/" target="_blank">OpenStreetMap Sweden</a> — Map data {attribution.OpenStreetMap}' 17339 }, 17340 variants: { 17341 Full: 'full', 17342 Base: 'base', 17343 RoadsAndLabels: 'roads_and_labels' 17344 } 17345 }, 17346 MapBox: { 17347 url: 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}{r}.png?access_token={accessToken}', 17348 options: { 17349 attribution: 17350 '<a href="https://www.mapbox.com/about/maps/" target="_blank">© Mapbox</a> ' + 17351 '{attribution.OpenStreetMap} ' + 17352 '<a href="https://www.mapbox.com/map-feedback/" target="_blank">Improve this map</a>', 17353 subdomains: 'abcd', 17354 id: 'mapbox.streets', 17355 accessToken: '<insert your access token here>', 17356 } 17357 }, 17358 Stamen: { 17359 url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}{r}.{ext}', 17360 options: { 17361 attribution: 17362 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, ' + 17363 '<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> — ' + 17364 'Map data {attribution.OpenStreetMap}', 17365 subdomains: 'abcd', 17366 minZoom: 0, 17367 maxZoom: 20, 17368 variant: 'toner', 17369 ext: 'png' 17370 }, 17371 variants: { 17372 Toner: 'toner', 17373 TonerBackground: 'toner-background', 17374 TonerHybrid: 'toner-hybrid', 17375 TonerLines: 'toner-lines', 17376 TonerLabels: 'toner-labels', 17377 TonerLite: 'toner-lite', 17378 Watercolor: { 17379 url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', 17380 options: { 17381 variant: 'watercolor', 17382 ext: 'jpg', 17383 minZoom: 1, 17384 maxZoom: 16 17385 } 17386 }, 17387 Terrain: { 17388 options: { 17389 variant: 'terrain', 17390 minZoom: 0, 17391 maxZoom: 18 17392 } 17393 }, 17394 TerrainBackground: { 17395 options: { 17396 variant: 'terrain-background', 17397 minZoom: 0, 17398 maxZoom: 18 17399 } 17400 }, 17401 TerrainLabels: { 17402 options: { 17403 variant: 'terrain-labels', 17404 minZoom: 0, 17405 maxZoom: 18 17406 } 17407 }, 17408 TopOSMRelief: { 17409 url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', 17410 options: { 17411 variant: 'toposm-color-relief', 17412 ext: 'jpg', 17413 bounds: [[22, -132], [51, -56]] 17414 } 17415 }, 17416 TopOSMFeatures: { 17417 options: { 17418 variant: 'toposm-features', 17419 bounds: [[22, -132], [51, -56]], 17420 opacity: 0.9 17421 } 17422 } 17423 } 17424 }, 17425 TomTom: { 17426 url: 'https://{s}.api.tomtom.com/map/1/tile/{variant}/{style}/{z}/{x}/{y}.{ext}?key={apikey}', 17427 options: { 17428 variant: 'basic', 17429 maxZoom: 22, 17430 attribution: 17431 '<a href="https://tomtom.com" target="_blank">© 1992 - ' + new Date().getFullYear() + ' TomTom.</a> ', 17432 subdomains: 'abcd', 17433 style: 'main', 17434 ext: 'png', 17435 apikey: '<insert your API key here>', 17436 }, 17437 variants: { 17438 Basic: 'basic', 17439 Hybrid: 'hybrid', 17440 Labels: 'labels' 17441 } 17442 }, 17443 Esri: { 17444 url: 'https://server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}', 17445 options: { 17446 variant: 'World_Street_Map', 17447 attribution: 'Tiles © Esri' 17448 }, 17449 variants: { 17450 WorldStreetMap: { 17451 options: { 17452 attribution: 17453 '{attribution.Esri} — ' + 17454 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' 17455 } 17456 }, 17457 DeLorme: { 17458 options: { 17459 variant: 'Specialty/DeLorme_World_Base_Map', 17460 minZoom: 1, 17461 maxZoom: 11, 17462 attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme' 17463 } 17464 }, 17465 WorldTopoMap: { 17466 options: { 17467 variant: 'World_Topo_Map', 17468 attribution: 17469 '{attribution.Esri} — ' + 17470 'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community' 17471 } 17472 }, 17473 WorldImagery: { 17474 options: { 17475 variant: 'World_Imagery', 17476 attribution: 17477 '{attribution.Esri} — ' + 17478 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' 17479 } 17480 }, 17481 WorldTerrain: { 17482 options: { 17483 variant: 'World_Terrain_Base', 17484 maxZoom: 13, 17485 attribution: 17486 '{attribution.Esri} — ' + 17487 'Source: USGS, Esri, TANA, DeLorme, and NPS' 17488 } 17489 }, 17490 WorldShadedRelief: { 17491 options: { 17492 variant: 'World_Shaded_Relief', 17493 maxZoom: 13, 17494 attribution: '{attribution.Esri} — Source: Esri' 17495 } 17496 }, 17497 WorldPhysical: { 17498 options: { 17499 variant: 'World_Physical_Map', 17500 maxZoom: 8, 17501 attribution: '{attribution.Esri} — Source: US National Park Service' 17502 } 17503 }, 17504 OceanBasemap: { 17505 options: { 17506 variant: 'Ocean_Basemap', 17507 maxZoom: 13, 17508 attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri' 17509 } 17510 }, 17511 NatGeoWorldMap: { 17512 options: { 17513 variant: 'NatGeo_World_Map', 17514 maxZoom: 16, 17515 attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC' 17516 } 17517 }, 17518 WorldGrayCanvas: { 17519 options: { 17520 variant: 'Canvas/World_Light_Gray_Base', 17521 maxZoom: 16, 17522 attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ' 17523 } 17524 } 17525 } 17526 }, 17527 OpenWeatherMap: { 17528 url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png?appid={apiKey}', 17529 options: { 17530 maxZoom: 19, 17531 attribution: 'Map data © <a href="http://openweathermap.org">OpenWeatherMap</a>', 17532 apiKey:'<insert your api key here>', 17533 opacity: 0.5 17534 }, 17535 variants: { 17536 Clouds: 'clouds', 17537 CloudsClassic: 'clouds_cls', 17538 Precipitation: 'precipitation', 17539 PrecipitationClassic: 'precipitation_cls', 17540 Rain: 'rain', 17541 RainClassic: 'rain_cls', 17542 Pressure: 'pressure', 17543 PressureContour: 'pressure_cntr', 17544 Wind: 'wind', 17545 Temperature: 'temp', 17546 Snow: 'snow' 17547 } 17548 }, 17549 HERE: { 17550 /* 17551 * HERE maps, formerly Nokia maps. 17552 * These basemaps are free, but you need an API key. Please sign up at 17553 * https://developer.here.com/plans 17554 */ 17555 url: 17556 'https://{s}.{base}.maps.api.here.com/maptile/2.1/' + 17557 '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' + 17558 'app_id={app_id}&app_code={app_code}&lg={language}', 17559 options: { 17560 attribution: 17561 'Map © 1987-' + new Date().getFullYear() + ' <a href="http://developer.here.com">HERE</a>', 17562 subdomains: '1234', 17563 mapID: 'newest', 17564 'app_id': '<insert your app_id here>', 17565 'app_code': '<insert your app_code here>', 17566 base: 'base', 17567 variant: 'normal.day', 17568 maxZoom: 20, 17569 type: 'maptile', 17570 language: 'eng', 17571 format: 'png8', 17572 size: '256' 17573 }, 17574 variants: { 17575 normalDay: 'normal.day', 17576 normalDayCustom: 'normal.day.custom', 17577 normalDayGrey: 'normal.day.grey', 17578 normalDayMobile: 'normal.day.mobile', 17579 normalDayGreyMobile: 'normal.day.grey.mobile', 17580 normalDayTransit: 'normal.day.transit', 17581 normalDayTransitMobile: 'normal.day.transit.mobile', 17582 normalDayTraffic: { 17583 options: { 17584 variant: 'normal.traffic.day', 17585 base: 'traffic', 17586 type: 'traffictile' 17587 } 17588 }, 17589 normalNight: 'normal.night', 17590 normalNightMobile: 'normal.night.mobile', 17591 normalNightGrey: 'normal.night.grey', 17592 normalNightGreyMobile: 'normal.night.grey.mobile', 17593 normalNightTransit: 'normal.night.transit', 17594 normalNightTransitMobile: 'normal.night.transit.mobile', 17595 reducedDay: 'reduced.day', 17596 reducedNight: 'reduced.night', 17597 basicMap: { 17598 options: { 17599 type: 'basetile' 17600 } 17601 }, 17602 mapLabels: { 17603 options: { 17604 type: 'labeltile', 17605 format: 'png' 17606 } 17607 }, 17608 trafficFlow: { 17609 options: { 17610 base: 'traffic', 17611 type: 'flowtile' 17612 } 17613 }, 17614 carnavDayGrey: 'carnav.day.grey', 17615 hybridDay: { 17616 options: { 17617 base: 'aerial', 17618 variant: 'hybrid.day' 17619 } 17620 }, 17621 hybridDayMobile: { 17622 options: { 17623 base: 'aerial', 17624 variant: 'hybrid.day.mobile' 17625 } 17626 }, 17627 hybridDayTransit: { 17628 options: { 17629 base: 'aerial', 17630 variant: 'hybrid.day.transit' 17631 } 17632 }, 17633 hybridDayGrey: { 17634 options: { 17635 base: 'aerial', 17636 variant: 'hybrid.grey.day' 17637 } 17638 }, 17639 hybridDayTraffic: { 17640 options: { 17641 variant: 'hybrid.traffic.day', 17642 base: 'traffic', 17643 type: 'traffictile' 17644 } 17645 }, 17646 pedestrianDay: 'pedestrian.day', 17647 pedestrianNight: 'pedestrian.night', 17648 satelliteDay: { 17649 options: { 17650 base: 'aerial', 17651 variant: 'satellite.day' 17652 } 17653 }, 17654 terrainDay: { 17655 options: { 17656 base: 'aerial', 17657 variant: 'terrain.day' 17658 } 17659 }, 17660 terrainDayMobile: { 17661 options: { 17662 base: 'aerial', 17663 variant: 'terrain.day.mobile' 17664 } 17665 } 17666 } 17667 }, 17668 FreeMapSK: { 17669 url: 'http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg', 17670 options: { 17671 minZoom: 8, 17672 maxZoom: 16, 17673 subdomains: '1234', 17674 bounds: [[47.204642, 15.996093], [49.830896, 22.576904]], 17675 attribution: 17676 '{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 <a href="http://freemap.sk">Freemap.sk</a>' 17677 } 17678 }, 17679 MtbMap: { 17680 url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png', 17681 options: { 17682 attribution: 17683 '{attribution.OpenStreetMap} & USGS' 17684 } 17685 }, 17686 CartoDB: { 17687 url: 'https://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}{r}.png', 17688 options: { 17689 attribution: '{attribution.OpenStreetMap} © <a href="https://carto.com/attributions">CARTO</a>', 17690 subdomains: 'abcd', 17691 maxZoom: 19, 17692 variant: 'light_all' 17693 }, 17694 variants: { 17695 Positron: 'light_all', 17696 PositronNoLabels: 'light_nolabels', 17697 PositronOnlyLabels: 'light_only_labels', 17698 DarkMatter: 'dark_all', 17699 DarkMatterNoLabels: 'dark_nolabels', 17700 DarkMatterOnlyLabels: 'dark_only_labels', 17701 Voyager: 'rastertiles/voyager', 17702 VoyagerNoLabels: 'rastertiles/voyager_nolabels', 17703 VoyagerOnlyLabels: 'rastertiles/voyager_only_labels', 17704 VoyagerLabelsUnder: 'rastertiles/voyager_labels_under' 17705 } 17706 }, 17707 HikeBike: { 17708 url: 'https://tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png', 17709 options: { 17710 maxZoom: 19, 17711 attribution: '{attribution.OpenStreetMap}', 17712 variant: 'hikebike' 17713 }, 17714 variants: { 17715 HikeBike: {}, 17716 HillShading: { 17717 options: { 17718 maxZoom: 15, 17719 variant: 'hillshading' 17720 } 17721 } 17722 } 17723 }, 17724 BasemapAT: { 17725 url: 'https://maps{s}.wien.gv.at/basemap/{variant}/normal/google3857/{z}/{y}/{x}.{format}', 17726 options: { 17727 maxZoom: 19, 17728 attribution: 'Datenquelle: <a href="https://www.basemap.at">basemap.at</a>', 17729 subdomains: ['', '1', '2', '3', '4'], 17730 format: 'png', 17731 bounds: [[46.358770, 8.782379], [49.037872, 17.189532]], 17732 variant: 'geolandbasemap' 17733 }, 17734 variants: { 17735 basemap: { 17736 options: { 17737 maxZoom: 20, // currently only in Vienna 17738 variant: 'geolandbasemap' 17739 } 17740 }, 17741 grau: 'bmapgrau', 17742 overlay: 'bmapoverlay', 17743 highdpi: { 17744 options: { 17745 variant: 'bmaphidpi', 17746 format: 'jpeg' 17747 } 17748 }, 17749 orthofoto: { 17750 options: { 17751 maxZoom: 20, // currently only in Vienna 17752 variant: 'bmaporthofoto30cm', 17753 format: 'jpeg' 17754 } 17755 } 17756 } 17757 }, 17758 nlmaps: { 17759 url: 'https://geodata.nationaalgeoregister.nl/tiles/service/wmts/{variant}/EPSG:3857/{z}/{x}/{y}.png', 17760 options: { 17761 minZoom: 6, 17762 maxZoom: 19, 17763 bounds: [[50.5, 3.25], [54, 7.6]], 17764 attribution: 'Kaartgegevens © <a href="kadaster.nl">Kadaster</a>' 17765 }, 17766 variants: { 17767 'standaard': 'brtachtergrondkaart', 17768 'pastel': 'brtachtergrondkaartpastel', 17769 'grijs': 'brtachtergrondkaartgrijs', 17770 'luchtfoto': { 17771 'url': 'https://geodata.nationaalgeoregister.nl/luchtfoto/rgb/wmts/1.0.0/2016_ortho25/EPSG:3857/{z}/{x}/{y}.png', 17772 } 17773 } 17774 }, 17775 NASAGIBS: { 17776 url: 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}', 17777 options: { 17778 attribution: 17779 'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ' + 17780 '(<a href="https://earthdata.nasa.gov">ESDIS</a>) with funding provided by NASA/HQ.', 17781 bounds: [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]], 17782 minZoom: 1, 17783 maxZoom: 9, 17784 format: 'jpg', 17785 time: '', 17786 tilematrixset: 'GoogleMapsCompatible_Level' 17787 }, 17788 variants: { 17789 ModisTerraTrueColorCR: 'MODIS_Terra_CorrectedReflectance_True
17789Color', 17790 ModisTerraBands367CR: 'MODIS_Terra_CorrectedReflectance_Bands367', 17791 ViirsEarthAtNight2012: { 17792 options: { 17793 variant: 'VIIRS_CityLights_2012', 17794 maxZoom: 8 17795 } 17796 }, 17797 ModisTerraLSTDay: { 17798 options: { 17799 variant: 'MODIS_Terra_Land_Surface_Temp_Day', 17800 format: 'png', 17801 maxZoom: 7, 17802 opacity: 0.75 17803 } 17804 }, 17805 ModisTerraSnowCover: { 17806 options: { 17807 variant: 'MODIS_Terra_Snow_Cover', 17808 format: 'png', 17809 maxZoom: 8, 17810 opacity: 0.75 17811 } 17812 }, 17813 ModisTerraAOD: { 17814 options: { 17815 variant: 'MODIS_Terra_Aerosol', 17816 format: 'png', 17817 maxZoom: 6, 17818 opacity: 0.75 17819 } 17820 }, 17821 ModisTerraChlorophyll: { 17822 options: { 17823 variant: 'MODIS_Terra_Chlorophyll_A', 17824 format: 'png', 17825 maxZoom: 7, 17826 opacity: 0.75 17827 } 17828 } 17829 } 17830 }, 17831 NLS: { 17832 // NLS maps are copyright National library of Scotland. 17833 // http://maps.nls.uk/projects/api/index.html 17834 // Please contact NLS for anything other than non-commercial low volume usage 17835 // 17836 // Map sources: Ordnance Survey 1:1m to 1:63K, 1920s-1940s 17837 // z0-9 - 1:1m 17838 // z10-11 - quarter inch (1:253440) 17839 // z12-18 - one inch (1:63360) 17840 url: 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', 17841 options: { 17842 attribution: '<a href="http://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>', 17843 bounds: [[49.6, -12], [61.7, 3]], 17844 minZoom: 1, 17845 maxZoom: 18, 17846 subdomains: '0123', 17847 } 17848 }, 17849 JusticeMap: { 17850 // Justice Map (http://www.justicemap.org/) 17851 // Visualize race and income data for your community, county and country. 17852 // Includes tools for data journalists, bloggers and community activists. 17853 url: 'http://www.justicemap.org/tile/{size}/{variant}/{z}/{x}/{y}.png', 17854 options: { 17855 attribution: '<a href="http://www.justicemap.org/terms.php">Justice Map</a>', 17856 // one of 'county', 'tract', 'block' 17857 size: 'county', 17858 // Bounds for USA, including Alaska and Hawaii 17859 bounds: [[14, -180], [72, -56]] 17860 }, 17861 variants: { 17862 income: 'income', 17863 americanIndian: 'indian', 17864 asian: 'asian', 17865 black: 'black', 17866 hispanic: 'hispanic', 17867 multi: 'multi', 17868 nonWhite: 'nonwhite', 17869 white: 'white', 17870 plurality: 'plural' 17871 } 17872 }, 17873 Wikimedia: { 17874 url: 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}{r}.png', 17875 options: { 17876 attribution: '<a href="https://wikimediafoundation.org/wiki/Maps_Terms_of_Use">Wikimedia</a>', 17877 minZoom: 1, 17878 maxZoom: 19 17879 } 17880 }, 17881 GeoportailFrance: { 17882 url: 'https://wxs.ign.fr/{apikey}
17882/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE={style}&TILEMATRIXSET=PM&FORMAT={format}&LAYER={variant}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}', 17883 options: { 17884 attribution: '<a target="_blank" href="https://www.geoportail.gouv.fr/">Geoportail France</a>', 17885 bounds: [[-75, -180], [81, 180]], 17886 minZoom: 2, 17887 maxZoom: 18, 17888 // Get your own geoportail apikey here : http://professionnels.ign.fr/ign/contrats/ 17889 // NB : 'choisirgeoportail' is a demonstration key that comes with no guarantee 17890 apikey: 'choisirgeoportail', 17891 format: 'image/jpeg', 17892 style : 'normal', 17893 variant: 'GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD' 17894 }, 17895 variants: { 17896 parcels: { 17897 options : { 17898 variant: 'CADASTRALPARCELS.PARCELS', 17899 maxZoom: 20, 17900 style : 'bdparcellaire', 17901 format: 'image/png' 17902 } 17903 }, 17904 ignMaps: 'GEOGRAPHICALGRIDSYSTEMS.MAPS', 17905 maps: 'GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD', 17906 orthos: { 17907 options: { 17908 maxZoom: 19, 17909 variant: 'ORTHOIMAGERY.ORTHOPHOTOS' 17910 } 17911 } 17912 } 17913 }, 17914 OneMapSG: { 17915 url: 'https://maps-{s}.onemap.sg/v3/{variant}/{z}/{x}/{y}.png', 17916 options: { 17917 variant: 'Default', 17918 minZoom: 11, 17919 maxZoom: 18, 17920 bounds: [[1.56073, 104.11475], [1.16, 103.502]], 17921 attribution: '<img src="https://docs.onemap.sg/maps/images/oneMap64-01.png" style="height:20px;width:20px;"/> New OneMap | Map data © contributors, <a href="http://SLA.gov.sg">Singapore Land Authority</a>' 17922 }, 17923 variants: { 17924 Default: 'Default', 17925 Night: 'Night', 17926 Original: 'Original', 17927 Grey: 'Grey', 17928 LandLot: 'LandLot' 17929 } 17930 } 17931 }; 17932 17933 L.tileLayer.provider = function (provider, options) { 17934 return new L.TileLayer.Provider(provider, options); 17935 }; 17936 17937 return L; 17938})); 17939; 17940/*! 17941 * jScrollPane - v2.0.19 - 2013-11-16 17942 * http://jscrollpane.kelvinluck.com/ 17943 * 17944 * Copyright (c) 2013 Kelvin Luck 17945 * Dual licensed under the MIT or GPL licenses. 17946 */ 17947! function(a, b, c) { 17948 a.fn.jScrollPane = function(d) { 17949 function e(d, e) { 17950 function f(b) { 17951 var e, h, j, l, m, n, q = !1, 17952 r = !1; 17953 if (P = b, Q === c) m = d.scrollTop(), n = d.scrollLeft(), d.css({ 17954 overflow: "hidden", 17955 padding: 0 17956 }), R = d.innerWidth() + tb, S = d.innerHeight(), d.width(R), Q = a('<div class="jspPane" />').css("padding", sb).append(d.children()), T = a('<div class="jspContainer" />').css({ 17957 width: R + "px", 17958 height: S + "px" 17959 }).append(Q).appendTo(d); 17960 else { 17961 if (d.css("width", ""), q = P.stickToBottom && C(), r = P.stickToRight && D(), l = d.innerWidth() + tb != R || d.outerHeight() != S, l && (R = d.innerWidth() + tb, S = d.innerHeight(), T.css({ 17962 width: R + "px", 17963 height: S + "px" 17964 })), !l && ub == U && Q.outerHeight() == V) return d.width(R), void 0; 17965 ub = U, Q.css("width", ""), d.width(R), T.find(">.jspVerticalBar,>.jspHorizontalBar").remove().end() 17966 } 17967 Q.css("overflow", "auto"), U = b.contentWidth ? b.contentWidth : Q[0].scrollWidth, V = Q[0].scrollHeight, Q.css("overflow", ""), W = U / R, X = V / S, Y = X > 1, Z = W > 1, Z || Y ? (d.addClass("jspScrollable"), e = P.maintainPosition && (ab || db), e && (h = A(), j = B()), g(), i(), k(), e && (y(r ? U - R : h, !1), x(q ? V - S : j, !1)), H(), E(), N(), P.enableKeyboardNavigation && J(), P.clickOnTrack && o(), L(), P.hijackInternalLinks && M()) : (d.removeClass("jspScrollable"), Q.css({ 17968 top: 0, 17969 left: 0, 17970 width: T.width() - tb 17971 }), F(), I(), K(), p()), P.autoReinitialise && !rb ? rb = setInterval(function() { 17972 f(P) 17973 }, P.autoReinitialiseDelay) : !P.autoReinitialise && rb && clearInterval(rb), m && d.scrollTop(0) && x(m, !1), n && d.scrollLeft(0) && y(n, !1), d.trigger("jsp-initialised", [Z || Y]) 17974 } 17975 17976 function g() { 17977 Y && (T.append(a('<div class="jspVerticalBar" />').append(a('<div class="jspCap jspCapTop" />'), a('<div class="jspTrack" />').append(a('<div class="jspDrag" />').append(a('<div class="jspDragTop" />'), a('<div class="jspDragBottom" />'))), a('<div class="jspCap jspCapBottom" />'))), eb = T.find(">.jspVerticalBar"), fb = eb.find(">.jspTrack"), $ = fb.find(">
17977.jspDrag"), P.showArrows && (jb = a('<a class="jspArrow jspArrowUp" />').bind("mousedown.jsp", m(0, -1)).bind("click.jsp", G), kb = a('<a class="jspArrow jspArrowDown" />').bind("mousedown.jsp", m(0, 1)).bind("click.jsp", G), P.arrowScrollOnHover && (jb.bind("mouseover.jsp", m(0, -1, jb)), kb.bind("mouseover.jsp", m(0, 1, kb))), l(fb, P.verticalArrowPositions, jb, kb)), hb = S, T.find(">.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow").each(function() { 17978 hb -= a(this).outerHeight() 17979 }), $.hover(function() { 17980 $.addClass("jspHover") 17981 }, function() { 17982 $.removeClass("jspHover") 17983 }).bind("mousedown.jsp", function(b) { 17984 a("html").bind("dragstart.jsp selectstart.jsp", G), $.addClass("jspActive"); 17985 var c = b.pageY - $.position().top; 17986 return a("html").bind("mousemove.jsp", function(a) { 17987 r(a.pageY - c, !1) 17988 }).bind("mouseup.jsp mouseleave.jsp", q), !1 17989 }), h()) 17990 } 17991 17992 function h() { 17993 fb.height(hb + "px"), ab = 0, gb = P.verticalGutter + fb.outerWidth(), Q.width(R - gb - tb); 17994 try { 17995 0 === eb.position().left && Q.css("margin-left", gb + "px") 17996 } catch (a) {} 17997 } 17998 17999 function i() { 18000 Z && (T.append(a('<div class="jspHorizontalBar" />').append(a('<div class="jspCap jspCapLeft" />'), a('<div class="jspTrack" />').append(a('<div class="jspDrag" />').append(a('<div class="jspDragLeft" />'), a('<div class="jspDragRight" />'))), a('<div class="jspCap jspCapRight" />'))), lb = T.find(">.jspHorizontalBar"), mb = lb.find(">.jspTrack"), bb = mb.find(">.jspDrag"), P.showArrows && (pb = a('<a class="jspArrow jspArrowLeft" />').bind("mousedown.jsp", m(-1, 0)).bind("click.jsp", G), qb = a('<a class="jspArrow jspArrowRight" />').bind("mousedown.jsp", m(1, 0)).bind("click.jsp", G), P.arrowScrollOnHover && (pb.bind("mouseover.jsp", m(-1, 0, pb)), qb.bind("mouseover.jsp", m(1, 0, qb))), l(mb, P.horizontalArrowPositions, pb, qb)), bb.hover(function() { 18001 bb.addClass("jspHover") 18002 }, function() { 18003 bb.removeClass("jspHover") 18004 }).bind("mousedown.jsp", function(b) { 18005 a("html").bind("dragstart.jsp selectstart.jsp", G), bb.addClass("jspActive"); 18006 var c = b.pageX - bb.position().left; 18007 return a("html").bind("mousemove.jsp", function(a) { 18008 t(a.pageX - c, !1) 18009 }).bind("mouseup.jsp mouseleave.jsp", q), !1 18010 }), nb = T.innerWidth(), j()) 18011 } 18012 18013 function j() { 18014 T.find(">.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow").each(function() { 18015 nb -= a(this).outerWidth() 18016 }), mb.width(nb + "px"), db = 0 18017 } 18018 18019 function k() { 18020 if (Z && Y) { 18021 var b = mb.outerHeight(), 18022 c = fb.outerWidth(); 18023 hb -= b, a(lb).find(">.jspCap:visible,>.jspArrow").each(function() { 18024 nb += a(this).outerWidth() 18025 }), nb -= c, S -= c, R -= b, mb.parent().append(a('<div class="jspCorner" />').css("width", b + "px")), h(), j() 18026 } 18027 Z && Q.width(T.outerWidth() - tb + "px"), V = Q.outerHeight(), X = V / S, Z && (ob = Math.ceil(1 / W * nb), ob > P.horizontalDragMaxWidth ? ob = P.horizontalDragMaxWidth : ob < P.horizontalDragMinWidth && (ob = P.horizontalDragMinWidth), bb.width(ob + "px"), cb = nb - ob, u(db)), Y && (ib = Math.ceil(1 / X * hb), ib > P.verticalDragMaxHeight ? ib = P.verticalDragMaxHeight : ib < P.verticalDragMinHeight && (ib = P.verticalDragMinHeight), $.height(ib + "px"), _ = hb - ib, s(ab)) 18028 } 18029 18030 function l(a, b, c, d) { 18031 var e, f = "before", 18032 g = "after"; 18033 "os" == b && (b = /Mac/.test(navigator.platform) ? "after" : "split"), b == f ? g = b : b == g && (f = b, e = c, c = d, d = e), a[f](c)[g](d) 18034 } 18035 18036 function m(a, b, c) { 18037 return function() { 18038 return n(a, b, this, c), this.blur(), !1 18039 } 18040 } 18041 18042 function n(b, c, d, e) { 18043 d = a(d).addClass("jspActive"); 18044 var f, g, h = !0, 18045 i = function() { 18046 0 !== b && vb.scrollByX(b * P.arrowButtonSpeed), 0 !== c && vb.scrollByY(c * P.arrowButtonSpeed), g = setTimeout(i, h ? P.initialDelay : P.arrowRepeatFreq), h = !1 18047 }; 18048 i(), f = e ? "mouseout.jsp" : "mouseup.jsp", e = e || a("html"), e.bind(f, function() { 18049 d.removeClass("jspActive"), g && clearTimeout(g), g = null, e.unbind(f) 18050 }) 18051 } 18052 18053 function o() {
18054 p(), Y && fb.bind("mousedown.jsp", function(b) { 18055 if (b.originalTarget === c || b.originalTarget == b.currentTarget) { 18056 var d, e = a(this), 18057 f = e.offset(), 18058 g = b.pageY - f.top - ab, 18059 h = !0, 18060 i = function() { 18061 var a = e.offset(), 18062 c = b.pageY - a.top - ib / 2, 18063 f = S * P.scrollPagePercent, 18064 k = _ * f / (V - S); 18065 if (0 > g) ab - k > c ? vb.scrollByY(-f) : r(c); 18066 else { 18067 if (!(g > 0)) return j(), void 0; 18068 c > ab + k ? vb.scrollByY(f) : r(c) 18069 } 18070 d = setTimeout(i, h ? P.initialDelay : P.trackClickRepeatFreq), h = !1 18071 }, 18072 j = function() { 18073 d && clearTimeout(d), d = null, a(document).unbind("mouseup.jsp", j) 18074 }; 18075 return i(), a(document).bind("mouseup.jsp", j), !1 18076 } 18077 }), Z && mb.bind("mousedown.jsp", function(b) { 18078 if (b.originalTarget === c || b.originalTarget == b.currentTarget) { 18079 var d, e = a(this), 18080 f = e.offset(), 18081 g = b.pageX - f.left - db, 18082 h = !0, 18083 i = function() { 18084 var a = e.offset(), 18085 c = b.pageX - a.left - ob / 2, 18086 f = R * P.scrollPagePercent, 18087 k = cb * f / (U - R); 18088 if (0 > g) db - k > c ? vb.scrollByX(-f) : t(c); 18089 else { 18090 if (!(g > 0)) return j(), void 0; 18091 c > db + k ? vb.scrollByX(f) : t(c) 18092 } 18093 d = setTimeout(i, h ? P.initialDelay : P.trackClickRepeatFreq), h = !1 18094 }, 18095 j = function() { 18096 d && clearTimeout(d), d = null, a(document).unbind("mouseup.jsp", j) 18097 }; 18098 return i(), a(document).bind("mouseup.jsp", j), !1 18099 } 18100 }) 18101 } 18102 18103 function p() { 18104 mb && mb.unbind("mousedown.jsp"), fb && fb.unbind("mousedown.jsp") 18105 } 18106 18107 function q() { 18108 a("html").unbind("dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp"), $ && $.removeClass("jspActive"), bb && bb.removeClass("jspActive") 18109 } 18110 18111 function r(a, b) { 18112 Y && (0 > a ? a = 0 : a > _ && (a = _), b === c && (b = P.animateScroll), b ? vb.animate($, "top", a, s) : ($.css("top", a), s(a))) 18113 } 18114 18115 function s(a) { 18116 a === c && (a = $.position().top), T.scrollTop(0), ab = a; 18117 var b = 0 === ab, 18118 e = ab == _, 18119 f = a / _, 18120 g = -f * (V - S); 18121 (wb != b || yb != e) && (wb = b, yb = e, d.trigger("jsp-arrow-change", [wb, yb, xb, zb])), v(b, e), Q.css("top", g), d.trigger("jsp-scroll-y", [-g, b, e]).trigger("scroll") 18122 } 18123 18124 function t(a, b) { 18125 Z && (0 > a ? a = 0 : a > cb && (a = cb), b === c && (b = P.animateScroll), b ? vb.animate(bb, "left", a, u) : (bb.css("left", a), u(a))) 18126 } 18127 18128 function u(a) { 18129 a === c && (a = bb.position().left), T.scrollTop(0), db = a; 18130 var b = 0 === db, 18131 e = db == cb, 18132 f = a / cb, 18133 g = -f * (U - R); 18134 (xb != b || zb != e) && (xb = b, zb = e, d.trigger("jsp-arrow-change", [wb, yb, xb, zb])), w(b, e), Q.css("left", g), d.trigger("jsp-scroll-x", [-g, b, e]).trigger("scroll") 18135 } 18136 18137 function v(a, b) { 18138 P.showArrows && (jb[a ? "addClass" : "removeClass"]("jspDisabled"), kb[b ? "addClass" : "removeClass"]("jspDisabled")) 18139 } 18140 18141 function w(a, b) { 18142 P.showArrows && (pb[a ? "addClass" : "removeClass"]("jspDisabled"), qb[b ? "addClass" : "removeClass"]("jspDisabled")) 18143 } 18144 18145 function x(a, b) { 18146 var c = a / (V - S); 18147 r(c * _, b) 18148 } 18149 18150 function y(a, b) { 18151 var c = a / (U - R); 18152 t(c * cb, b) 18153 } 18154 18155 function z(b, c, d) { 18156 var e, f, g, h, i, j, k, l, m, n = 0, 18157 o = 0; 18158 try { 18159 e = a(b) 18160 } catch (p) { 18161 return 18162 } 18163 for (f = e.outerHeight(), g = e.outerWidth(), T.scrollTop(0), T.scrollLeft(0); !e.is(".jspPane");) 18164 if (n += e.position().top, o += e.position().left, e = e.offsetParent(), /^body|html$/i.test(e[0].nodeName)) return; 18165 h = B(), j = h + S, h > n || c ? l = n - P.horizontalGutter : n + f > j && (l = n - S + f + P.horizontalGutter), isNaN(l) || x(l, d), i = A(), k = i + R, i > o || c ? m = o - P.horizontalGutter : o + g > k && (m = o - R + g + P.horizontalGutter), isNaN(m) || y(m, d) 18166 } 18167 18168 function A() { 18169 return -Q.position().left 18170 } 18171 18172 function B() { 18173 return -Q.position().top 18174 } 18175 18176 function C() { 18177 var a = V - S; 18178 return a > 20 && a - B() < 10 18179 } 18180 18181 function D() { 18182 var a = U - R; 18183 return a > 20 && a - A() < 10 18184 } 18185 18186 function E() { 18187 T.unbind(Bb).bind(Bb, function(a, b, c, d) { 18188 var e = db, 18189 f = ab, 18190 g = a.deltaFactor || P.mouseWheelSpeed; 18191 return vb.scrollBy(c * g, -d * g, !1), e == db && f == ab 18192 }) 18193 } 18194 18195 function F() { 18196 T.unbind(Bb) 18197 } 18198 18199 function G() { 18200 return !1 18201 } 18202 18203 function H() { 18204 Q.find(":input,a").unbind("focus.jsp").bind("focus.jsp", function(a) { 18205 z(a.target, !1) 18206 }) 18207 } 18208 18209 function I() { 18210 Q.find(":input,a").unbind("focus.jsp") 18211 } 18212 18213 function J() { 18214 function b() { 18215 var a = db, 18216 b = ab; 18217 switch (c) { 18218 case 40: 18219 vb.scrollByY(P.keyboardSpeed, !1); 18220 break; 18221 case 38: 18222 vb.scrollByY(-P.keyboardSpeed, !1); 18223 break; 18224 case 34: 18225 case 32: 18226 vb.scrollByY(S * P.scrollPagePercent, !1); 18227 break; 18228 case 33: 18229 vb.scrollByY(-S * P.scrollPagePercent, !1); 18230 break; 18231 case 39: 18232 vb.scrollByX(P.keyboardSpeed, !1); 18233 break; 18234 case 37: 18235 vb.scrollByX(-P.keyboardSpeed, !1) 18236 } 18237 return e = a != db || b != ab 18238 } 18239 var c, e, f = []; 18240 Z && f.push(lb[0]), Y && f.push(eb[0]), Q.focus(function() { 18241 d.focus() 18242 }
18242), d.attr("tabindex", 0).unbind("keydown.jsp keypress.jsp").bind("keydown.jsp", function(d) { 18243 if (d.target === this || f.length && a(d.target).closest(f).length) { 18244 var g = db, 18245 h = ab; 18246 switch (d.keyCode) { 18247 case 40: 18248 case 38: 18249 case 34: 18250 case 32: 18251 case 33: 18252 case 39: 18253 case 37: 18254 c = d.keyCode, b(); 18255 break; 18256 case 35: 18257 x(V - S), c = null; 18258 break; 18259 case 36: 18260 x(0), c = null 18261 } 18262 return e = d.keyCode == c && g != db || h != ab, !e 18263 } 18264 }).bind("keypress.jsp", function(a) { 18265 return a.keyCode == c && b(), !e 18266 }), P.hideFocus ? (d.css("outline", "none"), "hideFocus" in T[0] && d.attr("hideFocus", !0)) : (d.css("outline", ""), "hideFocus" in T[0] && d.attr("hideFocus", !1)) 18267 } 18268 18269 function K() { 18270 d.attr("tabindex", "-1").removeAttr("tabindex").unbind("keydown.jsp keypress.jsp") 18271 } 18272 18273 function L() { 18274 if (location.hash && location.hash.length > 1) { 18275 var b, c, d = escape(location.hash.substr(1)); 18276 try { 18277 b = a("#" + d + ', a[name="' + d + '"]') 18278 } catch (e) { 18279 return 18280 } 18281 b.length && Q.find(d) && (0 === T.scrollTop() ? c = setInterval(function() { 18282 T.scrollTop() > 0 && (z(b, !0), a(document).scrollTop(T.position().top), clearInterval(c)) 18283 }, 50) : (z(b, !0), a(document).scrollTop(T.position().top))) 18284 } 18285 } 18286 18287 function M() { 18288 a(document.body).data("jspHijack") || (a(document.body).data("jspHijack", !0), a(document.body).delegate("a[href*=#]", "click", function(c) { 18289 var d, e, f, g, h, i, j = this.href.substr(0, this.href.indexOf("#")), 18290 k = location.href; 18291 if (-1 !== location.href.indexOf("#") && (k = location.href.substr(0, location.href.indexOf("#"))), j === k) { 18292 d = escape(this.href.substr(this.href.indexOf("#") + 1)); 18293 try { 18294 e = a("#" + d + ', a[name="' + d + '"]') 18295 } catch (l) { 18296 return 18297 } 18298 e.length && (f = e.closest(".jspScrollable"), g = f.data("jsp"), g.scrollToElement(e, !0), f[0].scrollIntoView && (h = a(b).scrollTop(), i = e.offset().top, (h > i || i > h + a(b).height()) && f[0].scrollIntoView()), c.preventDefault()) 18299 } 18300 })) 18301 } 18302 18303 function N() { 18304 var a, b, c, d, e, f = !1; 18305 T.unbind("touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick").bind("touchstart.jsp", function(g) { 18306 var h = g.originalEvent.touches[0]; 18307 a = A(), b = B(), c = h.pageX, d = h.pageY, e = !1, f = !0 18308 }).bind("touchmove.jsp", function(g) { 18309 if (f) { 18310 var h = g.originalEvent.touches[0], 18311 i = db, 18312 j = ab; 18313 return vb.scrollTo(a + c - h.pageX, b + d - h.pageY), e = e || Math.abs(c - h.pageX) > 5 || Math.abs(d - h.pageY) > 5, i == db && j == ab 18314 } 18315 }).bind("touchend.jsp", function() { 18316 f = !1 18317 }).bind("click.jsp-touchclick", function() { 18318 return e ? (e = !1, !1) : void 0 18319 }) 18320 } 18321 18322 function O() { 18323 var a = B(), 18324 b = A(); 18325 d.removeClass("jspScrollable").unbind(".jsp"), d.replaceWith(Ab.append(Q.children())), Ab.scrollTop(a), Ab.scrollLeft(b), rb && clearInterval(rb) 18326 } 18327 var P, Q, R, S, T, U, V, W, X, Y, Z, $, _, ab, bb, cb, db, eb, fb, gb, hb, ib, jb, kb, lb, mb, nb, ob, pb, qb, rb, sb, tb, ub, vb = this, 18328 wb = !0, 18329 xb = !0, 18330 yb = !1, 18331 zb = !1, 18332 Ab = d.clone(!1, !1).empty(), 18333 Bb = a.fn.mwheelIntent ? "mwheelIntent.jsp" : "mousewheel.jsp"; 18334 "border-box" === d.css("box-sizing") ? (sb = 0, tb = 0) : (sb = d.css("paddingTop") + " " + d.
18334css("paddingRight") + " " + d.css("paddingBottom") + " " + d.css("paddingLeft"), tb = (parseInt(d.css("paddingLeft"), 10) || 0) + (parseInt(d.css("paddingRight"), 10) || 0)), a.extend(vb, { 18335 reinitialise: function(b) { 18336 b = a.extend({}, P, b), f(b) 18337 }, 18338 scrollToElement: function(a, b, c) { 18339 z(a, b, c) 18340 }, 18341 scrollTo: function(a, b, c) { 18342 y(a, c), x(b, c) 18343 }, 18344 scrollToX: function(a, b) { 18345 y(a, b) 18346 }, 18347 scrollToY: function(a, b) { 18348 x(a, b) 18349 }, 18350 scrollToPercentX: function(a, b) { 18351 y(a * (U - R), b) 18352 }, 18353 scrollToPercentY: function(a, b) { 18354 x(a * (V - S), b) 18355 }, 18356 scrollBy: function(a, b, c) { 18357 vb.scrollByX(a, c), vb.scrollByY(b, c) 18358 }, 18359 scrollByX: function(a, b) { 18360 var c = A() + Math[0 > a ? "floor" : "ceil"](a), 18361 d = c / (U - R); 18362 t(d * cb, b) 18363 }, 18364 scrollByY: function(a, b) { 18365 var c = B() + Math[0 > a ? "floor" : "ceil"](a), 18366 d = c / (V - S); 18367 r(d * _, b) 18368 }, 18369 positionDragX: function(a, b) { 18370 t(a, b) 18371 }, 18372 positionDragY: function(a, b) { 18373 r(a, b) 18374 }, 18375 animate: function(a, b, c, d) { 18376 var e = {}; 18377 e[b] = c, a.animate(e, { 18378 duration: P.animateDuration, 18379 easing: P.animateEase, 18380 queue: !1, 18381 step: d 18382 }) 18383 }, 18384 getContentPositionX: function() { 18385 return A() 18386 }, 18387 getContentPositionY: function() { 18388 return B() 18389 }, 18390 getContentWidth: function() { 18391 return U 18392 }, 18393 getContentHeight: function() { 18394 return V 18395 }, 18396 getPercentScrolledX: function() { 18397 return A() / (U - R) 18398 }, 18399 getPercentScrolledY: function() { 18400 return B() / (V - S) 18401 }, 18402 getIsScrollableH: function() { 18403 return Z 18404 }, 18405 getIsScrollableV: function() { 18406 return Y 18407 }, 18408 getContentPane: function() { 18409 return Q 18410 }, 18411 scrollToBottom: function(a) { 18412 r(_, a) 18413 }, 18414 hijackInternalLinks: a.noop, 18415 destroy: function() { 18416 O() 18417 } 18418 }), f(e) 18419 } 18420 return d = a.extend({}, a.fn.jScrollPane.defaults, d), a.each(["arrowButtonSpeed", "trackClickSpeed", "keyboardSpeed"], function() { 18421 d[this] = d[this] || d.speed 18422 }), this.each(function() { 18423 var b = a(this), 18424 c = b.data("jsp"); 18425 c ? c.reinitialise(d) : (a("script", b).filter('[type="text/javascript"],:not([type])').remove(), c = new e(b, d), b.data("jsp", c)) 18426 }) 18427 }, a.fn.jScrollPane.defaults = { 18428 showArrows: !1, 18429 maintainPosition: !0, 18430 stickToBottom: !1, 18431 stickToRight: !1, 18432 clickOnTrack: !0, 18433 autoReinitialise: !1, 18434 autoReinitialiseDelay: 500, 18435 verticalDragMinHeight: 0, 18436 verticalDragMaxHeight: 99999, 18437 horizontalDragMinWidth: 0, 18438 horizontalDragMaxWidth: 99999, 18439 contentWidth: c, 18440 animateScroll: !1, 18441 animateDuration: 300, 18442 animateEase: "linear", 18443 hijackInternalLinks: !1, 18444 verticalGutter: 4, 18445 horizontalGutter: 4, 18446 mouseWheelSpeed: 3, 18447 arrowButtonSpeed: 0, 18448 arrowRepeatFreq: 50, 18449 arrowScrollOnHover: !1, 18450 trackClickSpeed: 0, 18451 trackClickRepeatFreq: 70, 18452 verticalArrowPositions: "split", 18453 horizontalArrowPositions: "split", 18454 enableKeyboardNavigation: !0, 18455 hideFocus: !1, 18456 keyboardSpeed: 0, 18457 initialDelay: 300, 18458 speed: 30, 18459 scrollPagePercent: .8 18460 } 18461}(jQuery, this);; 18462/*! This file is auto-generated */ 18463/*! 18464 * imagesLoaded PACKAGED v5.0.0 18465 * JavaScript is all like "You images are done yet or what?" 18466 * MIT License 18467 */ 18468!function(t,e){"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,(function(){function t(){}let e=t.prototype;return e.on=function(t,e){if(!t||!e)return this;let i=this._events=this._events||{},s=i[t]=i[t]||[];return s.includes(e)||s.push(e),this},e.once=function(t,e){if(!t||!e)return this;this.on(t,e);let i=this._onceEvents=this._onceEvents||{};return(i[t]=i[t]||{})[e]=!0,this},e.off=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;let s=i.indexOf(e);return-1!=s&&i.splice(s,1),this},e.emitEvent=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;i=i.slice(0),e=e||[];let s=this._onceEvents&&this._onceEvents[t];for(let n of i){s&&s[n]&&(this.off(t,n),delete s[n]),n.apply(this,e)}return this},e.allOff=function(){return delete this._events,delete this._onceEvents,this},t})), 18469/*! 18470 * imagesLoaded v5.0.0 18471 * JavaScript is all like "You images are done yet or what?" 18472 * MIT License 18473 */ 18474function(t,e){"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,(function(t,e){let i=t.jQuery,s=t.console;
vendor: 4,185 bytes, lines 18474-18475
18474function n(t,e,o){if(!(this instanceof n))return new n(t,e,o);let r=t;var h;("string"==typeof t&&(r=document.querySelectorAll(t)),r)?(this.elements=(h=r,Array.isArray(h)?h:"object"==typeof h&&"number"==typeof h.length?[...h]:[h]),this.options={},"function"==typeof e?o=e:Object.assign(this.options,e),o&&this.on("always",o),this.getImages(),i&&(this.jqDeferred=new i.Deferred),setTimeout(this.check.bind(this))):s.error(`Bad element for imagesLoaded ${r||t}`)}n.prototype=Object.create(e.prototype),n.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)};const o=[1,9,11];n.prototype.addElementImages=function(t){"IMG"===t.nodeName&&this.addImage(t),!0===this.options.background&&this.addElementBackgroundImages(t);let{nodeType:e}=t;if(!e||!o.includes(e))return;let i=t.querySelectorAll("img");for(let t of i)this.addImage(t);if("string"==typeof this.options.background){let e=t.querySelectorAll(this.options.background);for(let t of e)this.addElementBackgroundImages(t)}};const r=/url\((['"])?(.*?)\1\)/gi;function h(t){this.img=t}function d(t,e){this.url=t,this.element=e,this.img=new Image}return n.prototype.addElementBackgroundImages=function(t){let e=getComputedStyle(t);if(!e)return;let i=r.exec(e.backgroundImage);for(;null!==i;){let s=i&&i[2];s&&this.addBackground(s,t),i=r.exec(e.backgroundImage)}},n.prototype.addImage=function(t){let e=new h(t);this.images.push(e)},n.prototype.addBackground=function(t,e){let i=new d(t,e);this.images.push(i)},n.prototype.check=function(){if(this.progressedCount=0,this.hasAnyBroken=!1,!this.images.length)return void this.complete();let t=(t,e,i)=>{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n}));; 18475/*! This file is auto-generated */
vendor: 24,103 bytes, lines 18476-18484
18476/*! 18477 * Masonry PACKAGED v4.2.2 18478 * Cascading grid layout library 18479 * https://masonry.desandro.com 18480 * MIT License 18481 * by David DeSandro 18482 */ 18483 18484!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(t,r),delete n[r]),r.apply(this,e)}return this}},e.allOff=function(){delete this._events,delete this._onceEvents},t}),function(t,e){"function"==typeof define&&define.amd?define("get-size/get-size",e):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s=200==Math.round(t(o.width)),r.isBoxSizeOuter=s,i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function(e,i){return e[t](i)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["desandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e};var n=Array.prototype.slice;i.makeArray=function(t){if(Array.isArray(t))return t;if(null===t||void 0===t)return[];var e="object"==typeof t&&"number"==typeof t.length;return e?n.call(t):[t]},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t.parentNode&&t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),r=0;r<i.length;r++)o.push(i[r])}}),o},i.debounceMethod=function(t,e,i){i=i||100;var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i)}},i.docReady=function(t){var e=document.readyState;"complete"==e||"interactive"==e?setTimeout(t):document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var o=t.console;return i.htmlInit=function(e,n){i.docReady(function(){var r=i.toDashed(n),s="data-"+r,a=document.querySelectorAll("["+s+"]"),h=document.querySelectorAll(".js-"+r),u=i.makeArray(a).concat(i.makeArray(h)),d=s+"-options",l=t.jQuery;u.forEach(function(t){var i,r=t.getAttribute(s)||t.getAttribute(d);try{i=r&&JSON.parse(r)}catch(a){return void(o&&o.error("Error parsing "+s+" on "+t.className+": "+a))}var h=new e(t,i);l&&l.data(t,n,h)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var r=document.documentElement.style,s="string"==typeof r.transition?"transition":"WebkitTransition",a="string"==typeof r.transform?"transform":"WebkitTransform",h={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[s],u={transform:a,transition:s,transitionDuration:s+"Duration",transitionProperty:s+"Property",transitionDelay:s+"Delay"},d=n.prototype=Object.create(t.prototype);d.constructor=n,d._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},d.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},d.getSize=function(){this.size=e(this.element)},d.css=function(t){var e=this.element.style;for(var i in t){var n=u[i]||i;e[n]=t[i]}},d.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],r=parseFloat(n),s=parseFloat(o),a=this.layout.size;-1!=n.indexOf("%")&&(r=r/100*a.width),-1!=o.indexOf("%")&&(s=s/100*a.height),r=isNaN(r)?0:r,s=isNaN(s)?0:s,r-=e?a.paddingLeft:a.paddingRight,s-=i?a.paddingTop:a.paddingBottom,this.position.x=r,this.position.y=s},d.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",r=i?"left":"right",s=i?"right":"left",a=this.position.x+t[o];e[r]=this.getXValue(a),e[s]="";var h=n?"paddingTop":"paddingBottom",u=n?"top":"bottom",d=n?"bottom":"top",l=this.position.y+t[h];e[u]=this.getYValue(l),e[d]="",this.css(e),this.emitEvent("layout",[this])},d.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},d.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},d._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=t==this.position.x&&e==this.position.y;if(this.setPosition(t,e),o&&!this.isTransitioning)return void this.layoutPosition();var r=t-i,s=e-n,a={};a.transform=this.getTranslate(r,s),this.transition({to:a,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},d.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},d.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},d.moveTo=d._transitionTo,d.setPosition=function(t,e){this.position.x=parseFloat(t),this.position.y=parseFloat(e)},d._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},d.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var l="opacity,"+o(a);d.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:l,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(h,this,!1)}},d.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},d.onotransitionend=function(t){this.ontransitionend(t)};var c={"-webkit-transform":"transform"};d.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=c[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},d.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(h,this,!1),this.isTransitioning=!1},d._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var f={transitionProperty:"",transitionDuration:"",transitionDelay:""};return d.removeTransitionStyles=function(){this.css(f)},d.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},d.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},d.remove=function(){return s&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},d.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},d.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},d.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},d.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},d.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},d.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function(t,e,i,n,o){"use strict";function r(t,e){var i=n.getQueryElement(t);if(!i)return void(h&&h.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,u&&(this.$element=u(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++l;this.element.outlayerGUID=o,c[o]=this,this._create();var r=this._getOption("initLayout");r&&this.layout()}function s(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=m[n]||1;return i*o}var h=t.console,u=t.jQuery,d=function(){},l=0,c={};r.namespace="outlayer",r.Item=o,r.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var f=r.prototype;n.extend(f,e.prototype),f.option=function(t){n.extend(this.options,t)},f._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},r.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},f._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},f.reloadItems=function(){this.items=this._itemize(this.element.children)},f._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var r=e[o],s=new i(r,this);n.push(s)}return n},f._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},f.getItemElements=function(){return this.items.map(function(t){return t.element})},f.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},f._init=f.layout,f._resetLayout=function(){this.getSize()},f.getSize=function(){this.size=i(this.element)},f._getMeasurement=function(t,e){var n,o=this.options[t];o?("string"==typeof o?n=this.element.querySelector(o):o instanceof HTMLElement&&(n=o),this[t]=n?i(n)[e]:o):this[t]=0},f.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},f._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},f._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},f._getItemLayoutPosition=function(){return{x:0,y:0}},f._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},f.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},f._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},f._postLayout=function(){this.resizeContainer()},f.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},f._getContainerSize=d,f._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},f._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s==r&&i()}var o=this,r=e.length;if(!e||!r)return void i();var s=0;e.forEach(function(e){e.once(t,n)})},f.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),u)if(this.$element=this.$element||u(this.element),e){var o=u.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},f.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},f.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},f.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},f.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},f._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},f._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},f._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},f._manageStamp=d,f._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),r={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return r},f.handleEvent=n.handleEvent,f.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},f.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},f.onresize=function(){this.resize()},n.debounceMethod(r,"onresize",100),f.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},f.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},f.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},f.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},f.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},f.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},f.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},f.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},f.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},f.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},f.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},f.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},f.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete c[e],delete this.element.outlayerGUID,u&&u.removeData(this.element,this.constructor.namespace)},r.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&c[e]},r.create=function(t,e){var i=s(r);return i.defaults=n.extend({},r.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},r.compatOptions),i.namespace=t,i.data=r.data,i.Item=s(o),n.htmlInit(i,t),u&&u.bridget&&u.bridget(t,i),i};var m={ms:1,s:1e3};return r.Item=o,r}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function(t,e){var i=t.create("masonry");i.compatOptions.fitWidth="isFitWidth";var n=i.prototype;return n._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0,this.horizontalColIndex=0},n.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i});
18484; 18485/*! 18486 * Masonry v2 shim 18487 * to maintain backwards compatibility 18488 * as of Masonry v3.1.2 18489 * 18490 * Cascading grid layout library 18491 * http://masonry.desandro.com 18492 * MIT License 18493 * by David DeSandro 18494 */ 18495!function(a){"use strict";var b=a.Masonry;b.prototype._remapV2Options=function(){this._remapOption("gutterWidth","gutter"),this._remapOption("isResizable","isResizeBound"),this._remapOption("isRTL","isOriginLeft",function(a){return!a});var a=this.options.isAnimated;if(void 0!==a&&(this.options.transitionDuration=a?this.options.transitionDuration:0),void 0===a||a){var b=this.options.animationOptions,c=b&&b.duration;c&&(this.options.transitionDuration="string"==typeof c?c:c+"ms")}},b.prototype._remapOption=function(a,b,c){var d=this.options[a];void 0!==d&&(this.options[b]=c?c(d):d)};var c=b.prototype._create;b.prototype._create=function(){var a=this;this._remapV2Options(),c.apply(this,arguments),setTimeout(function(){jQuery(a.element).addClass("masonry")},0)};var d=b.prototype.layout;b.prototype.layout=function(){this._remapV2Options(),d.apply(this,arguments)};var e=b.prototype.option;b.prototype.option=function(){e.apply(this,arguments),this._remapV2Options()};var f=b.prototype._itemize;b.prototype._itemize=function(a){var b=f.apply(this,arguments);return jQuery(a).addClass("masonry-brick"),b};var g=b.prototype.measureColumns;b.prototype.measureColumns=function(){var a=this.options.columnWidth;a&&"function"==typeof a&&(this.getContainerWidth(),this.columnWidth=a(this.containerWidth)),g.apply(this,arguments)},b.prototype.reload=function(){this.reloadItems.apply(this,arguments),this.layout.apply(this)};var h=b.prototype.destroy;b.prototype.destroy=function(){var a=this.getItemElements();jQuery(this.element).removeClass("masonry"),jQuery(a).removeClass("masonry-brick"),h.apply(this,arguments)}}(window);; 18496function wpomp_set_consent_cookies(){wpomp_set_cookie("wpomp_show_map","yes",wpomp_flocal.days_to_remember),window.location.reload()}function wpomp_set_noconsent_cookies(){wpomp_set_cookie("wpomp_show_map","no",wpomp_flocal.days_to_remember),window.location.reload()}function wpomp_get_cookie(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i<n.length;i++){for(var s=n[i];" "==s.charAt(0);)s=s.substring(1);if(0==s.indexOf(t))return s.substring(t.length,s.length)}return null}function wpomp_set_cookie(e,t,n){var i=new Date;i.setTime(i.getTime()+24*n*60*60*1e3);var s="expires="+i.toUTCString();document.cookie=e+"="+t+"; "+s+"; path=/"}!function(e){"use strict";e.fn.pagination=function(e,t){return t=jQuery.extend({items_per_page:10,num_display_entries:10,current_page:0,num_edge_entries:0,link_to:"#",prev_text:"Prev",next_text:"Next",ellipse_text:"...",prev_show_always:!1,next_show_always:!1,data_source:"",listing_container:"",callback:function(){return!1}},t||{}),this.each(function(){function n(){return Math.ceil(e/t.items_per_page)}function i(e,n){a=e,s();var i=t.callback(e,o);return i||(n.stopPropagation?n.stopPropagation():n.cancelBubble=!0),i}function s(){o.empty();var e=function(){var e=Math.ceil(t.num_display_entries/2),i=n(),s=i-t.num_display_entries;return[a>e?Math.max(Math.min(a-e,s),0):0,a>e?Math.min(a+e,i):Math.min(t.num_display_entries,i)]}(),s=n(),r=function(e,n){if(e=e<0?0:e<s?e:s-1,n=jQuery.extend({text:e+1,classes:""},n||{}),e==a)var r=jQuery("<span class='current'>"+n.text+"</span>");else r=jQuery("<a>"+n.text+"</a>").bind("click",function(e){return function(t){return i(e,t)}}(e)).attr("href",t.link_to.replace(/__id__/,e));n.classes&&r.addClass(n.classes),o.append(r)};if(t.prev_text&&(a>0||t.prev_show_always)&&r(a-1,{text:t.prev_text,classes:"prev"}),s>1){if(e[0]>0&&t.num_edge_entries>0){for(var p=Math.min(t.num_edge_entries,e[0]),l=0;l<p;l++)r(l);t.num_edge_entries<e[0]&&t.ellipse_text&&jQuery("<span>"+t.ellipse_text+"</span>").appendTo(o)}for(l=e[0];l<e[1];l++)r(l);if(e[1]<s&&t.num_edge_entries>0){s-t.num_edge_entries>e[1]&&t.ellipse_text&&jQuery("<span>"+t.ellipse_text+"</span>").appendTo(o);for(l=Math.max(s-t.num_edge_entries,e[1]);l<s;l++)r(l)}}t.next_text&&(a<s-1||t.next_show_always)&&r(a+1,{text:t.next_text,classes:"next"})}var a=t.current_page;e=!e||e<0?1:e,t.items_per_page=!t.items_per_page||t.items_per_page<0?1:t.items_per_page;var o=jQuery(this);this.selectPage=function(e){i(e)},this.prevPage=function(){return a>0&&(i(a-1),!0)},this.nextPage=function(){return a<n()-1&&(i(a+1),!0)},s(),t.callback(a,this)})},e(document).ready(function(e){e(".gm-style-iw").parent().parent().addClass("wpomp_infowindow_css"),e("div.scroll-pane").jScrollPane(),e(".wpomp-social-share").on("click",function(t){t.preventDefault();var n=e(this).attr("href");""==n.split("&url=")[1]&&(n+=window.location.href);var i=screen.width/2-250,s=screen.height/2-150;window.open(n,"","menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=500,height=300,top="+s+",left="+i)});e(".categories_filter span a").on("click",function(t){var n=e(this).closest(".wpomp_map_container"),i=e(n).find("div.wpomp_categories");if(e(this).hasClass("wpomp_grid"))e(this).addClass("active"),e(n).find("span a.wpomp_list").removeClass("active"),e(n).find("span a.wpomp_print").removeClass("active"),i.fadeOut(500,function(){i.removeClass("wpomp_listing_list").addClass("wpomp_listing_grid"),i.show();try{var t=e(n).find(".wpomp_listing_grid");if(t){var s=e(t).data("masonry");s&&s.destroy();var a=e(t).imagesLoaded(function(){a.masonry({itemSelector:".wpomp_listing_grid .wpomp_locations",columnWidth:".wpomp_listing_grid .wpomp_locations"})})}}catch(e){console.log(e)}});else if(e(this).hasClass("wpomp_list")){if(e(n).find(".wpomp_listing_grid").hasClass("masonry"))e(n).find(".wpomp_listing_grid").data("masonry").destroy();e(this).addClass("active"),e(n).find("span a.wpomp_grid").removeClass("active"),e(n).find("span a.wpomp_print").removeClass("active"),i.fadeOut(500,function(){i.removeClass("wpomp_listing_grid").addClass("wpomp_listing_list"),e(n).find(".wpomp_locations").equalHeightGrid(),i.fadeIn(500)})}else e(this).hasClass("wpomp_print")&&(e(this).addClass("active"),e(n).find("span a.wpomp_grid").removeClass("active"),e(n).find("span a.wpomp_list").removeClass("active"),e(n).find("span a.wpomp_print").removeClass("active"))})}),e.fn.equalHeight=function(){var t=[];return e.each(this,function(n,i){var s;$element=e(i),s="border-box"==$element.css("box-sizing")||"border-box"==$element.css("-moz-box-sizing")?$element.innerHe
18496ight():$element.height(),t.push(s)}),this.css("height",Math.max.apply(window,t)+"px"),this},e.fn.equalHeightGrid=function(t){this.css("height","auto");for(var n=0;n<this.length;n++)if(n%t==0){for(var i=e(this[n]),s=1;s<t;s++)i=i.add(this[n+s]);i.equalHeight()}return this},e.fn.detectGridColumns=function(){var t=0,n=0;return this.each(function(i,s){var a=e(s).offset().top;if(0!==t&&a!=t)return!1;n++,t=a}),n},e.fn.responsiveEqualHeightGrid=function(){var t=this;function n(){var e=t.detectGridColumns();t.equalHeightGrid(e)}return e(window).bind("resize load",n),n(),this};var t=/([^&=]+)=?([^&]*)/g,n=/\+/g,i=function(e){return decodeURIComponent(e.replace(n," "))};e.parseParams=function(e){for(var n,s={};n=t.exec(e);){var a=i(n[1]),o=i(n[2]);"[]"===a.substring(a.length-2)?(s[a=a.substring(0,a.length-2)]||(s[a]=[])).push(o):s[a]=o}return s}}(jQuery);; 18497!function(t,a,e,i){"use strict";var o=function(t){this.options=t};o.prototype.create_element=function(t,a,i){t.className="wpomp-control-outer";var o=e.createElement("div");o.className="wpomp-control-inner",t.appendChild(o);var n=e.createElement("div");n.className="wpomp-control-content",n.innerHTML=i,o.appendChild(n)};var n=function(a,e){var i;this.element=a,e=JSON.parse(atob(e)),this.map_data=t.extend({},{},e),i=this.map_data.map_options,this.settings=t.extend({min_zoom:"0",max_zoom:"19",zoom:"5",map_type_id:"mapbox.streets",scroll_wheel:!0,map_visual_refresh:!1,full_screen_control:!1,full_screen_control_position:"bottomright",zoom_control:!0,zoom_control_style:"SMALL",zoom_
18497control_position:"topleft",map_type_control:!0,map_type_control_style:"HORIZONTAL_BAR",map_type_control_position:"topright",scale_control:!0,overview_map_control:!0,center_lat:"40.6153983",center_lng:"-74.2535216",draggable:!0,gesture:"auto",infowindow_open_event:"click",map_data_provider:"openstreet",map_tile_url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",search_control:!1,locateme_control:!1,map_type_control:!1},{},i),this.container=t("div[rel='"+t(this.element).attr("id")+"']"),this.places=[],this.show_places=[],this.categories={},this.tabs=[],this.per_page_value=0,this.last_remove_cat_id="",this.last_selected_cat_id="",this.last_category_chkbox_action="",this.search_area="",this.url_filters=[],this.mbAttr='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',this.mbURL="",this.isMobile=!1,this.bingmaplayers={},this.infowindow_marker=L.popup({closeOnClick:!0===this.settings.close_infowindow_on_map_click}),this.init()};n.prototype={init:function(){var n=this;n.map_data.map_property&&1==n.map_data.map_property.debug_mode&&(console.log("*********wpomp Debug Mode Output*********"),console.log("Map ID ="+n.map_data.map_property.map_id),n.map_data.places&&console.log("Total Locations="+n.map_data.places.length),console.log("wpomp Object="),console.log(n.map_data),console.log("*********wpomp Debug Mode End Output*********"));var r="desktop",c=t(a).width();c<=480?r="smartphones":c>480&&c<=768?r="ipads":c>=1824&&(r="large-screens"),"desktop"!=r&&1==n.settings.mobile_specific&&(!0,n.isMobile=!0,n.settings.screens&&n.settings.screens[r]?(n.settings.width_mobile=n.settings.screens[r].map_width_mobile,n.settings.height_mobile=n.settings.screens[r].map_height_mobile,n.settings.zoom=parseInt(n.settings.screens[r].map_zoom_level_mobile),n.settings.draggable="false"!==n.settings.screens[r].map_draggable_mobile,n.settings.scroll_wheel="false"!==n.settings.screens[r].map_scrolling_wheel_mobile):(n.settings.width_mobile="",n.settings.height_mobile=""),""!=n.settings.width_mobile&&t(n.element).css("width",n.settings.width_mobile),""!=n.settings.height_mobile&&t(n.element).css("height",n.settings.height_mobile));var s={center:new L.LatLng(n.settings.center_lat,n.settings.center_lng),zoom:parseInt(n.settings.zoom),minZoom:parseInt(n.settings.min_zoom),maxZoom:parseInt(n.settings.max_zoom),scrollWheelZoom:n.settings.scroll_wheel,doubleClickZoom:!0===n.settings.doubleclickzoom,dragging:n.settings.draggable,zoomControl:!1,attributionControl:n.settings.attribution_screen_control,closePopupOnClick:!0===this.settings.close_infowindow_on_map_click};if(n.mbURL="https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token="+wpomp_local.accesstoken,"mapbox"==n.settings.map_data_provider)n.map=L.map(n.element,s),L.tileLayer(n.mbURL,{attribution:n.mbAttr,maxZoom:parseInt(n.settings.max_zoom),id:n.settings.map_type_id,accessToken:wpomp_local.accesstoken}).addTo(n.map);else if("mapquest"==n.settings.map_data_provider){var _={layers:[MQ.mapLayer()]},l=L.Util.extend({},s,_);n.map=L.map(n.element,l);L.control.attribution({prefix:!1}).addTo(n.map).addAttribution('<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>; \r\n© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors')}else if("bingmap"==n.settings.map_data_provider){n.map=L.map(n.element,s);var p={key:wpomp_local.wpomp_bingmap_key,detectRetina:!0},d={};["Aerial","AerialWithLabelsOnDemand","RoadOnDemand","CanvasDark","CanvasLight","CanvasGray"].forEach((function(t){d[t]=L.bingLayer(L.extend({imagerySet:t},p))})),n.bingmaplayers=d,d.CanvasGray.addTo(n.map)}else n.map=L.map(n.element,s),L.tileLayer(n.settings.map_tile_url,{maxZoom:parseInt(n.settings.max_zoom)}).addTo(n.map);if(n.settings.scale_control&&L.control.scale({position:"bottomleft"}).addTo(n.map),!0===n.settings.zoom_control&&L.control.zoom({position:n.settings.zoom_control_position}).addTo(n.map),"edit_location"==n.map_data.page&&setTimeout((function(){map.invalidateSize(!0)}),300),!0===n.settings.locateme_control)L.control.locate({strings:{title:"Show me where I am, yo!",popup:'<div class="wpomp_infowindow"><div class="wpomp_iw_content">You are within {distance} {unit} from this point</div></div>'},icon:"wpomp_locateme_control",drawCircle:!1,position:n.settings.locateme_control_position}).addTo(n.map);if(!0===n.settings.full_screen_control&&n.map.addControl(new L.Control.Fullscreen({position:n.settings.full_screen_control_position})),n.settings.map_type_control){var m=n.settings.openstreet_styles_markup;if("mapbox"==n.settings.map_data_provider&&(m=n.settings.map_box_styles_markup),"mapquest"==n.settings.map_data_provider&&(m=n.settings.mapquest_styles_markup),"bingmap"==n.settings.map_data_provider&&(m=n.settings.binmaps_styles_markup),n.map.addControl(new(L.Control.extend({options:{position:n.settings.map_type_control_position},onAdd:function(t){var a=L.DomUtil.create("div","info legend");return a.innerHTML=m,a.firstChild.onmousedown=a.firstChild.ondblclick=L.DomEvent.stopPropagation,a}}))),t(e).on("change","select.wpomp_map_type",(function(){var a=t(this).val(),e=n.settings.openstreet_styles[a];L.tileLayer(e,{maxZoom:parseInt(n.settings.max_zoom)}
18497).addTo(n.map)})),t(e).on("change","select.wpomp_mapbox_type",(function(){var a="https://api.mapbox.com/styles/v1/mapbox/"+t(this).val()+"/tiles/{z}/{x}/{y}?access_token="+wpomp_local.accesstoken;L.tileLayer(a,{maxZoom:parseInt(n.settings.max_zoom)}).addTo(n.map)})),"mapquest"==n.settings.map_data_provider){var g={Map:MQ.mapLayer(),Hybrid:MQ.hybridLayer(),Satellite:MQ.satelliteLayer(),Dark:MQ.darkLayer(),Light:MQ.lightLayer()};t(e).on("change","select.wpomp_mapquest_type",(function(){var a=t(this).val(),e=g[a];n.map.addLayer(e)}))}"bingmap"==n.settings.map_data_provider&&t(e).on("change","select.wpomp_bingmap_type",(function(){var a=t(this).val(),e=n.bingmaplayers[a];n.map.addLayer(e)}))}if(n.settings.search_control&&n.map.addControl(new(L.Control.extend({options:{position:n.settings.search_control_position},onAdd:function(t){var a=L.DomUtil.create("div","info legend");return a.innerHTML='<div><input type="text" name="wpomp_map_suggest" id="wpomp_map_suggest'+n.map_data.map_property.map_id+'" class="wpomp_map_suggest" placeholder="'+wpomp_local.autocomplete_placeholder+'" ></div>',a}}))),n.map_loaded(),n.responsive_map(),n.create_markers(),n.display_markers(),void 0!==n.settings.google_fonts&&n.load_google_fonts(n.settings.google_fonts),1==n.settings.map_control&&void 0!==n.settings.map_control_settings){var f=new o;t.each(n.settings.map_control_settings,(function(t,a){L.Control.Watermark=L.Control.extend({onAdd:function(t){var i=e.createElement("div");return f.create_element(i,n.map,a.html),i.index=1,i},onRemove:function(t){}}),L.control.watermark=function(t){return new L.Control.Watermark(t)},L.control.watermark({position:"bottomleft"}).addTo(n.map)}))}if(1==n.settings.search_control&&n.show_search_control(),n.map_data.listing){if(n.map_data.listing.default_sorting){var u="";"listorder"==n.map_data.listing.default_sorting.orderby&&(u="num"),n.sorting(n.map_data.listing.default_sorting.orderby,n.map_data.listing.default_sorting.inorder,u)}}else n.map_data.map_tabs!==i&&"undefined"!=n.map_data.map_tabs&&typeof n.map_data.map_tabs.category_tab!==i&&"undefined"!==n.map_data.map_tabs.category_tab&&typeof n.map_data.map_tabs.category_tab.cat_tab!==i&&n.map_data.map_tabs.category_tab.cat_tab&&(n.map_data.map_tabs.category_tab.cat_post_order===i&&(n.map_data.map_tabs.category_tab.cat_post_order="asc"),n.sorting("title",n.map_data.map_tabs.category_tab.cat_post_order));n.map_data.listing&&(t(n.container).on("click",".categories_filter_reset_btn",(function(){t(n.container).find(".wpomp_filter_wrappers select").each((function(){t(this).find("option:first").attr("selected","selected"),t(this).find("option:first").prop("selected","selected")})),t(".wpomp_search_input").val(""),n.update_filters()})),t(n.container).on("change",'[data-filter="dropdown"]',(function(){n.update_filters()})),t(n.container).on("click",'[data-filter="checklist"]',(function(){n.update_filters()})),t(n.container).on("click",'[data-filter="list"]',(function(){t(this).hasClass("fc_selected")?t(this).removeClass("fc_selected"):t(this).addClass("fc_selected"),n.update_filters()})),n.display_filters_listing(),n.custom_filters(),t.each(n.map_data.listing.filters,(function(a,e){t(n.container).find('select[name="'+e+'"]').on("change",(function(){n.update_filters()}))})),t(n.container).find('[data-filter="map-sorting"]').on("change",(function(){var a=t(this).val().split("__"),e="";""!==a[0]&&""!==a[1]&&(void 0!==a[2]&&(e=a[2]),n.sorting(a[0],a[1],e),n.update_places_listing())})),t(n.container).find('[data-name="radius"]').on("change",(function(){var a=t(n.container).find('[data-input="wpomp-search-text"]').val();a.length>=2&&""!=t(this).val()?t.get(location.protocol+"//nominatim.openstreetmap.org/search?format=json&q="+a,(function(t){if(Object.keys(t).length>0){var a=new L.LatLng(t[0].lat,t[0].lon);n.search_area=a,n.update_filters()}})):(n.search_area="",n.update_filters())})),t(n.container).find('[data-filter="map-perpage-location-sorting"]').on("change",(function(){n.per_page_value=t(this).val(),n.update_filters()})),t(n.container).find('[data-input="wpomp-search-text"]').on("keyup",(function(){var a=t(this).val();t(n.container).find('[data-filter="map-radius"]').val(""),n.search_area="",a.length>
18497=2&&1==n.map_data.listing.apply_default_radius?a.length>=2&&n.update_filters():n.update_filters()})),t(n.container).find(".location_pagination"+n.map_data.map_property.map_id).pagination(n.show_places.length,{callback:n.display_places_listing,map_data:n,items_per_page:n.map_data.listing.pagination.listing_per_page,prev_text:wpomp_local.prev,next_text:wpomp_local.next})),t(this.container).on("click",".wpomp_locateme_control",(function(){n.get_current_location((function(t){n.map.setCenter(t),n.map_center_marker&&n.map_center_marker.setPosition(t),n.set_center_circle&&n.set_center_circle.setCenter(t)}))})),void 0!==n.map_data.geojson&&n.load_json(n.map_data.geojson),t("body").on("click",".wpomp_marker_link",(function(){t("html, body").animate({scrollTop:t(n.container).offset().top-150},500),n.open_infowindow(t(this).data("marker"),t(this).data("source"))})),t(n.container).on("click",".wpomp_locations a[data-marker]",(function(){var a=this;t("html, body").animate({scrollTop:t(n.container).offset().top-150},500),t.each(n.map_data.places,(function(e,i){if(parseInt(i.id)==parseInt(t(a).data("marker"))&&i.source==t(a).data("source"))return n.map.panTo(i.marker.getLatLng()),!1})),setTimeout((function(){n.open_infowindow(t(a).data("marker"),t(a).data("source"))}),600)})),t(n.container).on("click",".wpomp_location_container a[data-marker]",(function(){n.open_infowindow(t(this).data("marker"),t(this).data("source"))})),n.google_auto_suggest(t(".wpomp_auto_suggest")),!0===n.settings.fit_bounds&&n.fit_bounds(),!0===n.settings.url_filters&&n.apply_url_filters(),void 0!==n.map_data.map_tabs&&(this.map_widgets(),t(n.container).find(".wpomp_toggle_main_container").find("div[id^='wpomp_tab_']").css("display","none"),n.settings.infowindow_filter_only!==i&&!1!==n.settings.infowindow_filter_only||(t(n.container).find("input[data-marker-category]").attr("checked",!0),t(n.container).find("input[data-marker-location]").attr("checked",!0),t(n.container).find("input[data-marker-category]").prop("checked",!0),t(n.container).find("input[data-marker-location]").prop("checked",!0)),void 0!==n.map_data.map_tabs&&this.map_data.map_tabs.category_tab&&!0===this.map_data.map_tabs.category_tab.select_all&&t(n.container).find('input[name="wpomp_select_all"]').click((function(){t(this).is(":checked")?(t(n.container).find("input[data-marker-category]").attr("checked",!0),t(n.container).find("input[data-marker-location]").attr("checked",!0),t(n.container).find("input[data-marker-category]").prop("checked",!0),t(n.container).find("input[data-marker-location]").prop("checked",!0)):(t(n.container).find("input[data-marker-category]").attr("checked",!1),t(n.container).find("input[data-marker-location]").attr("checked",!1),t(n.container).find("input[data-marker-category]").prop("checked",!1),t(n.container).find("input[data-marker-location]").prop("checked",!1)),n.update_filters()})),t(n.container).on("click",".wpomp_toggle_container",(function(){t(n.container).find(".wpomp_toggle_main_container").slideToggle("slow"),t(this).text()==wpomp_local.hide?t(this).text(wpomp_local.show):t(this).text(wpomp_local.hide)})),void 0!==n.map_data.map_tabs&&!0===n.map_data.map_tabs.hide_tabs_default&&t(n.container).find(".wpomp_toggle_container").trigger("click"),t(n.container).find(".wpomp_specific_route_item").attr("checked",!0),t(n.container).find(".wpomp_toggle_main_container").find("div[id^='wpomp_tab_']").first().css("display","block"),t(n.container).on("click","li[class^='wpomp-tab-'] a",(function(){t(n.container).find("li[class^='wpomp-tab-'] a").removeClass("active"),t(this).addClass("active"),t(n.container).find(".wpomp_toggle_main_container").find("div[id^='wpomp_tab_']").css("display","none"),t(n.container).find(".wpomp_toggle_main_container").find("#wpomp_tab_"+t(this).parent().attr("rel")).css("display","block")})),t(n.container).on("change","input[data-marker-category]",(function(){var a=t(this).data("marker-category"),e=this;if(t(e).data("child-cats")){var i=t(e).data("child-cats").toString();if(-1!==i.indexOf(","))var o=i.split(",");else(o=[]).push(i)}!1===t(this).is(":checked")?(n.last_remove_cat_id=a,n.last_category_chkbox_action="unchecked",t(e).closest('[data-container="wpomp-category-tab-item"]').find("input[data-marker-location]").attr("checked",!1),t(e).closest('[data-container="wpomp-category-tab-item"]').find("input[data-marker-location]").prop("checked",!1),o&&t.each(o,(function(a,i){t(e).parent().parent().find('[data-marker-category="'+i+'"]').attr("checked",!1),t(e).parent().parent().find('[data-marker-category="'+i+'"]').parent().find("input[data-marker-location]").attr("checked",!1),t(e).parent().parent().find('[data-marker-category="'+i+'"]').prop("checked",!1),t(e).parent().parent().find('[data-marker-category="'+i+'"]').parent().find("input[data-marker-location]").prop("checked",!1)}))):(n.last_selected_cat_id=a,n.last_category_chkbox_action="checked",t(e).closest('[data-container="wpomp-category-tab-item"]').find("input[data-marker-location]").attr("checked",!0),t(e).closest('[data-container="wpomp-category-tab-item"]').find("input[data-marker-location]").prop("checked",!0),o&&t.each(o,(function(a,i){t(e).parent().parent().find('[data-marker-category="'+i+'"]').attr("checked",!0),t(e).parent().parent().find('[data-marker-category="'+i+'"]').parent().find("input[data-marker-location]").attr("checked",!0),t(e).parent().parent().find('[data-marker-category="'+i+'"]').prop("checked",!0),t(e).parent().parent().find('[data-marker-category="'+i+'"]').parent().find("input[data-marker-location]").prop("checked",!0)}))),n.update_filters(),void 0!==n.map_data.places&&t.each(n.map_data.places,(function(t,a){n.get_updated_icon_image(a)}))})),t(n.container).on("change","input[data-marker-location]",(function(){n.update_filters()}))),t(n.container).find(".wpomp-accordion").accordion({speed:"slow"})},load_google_fonts:function(a){a&&a.length>0&&t.each(a,(function(t,a){a.indexOf(",")>=0&&(a=(a=a.split(","))[0]),a.indexOf('"')>=0&&(a=(a=a.replace('"',"")).replace('"',"")),WebFont.load({google:{families:[a]}})}))},get_updated_icon_image:function(a){var e=this;if((""!=e.last_remove_cat_id||""!=e.last_selected_cat_id)&&a.categories&&parseInt(a.categories.length)>1)if("unchecked"==e.last_category_chkbox_action){var i=parseInt(e.last_remove_cat_id);t.each(e.map_data.marker_category_icons,(function(t,e){if(t!=i){var o=L.icon({iconUrl:e,iconSize:[32,32],iconAnchor:[16,32],popupAnchor:[0,-55]});return a.marker.setIcon(o),!1}}))}else{i=e.last_selected_cat_id;t.each(e.map_data.marker_category_icons,(function(t,e){if(t==i){var o=L.icon({iconUrl:e,iconSize:[32,32],iconAnchor:[16,32]});return a.marker.setIcon(o),!1}}))}},map_widgets:function(){var a="";this.map_data.map_tabs.category_tab&&!0===this.map_data.map_tabs.category_tab.cat_tab&&this.widget_category(),"undefined"!=(a+=this.show_tabs())&&t(this.container).find(".wpomp_map_parent").append(a)},widget_category:function(){var a=this;if(!0===a.map_data.map_tabs.category_tab.select_all)var e='<div class="wpomp-select-all"><input checked="checked" type="checkbox" value="true" name="wpomp_select_all">  '+wpomp_local.select_all+"</div>";else e="";var o={},n={};void 0!==a.map_data.places&&t.each(a.map_data.places,(function(e,r){void 0!==r.categories&&t.each(r.categories,(function(t,e){var c=!0,s="";if(void 0!==a.map_data.map_tabs&&(s=a.search_category(a.map_data.map_tabs.category_tab.child_cats,e.id,[],o,n)),s.length>0&&(c=!1),void 0!==e.type&&"category"==e.type&&e.name&&1==c){void 0===o[e.id]&&(o[e.id]={},o[e.id].data=[]),o[e.id].cat_id=e.id,o[e.id].cat_title=e.name,o[e.id].cat_marker_icon=e.icon,e.extension_fields&&e.extension_fields.cat_order&&(o[e.id].cat_order=e.extension_fields.cat_order);var _="";r.location.redirect_permalink&&(_=r.location.redirect_permalink);var l="";r.location.redirect_custom_link&&(l=r.location.redirect_custom_link),o[e.id].data.push({cat_location_id:r.id,cat_location_title:r.title,cat_location_address:r.address,cat_location_zoom:r.location.zoom,onclick_action:r.location.onclick_action,redirect_permalink:_,redirect_custom_link:l,source:r.source})}else if(void 0!==e.type&&"category"==e.type&&e.name&&0==c){void 0===n[e.id]&&(n[e.id]={},n[e.id].data=[],n[e.id].parent_cat=s),n[e.id].cat_id=e.id,n[e.id].cat_title=e.name,n[e.id].cat_marker_icon=e.icon,e.extension_fields&&e.extension_fields.cat_order&&(n[e.id].cat_order=e.extension_fields.cat_order);_="";r.location.redirect_permalink&&(_=r.location.redirect_permalink);l="";r.location.redirect_custom_link&&(l=r.location.redirect_custom_link),n[e.id].data.push({cat_location_id:r.id,cat_location_title:r.title,cat_location_address:r.address,cat_location_zoom:r.location.zoom,onclick_action:r.location.onclick_action,redirect_permalink:_,redirect_custom_link:l,source:r.source}),o[s]!==i&&(void 0===o[s].child_cats&&(o[s].child_cats=[]),o[s].child_cats[e.id]=e.id)}}))}));var r=[];void 0!==o&&t.each(o,(function(e,i){var o=i.data.length;void 0!==n&&t.each(n,(function(a,e){e.parent_cat==i.cat_id&&(o+=e.data.length,t.each(n,(function(t,a){a.parent_cat==e.cat_id&&(o+=a.data.length)})))})),i.loc_count=o,"count"==a.map_data.map_tabs.category_tab.cat_order_by?r.push(i.loc_count):"category"==a.map_data.map_tabs.category_tab.cat_order_by?i.cat_order?r.push(i.cat_order):!i.
18497cat_order&&a.map_data.map_tabs.category_tab.all_cats[i.cat_id]&&a.map_data.map_tabs.category_tab.all_cats[i.cat_id].extensions_fields&&(i.cat_order=a.map_data.map_tabs.category_tab.all_cats[i.cat_id].extensions_fields.cat_order,r.push(i.cat_order)):i.cat_title?r.push(i.cat_title):!i.cat_title&&a.map_data.map_tabs.category_tab.all_cats[i.cat_id]&&(i.cat_title=a.map_data.map_tabs.category_tab.all_cats[i.cat_id].group_map_title,r.push(i.cat_title))})),void 0!==a.map_data.map_tabs&&"category"==a.map_data.map_tabs.category_tab.cat_order_by?r.sort((function(t,a){return t-a})):void 0!==a.map_data.map_tabs&&"count"==a.map_data.map_tabs.category_tab.cat_order_by?r.sort((function(t,a){return a-t})):r.sort();var c=[],s=[];t.each(r,(function(e,i){t.each(o,(function(e,o){var n;n="count"==a.map_data.map_tabs.category_tab.cat_order_by?o.loc_count:"category"==a.map_data.map_tabs.category_tab.cat_order_by?o.cat_order:o.cat_title,i==n&&-1==t.inArray(o.cat_id,s)&&(c.push(o),s.push(o.cat_id))}))})),void 0!==c&&t.each(c,(function(o,r){var c="";if(!r.cat_title&&a.map_data.map_tabs.category_tab.all_cats[r.cat_id]&&(r.cat_title=a.map_data.map_tabs.category_tab.all_cats[r.cat_id].group_map_title),!r.cat_marker_icon&&a.map_data.map_tabs.category_tab.all_cats[r.cat_id]&&(r.cat_marker_icon=a.map_data.map_tabs.category_tab.all_cats[r.cat_id].group_marker),void 0!==r.cat_marker_icon&&(c='<span class="arrow"><img src="'+r.cat_marker_icon+'"></span>'),e+='<div class="wpomp_tab_item" data-container="wpomp-category-tab-item">',r.child_cats!==i){r.child_cats=r.child_cats.filter((function(t){return""!==t}));var s=' data-child-cats="'+r.child_cats.join(",")+'"'}else s="";e+='<input type="checkbox"'+s+' data-marker-category="'+r.cat_id+'" value="'+r.cat_id+'">';var _=r.loc_count;t.each(a.map_data.map_tabs.category_tab.child_cats,(function(t,a){a==r.cat_id&&0==_&&(_="")}));var l="";if(!0===a.map_data.map_tabs.category_tab.show_count&&""!=_&&(l=" ("+_+")"),e+='<a href="javascript:void(0);" class="wpomp_cat_title wpomp-accordion accordion-close">'+r.cat_title+l+c+"</a>",!0!==a.map_data.map_tabs.category_tab.hide_location&&(e+='<div class="scroll-pane" style="max-height:300px;width:100%;">',e+='<ul class="wpomp_location_container">',t.each(r.data,(function(t,a){"marker"==a.onclick_action?e+='<li><input type="checkbox" data-marker-location="'+a.cat_location_id+'" value="'+a.cat_location_id+'" /><a data-source="'+a.source+'" data-marker="'+a.cat_location_id+'" data-zoom="'+a.cat_location_zoom+'" href="javascript:void(0);">'+a.cat_location_title+"</a></li>":"post"==a.onclick_action?e+='<li><input type="checkbox" data-marker-location="'+a.cat_location_id+'" value="'+a.cat_location_id+'" /><a href="'+a.redirect_permalink+'" target="_blank">'+a.cat_location_title+"</a></li>":"custom_link"==a.onclick_action&&(e+='<li><input type="checkbox" data-marker-location="'+a.cat_location_id+'" value="'+a.cat_location_id+'" /><a href="'+a.redirect_custom_link+'" target="_blank">'+a.cat_location_title+"</a></li>")})),e+="</ul>",e+="</div>"),e+="</div>",void 0!==n){e+=a.display_sub_categories(n,r.cat_id,"",20)}})),void 0!==a.map_data.map_tabs&&a.add_tab(a.map_data.map_tabs.category_tab.cat_tab_title,e)},add_tab:function(t,a){var e=[];e.title=t,e.content=a,this.tabs.push(e)},search_category:function(a,e,i,o,n){var r=this,c=!0;return t.each(a,(function(a,s){a==e&&(i=s,c=!1,void 0===n[e]&&(n[e]={},n[e].data=[],n[e].parent_cat=s,n[e].cat_id=e,t.each(r.categories,(function(t,a){a.group_map_id==e&&(n[e].cat_title=a.group_map_title,n[e].cat_marker_icon=a.group_marker)}))),i=r.search_category(r.map_data.map_tabs.category_tab.child_cats,s,i,o,n))})),1==c&&void 0===o[e]&&(o[e]={},o[e].data=[],o[e].cat_id=e,t.each(r.categories,(function(t,a){a.group_map_id==e&&(o[e].cat_title=a.group_map_title,o[e].cat_marker_icon=a.group_marker)}))),i},show_tabs:function(){if(!(0===this.tabs.length||this.map_data.listing&&1==this.map_data.listing.hide_map)){var a='<div class="wpomp_tabs_container cleanslate"><ul class="wpomp_tabs clearfix">';return t.each(this.tabs,(function(t,e){a+=0==t?'<li class="wpomp-tab-'+t+'" rel="'+t+'"><a class="active" href="javascript:void(0);">'+e.title+"</a></li>":'<li class="wpomp-tab-'+t+'" rel="'+t+'"><a href="javascript:void(0);">'+e.title+"</a></li>"})),a+="</ul>",a+='<div class="wpomp_toggle_main_container">',t.each(this.tabs,(function(t,e){a+='<div id="wpomp_tab_'+t+'">',a+=e.content,a+="</div>"})),a+='</div><div class="wpomp_toggle_container">'+wpomp_local.hide+"</div></div>"}},load_json:function(t){this.map.data.loadGeoJson(t)},wpomp_within_radius:function(a,e){var i=this,o=t(i.container).find('[data-name="radius"]').val(),n=i.map_data.listing.radius_dimension;
184971==i.map_data.listing.apply_default_radius&&""==o&&(o=i.map_data.listing.default_radius,n=i.map_data.listing.default_radius_dimension),o="km"==n?1e3*parseInt(o):1609.34*parseInt(o);var r=a.marker.getLatLng();return e.distanceTo(r)<o},marker_bind:function(a){this.event_listener(a,"drag",(function(){var a=this.getLatLng();t(".google_latitude").val(a.lat),t(".google_longitude").val(a.lng)}))},google_auto_suggest:function(a){a=t(".wpomp_auto_suggest");var e=this,i="",o="";wpomp_local.wpomp_country_specific&&1==wpomp_local.wpomp_country_specific&&wpomp_local.wpomp_countries&&null!=wpomp_local.wpomp_countries?(i=wpomp_local.wpomp_countries.join(","),o="https://nominatim.openstreetmap.org/search?countrycodes="+i):o="https://nominatim.openstreetmap.org/search",a.each((function(){var i=t(this).attr("id"),n={geojsonServiceAddress:o,map_obj:e,serachboxID:"#"+i};t(a).parent().GeoJsonAutocomplete(n)}))},display_sub_categories:function(a,e,o,n){var r=this,c=[];void 0!==a&&t.each(a,(function(e,i){var o=i.data.length;void 0!==a&&t.each(a,(function(e,n){
18497n.parent_cat==i.cat_id&&(o+=n.data.length,t.each(a,(function(t,a){a.parent_cat==n.cat_id&&(o+=a.data.length)})))})),i.loc_count=o,"count"==r.map_data.map_tabs.category_tab.cat_order_by?c.push(i.loc_count):"category"==r.map_data.map_tabs.category_tab.cat_order_by?i.cat_order?c.push(i.cat_order):!i.cat_order&&r.map_data.map_tabs.category_tab.all_cats[i.cat_id]&&(i.cat_order=r.map_data.map_tabs.category_tab.all_cats[i.cat_id].extensions_fields.cat_order,c.push(i.cat_order)):i.cat_title?c.push(i.cat_title):!i.cat_title&&r.map_data.map_tabs.category_tab.all_cats[i.cat_id]&&(i.cat_title=r.map_data.map_tabs.category_tab.all_cats[i.cat_id].group_map_title,c.push(i.cat_title))})),"category"==r.map_data.map_tabs.category_tab.cat_order_by?c.sort((function(t,a){return t-a})):"count"==r.map_data.map_tabs.category_tab.cat_order_by?c.sort((function(t,a){return a-t})):c.sort();var s=[],_=[];return t.each(c,(function(e,i){t.each(a,(function(a,e){var o;o="count"==r.map_data.map_tabs.category_tab.cat_order_by?e.loc_count:"category"==r.map_data.map_tabs.category_tab.cat_order_by?e.cat_order:e.cat_title,i==o&&-1==t.inArray(e.cat_id,_)&&(s.push(e),_.push(e.cat_id))}))})),t.each(s,(function(c,s){if(s.parent_cat==e){var _="";if(!s.cat_title&&r.map_data.map_tabs.category_tab.all_cats[s.cat_id]&&(s.cat_title=r.map_data.map_tabs.category_tab.all_cats[s.cat_id].group_map_title),!s.cat_marker_icon&&r.map_data.map_tabs.category_tab.all_cats[s.cat_id]&&(s.cat_marker_icon=r.map_data.map_tabs.category_tab.all_cats[s.cat_id].group_marker),void 0!==s.cat_marker_icon&&(_='<span class="arrow"><img src="'+s.cat_marker_icon+'"></span>'),o+='<div class="wpomp_tab_item" data-container="wpomp-category-tab-item" style="padding-left:'+n+'px;">',r.map_data.map_tabs.category_tab.parent_cats!==i&&r.map_data.map_tabs.category_tab.parent_cats[s.cat_id])var l=' data-child-cats="'+r.map_data.map_tabs.category_tab.parent_cats[s.cat_id].join(",")+'"';else l="";o+='<input type="checkbox"'+l+' data-parent-cat="'+e+'" data-marker-category="'+s.cat_id+'" value="'+s.cat_id+'">';var p=s.loc_count;t.each(r.map_data.map_tabs.category_tab.child_cats,(function(t,a){a==s.cat_id&&0==p&&(p="")}));var d="";d=!0===r.map_data.map_tabs.category_tab.show_count&&""!=p?" ("+p+")":"",o+='<a href="javascript:void(0);" class="wpomp_cat_title wpomp-accordion accordion-close">'+s.cat_title+d+_+"</a>",!0!==r.map_data.map_tabs.category_tab.hide_location&&(o+='<div class="scroll-pane" style="height: 97px; width:100%;">',o+='<ul class="wpomp_location_container">',t.each(s.data,(function(t,a){"marker"==a.onclick_action?o+='<li><input type="checkbox" data-marker-location="'+a.cat_location_id+'" value="'+a.cat_location_id+'" /><a data-marker="'+a.cat_location_id+'" data-zoom="'+a.cat_location_zoom+'" href="javascript:void(0);">'+a.cat_location_title+"</a></li>":"post"==a.onclick_action?o+='<li><input type="checkbox" data-marker-location="'+a.cat_location_id+'" value="'+a.cat_location_id+'" /><a href="'+a.redirect_permalink+'" target="_blank">'+a.cat_location_title+"</a></li>":"custom_link"==a.onclick_action&&(o+='<li><input type="checkbox" data-marker-location="'+a.cat_location_id+'" value="'+a.cat_location_id+'" /><a href="'+a.redirect_custom_link+'" target="_blank">'+a.cat_location_title+"</a></li>")})),o+="</ul>",o+="</div>"),o+="</div>",o+=r.display_sub_categories(a,s.cat_id,"",n+20)}else if(c+1==a.length)return})),o},sorting:function(t,a,e){switch(t){case"category":this.places.sort(this.sortByCategory),this.show_places.sort(this.sortByCategory),"desc"==a&&(this.places.reverse(),this.show_places.reverse());break;case"title":this.map_data.places!==i&&this.map_data.places.sort(this.sortByTitle),this.show_places!==i&&this.show_places.sort(this.sortByTitle),"desc"==a&&(this.map_data.places.reverse(),this.places.reverse(),this.show_places.reverse());break;case"address":this.map_data.places.sort(this.sortByAddress),this.show_places.sort(this.sortByAddress),"desc"==a&&(this.places.reverse(),this.show_places.reverse());break;default:var o=this.map_data.places[0];void 0!==o[t]?(this.map_data.places.sort(this.sortByPlace(t,e)),this.show_places.sort(this.sortByPlace(t,e))):void 0!==o.location[t]?(this.map_data.places.sort(this.sortByLocation(t,e)),this.show_places.sort(this.sortByLocation(t,e))):void 0!==o.location.extra_fields[t]&&(this.map_data.places.sort(this.sortByExtraFields(t,e)),this.show_places.sort(this.sortByExtraFields(t,e))),"desc"==a&&(this.places.reverse(),this.show_places.reverse())}},sortByExtraFields:function(t,a){return function(e,i){if(void 0!==i.location.extra_fields[t]&&void 0!==e.location.extra_fields[t]){if(null==i.location.extra_fields[t]&&(i.location.extra_fields[t]=""),null==e.location.extra_fields[t]&&(e.location.extra_fields[t]=""),"num"==a)var o=parseInt(e.location.extra_fields[t]),n=parseInt(i.location.extra_fields[t]);else o=String(e.location.extra_fields[t]).toLowerCase(),n=String(i.location.extra_fields[t]).toLowerCase();return o<n?-1:o>n?1:0}}},sortByLocation:function(t,a){return function(e,i){if(i.location[t]&&e.location[t]&&e.location[t]&&i.location[t]){var o=String(e.location[t]).toLowerCase(),n=String(i.location[t]).toLowerCase();return"num"==a&&(o=parseInt(o),n=parseInt(n)),o<n?-1:o>n?1:0}}},sortByPlace:function(t,a){return function(e,i){if(i[t]&&e[t]&&e[t]&&i[t]){var o=e[t],n=i[t];if("num"==a)o=parseInt(o),n=parseInt(n);else o=String(o).toLowerCase(),n=String(n).toLowerCase();return o<n?-1:o>n?1:0}}},sortByCategory:function(t,a){if(a.categories[0]&&t.categories[0]&&t.categories[0].name&&a.categories[0].name){var e=String(t.categories[0].name).toLowerCase(),i=String(a.categories[0].name).toLowerCase();return e<i?-1:e>i?1:0}},sortByTitle:function(t,a){var e=String(t.title).toLowerCase(),i=String(a.title).toLowerCase();return e<i?-1:e>i?1:0},sortByValue:function(t,a){var e=String(t).toLowerCase(),i=String(a).toLowerCase();return e<i?-1:e>i?1:0},sortByAddress:function(t,a){var e=String(t.address).toLowerCase(),i=String(a.address).toLowerCase();return e<i?-1:e>i?1:0},update_filters:function(){var a=this,e={},i=t(a.container).find('[data-filter="dropdown"]'),o=t(a.container).find('[data-filter="checklist"]:checked'),n=t(a.container).find('[data-filter="list"].fc_selected');t.each(i,(function(a,i){""!=t(this).val()&&(void 0===e[t(this).data("name")]&&(e[t(this).data("name")]=[]),e[t(this).data("name")].push(t(this).val()))})),t.each(o,(function(a,i){void 0===e[t(this).data("name")]&&(e[t(this).data("name")]=[]),e[t(this).data("name")].push(t(this).val())})),t.each(n,(function(a,i){void 0===e[t(this).data("name")]&&(e[t(this).data("name")]=[]),e[t(this).data("name")].push(t(this).data("value").toString())})),this.apply_filters(e)},apply_url_filters:function(){var a=this,e=location.search.substring(1),i=t.parseParams(e||"");t.isEmptyObject(i)||(a.url_filters=i,t.each(i,(function(e,i){"search"==e&&t(a.container).find('[data-input="wpomp-search-text"]').val(i)})),a.apply_filters({}))},apply_filters:function(a){var e=this,o=!0;e.show_places=[];var n=!1;if(t(e.container).find('[data-input="wpomp-search-text"]').length>0){var r=t(e.container).find('[data-input="wpomp-search-text"]').val();(r=String(r).toLowerCase()).length>0&&(n=!0)}if(e.map_data.map_tabs&&e.map_data.map_tabs.category_tab&&!0===e.map_data.map_tabs.category_tab.cat_tab||t(e.container).find("input[data-marker-category]").length>0){var c=t(e.container).find("input[data-marker-category]:checked"),s=[],_=[];c.length>0&&t.each(c,(function(a,e){s.push(t(e).data("marker-category"));var i=t(e).closest('[data-container="wpomp-category-tab-item"]').find("input[data-marker-location]:not(:checked)");i.length>0&&t.each(i,(function(a,e){_.push(t(e).data("marker-location"))}))}));
18497var l=t(e.container).find('[data-container="wpomp-category-tab-item"]').find("input[data-marker-location]:checked"),p=[];l.length>0&&t.each(l,(function(a,e){p.push(t(e).data("marker-location"))}))}if(void 0!==e.map_data.places&&t.each(e.map_data.places,(function(c,l){if(o=!0,void 0!==a&&t.each(a,(function(a,e){var i=!1;if(t.isArray(e)){if(void 0!==l.categories&&"category"==a&&t.each(l.categories,(function(a,o){t.inArray(o.id,e)>-1&&(i=!0)})),void 0!==l.custom_filters&&t.each(l.custom_filters,(function(o,n){a==o&&(i=!1,t.isArray(n)?t.each(n,(function(a,o){t.inArray(o,e)>-1&&(i=!0)})):n==e.val&&(i=!0))})),void 0!==l[a])t.inArray(l[a],e)>-1&&(i=!0);else if(void 0!==l.location[a])t.inArray(l.location[a],e)>-1&&(i=!0);else if(l.location.extra_fields&&void 0!==l.location.extra_fields[a]){var n=e[0];(l.location.extra_fields[a]&&l.location.extra_fields[a].indexOf(n)>-1||t.inArray(l.location.extra_fields[a],e)>-1)&&(i=!0)}0==i&&(o=!1)}else e.val=""})),!0===n&&!0===o&&(o=l.title!=i&&String(l.title).toLowerCase().indexOf(r)>=0||(l.content!=i&&String(l.content).toLowerCase().indexOf(r)>=0||(String(l.location.lat).toLowerCase().indexOf(r)>=0||(String(l.location.lng).toLowerCase().indexOf(r)>=0||(!!(l.address&&String(l.address).toLowerCase().indexOf(r)>=0)||(!!(l.location.state&&String(l.location.state).toLowerCase().indexOf(r)>=0)||(!!(l.location.country&&String(l.location.country).toLowerCase().indexOf(r)>=0)||(!!(l.location.postal_code&&String(l.location.postal_code).toLowerCase().indexOf(r)>=0)||(!!(l.location.city&&String(l.location.city).toLowerCase().indexOf(r)>=0)||void 0!==e.search_area&&""!=e.search_area&&!0===e.wpomp_within_radius(l,e.search_area))))))))),void 0!==l.location.extra_fields&&t.each(l.location.extra_fields,(function(t,a){a&&(a=a.toString())&&String(a).toLowerCase().indexOf(r)>=0&&(o=!0)}))),(l.categories.length==i||"undefined"==l.categories.length)&&s&&s.length>0&&0==t(e.container).find('input[name="wpomp_select_all"]').is(":checked")&&o&&(o=!1),s&&0!=o&&l.categories.length!=i){var d=!1;0===s.length?void 0!==l.categories&&t.each(l.categories,(function(t,a){""===a.id&&(d=!0)})):void 0!==l.categories&&t.each(l.categories,(function(a,e){if(""===e.id)d=!0;else if(t.inArray(parseInt(e.id),s)>-1){d=!0;var i=L.icon({iconUrl:e.icon,iconSize:[32,32],iconAnchor:[16,32],popupAnchor:[0,-55]});l.marker.setIcon(i)}})),0!==_.length&&t.inArray(parseInt(l.id),_)>-1&&(d=!1),o=!1!==d,0!==p.length&&t.inArray(parseInt(l.id),p)>-1&&(o=!0)}l.marker.visible=o,0==o?l.marker.remove():l.marker.addTo(e.map),!0===o&&e.show_places.push(l)})),typeof e.map_data.map_options.bound_map_after_filter!=typeof i&&!0===e.map_data.map_options.bound_map_after_filter){var d=new L.LatLngBounds;if(e.show_places.length>0){for(var m=0;m<e.show_places.length;m++)d.extend(new L.LatLng(parseFloat(e.show_places[m].location.lat),parseFloat(e.show_places[m].location.lng)));e.map.fitBounds(d)}}if(e.map_data.listing){if(t(e.container).find('[data-filter="map-sorting"]').val()){var g=t(e.container).find('[data-filter="map-sorting"]').val().split("__"),f="";""!==g[0]&&""!==g[1]&&(void 0!==g[2]&&(f=g[2]),e.sorting(g[0],g[1],f))}else if(e.map_data.listing.default_sorting){f="";"listorder"==e.map_data.listing.default_sorting.orderby&&(f="num"),e.sorting(e.map_data.listing.default_sorting.orderby,e.map_data.listing.default_sorting.inorder,f)}e.update_places_listing()}},create_perpage_option:function(){var t="";return t+='<select name="map_perpage_location_sorting" data-filter="map-perpage-location-sorting" class="choose_salutation">',t+='<option value="'+this.map_data.listing.pagination.listing_per_page+'">'+wpomp_local.show_locations+"</option>",t+='<option value="25">25</option>',t+='<option value="50">50</option>',t+='<option value="100">100</option>',t+='<option value="200">200</option>',t+='<option value="500">500</option>',t+='<option value="'+this.show_places.length+'">'+wpomp_local.all_location+"</option>",t+="</select>"},create_sorting:function(){var a="";return!0===this.map_data.listing.display_sorting_filter&&(a+='<select name="map_sorting" data-filter="map-sorting"><option value="">'+wpomp_local.sort_by+"</option>
18497",t.each(this.map_data.listing.sorting_options,(function(t,e){a+="<option value='"+t+"'>"+e+"</option>"})),a+="</select>"),a},create_radius:function(){var a="";if(!0===this.map_data.listing.display_radius_filter){a+='<select data-name="radius" name="map_radius"><option value="">'+wpomp_local.select_radius+"</option>";var e=this.map_data.listing.radius_options,o=this.map_data.listing.radius_dimension;e!=i&&t.each(e.split(","),(function(t,e){a+="miles"==o?"<option value='"+e+"'>"+e+" "+wpomp_local.miles+"</option>":"<option value='"+e+"'>"+e+" "+wpomp_local.km+"</option>"})),a+="</select>"}return a},custom_filters:function(){var a=this,e=this.map_data.places,i=this.map_data.filters;void 0!==i&&void 0!==i.custom_filters&&0!=i.custom_filters.length&&t.each(i.custom_filters,(function(o,n){var r="",c={};t.each(n,(function(o,n){t.each(n,(function(a,o){t.each(e,(function(e,o){if("category"==a)void 0===o.categories&&(o.categories={}),t.each(o.categories,(function(t,a){void 0===c[a.type]&&(c[a.type]={}),a.name&&(c[a.type][a.name]=a.id)}));else{if(void 0!==o[a]&&(void 0===c[a]&&(c[a]={}),o[a]&&(c[a][o[a]]=o[a])),void 0!==o.location.extra_fields[a]&&(void 0===c[a]&&(c[a]={}),o.location.extra_fields[a]&&(c[a][o.location.extra_fields[a]]=o.location.extra_fields[a])),void 0!==o.location[a]&&(void 0===c[a]&&(c[a]={}),o.location[a]&&(c[a][o.location[a]]=o.location[a])),void 0!==o.custom_filters&&void 0!==o.custom_filters[a]&&(void 0===c[a]&&(c[a]={}),o.custom_filters[a])){var n=o.custom_filters[a];t.isArray(n)?t.each(n,(function(t,e){c[a][e]=e})):c[a][n]=n}if("radius"==a){void 0===c[a]&&(c[a]={});var r=i.radius_options,s=i.radius_dimension;t.each(r.split(","),(function(t,e){"miles"==s?c[a][e+" "+wpomp_local.miles]=e:c[a][e+" "+wpomp_local.km]=e}))}}}))})),"dropdown"==o&&void 0!==c&&t.each(c,(function(e,i){i=a.sort_object_by_value(i),i=a.sort_object_by_unique_values(i),r+='<select data-filter="dropdown" name="place_'+e+'" data-name = "'+e+'">',r+='<option value="">'+(n[e]?n[e]:"Select "+e)+"</option>",t.each(i,(function(t,a){var e=a;""!=(a=(a=a.replace("'","'")).replace('"',"""))&&null!=a&&(r+="<option value='"+a+"'>"+e+"</option>")})),r+="</select>"})),"checklist"==o&&void 0!==c&&t.each(c,(function(a,e){r+='<div class="wpomp_filters_checklist">',r+='<label data-filter = "place_'+a+'" >'+(i.custom_filters[a]?i.custom_filters[a]:"Select "+a)+"</label>",t.each(e,(function(t,e){""!=e&&null!=e&&(r+="<input data-filter='checklist' type='checkbox' data-name = '"+a+"' value='"+e+"'>"+t)})),r+="</div>"})),"list"==o&&void 0!==c&&t.each(c,(function(a,e){r+='<div class="wpomp_filters_list">',r+='<label data-filter = "place_'+a+'" >'+(i.custom_filters[a]?i.custom_filters[a]:"Select "+a)+"</label><ul>",t.each(e,(function(t,e){""!=e&&null!=e&&(r+="<li data-filter='list' data-name = '"+a+"' data-value='"+e+"'>"+t+"</li>")})),r+="</ul></div>"}))})),t("body").find(i.filters_container).append(r)}))},sort_object_by_keyvalue:function(t,a,e,i){var o=[];for(var n in t)o.push(t[n]);return o.sort(this.sortByPlace(a,e)),"desc"==i&&o.reverse(),o},sort_object_by_unique_values:function(t){var a=[];for(var e in t)t[e].indexOf(",")>-1?t[e].split(/\s*,\s*/).forEach((function(t){a.push(t.trim())})):a.push(t[e].trim());return a.filter((function(t,e){return a.indexOf(t)==e})).sort()},sort_object_by_value:function(t){var a=[];for(var e in t)a.push(e);a.sort(this.sortByValue);for(var i={},o=0;o<a.length;o++)i[a[o]]=t[a[o]];return i},create_filters:function(){var a=this,e={},i=this.map_data.places,o=this.map_data.listing,n=o.display_taxonomies_all_filter;t.each(i,(function(a,i){void 0===i.categories&&(i.categories={}),t.each(i.categories,(function(t,a){void 0===e[a.type]&&(e[a.type]={}),a.name&&(a.extension_fields&&a.extension_fields.cat_order?e[a.type][a.name]={id:a.id,order:a.extension_fields.cat_order,name:a.name}:e[a.type][a.name]={id:a.id,order:0,name:a.name})}))}));var r="",c="name",s="",_="asc";return a.map_data.listing&&a.map_data.listing.default_sorting&&("listorder"==a.map_data.listing.default_sorting.orderby&&(c="order",s="num",_=a.map_data.listing.default_sorting.inorder),_=a.map_data.listing.default_sorting.inorder),t.each(e,(function(e,i){if(!0===o.display_category_filter&&"category"==e)r+='<select data-filter="dropdown" data-name="category" name="place_'+e+'">',r+='<option value="">'+wpomp_local.select_category+"</option>",i=a.sort_object_by_keyvalue(i,c,s,_),t.each(i,(function(t,a){r+="<option value='"+a.id+"'>"+a.name+"</option>"})),r+="</select>";else if(!0===o.display_taxonomies_filter){if(null===n)return!1;n.indexOf(e)>-1&&(r+='<select data-filter="dropdown" data-name="category" name="place_'+e+'">',r+='<option value="">Select '+e+"</option>",t.each(i,(function(t,a){r+="<option value='"+a+"'>"+t+"</option>"})),r+="</select>")}})),r},update_places_listing:function(){var a=this;a.per_page_value>0?a.per_page_value=a.per_page_value:a.per_page_value=a.map_data.listing.pagination.listing_per_page,t(a.container).find(".location_pagination"+a.map_data.map_property.map_id).pagination(a.show_places.length,{callback:a.display_places_listing,map_data:a,items_per_page:a.per_page_value,prev_text:wpomp_local.prev,next_text:wpomp_local.next})},display_filters_listing:function(){if(this.map_data.listing){var a=this.map_data.listing.hide_locations,e=this.map_data.listing.list_grid;if(1!=a){var i='<div class="wpomp_listing_container">';i+="<div class='wpomp_categories wpomp_print_listing "+e+"' data-container='wpomp-listing-"+t(this.element).attr("id")+"'></div>",i+="</div>",t(this.map_data.listing.listing_container).html(i)}this.map_data.listing.filters_position;var o=this.display_filters();"undefined"!==this.map_data.layoutManager&&"true"==this.map_data.layoutManager?t(this.container).find(".wpgmp_filter_wrappers").length>0&&t(this.container).find(".wpgmp_filter_wrappers").html(this.listing_filter_content):t(this.container).find(".wpomp_filter_wrappers").html(o)}},display_filters:function(){var t=this.map_data.listing.hide_locations,a="";if(a+='<div class="wpomp_before_listing">'+this.map_data.listing.listing_header+"</div>",!0===this.map_data.listing.display_search_form){var e="";!0===this.map_data.listing.search_field_autosuggest&&(e="wpomp_auto_suggest"),a+='<div class="wpomp_listing_header"><div class="wpomp_search_form"><input id="searchBox" type="text" rel="24" data-input="wpomp-search-text" name="wpomp_search_input" class="wpomp_search_input '+e+'" placeholder="'+wpomp_local.search_placeholder+'"></div></div>'}return a+='<div class="categories_filter">'+this.create_filters()+'<div data-container="wpomp-filters-container"></div>',1!=t&&(a+=this.create_sorting()+""),1!=t&&!0===this.map_data.listing.display_location_per_page_filter&&(a+=" "+this.create_perpage_option()+" "),a+=" "+this.create_radius()+" ",1!=t&&!0===this.map_data.listing.display_grid_option&&(a+=" "+wpomp_local.img_grid+wpomp_local.img_list),void 0!==this.map_data.map_options.display_reset_button&&!0===this.map_data.map_options.display_reset_button&&(a+='<div class="categories_filter_reset"><input type="button" class="categories_filter_reset_btn" name="categories_filter_reset_btn" value="'+this.map_data.map_options.map_reset_button_text+'"></div>'),a+="</div>"},display_places_listing:function(a,e){var o="",n=this,r=(t('select[name = "place_category"]'),10);r=n.items_per_page?n.items_per_page:n.map_data.map_data.listing.pagination.listing_per_page;var c=n.map_data.show_places,s=n.map_data.map_data.listing.listing_container,_=n.map_data.map_data.listing.listing_placeholder,l=Math.min((a+1)*r,c.length),p="",d="";if(l>0)for(var m=a*r;m<l;m++){var g=c[m],f=_;g.id&&("marker"==g.location.onclick_action?(p='<a href="javascript:void(0);" data-source="'+g.source+'" class="place_title" data-zoom="'+g.location.zoom+'" data-marker="'+g.id+'" >'+g.title+"</a>",d='href="javascript:void(0);" data-source="'+g.source+'" data-zoom="'+g.location.zoom+'" data-marker="'+g.id+'"'):"post"==g.location.onclick_action?(p='<a href="'+g.location.redirect_permalink+'" target="_blank">'+g.title+"</a>",d='href="'+g.location.redirect_permalink+'" target="_blank"'):"custom_link"==g.location.onclick_action?(p='<a href="'+g.location.redirect_custom_link+'" target="_blank">'+g.title+"</a>",d='href="'+g.location.redirect_custom_link+'" target="_blank"'):(p='<a href="javascript:void(0);" class="place_title" data-source="'+g.source+'" data-zoom="'+g.location.zoom+'" data-marker="'+g.id+'" >'+g.title+"</a>",d='href="javascript:void(0);"data-source="'+g.source+'" data-zoom="'+g.location.zoom+'" data-marker="'+g.id+'"'));var u=[],h=[],v={};if(g.categories)for(var w=0;w<g.categories.length;w++)if(""!==g.categories[w].icon&&u.push("<img title='"+g.categories[w].name+"' alt='"+g.categories[w].name+"' src='"+g.categories[w].icon+"' />"),"category"==g.categories[w].type&&""!=g.categories[w].name&&h.push(g.categories[w].name),"category"!=g.categories[w].type){if(void 0===g.categories[w].name)continue;if(g.categories[w].name)var y=",";void 0===v[g.categories[w].type]&&(v[g.categories[w].type]=""),v[g.categories[w].type]+=g.categories[w].name+y}var k="";k="post"==g.source?g.location.extra_fields.post_featured_image:g.location.marker_image;var b={"{marker_id}":g.id,"{marker_title}":p,"{marker_address}":g.address,"{marker_latitude}":g.location.lat,"{marker_longitude}":g.location.lng,"{marker_city}":g.location.city,"{marker_state}":g.location.state,"{marker_country}":g.location.country,"{marker_postal_code}":g.location.postal_code,"{marker_zoom}":g.location.zoom,"{marker_icon}":u,"{marker_category}":h.join(", "),"{marker_message}":g.content,"{marker_image}":k,"{marker_featured_image}":k,"{wpomp_listing_html}":g.listing_hook,"{onclick_action}":d};if(void 0!==g.location.extra_fields)for(var x in g.location.extra_fields)g.location.extra_fields[x]?b["{"+x+"}"]=g.location.extra_fields[x]:b["{"+x+"}"]="<div class='wpomp_empty'>wpomp_empty</div>";if(n.map_data.map_data.map_options.link_extra_field!=i&&""!=n.map_data.map_data.map_options.link_extra_field){var L=n.map_data.map_data.map_options.link_extra_field;for(var C in L)"<div class='wpomp_empty'>wpomp_empty</div>"!=b[C]&&""!=C&&(f=f.replace(C,L[C]))}for(var z in b)b[z]!=i&&"undefined"!=b[z]||(b[z]="");if(v)for(var S in v)b["{"+S+"}"]=A(v[S]);var A=function(t){var a=t.lastIndexOf(",");return t.substring(0,a)};o+=f=f.replace(/{[^{}]+}/g,(function(t){return t in b?b[t]:""}))}else o="<div class='wpomp_no_locations'>"+wpomp_local.wpomp_location_no_results+"</div>";o+='<div id="wpomp_pagination"></div>',o='<div class="fc-'+n.map_data.map_data.listing.list_item_skin.type+"-"+n.map_data.map_data.listing.list_item_skin.name+' fc-wait"><div data-page="2" class="fc-component-6" data-layout="'+n.map_data.map_data.listing.list_item_skin.name+'" >'+o+"</div></div>",t(s).find(".wpomp_categories").html(o),t(s).find(".wpomp_extra_field:contains('wpomp_empty')").remove(),t(s).find(".wpomp_empty").prev().remove(),t(s).find(".wpomp_empty").remove();try{var I=t(s).find(".wpomp_listing_grid");if(I){var O=t(I).data("masonry");O&&O.destroy();var j=t(I).imagesLoaded((function(){j.masonry({itemSelector:".wpomp_listing_grid .wpomp_locations",columnWidth:".wpomp_listing_grid .wpomp_locations"})}))}}catch(t){console.log(t)}return!1},open_infowindow:function(a,e){var i=this;t.each(this.map_data.places,(function(t,o){parseInt(o.id)==parseInt(a)&&o.source==e&&i.openInfoWindow(o)}))},event_listener:function(t,a,e){t.on(a,e)},map_loaded:function(){var a=this;a.map.getCenter();!0===a.settings.center_by_nearest?a.center_by_nearest():!0===a.settings.show_center_marker&&a.show_center_marker(),!1===a.settings.center_by_nearest&&!0===a.settings.show_center_circle&&a.show_center_circle(),t("body").on("click",".fc-accordion-tab",(function(){if(t(this).hasClass("active")){t(this).removeClass("active");t(this).next().removeClass("active")}else{t(".fc-accordion-tab").removeClass("active"),t(".fc-accordion dd").removeClass("active"),t(this).addClass("active");t(this).next().addClass("active")}}))},responsive_map:function(){this.map},show_search_control:function(){var a=this,e=t(".wpomp_map_suggest"),i="",o="";wpomp_local.wpomp_country_specific&&1==wpomp_local.wpomp_country_specific&&wpomp_local.wpomp_countries&&null!=wpomp_local.wpomp_countries?(i=wpomp_local.wpomp_countries.join(","),o="https://nominatim.openstreetmap.org/search?countrycodes="+i):o="https://nominatim.openstreetmap.org/search",e.each((function(){var i=t(this).attr("id"),n={geojsonServiceAddress:o,map_obj:a,serachboxID:"#"+i};t(e).parent().GeoJsonAutocomplete(n)}))},fit_bounds:function(){var t=this.map_data.places,a=new L.LatLngBounds;t!==i&&t.forEach((function(t){t.location.lat&&t.location.lng&&a.extend(new L.LatLng(parseFloat(t.location.lat),parseFloat(t.location.lng)))})),this.map.fitBounds(a)},create_markers:function(){var a,e=this,o=e.map_data.places,n=[];t.each(o,(function(t,o){if(o.location.lat&&o.location.lng){void 0===o.categories&&(o.c
18497ategories={}),void 0===o.location.icon&&(o.location.icon=e.settings.marker_default_icon),o.marker=new L.Marker(new L.LatLng(parseFloat(o.location.lat),parseFloat(o.location.lng)),{icon:L.icon({iconUrl:o.location.icon,iconSize:[32,32],iconAnchor:[16,32],popupAnchor:[0,-55]}),draggable:o.location.draggable}),(o.location.infowindow_disable||"manual"!=o.source)&&o.marker.bindPopup(o.content),!0===e.settings.infowindow_filter_only?(o.marker.visible=!1,o.marker.remove()):o.marker.addTo(e.map),"edit_location"==e.map_data.page&&e.marker_bind(o.marker);var r=[];if(void 0!==o.categories)for(var c in o.categories)r.push(o.categories[c].name);var s="",_="";_="post"==o.source?o.location.extra_fields.post_featured_image:o.location.marker_image;var l="",p="fc-infowindow-";if("post"==o.source?(l=e.settings.infowindow_geotags_setting,p="wpomp_infowindow_post fc-item-"+e.settings.infowindow_post_skin.name):(l=e.settings.infowindow_setting,"edit_location"!=e.map_data.page&&e.settings.infowindow_skin&&(p="fc-infowindow-"+e.settings.infowindow_skin.name)),void 0===l&&(l=o.content),a={"{marker_id}":o.id,"{marker_title}":o.title,"{marker_address}":o.address,"{marker_latitude}":o.location.lat,"{marker_longitude}":o.location.lng,"{marker_city}":o.location.city,"{marker_state}":o.location.state,"{marker_country}":o.location.country,"{marker_postal_code}":o.location.postal_code,"{marker_zoom}":o.location.zoom,"{marker_icon}":o.location.icon,"{marker_category}":r.join(", "),"{marker_message}":o.content,"{marker_image}":_},void 0!==o.location.extra_fields)for(var d in o.location.extra_fields)o.location.extra_fields[d]?a["{"+d+"}"]=o.location.extra_fields[d]:a["{"+d+"}"]="<div class='wpomp_empty'></div>";s=""===(s=l=l.replace(/{[^{}]+}/g,(function(t){return t in a&&a[t]!=i?a[t]:""})))?!0===e.settings.map_infowindow_customisations&&!0===e.settings.show_infowindow_header?'<div class="wpomp_infowindow '+p+'"><div class="wpomp_iw_head"><div class="wpomp_iw_head_content">'+o.title+'</div></div><div class="wpomp_iw_content">'+o.content+"</div></div>":'<div class="wpomp_infowindow '+p+'"><div class="wpomp_iw_content">'+o.content+"</div></div>":!0===e.settings.map_infowindow_customisations&&!0===e.settings.show_infowindow_header?'<div class="wpomp_infowindow '+p+'"><div class="wpomp_iw_head"><div class="wpomp_iw_head_content">'+o.title+'</div></div><div class="wpomp_iw_content">'+s+"</div></div>":'<div class="wpomp_infowindow '+p+'"><div class="wpomp_iw_content">'+s+"</div></div>",o.infowindow_data=s,o.infowindow=e.infowindow_marker,(!0===o.location.infowindow_default_open||!0===e.settings.default_infowindow_open)&&e.openInfoWindow(o);var m=e.settings.infowindow_open_event;e.isMobile&&(m="click"),e.event_listener(o.marker,m,(function(){(o.location.infowindow_disable||"manual"!=o.source)&&e.openInfoWindow(o)})),e.places.push(o)}else n.push(t)})),t.each(n,(function(t,a){delete o[n]}))},display_markers:function(){var a=this;a.show_places=[],a.categories=[];for(var e={},i=0;i<a.places.length;i++)!0===a.settings.infowindow_filter_only?a.places[i].marker.remove():a.places[i].marker.addTo(a.map),a.show_places.push(this.places[i]),void 0!==a.places[i].categories&&t.each(a.places[i].categories,(function(t,a){void 0===e[a.name]&&(e[a.name]=a)}));this.categories=e},show_center_circle:function(){var t=this;""==t.settings.center_circle_radius&&(t.settings.center_circle_radius=5);var a=t.map.getCenter();L.circle(a,{fillColor:t.settings.center_circle_fillcolor,fillOpacity:t.settings.center_circle_fillopacity,color:t.settings.center_circle_strokecolor,opacity:t.settings.center_circle_strokeopacity,weight:t.settings.center_circle_strokeweight,radius:1e3*parseInt(t.settings.center_circle_radius)}).addTo(t.map)},show_center_marker:function(){var t=this;t.settings.center_marker_infowindow;var a=t.map.getCenter();t.map_center_marker=new L.Marker(a,{icon:L.icon({iconUrl:t.settings.center_marker_icon,iconSize:[32,32],iconAnchor:[16,32],popupAnchor:[0,-30]}),draggable:!0}).addTo(t.map),void 0===t.map_center_info&&(t.map_center_info=t.infowindow_marker),""!=t.settings.center_marker_infowindow&&t.event_listener(t.map_center_marker,"click",(function(){var e="";e=t.settings.center_marker_infowindow!=i?t.settings.center_marker_infowindow:wpomp_local.default_center_msg,t.map_center_info.setContent('<div class="wpomp_infowindow"><div class="wpomp_iw_content">'+e+"</div></div>"),t.map_center_info.setLatLng(a).openOn(t.map)}))},center_by_nearest:function(){var t=this;this.get_current_location((function(a){t.user_location_marker||(t.user_location_marker=new L.Marker(a,{icon:L.icon({iconUrl:t.settings.center_marker_icon,iconSize:[32,32],iconAnchor:[16,32],popupAnchor:[0,-30]}),title:wpomp_local.center_location_message}).addTo(t.map)),void 0===t.map_center_info&&(t.map_center_info=t.infowindow_marker),""!=t.settings.center_marker_infowindow&&t.event_listener(t.user_location_marker,"click",(function(){var e="";t.settings.center_marker_infowindow!=i&&(e=t.settings.center_marker_infowindow),t.map_center_info.setContent('<div class="wpomp_infowindow"><div class="wpomp_iw_content">'+e+"</div></div>"),t.map_center_info.setLatLng(a).openOn(t.map)}
18497)),t.map.setView(a,t.settings.zoom),!0===t.settings.show_center_circle&&t.show_center_circle(),t.map_data.listing&&1==t.map_data.listing.apply_default_radius&&(t.search_area=a)}),(function(a){t.user_location_marker||(t.user_location_marker=new L.Marker(a,{icon:L.icon({iconUrl:t.settings.center_marker_icon,iconSize:[32,32],iconAnchor:[16,32],popupAnchor:[0,-30]}),title:wpomp_local.center_location_message}).addTo(t.map)),void 0===t.map_center_info&&(t.map_center_info=t.infowindow_marker),""!=t.settings.center_marker_infowindow&&t.event_listener(t.user_location_marker,"click",(function(){var e="";t.settings.center_marker_infowindow!=i&&(e=t.settings.center_marker_infowindow),t.map_center_info.setContent('<div class="wpomp_infowindow"><div class="wpomp_iw_content">'+e+"</div></div>"),t.map_center_info.setLatLng(a).openOn(t.map)})),t.map.panTo(a),!0===t.settings.show_center_circle&&t.show_center_circle(),t.map_data.listing&&1==t.map_data.listing.apply_default_radius&&(t.search_area=a)}))},get_current_location:function(t,a){var e=this;void 0===e.user_location?navigator.geolocation.getCurrentPosition((function(a){e.user_location=new L.LatLng(a.coords.latitude,a.coords.longitude),t&&t(e.user_location)}),(function(t){e.user_location=e.map.getCenter(),a&&a(e.user_location)}),{enableHighAccuracy:!0,timeout:5e4,maximumAge:0}):t&&t(e.user_location)},openInfoWindow:function(e){var o=this;"post"==e.source?o.settings.infowindow_post_skin.name:"edit_location"!=o.map_data.page&&o.settings.infowindow_skin&&o.settings.infowindow_skin.name,e.infowindow=e.marker.getPopup(),e.infowindow!=i&&(e.infowindow.setContent(e.infowindow_data),"post"==e.location.onclick_action?"yes"==e.location.open_new_tab?a.open(e.location.redirect_permalink,"_blank"):a.open(e.location.redirect_permalink,"_self"):"custom_link"==e.location.onclick_action?"yes"==e.location.open_new_tab?a.open(e.location.redirect_custom_link,"_blank"):a.open(e.location.redirect_custom_link,"_self"):(e.infowindow.setLatLng(e.marker.getLatLng()).openOn(o.map),void 0!==o.settings.infowindow_click_change_center&&1==o.settings.infowindow_click_change_center&&o.map.panTo(e.marker.getLatLng()),void 0!==o.settings.infowindow_click_change_zoom&&o.settings.infowindow_click_change_zoom>0&&(o.map.setZoom(o.settings.infowindow_click_change_zoom),o.map.panTo(e.marker.getLatLng()))),t(o.container).find(".wpomp_empty").prev().remove(),t(o.container).find(".wpomp_empty").remove())}},t.fn.osm_maps=function(a,e){return this.each((function(i){t.data(this,"wpomp_maps")||t.data(this,"wpomp_maps",new n(this,a,e))})),this}}(jQuery,window,document);;
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.