PageSourceSearch

https://bvgh.org/_static/??-eJylU8FuwyAM/aElrFKn5TLtsGv/YXLAqcgMZh…899rP8hznSz2eAXWsTv7u3w2r10z4fuePwB5B6N8Q==

js bvgh.org collected 2026-09-24 19:45:44 UTC 834,820 bytes, 18,497 lines download raw bytes

1!function(){"use strict";var e,t={noop:function(){},texturize:function(e){return(e=(e=(e=(e+="").replace(/'/g,"&#8217;").replace(/&#039;/g,"&#8217;")).replace(/"/g,"&#8221;").replace(/&#034;/g,"&#8221;").replace(/&quot;/g,"&#8221;").replace(/[\u201D]/g,"&#8221;")).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:"&#x2212;",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="&#215;",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( /&nbsp;/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>'&lt;' and '&gt;' - div elements</li>
13606		 *         <li>'&lt;"class" and '&gt;' - div with a class</li>
13607		 *         <li>'&lt;"#id" and '&gt;' - div with an ID</li>
13608		 *       </ul>
13609		 *     </li>
13610		 *     <li>Examples:
13611		 *       <ul>
13612		 *         <li>'&lt;"wrapper"flipt&gt;'</li>
13613		 *         <li>'&lt;lf&lt;t&gt;ip&gt;'</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": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
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) == '&pound;' ) {
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">&#x2026;</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, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
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					'&copy; <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: '&copy; 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: &copy; <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: &copy; <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: &copy; <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: &copy; <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: &copy; <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: &copy; <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					'&copy; <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> &mdash; 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">&copy; 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> &mdash; ' +
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">&copy;  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 &copy; Esri'
17448			},
17449			variants: {
17450				WorldStreetMap: {
17451					options: {
17452						attribution:
17453							'{attribution.Esri} &mdash; ' +
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} &mdash; Copyright: &copy;2012 DeLorme'
17463					}
17464				},
17465				WorldTopoMap: {
17466					options: {
17467						variant: 'World_Topo_Map',
17468						attribution:
17469							'{attribution.Esri} &mdash; ' +
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} &mdash; ' +
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} &mdash; ' +
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} &mdash; Source: Esri'
17495					}
17496				},
17497				WorldPhysical: {
17498					options: {
17499						variant: 'World_Physical_Map',
17500						maxZoom: 8,
17501						attribution: '{attribution.Esri} &mdash; Source: US National Park Service'
17502					}
17503				},
17504				OceanBasemap: {
17505					options: {
17506						variant: 'Ocean_Basemap',
17507						maxZoom: 13,
17508						attribution: '{attribution.Esri} &mdash; 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} &mdash; 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} &mdash; 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 &copy; <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 &copy; 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} &amp; USGS'
17684			}
17685		},
17686		CartoDB: {
17687			url: 'https://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}{r}.png',
17688			options: {
17689				attribution: '{attribution.OpenStreetMap} &copy; <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 &copy; <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 &copy; 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 &copy; <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">&nbsp&nbsp'+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("'","&#39;")).replace('"',"&#34;"))&&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.