From 12538f3721a48fff73fc080a809fc689ff508b3b Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Fri, 15 Apr 2016 14:46:17 +0200 Subject: [PATCH 01/27] grabbing cursor when grabbing a point --- app/js/events.js | 1 + dist/m4n.js | 1 + dist/m4n.min.js | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/js/events.js b/app/js/events.js index 5cbcc45..5bba47a 100644 --- a/app/js/events.js +++ b/app/js/events.js @@ -154,6 +154,7 @@ var events = { helpers.setInteractTime(); e.preventDefault(); + main.object.canvas.classList.remove('pointing'); main.object.canvas.classList.add('grabbing'); main.globals.offset.changeBy( diff --git a/dist/m4n.js b/dist/m4n.js index a8006b9..caa2ece 100644 --- a/dist/m4n.js +++ b/dist/m4n.js @@ -2142,6 +2142,7 @@ var M4nInteractive = (function(options, container, callback) { helpers.setInteractTime(); e.preventDefault(); + main.object.canvas.classList.remove('pointing'); main.object.canvas.classList.add('grabbing'); main.globals.offset.changeBy( diff --git a/dist/m4n.min.js b/dist/m4n.min.js index 941a6f8..2f0e07c 100644 --- a/dist/m4n.min.js +++ b/dist/m4n.min.js @@ -1,2 +1,2 @@ -var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x),top:Math.min(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)},this.size={width:Math.max(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x)-this.position.left,height:Math.max(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||!g.nextTo?g.nextTo?i():g.left?j():g.right?k():h():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY))),1==a.touches.length&&m.globals.doubleTap===!0&&(m.globals.isScaling=!0,m.globals.startDistance=1,m.globals.lastPos={x:(m.globals.clickStart.x+a.touches[0].pageX)/2,y:(m.globals.clickStart.y+a.touches[0].pageY)/2})},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){for(var c=m.globals.new_distance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}());null===f;)d--,f=m.object.levels.getLevel(f);if(d>0){var g=[e,f],h={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(h.x-g[1].size.width/g[0].size.width*(h.x-m.globals.offset.get().x),h.y-g[1].size.height/g[0].size.height*(h.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),m.object.levels.getCurrent().draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.new_distance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.new_distance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)), -b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x),top:Math.min(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)},this.size={width:Math.max(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x)-this.position.left,height:Math.max(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||!g.nextTo?g.nextTo?i():g.left?j():g.right?k():h():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY))),1==a.touches.length&&m.globals.doubleTap===!0&&(m.globals.isScaling=!0,m.globals.startDistance=1,m.globals.lastPos={x:(m.globals.clickStart.x+a.touches[0].pageX)/2,y:(m.globals.clickStart.y+a.touches[0].pageY)/2})},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){for(var c=m.globals.new_distance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}());null===f;)d--,f=m.object.levels.getLevel(f);if(d>0){var g=[e,f],h={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(h.x-g[1].size.width/g[0].size.width*(h.x-m.globals.offset.get().x),h.y-g[1].size.height/g[0].size.height*(h.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),m.object.levels.getCurrent().draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.new_distance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.new_distance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth, +m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)),b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y Date: Fri, 15 Apr 2016 16:48:49 +0200 Subject: [PATCH 02/27] optimise grunt file --- gruntfile.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gruntfile.js b/gruntfile.js index 2b256d8..133cbd4 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -1,17 +1,19 @@ module.exports = function(grunt) { - // All tasks required for 1 build - var task = ['template', 'jsbeautifier', 'less', 'uglify']; - grunt.initConfig({ watch: { - default: { + javascript: { + files: [ + 'app/**/*.js' + ], + tasks: ['template', 'jsbeautifier', 'uglify'] + }, + less: { files: [ - 'app/**/*.js', 'app/**/*.less' ], - tasks: task + tasks: ['less'] } }, @@ -50,5 +52,5 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-less'); - grunt.registerTask('default', task.concat('watch')); + grunt.registerTask('default', ['template', 'jsbeautifier', 'uglify', 'less', 'watch']); }; \ No newline at end of file From c5a6e39972cd780f81936315cf7686f07f89dd4e Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Mon, 25 Apr 2016 10:53:54 +0200 Subject: [PATCH 03/27] Fix #5 --- app/js/classes/popup.js | 5 +++-- dist/m4n.js | 5 +++-- dist/m4n.min.js | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/js/classes/popup.js b/app/js/classes/popup.js index 9f3cbee..5fc852c 100644 --- a/app/js/classes/popup.js +++ b/app/js/classes/popup.js @@ -226,6 +226,7 @@ Popup.prototype.generateHTML = function() { var popup = document.createElement("div"); popup.id = this.html_id; + popup.style.zIndex = main.object.canvas.style.zIndex +1; var title_html = helpers.createElement("div", "m4n-title"); title_html.innerHTML = title; @@ -368,9 +369,9 @@ Popup.prototype.generatePopover = function(popup, title_html, info_html, media_h }; // TODO redo if statements; redo - if((fits.above || !fits.beneath) && fits.nextTo) { + if((fits.above || !fits.beneath) && !fits.nextTo) { showAbove(); - } else if(fits.nextTo) { + } else if(!fits.nextTo) { showBeneath(); } else if(fits.left) { showLeft(); diff --git a/dist/m4n.js b/dist/m4n.js index caa2ece..95bf71e 100644 --- a/dist/m4n.js +++ b/dist/m4n.js @@ -1385,6 +1385,7 @@ var M4nInteractive = (function(options, container, callback) { var popup = document.createElement("div"); popup.id = this.html_id; + popup.style.zIndex = main.object.canvas.style.zIndex + 1; var title_html = helpers.createElement("div", "m4n-title"); title_html.innerHTML = title; @@ -1527,9 +1528,9 @@ var M4nInteractive = (function(options, container, callback) { }; // TODO redo if statements; redo - if ((fits.above || !fits.beneath) && fits.nextTo) { + if ((fits.above || !fits.beneath) && !fits.nextTo) { showAbove(); - } else if (fits.nextTo) { + } else if (!fits.nextTo) { showBeneath(); } else if (fits.left) { showLeft(); diff --git a/dist/m4n.min.js b/dist/m4n.min.js index 2f0e07c..ad2d03e 100644 --- a/dist/m4n.min.js +++ b/dist/m4n.min.js @@ -1,2 +1,2 @@ -var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x),top:Math.min(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)},this.size={width:Math.max(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x)-this.position.left,height:Math.max(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||!g.nextTo?g.nextTo?i():g.left?j():g.right?k():h():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY))),1==a.touches.length&&m.globals.doubleTap===!0&&(m.globals.isScaling=!0,m.globals.startDistance=1,m.globals.lastPos={x:(m.globals.clickStart.x+a.touches[0].pageX)/2,y:(m.globals.clickStart.y+a.touches[0].pageY)/2})},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){for(var c=m.globals.new_distance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}());null===f;)d--,f=m.object.levels.getLevel(f);if(d>0){var g=[e,f],h={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(h.x-g[1].size.width/g[0].size.width*(h.x-m.globals.offset.get().x),h.y-g[1].size.height/g[0].size.height*(h.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),m.object.levels.getCurrent().draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.new_distance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.new_distance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth, -m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)),b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x),top:Math.min(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)},this.size={width:Math.max(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x)-this.position.left,height:Math.max(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY))),1==a.touches.length&&m.globals.doubleTap===!0&&(m.globals.isScaling=!0,m.globals.startDistance=1,m.globals.lastPos={x:(m.globals.clickStart.x+a.touches[0].pageX)/2,y:(m.globals.clickStart.y+a.touches[0].pageY)/2})},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){for(var c=m.globals.new_distance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}());null===f;)d--,f=m.object.levels.getLevel(f);if(d>0){var g=[e,f],h={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(h.x-g[1].size.width/g[0].size.width*(h.x-m.globals.offset.get().x),h.y-g[1].size.height/g[0].size.height*(h.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),m.object.levels.getCurrent().draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.new_distance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.new_distance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight, +m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)),b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y Date: Mon, 25 Apr 2016 14:48:53 +0200 Subject: [PATCH 04/27] Bild api request lowest and highest level --- app/js/classes/levels.js | 9 +++++++-- dist/m4n.js | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/js/classes/levels.js b/app/js/classes/levels.js index 8f48b75..e9173b8 100644 --- a/app/js/classes/levels.js +++ b/app/js/classes/levels.js @@ -18,7 +18,7 @@ var Levels = function(levels) { /** * Get the ideal level for the current canvas size - * @returns {number} The level number + * @returns {Level} The level number */ Levels.prototype.getIdealLevel = function() { var level = this.getLevel(0); @@ -56,7 +56,12 @@ Levels.prototype.getApiObject = function() { levels.push(item.getApiObject()); }); - return { current: this.current, levels: levels }; + return { + current: this.current, + highest: this.getHighest().level, + lowest: this.getLowest().level, + levels: levels + }; }; /** diff --git a/dist/m4n.js b/dist/m4n.js index 95bf71e..b9ef5a7 100644 --- a/dist/m4n.js +++ b/dist/m4n.js @@ -831,7 +831,7 @@ var M4nInteractive = (function(options, container, callback) { /** * Get the ideal level for the current canvas size - * @returns {number} The level number + * @returns {Level} The level number */ Levels.prototype.getIdealLevel = function() { var level = this.getLevel(0); @@ -871,6 +871,8 @@ var M4nInteractive = (function(options, container, callback) { return { current: this.current, + highest: this.getHighest().level, + lowest: this.getLowest().level, levels: levels }; }; From 2566fd040b6f6e6e5a2d60ef107763318e704f88 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Mon, 25 Apr 2016 15:20:24 +0200 Subject: [PATCH 05/27] Fix crash on mobile #6 --- app/js/classes/level.js | 10 +++++++ app/js/events.js | 55 +++++++++++++++++------------------ app/js/globals.js | 2 +- dist/m4n.js | 63 +++++++++++++++++++++++------------------ dist/m4n.min.js | 4 +-- 5 files changed, 74 insertions(+), 60 deletions(-) diff --git a/app/js/classes/level.js b/app/js/classes/level.js index 9b69d4e..59b927c 100644 --- a/app/js/classes/level.js +++ b/app/js/classes/level.js @@ -60,8 +60,14 @@ Level.prototype.checkLoaded = function() { Level.prototype.draw = function() { main.object.popups.hideAll(); + + main.object.context.save(); + main.object.context.setTransform(1, 0, 0, 1, 0, 0); + main.object.context.clearRect(0, 0, main.object.canvas.width, main.object.canvas.height); + main.object.context.restore(); + main.globals.offset.changeTo( this.getBounds(true, main.globals.offset.get().x), this.getBounds(false, main.globals.offset.get().y) @@ -69,6 +75,10 @@ Level.prototype.draw = function() { this.tiles.draw(); + if(main.dev) { + this.points.draw(); + } + main.object.levels.setCurrent(this.level); triggerEvent("level_drawn", this.getApiObject()); }; diff --git a/app/js/events.js b/app/js/events.js index 5bba47a..d882247 100644 --- a/app/js/events.js +++ b/app/js/events.js @@ -44,16 +44,16 @@ var events = { } // Android zoom - if(e.touches.length == 1 && main.globals.doubleTap === true) { - main.globals.isScaling = true; - // main.object.context.save(); - main.globals.startDistance = 1; - - main.globals.lastPos = { - x: (main.globals.clickStart.x + e.touches[0].pageX) / 2, - y: (main.globals.clickStart.y + e.touches[0].pageY) / 2 - }; - } + // if(e.touches.length == 1 && main.globals.doubleTap === true) { + // main.globals.isScaling = true; + // // main.object.context.save(); + // main.globals.startDistance = 1; + // + // main.globals.lastPos = { + // x: (main.globals.clickStart.x + e.touches[0].pageX) / 2, + // y: (main.globals.clickStart.y + e.touches[0].pageY) / 2 + // }; + // } }, /** @@ -92,8 +92,8 @@ var events = { if(e.target.id == main.canvas) { helpers.setInteractTime(); if(helpers.validateTouchMoveClickMargin(main.globals.clickStart, main.globals.dragPosition) && !main.globals.isScaling) { - var point = main.object.levels.getCurrent().points - .hitAPoint(main.globals.dragPosition.x, main.globals.dragPosition.y); + var point = main.object.levels.getCurrent() + .points.hitAPoint(main.globals.dragPosition.x, main.globals.dragPosition.y); if(point !== null) { main.object.popups.get(point.number).show(); } else { @@ -110,37 +110,31 @@ var events = { } } } + if(main.globals.isScaling) { - var differrence = main.globals.new_distance - main.globals.startDistance; - var steps = Math.round( Math.abs(differrence) / 100 ); + var difference = main.globals.newDistance - main.globals.startDistance; + var steps = Math.round(Math.abs(difference) / 100); var currentLevel = main.object.levels.getCurrent(); var newLevel = main.object.levels.getLevel(currentLevel.level + function() { - if(differrence > 0) { return steps; } + if(difference > 0) { return steps; } else { return -steps; } - }()); - - while(newLevel === null) { - steps--; - newLevel = main.object.levels.getLevel(newLevel); - } + }()) || currentLevel; if(steps > 0) { - var levels = [currentLevel, newLevel]; - var pinchCentre = {x: main.globals.lastPos.x, y: main.globals.lastPos.y}; + var pinchCentre = { x: main.globals.lastPos.x, y: main.globals.lastPos.y }; main.globals.offset.changeTo( - pinchCentre.x - (levels[1].size.width / levels[0].size.width) * (pinchCentre.x - main.globals.offset.get().x), - pinchCentre.y - (levels[1].size.height / levels[0].size.height) * (pinchCentre.y - main.globals.offset.get().y) + pinchCentre.x - (newLevel.size.width / currentLevel.size.width) * (pinchCentre.x - main.globals.offset.get().x), + pinchCentre.y - (newLevel.size.height / currentLevel.size.height) * (pinchCentre.y - main.globals.offset.get().y) ); main.object.levels.change(newLevel.level); - main.globals.startDistance = 0; main.globals.isScaling = false; } main.object.context.setTransform(1, 0, 0, 1, 0, 0); - main.object.levels.getCurrent().draw(); + newLevel.draw(); } }, @@ -163,6 +157,9 @@ var events = { ); main.globals.dragPosition = { x: e.pageX, y: e.pageY }; + + main.object.context.fillRect(e.pageX - 5, e.pageY -5, 10, 10); + currentLevel.draw(); } else if(e.target.id == main.canvas) { var point = currentLevel.points.hitAPoint(e.layerX, e.layerY); @@ -205,7 +202,7 @@ var events = { }; if(new_offset.x !== main.globals.offset.get().x && new_offset.y !== main.globals.offset.get().y) { if(main.globals.doubleTap === true && main.globals.isScaling) { // if the user has double tapped and is holding down his/her finger - main.globals.new_distance = Math.sqrt( + main.globals.newDistance = Math.sqrt( (main.globals.clickStart.x - fingers[0].pageX) * (main.globals.clickStart.x - fingers[0].pageX) + (main.globals.clickStart.y - fingers[0].pageY) * (main.globals.clickStart.y - fingers[0].pageY) ); @@ -224,7 +221,7 @@ var events = { } else if(fingers.length === 2) { if(main.globals.isScaling === true) { // Todo: improve delta calculation - main.globals.new_distance = Math.sqrt( + main.globals.newDistance = Math.sqrt( (fingers[0].pageX - fingers[1].pageX) * (fingers[0].pageX - fingers[1].pageX) + (fingers[0].pageY - fingers[1].pageY) * (fingers[0].pageY - fingers[1].pageY) ); diff --git a/app/js/globals.js b/app/js/globals.js index 7b9d531..869f521 100644 --- a/app/js/globals.js +++ b/app/js/globals.js @@ -31,7 +31,7 @@ main.globals = { main.globals.mapOffset.y += y; }, changeTo: function (x, y) { - main.globals.mapOffset = {x: x, y: y}; + main.globals.mapOffset = { x: x, y: y }; }, get: function () { return main.globals.mapOffset; diff --git a/dist/m4n.js b/dist/m4n.js index b9ef5a7..13e0c2a 100644 --- a/dist/m4n.js +++ b/dist/m4n.js @@ -762,8 +762,14 @@ var M4nInteractive = (function(options, container, callback) { Level.prototype.draw = function() { main.object.popups.hideAll(); + + main.object.context.save(); + main.object.context.setTransform(1, 0, 0, 1, 0, 0); + main.object.context.clearRect(0, 0, main.object.canvas.width, main.object.canvas.height); + main.object.context.restore(); + main.globals.offset.changeTo( this.getBounds(true, main.globals.offset.get().x), this.getBounds(false, main.globals.offset.get().y) @@ -771,6 +777,10 @@ var M4nInteractive = (function(options, container, callback) { this.tiles.draw(); + if (main.dev) { + this.points.draw(); + } + main.object.levels.setCurrent(this.level); triggerEvent("level_drawn", this.getApiObject()); }; @@ -2029,16 +2039,16 @@ var M4nInteractive = (function(options, container, callback) { } // Android zoom - if (e.touches.length == 1 && main.globals.doubleTap === true) { - main.globals.isScaling = true; - // main.object.context.save(); - main.globals.startDistance = 1; - - main.globals.lastPos = { - x: (main.globals.clickStart.x + e.touches[0].pageX) / 2, - y: (main.globals.clickStart.y + e.touches[0].pageY) / 2 - }; - } + // if(e.touches.length == 1 && main.globals.doubleTap === true) { + // main.globals.isScaling = true; + // // main.object.context.save(); + // main.globals.startDistance = 1; + // + // main.globals.lastPos = { + // x: (main.globals.clickStart.x + e.touches[0].pageX) / 2, + // y: (main.globals.clickStart.y + e.touches[0].pageY) / 2 + // }; + // } }, /** @@ -2077,8 +2087,8 @@ var M4nInteractive = (function(options, container, callback) { if (e.target.id == main.canvas) { helpers.setInteractTime(); if (helpers.validateTouchMoveClickMargin(main.globals.clickStart, main.globals.dragPosition) && !main.globals.isScaling) { - var point = main.object.levels.getCurrent().points - .hitAPoint(main.globals.dragPosition.x, main.globals.dragPosition.y); + var point = main.object.levels.getCurrent() + .points.hitAPoint(main.globals.dragPosition.x, main.globals.dragPosition.y); if (point !== null) { main.object.popups.get(point.number).show(); } else { @@ -2095,43 +2105,37 @@ var M4nInteractive = (function(options, container, callback) { } } } + if (main.globals.isScaling) { - var differrence = main.globals.new_distance - main.globals.startDistance; - var steps = Math.round(Math.abs(differrence) / 100); + var difference = main.globals.newDistance - main.globals.startDistance; + var steps = Math.round(Math.abs(difference) / 100); var currentLevel = main.object.levels.getCurrent(); var newLevel = main.object.levels.getLevel(currentLevel.level + function() { - if (differrence > 0) { + if (difference > 0) { return steps; } else { return -steps; } - }()); - - while (newLevel === null) { - steps--; - newLevel = main.object.levels.getLevel(newLevel); - } + }()) || currentLevel; if (steps > 0) { - var levels = [currentLevel, newLevel]; var pinchCentre = { x: main.globals.lastPos.x, y: main.globals.lastPos.y }; main.globals.offset.changeTo( - pinchCentre.x - (levels[1].size.width / levels[0].size.width) * (pinchCentre.x - main.globals.offset.get().x), - pinchCentre.y - (levels[1].size.height / levels[0].size.height) * (pinchCentre.y - main.globals.offset.get().y) + pinchCentre.x - (newLevel.size.width / currentLevel.size.width) * (pinchCentre.x - main.globals.offset.get().x), + pinchCentre.y - (newLevel.size.height / currentLevel.size.height) * (pinchCentre.y - main.globals.offset.get().y) ); main.object.levels.change(newLevel.level); - main.globals.startDistance = 0; main.globals.isScaling = false; } main.object.context.setTransform(1, 0, 0, 1, 0, 0); - main.object.levels.getCurrent().draw(); + newLevel.draw(); } }, @@ -2157,6 +2161,9 @@ var M4nInteractive = (function(options, container, callback) { y: e.pageY }; + + main.object.context.fillRect(e.pageX - 5, e.pageY - 5, 10, 10); + currentLevel.draw(); } else if (e.target.id == main.canvas) { var point = currentLevel.points.hitAPoint(e.layerX, e.layerY); @@ -2199,7 +2206,7 @@ var M4nInteractive = (function(options, container, callback) { }; if (new_offset.x !== main.globals.offset.get().x && new_offset.y !== main.globals.offset.get().y) { if (main.globals.doubleTap === true && main.globals.isScaling) { // if the user has double tapped and is holding down his/her finger - main.globals.new_distance = Math.sqrt( + main.globals.newDistance = Math.sqrt( (main.globals.clickStart.x - fingers[0].pageX) * (main.globals.clickStart.x - fingers[0].pageX) + (main.globals.clickStart.y - fingers[0].pageY) * (main.globals.clickStart.y - fingers[0].pageY) ); @@ -2221,7 +2228,7 @@ var M4nInteractive = (function(options, container, callback) { } else if (fingers.length === 2) { if (main.globals.isScaling === true) { // Todo: improve delta calculation - main.globals.new_distance = Math.sqrt( + main.globals.newDistance = Math.sqrt( (fingers[0].pageX - fingers[1].pageX) * (fingers[0].pageX - fingers[1].pageX) + (fingers[0].pageY - fingers[1].pageY) * (fingers[0].pageY - fingers[1].pageY) ); diff --git a/dist/m4n.min.js b/dist/m4n.min.js index ad2d03e..bd51fc4 100644 --- a/dist/m4n.min.js +++ b/dist/m4n.min.js @@ -1,2 +1,2 @@ -var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x),top:Math.min(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)},this.size={width:Math.max(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x)-this.position.left,height:Math.max(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY))),1==a.touches.length&&m.globals.doubleTap===!0&&(m.globals.isScaling=!0,m.globals.startDistance=1,m.globals.lastPos={x:(m.globals.clickStart.x+a.touches[0].pageX)/2,y:(m.globals.clickStart.y+a.touches[0].pageY)/2})},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){for(var c=m.globals.new_distance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}());null===f;)d--,f=m.object.levels.getLevel(f);if(d>0){var g=[e,f],h={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(h.x-g[1].size.width/g[0].size.width*(h.x-m.globals.offset.get().x),h.y-g[1].size.height/g[0].size.height*(h.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),m.object.levels.getCurrent().draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.new_distance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.new_distance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight, -m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)),b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.save(),m.object.context.setTransform(1,0,0,1,0,0),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.object.context.restore(),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.dev&&this.points.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,highest:this.getHighest().level,lowest:this.getLowest().level,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x),top:Math.min(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)},this.size={width:Math.max(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x)-this.position.left,height:Math.max(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY)))},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){var c=m.globals.newDistance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}())||e;if(d>0){var g={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(g.x-f.size.width/e.size.width*(g.x-m.globals.offset.get().x),g.y-f.size.height/e.size.height*(g.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),f.draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},m.object.context.fillRect(a.pageX-5,a.pageY-5,10,10),b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.newDistance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.newDistance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)), +b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y Date: Mon, 25 Apr 2016 15:24:13 +0200 Subject: [PATCH 06/27] Update docs --- docs.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs.md b/docs.md index 8376171..ed83b28 100644 --- a/docs.md +++ b/docs.md @@ -253,6 +253,14 @@ The API `levels` function will return an array of all `level` objects as describ * The current level */ current: 0, + /** + * The highest level + */ + highest: -2, + /** + * The lowest level + */ + lowest: 2, /** * All level object as described above */ From bb9cc6250db2d80939be589b9a01a2e5ff28c638 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Thu, 28 Apr 2016 11:41:34 +0200 Subject: [PATCH 07/27] fix polygons with more than 4 points --- app/js/classes/point.js | 8 ++++---- dist/m4n.js | 16 ++++++++++++---- dist/m4n.min.js | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/js/classes/point.js b/app/js/classes/point.js index e851ca2..8176ce1 100644 --- a/app/js/classes/point.js +++ b/app/js/classes/point.js @@ -15,12 +15,12 @@ var Point = function(point) { } // TODO refactor to support all formats this.position = { - left: Math.min(this.shape[0].x, this.shape[1].x, this.shape[2].x, this.shape[3].x), - top: Math.min(this.shape[0].y, this.shape[1].y, this.shape[2].y, this.shape[3].y) + left: Math.min.apply(null, this.shape.map(function(item) { return item.x })), + top: Math.min.apply(null, this.shape.map(function(item) { return item.y })) }; this.size = { - width: Math.max(this.shape[0].x, this.shape[1].x, this.shape[2].x, this.shape[3].x) - this.position.left, - height: Math.max(this.shape[0].y, this.shape[1].y, this.shape[2].y, this.shape[3].y) - this.position.top + width: Math.max.apply(null, this.shape.map(function(item) { return item.x })) - this.position.left, + height: Math.max.apply(null, this.shape.map(function(item) { return item.y })) - this.position.top }; }; diff --git a/dist/m4n.js b/dist/m4n.js index 13e0c2a..c415362 100644 --- a/dist/m4n.js +++ b/dist/m4n.js @@ -1040,12 +1040,20 @@ var M4nInteractive = (function(options, container, callback) { } // TODO refactor to support all formats this.position = { - left: Math.min(this.shape[0].x, this.shape[1].x, this.shape[2].x, this.shape[3].x), - top: Math.min(this.shape[0].y, this.shape[1].y, this.shape[2].y, this.shape[3].y) + left: Math.min.apply(null, this.shape.map(function(item) { + return item.x + })), + top: Math.min.apply(null, this.shape.map(function(item) { + return item.y + })) }; this.size = { - width: Math.max(this.shape[0].x, this.shape[1].x, this.shape[2].x, this.shape[3].x) - this.position.left, - height: Math.max(this.shape[0].y, this.shape[1].y, this.shape[2].y, this.shape[3].y) - this.position.top + width: Math.max.apply(null, this.shape.map(function(item) { + return item.x + })) - this.position.left, + height: Math.max.apply(null, this.shape.map(function(item) { + return item.y + })) - this.position.top }; }; diff --git a/dist/m4n.min.js b/dist/m4n.min.js index bd51fc4..5829157 100644 --- a/dist/m4n.min.js +++ b/dist/m4n.min.js @@ -1,2 +1,2 @@ -var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.save(),m.object.context.setTransform(1,0,0,1,0,0),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.object.context.restore(),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.dev&&this.points.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,highest:this.getHighest().level,lowest:this.getLowest().level,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x),top:Math.min(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)},this.size={width:Math.max(this.shape[0].x,this.shape[1].x,this.shape[2].x,this.shape[3].x)-this.position.left,height:Math.max(this.shape[0].y,this.shape[1].y,this.shape[2].y,this.shape[3].y)-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY)))},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){var c=m.globals.newDistance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}())||e;if(d>0){var g={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(g.x-f.size.width/e.size.width*(g.x-m.globals.offset.get().x),g.y-f.size.height/e.size.height*(g.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),f.draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},m.object.context.fillRect(a.pageX-5,a.pageY-5,10,10),b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.newDistance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.newDistance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)), +var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.save(),m.object.context.setTransform(1,0,0,1,0,0),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.object.context.restore(),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.dev&&this.points.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,highest:this.getHighest().level,lowest:this.getLowest().level,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min.apply(null,this.shape.map(function(a){return a.x})),top:Math.min.apply(null,this.shape.map(function(a){return a.y}))},this.size={width:Math.max.apply(null,this.shape.map(function(a){return a.x}))-this.position.left,height:Math.max.apply(null,this.shape.map(function(a){return a.y}))-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY)))},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){var c=m.globals.newDistance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}())||e;if(d>0){var g={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(g.x-f.size.width/e.size.width*(g.x-m.globals.offset.get().x),g.y-f.size.height/e.size.height*(g.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),f.draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},m.object.context.fillRect(a.pageX-5,a.pageY-5,10,10),b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.newDistance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.newDistance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)), b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y Date: Thu, 28 Apr 2016 12:28:31 +0200 Subject: [PATCH 08/27] Fix popups jumping around when they're bigger than the canvas --- app/js/classes/popup.js | 23 +++++++++++++++-------- dist/m4n.js | 23 +++++++++++++++-------- dist/m4n.min.js | 2 +- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/app/js/classes/popup.js b/app/js/classes/popup.js index 5fc852c..2fc4cb9 100644 --- a/app/js/classes/popup.js +++ b/app/js/classes/popup.js @@ -61,17 +61,24 @@ Popup.prototype.show = function(center) { var object = { x: 0, y: 0 }; var location = point.location(); + if(location.location.x !== "center" || location.location.y !== "center") { - if(location.left < 5) { - object.x = 5 - location.left; - } else if(location.right < 5) { - object.x = -(5 - location.right); + // Check if popup isn't wider than the canvas + if(!(location.left < 0 && location.right < 0)) { + if(location.left < 5) { + object.x = 5 - location.left; + } else if(location.right < 5) { + object.x = -(5 - location.right); + } } - if(location.top < 5) { - object.y = 5 - location.top; - } else if(location.bottom < 5) { - object.y = -(5 - location.bottom); + // Check if the popup isn't higher than the canvas + if(!(location.top < 0 && location.bottom < 0)) { + if(location.top < 5) { + object.y = 5 - location.top; + } else if(location.bottom < 5) { + object.y = -(5 - location.bottom); + } } if(object.x !== 0 || object.y !== 0) { diff --git a/dist/m4n.js b/dist/m4n.js index c415362..c09a281 100644 --- a/dist/m4n.js +++ b/dist/m4n.js @@ -1240,17 +1240,24 @@ var M4nInteractive = (function(options, container, callback) { }; var location = point.location(); + if (location.location.x !== "center" || location.location.y !== "center") { - if (location.left < 5) { - object.x = 5 - location.left; - } else if (location.right < 5) { - object.x = -(5 - location.right); + // Check if popup isn't wider than the canvas + if (!(location.left < 0 && location.right < 0)) { + if (location.left < 5) { + object.x = 5 - location.left; + } else if (location.right < 5) { + object.x = -(5 - location.right); + } } - if (location.top < 5) { - object.y = 5 - location.top; - } else if (location.bottom < 5) { - object.y = -(5 - location.bottom); + // Check if the popup isn't higher than the canvas + if (!(location.top < 0 && location.bottom < 0)) { + if (location.top < 5) { + object.y = 5 - location.top; + } else if (location.bottom < 5) { + object.y = -(5 - location.bottom); + } } if (object.x !== 0 || object.y !== 0) { diff --git a/dist/m4n.min.js b/dist/m4n.min.js index 5829157..e56990c 100644 --- a/dist/m4n.min.js +++ b/dist/m4n.min.js @@ -1,2 +1,2 @@ -var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.save(),m.object.context.setTransform(1,0,0,1,0,0),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.object.context.restore(),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.dev&&this.points.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,highest:this.getHighest().level,lowest:this.getLowest().level,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min.apply(null,this.shape.map(function(a){return a.x})),top:Math.min.apply(null,this.shape.map(function(a){return a.y}))},this.size={width:Math.max.apply(null,this.shape.map(function(a){return a.x}))-this.position.left,height:Math.max.apply(null,this.shape.map(function(a){return a.y}))-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY)))},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){var c=m.globals.newDistance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}())||e;if(d>0){var g={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(g.x-f.size.width/e.size.width*(g.x-m.globals.offset.get().x),g.y-f.size.height/e.size.height*(g.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),f.draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},m.object.context.fillRect(a.pageX-5,a.pageY-5,10,10),b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.newDistance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.newDistance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)), +var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.save(),m.object.context.setTransform(1,0,0,1,0,0),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.object.context.restore(),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.dev&&this.points.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,highest:this.getHighest().level,lowest:this.getLowest().level,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min.apply(null,this.shape.map(function(a){return a.x})),top:Math.min.apply(null,this.shape.map(function(a){return a.y}))},this.size={width:Math.max.apply(null,this.shape.map(function(a){return a.x}))-this.position.left,height:Math.max.apply(null,this.shape.map(function(a){return a.y}))-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY)))},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){var c=m.globals.newDistance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}())||e;if(d>0){var g={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(g.x-f.size.width/e.size.width*(g.x-m.globals.offset.get().x),g.y-f.size.height/e.size.height*(g.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),f.draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},m.object.context.fillRect(a.pageX-5,a.pageY-5,10,10),b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.newDistance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.newDistance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)), b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y Date: Tue, 3 May 2016 16:52:16 +0200 Subject: [PATCH 09/27] Add missing parameter in docs --- docs.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs.md b/docs.md index ed83b28..0c3c26f 100644 --- a/docs.md +++ b/docs.md @@ -48,7 +48,7 @@ First we have a div tag which will act as a container for the canvas and other v The M4nInteractive class accepts the following parameters: -1. A JSON object with the settings for the map +1. A JSON object with the settings for the map. - __path__. The id that was generated with the map render job. - If your environment is *download* then this path should be the absolute path to the folder where the map.json file and images from the map are in. - __environment__. (optional; default "online") The specific environment of your map. @@ -75,7 +75,7 @@ The M4nInteractive class accepts the following parameters: 3. The callback (optional), this will be called after the map has finished initializing. Best used for subscribing to custom events. The callback function has 1 parameter, the map object, as described below. ## The Map Object -The final object that will be returned to your variable will have a couple of properties +The final object that will be returned to your variable will have a couple of properties. ```js { @@ -180,7 +180,7 @@ In the API you will find a number of functions which can be used to interact wit ``` #### popup -The API `popup` function will return a specific popup, its structure is as follows +The API `popup` function will return a specific popup, its structure is as follows. ```js { @@ -211,16 +211,17 @@ The API `popup` function will return a specific popup, its structure is as follo toggle: function(center, force) {}, /** * Hide the popup + * @param {boolean} [force=false] - Force hiding the popup */ - hide: function() {} + hide: function(force) {} } ``` #### popups -The API `popups` function will return an array of all `popup` objects as described above +The API `popups` function will return an array of all `popup` objects as described above. #### level -The API `level` function will return a specific level, its structure is as follows +The API `level` function will return a specific level, its structure is as follows. ```js { @@ -245,7 +246,7 @@ The API `level` function will return a specific level, its structure is as follo ``` #### levels -The API `levels` function will return an array of all `level` objects as described above as well as the current level +The API `levels` function will return an array of all `level` objects as described above as well as the current level. ```js { From 31864706cc9d2cb2deed0a306a46ba6dd2248640 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Wed, 4 May 2016 16:38:08 +0200 Subject: [PATCH 10/27] Removed dist files & added production build script --- dist/.gitignore | 2 - dist/m4n.js | 2650 ----------------------------------------------- dist/m4n.min.js | 2 - gruntfile.js | 27 +- 4 files changed, 19 insertions(+), 2662 deletions(-) delete mode 100644 dist/m4n.js delete mode 100644 dist/m4n.min.js diff --git a/dist/.gitignore b/dist/.gitignore index a8d2c6c..d6b7ef3 100644 --- a/dist/.gitignore +++ b/dist/.gitignore @@ -1,4 +1,2 @@ * !.gitignore -!m4n*.js -!style.css diff --git a/dist/m4n.js b/dist/m4n.js deleted file mode 100644 index c09a281..0000000 --- a/dist/m4n.js +++ /dev/null @@ -1,2650 +0,0 @@ -/** - * @file Maps4News Interactive Map - * @copyright Maps4News 2016 - * - * M4nInteractive 2.0.4 - */ -var M4nInteractive = (function(options, container, callback) { - "use strict"; - var main = this; - - /** - * Do initial setup - */ - (function(options) { - main.startTime = new Date().getTime(); - - if (!options.path) throw 'M4nInteractive Parameter \'path\' is missing'; - if (!container) throw 'M4nInteractive: No container was given'; - - main.interact = options.interact || "scroll"; - main.environment = options.environment || "online"; - - main.version = { - map: '2.0', - code: '2.0.4' - }; // TODO Add version to json for verification - - main.dev = main.environment == 'development' || (options.debug && options.debug == "true"); - - main.isMobile = /Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); - main.isIframe = window.location !== window.parent.location; - - main.canvas = "m4n-" + Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); // Unique ID for canvas - - main.url = main.json = ''; - switch (main.environment) { - case 'development': - main.url = location.href.split("/").slice(0, -1).join("/") + '/output/' + options.path + '/'; - main.json = main.url + 'map.json'; - break; - case 'local': - main.url = options.path.replace(/\/$/, '') + '/'; // Path to images - main.json = main.url + 'map.json'; - break; - default: - main.url = 'https://' + main.environment + ".maps4news.com/output/" + options.path + '/'; - main.json = 'https://' + main.environment + ".maps4news.com/ia/" + main.version.map + "/?id=" + encodeURIComponent(options.path); - break; - } - })(options); - - /** - * A Collection of external APIs used and methods to initialize them - */ - var externalAPIs = { - youtube: { - /** - * Check if an api is needed - */ - checkIfNeeded: function() { - var needed = false; - main.object.popups.list.forEach(function(item) { - if (item.media_type === "youtube") { - needed = true; - externalAPIs.youtube.download(); - return false; - } - }); - return needed; - }, - /** - * Download the YouTube API script - */ - download: function() { - if (typeof YT == 'undefined') { - var youtube = document.createElement('script'); - youtube.src = "//www.youtube.com/player_api"; - var script_tag = document.getElementsByTagName('script')[0]; - script_tag.parentNode.insertBefore(youtube, script_tag); - } - }, - /** - * Enable youtube control on the popups - */ - enable: function() { - if (main.object !== null && typeof YT !== 'undefined') { - main.object.popups.list.forEach(function(item) { - if (item.media_type === "youtube") { - item.youtube = new YT.Player(item.html_id + '-youtube'); - } - }); - } - } - } - }; - - document.addEventListener("onYouTubeIframeAPIReady", externalAPIs.youtube.enable, false); - - /** - * Fire a youtube api ready event - * "onYouTubeIframeAPIReady" is a core function from the youtube api - */ - window.onYouTubeIframeAPIReady = function() { - document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady", null)); - }; - - /** - * Download the JSON file - */ - var request = new XMLHttpRequest(); - request.open('GET', main.json, true); - request.onreadystatechange = function() { - if (request.readyState == 4 && request.status == 200) { - initializeM4n(request.responseText); - } else if (request.status !== 200) { - console.error("Something went wrong!", request); - } - }; - request.send(); - - /** - * Initialize the map - * Parse the JSON file, create HTML elements, - * Enable YouTube and event listeners - */ - function initializeM4n(mapJson) { - createHtmlElements(); - - main.object = revive(mapJson); - - if (main.object.levels.count() > 1) { - createZoomControls(); - } - - if (!container.hasPredefinedHeight) { - var level = main.object.levels.getCurrent(); - main.object.canvas.height = container.clientWidth * (level.size.height / level.size.width); - } - - for (var api in externalAPIs) { - if (externalAPIs.hasOwnProperty(api)) { - externalAPIs[api].checkIfNeeded(); - } - } - - enableEventListeners(); - - main.object.popups.generateHTML(); - main.api.reset(); - - if (typeof callback === 'function') callback(returnObject); - - main.endTime = new Date().getTime(); - if (main.dev) { - console.info("It took " + (main.endTime - main.startTime) + "ms to start up"); - } - } - - /** - * Activate the event listeners - */ - function enableEventListeners() { - main.object.canvas.addEventListener('mousedown', events.mouseDown); - main.object.canvas.addEventListener('touchstart', events.touchStart); - - document.addEventListener('mouseup', events.mouseUp); - document.addEventListener('touchend', events.touchEnd); - - document.addEventListener('mousemove', events.mouseMove); - document.addEventListener('touchmove', events.touchMove); - - main.object.canvas.addEventListener('mousewheel', events.mouseWheel); - main.object.canvas.addEventListener('DOMMouseScroll', events.mouseWheel); - - main.object.canvas.addEventListener('contextmenu', events.contextMenu); - - window.addEventListener('resize', events.resize); - window.addEventListener('orientationchange', events.resize); - } - - /** - * Keep track of the canvas' transform - * @param {object} ctx - the context - */ - function trackTransforms(ctx) { - var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg'); - var xform = svg.createSVGMatrix(); - ctx.getTransform = function() { - return xform; - }; - - var savedTransforms = []; - var save = ctx.save; - ctx.save = function() { - savedTransforms.push(xform.translate(0, 0)); - return save.call(ctx); - }; - - var restore = ctx.restore; - ctx.restore = function() { - xform = savedTransforms.pop(); - return restore.call(ctx); - }; - - var scale = ctx.scale; - ctx.scale = function(sx, sy) { - xform = xform.scaleNonUniform(sx, sy); - return scale.call(ctx, sx, sy); - }; - - var rotate = ctx.rotate; - ctx.rotate = function(radians) { - xform = xform.rotate(radians * 180 / Math.PI); - return rotate.call(ctx, radians); - }; - - var translate = ctx.translate; - ctx.translate = function(dx, dy) { - xform = xform.translate(dx, dy); - return translate.call(ctx, dx, dy); - }; - - var transform = ctx.transform; - ctx.transform = function(a, b, c, d, e, f) { - var m2 = svg.createSVGMatrix(); - m2.a = a; - m2.b = b; - m2.c = c; - m2.d = d; - m2.e = e; - m2.f = f; - xform = xform.multiply(m2); - return transform.call(ctx, a, b, c, d, e, f); - }; - - var setTransform = ctx.setTransform; - ctx.setTransform = function(a, b, c, d, e, f) { - xform.a = a; - xform.b = b; - xform.c = c; - xform.d = d; - xform.e = e; - xform.f = f; - return setTransform.call(ctx, a, b, c, d, e, f); - }; - - var pt = svg.createSVGPoint(); - ctx.transformedPoint = function(x, y) { - pt.x = x; - pt.y = y; - return pt.matrixTransform(xform.inverse()); - }; - } - - /** - * Will build the map object from a json file - * @param {string} string_json - The json string in which the map is defined - */ - function revive(string_json) { - var classes = { - levels: Levels, - level: Level, - tiles: Tiles, - tile: Tile, - points: Points, - point: Point, - popup: Popup, - popups: Popups - }; - var json = JSON.parse(string_json, function(key, value) { - if (value !== null) { - if (key === "") { - return new Map(value); - } - if (value !== null) { - if (!value._type) { - return value; - } else { - if (classes[value._type]) { - return new classes[value._type](value); - } else { - console.error("Unknown class type in save: " + value._type); - return null; - } - } - } - } - }); - - /** - * A Hack to add the level to every tile - * TODO find a better way to do this - */ - json.levels.list.forEach(function(level) { - level.tiles.list.forEach(function(tile) { - tile.level = level.level; - }); - }); - return json; - } - - /** - * Create the necessary html elements - */ - function createHtmlElements() { - // Disable margin inside the iframe body - if (main.isIframe) { - document.body.style.margin = "0"; - } - - // Load css - if (document.getElementById("m4n-style") === null) { - var style = document.createElement("link"); - style.id = "m4n-style"; - style.rel = "stylesheet"; - style.type = "text/css"; - style.href = (function() { - switch (options.environment) { - case 'development': - return location.href.split("/").slice(0, -1).join("/") + '/style.css'; - case 'local': - return options.path + 'style.css'; - default: - return '//' + options.environment + '.maps4news.com/ia/' + main.version.map + '/style.css'; - } - })(); - document.head.appendChild(style); - } - - // Reload custom css file - var customStyle = document.getElementById("m4n-style-custom"); - if (customStyle !== null) { - var newCustomStyle = document.createElement("link"); - newCustomStyle.id = "m4n-style-custom"; - newCustomStyle.rel = "stylesheet"; - newCustomStyle.type = "text/css"; - newCustomStyle.href = customStyle.href; - - document.head.removeChild(customStyle); - document.head.appendChild(newCustomStyle); - } - - // Create the canvas - var canvas = document.getElementById(main.canvas); - if (canvas !== null) { - if (canvas.classList.contains("m4n-canvas")) { - throw "Map already initialized for " + main.canvas; - } else { - main.canvas = main.canvas + "-" + Math.random().toString(36).substring(7); - canvas = helpers.createElement("canvas", "m4n-canvas"); - canvas.id = main.canvas; - } - } else { - canvas = helpers.createElement("canvas", "m4n-canvas"); - canvas.id = main.canvas; - } - - if (main.interact == "smart") { - var overlay = helpers.createElement("div", "timeout-overlay", { - "click": function() { - hideOverlay(); - }, - "touchstart": function(e) { - main.globals.dragPosition = { - x: e.touches[0].clientX, - y: e.touches[0].clientY - }; - main.globals.clickStart = { - x: e.touches[0].clientX, - y: e.touches[0].clientY - }; - }, - "touchmove": function(e) { - main.globals.dragPosition = { - x: e.touches[0].clientX, - y: e.touches[0].clientY - }; - }, - "touchend": function() { - if (helpers.validateTouchMoveClickMargin(main.globals.clickStart, main.globals.dragPosition)) { - hideOverlay(); - } - } - }); - - var hideOverlay = function() { - overlay.style.display = "none"; - helpers.setInteractTime(); - }; - - overlay.style.display = "block"; - main.timeoutOverlay = overlay; - container.appendChild(overlay); - } - - container.id = main.canvas + '-container'; - container.classList.add("m4n-container"); - container.style.height = "100%"; - container.style.width = "100%"; - container.hasPredefinedHeight = container.clientHeight !== 0; - - var popupContainer = document.createElement("div"); - popupContainer.id = main.canvas + "-popup-container"; - - container.appendChild(popupContainer); - container.appendChild(canvas); - - canvas.height = container.clientHeight; - canvas.width = container.clientWidth; - } - - /** - * Create the zoom controls - */ - function createZoomControls() { - // Zoom controls - var zoom_container = helpers.createElement('div', 'm4n-zoom-container'); - var zoom_control_in = helpers.createElement('div', 'm4n-zoom-button', { - 'click': function() { - if (!zoom_control_in.classList.contains('disabled')) { - main.api.zoom.in(); - } - } - }); - var zoom_control_out = helpers.createElement('div', 'm4n-zoom-button', { - 'click': function() { - if (!zoom_control_out.classList.contains('disabled')) { - main.api.zoom.out(); - } - } - }); - - addEventListener("level_changed", function() { - var currentLevel = main.object.levels.getCurrent(); - - zoom_control_out.classList.remove('disabled'); - zoom_control_in.classList.remove('disabled'); - - if (currentLevel.level == main.object.levels.getHighest().level) { - zoom_control_out.classList.add('disabled'); - } else if (currentLevel.level == main.object.levels.getLowest().level) { - zoom_control_in.classList.add('disabled'); - } - }); - - zoom_container.style.zIndex = main.object.canvas.style.zIndex + 1; - - zoom_container.appendChild(zoom_control_in); - zoom_container.appendChild(zoom_control_out); - - container.appendChild(zoom_container); - } - - /** - * Custom event listener service - * @param {string} event - the event that callback should be triggered - * @param {function} callback - the callback method - * @returns {number} The listener id - */ - function addEventListener(event, callback) { - if (typeof event !== 'string') { - throw "event must be a string; " + event + " given"; - } - if (typeof callback !== 'function') { - throw "callback must be a function"; - } - - if (!main.dispatchEvents[event]) { - main.dispatchEvents[event] = []; - } - - if (main.dev) { - console.log("Event listener for event \"" + event + "\" added", callback); - } - - return main.dispatchEvents[event].push(callback); - } - - /** - * Remove an event listener - * @param {string} event - the event to unsubscribe from - * @param {number} id - the id of the listener - */ - function removeEventListener(event, id) { - if (typeof event !== 'string') { - throw "event must be a string; " + event + " given"; - } - if (typeof id !== 'number') { - throw "id must be a number; " + id + " given"; - } - - if (!main.dispatchEvents[event]) { - throw "unknown event"; - } - if (!main.dispatchEvents[event][id - 1]) { - throw "unknown listener"; - } - - if (main.dev) { - console.log("Event listener for event \"" + event + "\" removed", main.dispatchEvents[event][id - 1]); - } - - delete main.dispatchEvents[event][id - 1]; - } - - /** - * Trigger a custom event - * @param {string} event - the name of the event that should be triggered - * @param {object} object - the parameter for the callback function - */ - function triggerEvent(event, object) { - if (main.dispatchEvents[event]) { - main.dispatchEvents[event].forEach(function(item) { - item(object); - }); - } - } - - /** - * Empty object to save event listener functions in. - * @type {object} - */ - main.dispatchEvents = {}; - - /** - * The interactive api - * @type {object} - */ - main.api = { - - /** - * Get a specific popup object - * @param {number} i - number of the popup - * @returns {object|null} The popup api object - */ - popup: function(i) { - var popup = main.object.popups.get(i); - if (popup === null) { - throw "Popup " + i + " not found"; - } - return popup.getApiObject(); - }, - - /** - * Get all popups - * @returns {object} The popups api object - */ - popups: function() { - return main.object.popups.getApiObject(); - }, - - /** - * Get a specific level object - * @param {number} i - The number of the level - * @returns {object|null} The level api object - */ - level: function(i) { - var level = main.object.levels.getLevel(i); - return level.getApiObject() || null; - }, - - /** - * Get all levels - * - * @returns {object} The levels api object - */ - levels: function() { - return main.object.levels.getApiObject(); - }, - - /** - * Resets the map to its initial state - */ - reset: function() { - var current = main.object.levels.getIdealLevel(); - - main.globals.offset.changeTo(-((current.size.width / 2) - (main.object.canvas.width / 2)), -((current.size.height / 2) - (main.object.canvas.height / 2))); - - main.object.levels.change(current.level); - }, - - /** - * Try to refit the canvas inside the container - */ - refit: function() { - events.resize(); - }, - - /** - * Zoom functions - */ - zoom: { - - /** - * Zoom to a specific level - * @param {number} value - number of the level - */ - to: function(value) { - value = typeof value === 'number' ? value : 0; - var offset = { - x: main.object.canvas.clientWidth / 2, - y: main.object.canvas.clientHeight / 2 - }; - var levels = main.object.levels.getLevels([main.object.levels.current, value]); - if (levels[1] !== null) { - main.globals.offset.changeTo( - offset.x - (levels[1].size.width / levels[0].size.width) * - (offset.x - main.globals.offset.get().x), - offset.y - (levels[1].size.height / levels[0].size.height) * - (offset.y - main.globals.offset.get().y) - ); - main.object.levels.change(levels[1].level); - } - }, - - /** - * Zoom in 1 level - */ - in : function() { - this.to(main.object.levels.current + 1); - }, - - /** - * Zoom out 1 level - */ - out: function() { - this.to(main.object.levels.current - 1); - } - }, - - /** - * Move functions - */ - move: { - - /** - * Move the map (40px * factor) to the left - * @param {number} factor - */ - left: function(factor) { - var level = main.object.levels.getCurrent(); - main.globals.offset.changeBy(-40 * (factor || 1), 0); - level.draw(); - }, - - /** - * Move the map (40px * factor) to the right - * @param {number} factor - */ - right: function(factor) { - var level = main.object.levels.getCurrent(); - main.globals.offset.changeBy(40 * (factor || 1), 0); - level.draw(); - }, - - /** - * Move the map (40px * factor) up - * @param {number} factor - */ - up: function(factor) { - var level = main.object.levels.getCurrent(); - main.globals.offset.changeBy(0, -40 * (factor || 1)); - level.draw(); - }, - - /** - * Move the map (40px * factor) down - * @param {number} factor - */ - down: function(factor) { - var level = main.object.levels.getCurrent(); - main.globals.offset.changeBy(0, 40 * (factor || 1)); - level.draw(); - } - } - }; - - /** - * The interactive base structure - * @class - * @param {object} value - */ - var Map = function(value) { - this._type = "map"; - - this.container = document.getElementById(main.canvas + "-container"); - - this.canvas = document.getElementById(main.canvas); - - this.context = this.canvas.getContext("2d"); - - trackTransforms(this.context); - - this.popupContainer = document.getElementById(main.canvas + "-popup-container"); - - for (var key in value) { - if (value.hasOwnProperty(key)) { - this[key] = value[key]; - } - } - }; - - /** - * The level class - * @class - * @param {object} level - The level json object - */ - var Level = function(level) { - this._type = "level"; - - this.is_loaded = false; - this.tiles = {}; - - if (level !== false) { - for (var property in level) { - if (level.hasOwnProperty(property)) { - this[property] = level[property]; - } - } - } - }; - - /** - * - * - * @returns {object} - */ - Level.prototype.getApiObject = function() { - return { - level: this.level, - isLoaded: this.is_loaded, - changeTo: function() { - main.object.levels.change(this.level); - }.bind(this), - load: function() { - this.load(); - }.bind(this) - }; - }; - - /** - * Check if all tiles have been loaded - */ - Level.prototype.checkLoaded = function() { - var loadedTiles = 0; - - this.tiles.list.forEach(function(tile) { - if (tile.state > 1) { - loadedTiles++; - } - }); - - if (loadedTiles === this.tiles.list.length) { - this.is_loaded = true; - triggerEvent("level_loaded", this.getApiObject()); - } - }; - - /** - * Draws a level on screen - */ - Level.prototype.draw = function() { - main.object.popups.hideAll(); - - - main.object.context.save(); - main.object.context.setTransform(1, 0, 0, 1, 0, 0); - - main.object.context.clearRect(0, 0, main.object.canvas.width, main.object.canvas.height); - - main.object.context.restore(); - - main.globals.offset.changeTo( - this.getBounds(true, main.globals.offset.get().x), - this.getBounds(false, main.globals.offset.get().y) - ); - - this.tiles.draw(); - - if (main.dev) { - this.points.draw(); - } - - main.object.levels.setCurrent(this.level); - triggerEvent("level_drawn", this.getApiObject()); - }; - - /** - * Load tiles in the background - */ - Level.prototype.load = function() { - if (!this.is_loaded) { - this.tiles.load(); - } - }; - - /** - * Checks if the cursor is on the map (when there's whitespace in the canvas) - * @param {number} x - The x coordinate - * @param {number} y - The y coordinate - * @returns {boolean} Is the cursor on the map? - */ - Level.prototype.isOn = function(x, y) { - return ( - x > main.globals.offset.get().x && - x < this.size.width + main.globals.offset.get().x && - y > main.globals.offset.get().y && - y < this.size.height + main.globals.offset.get().y - ); - }; - - /** - * Checks if the user will drag the map of the side of the canvas and prevents this - * @param {boolean} forXAxis - If the call to this method is intended for use with the x axis - * @param {number} movement - The new location the user dragged the map to - * @returns {number} The corrected new location for the map - */ - Level.prototype.getBounds = function(forXAxis, movement) { - var offset = forXAxis ? - main.object.canvas.clientWidth - this.size.width : - main.object.canvas.clientHeight - this.size.height; - return Math.max(Math.min(offset, 0), Math.min(Math.max(offset, 0), movement)); - }; - /** - * The levels class - * @class - * @param {Level[]} levels - A list of level objects - */ - var Levels = function(levels) { - this._type = "levels"; - this.current = 0; - - if (levels !== false) { - for (var property in levels) { - if (levels.hasOwnProperty(property)) { - this[property] = levels[property]; - } - } - } - }; - - /** - * Get the ideal level for the current canvas size - * @returns {Level} The level number - */ - Levels.prototype.getIdealLevel = function() { - var level = this.getLevel(0); - - this.getAllExcept(0).forEach(function(item) { - if (level !== null) { - var difference, prev_difference; - if (main.object.canvas.clientWidth >= main.object.canvas.clientHeight) { // If wider - difference = Math.abs(main.object.canvas.width - item.requested_area.size.width); - prev_difference = Math.abs(main.object.canvas.width - level.requested_area.size.width); - } else { // If higher - difference = Math.abs(main.object.canvas.height - item.requested_area.size.height); - prev_difference = Math.abs(main.object.canvas.height - level.requested_area.size.height); - } - - if (difference < prev_difference) { - level = item; - } - } else { - level = item; - } - }); - return level; - }; - - /** - * The levels api object - * - * @returns {object} - */ - Levels.prototype.getApiObject = function() { - var levels = []; - - this.list.forEach(function(item) { - levels.push(item.getApiObject()); - }); - - return { - current: this.current, - highest: this.getHighest().level, - lowest: this.getLowest().level, - levels: levels - }; - }; - - /** - * Change the current map - * @param {number} level - The level to change to - */ - Levels.prototype.setCurrent = function(level) { - if (this.current !== level) { - this.current = level; - } - }; - - /** - * Get a specific level - * @param {number} level - The level to return - * @returns {Level|null} the requested level object or null if it wasn't found - */ - Levels.prototype.getLevel = function(level) { - for (var i = 0; i < main.object.levels.list.length; i++) { - if (main.object.levels.list[i].level == level) { - return main.object.levels.list[i]; - } - } - return null; - }; - - /** - * Returns the requested level objects - * @param {number[]} rLevels - The levels you want to get - * @returns {Level[]} Array of level objects - */ - Levels.prototype.getLevels = function(rLevels) { - var levels = []; - - for (var i = 0; i < rLevels.length; i++) { - levels.push(this.getLevel(rLevels[i])); - } - return levels; - }; - - /** - * Get all levels except the given ones - * @param {number|Array} numbers - the number not to return - */ - Levels.prototype.getAllExcept = function(numbers) { - if (typeof numbers == "number") { - numbers = [numbers]; - } - - var levels = []; - this.list.forEach(function(item) { - if (numbers.indexOf(item.level) === -1) { - levels.push(item); - } - }); - return levels; - }; - - /** - * Get the current level - * @returns {Level} The current level object - */ - Levels.prototype.getCurrent = function() { - return this.getLevel(this.current); - }; - - /** - * Get the highest level (lowest number) - * @returns {Level} Level object - */ - Levels.prototype.getHighest = function() { - var level = this.getCurrent(); - - this.list.forEach(function(item) { - if (item.level < level.level) { - level = item; - } - }); - return level; - }; - - /** - * Get the lowest level (highest number) - * @returns {Level} Level object - */ - Levels.prototype.getLowest = function() { - var level = this.getCurrent(); - - this.list.forEach(function(item) { - if (item.level > level.level) { - level = item; - } - }); - return level; - }; - - /** - * Change the level and draw it - * @param {number} level - The level to change to - */ - Levels.prototype.change = function(level) { - var levels = this.getLevels([level, level + 1, level - 1]); - if (levels[0] !== null) { - var changeTo = function(level) { - window.requestAnimationFrame(function() { - level.draw(); - triggerEvent("level_changed", level.getApiObject()); - }); - }; - - if (!levels[0].is_loaded) { - levels[0].load(); - var eventId = addEventListener("level_loaded", function(e) { - if (e.level == level) { - changeTo(levels[0]); // TODO draw safety check - removeEventListener("level_loaded", eventId); - } - }); - } else { - changeTo(levels[0]); - } - - if (levels[1] !== null) { - levels[1].load(); - } - if (levels[2] !== null) { - levels[2].load(); - } - } - }; - - /** - * Get the number of levels - * @returns {number} The number of levels in the map - */ - Levels.prototype.count = function() { - return this.list.length; - }; - /** - * The point class - * @class - * @param {object} point - The json point object - */ - var Point = function(point) { - this._type = "point"; - - if (point !== false) { - for (var property in point) { - if (point.hasOwnProperty(property)) { - this[property] = point[property]; - } - } - } - // TODO refactor to support all formats - this.position = { - left: Math.min.apply(null, this.shape.map(function(item) { - return item.x - })), - top: Math.min.apply(null, this.shape.map(function(item) { - return item.y - })) - }; - this.size = { - width: Math.max.apply(null, this.shape.map(function(item) { - return item.x - })) - this.position.left, - height: Math.max.apply(null, this.shape.map(function(item) { - return item.y - })) - this.position.top - }; - }; - - /** - * Draw a border around a point - */ - Point.prototype.draw = function() { - main.object.context.strokeRect( - this.position.left + main.globals.offset.get().x, - this.position.top + main.globals.offset.get().y, - this.size.width, - this.size.height - ); - }; - - /** - * Check if the user clicked on a specific point - * @param {number} x - The x value from the user - * @param {number} y - The y value from the user - * @returns {boolean} Did the user click on a point? - */ - Point.prototype.isOn = function(x, y) { - return ( - x > this.position.left + main.globals.offset.get().x && - x < this.position.left + this.size.width + main.globals.offset.get().x && - y > this.position.top + main.globals.offset.get().y && - y < this.position.top + this.size.height + main.globals.offset.get().y - ); - }; - - /** - * Get info about the current position of a point - * @returns {object} - */ - Point.prototype.location = function() { - var object = { - left: this.position.left + main.globals.offset.get().x, - top: this.position.top + main.globals.offset.get().y, - right: -(this.position.left + main.globals.offset.get().x - main.object.canvas.clientWidth + this.size.width), - bottom: -(this.position.top + main.globals.offset.get().y - main.object.canvas.clientHeight + this.size.height) - }; - - object.location = { - x: (function() { - if (object.left < 5) { - return "left"; - } else if (object.right < 5) { - return "right"; - } - return "center"; - })(), - y: (function() { - if (object.top < 5) { - return "above"; - } else if (object.bottom < 5) { - return "beneath"; - } - return "center"; - })() - }; - - return object; - }; - /** - * The points class - * @class - * @param {Point[]} points - A list of point classes - */ - var Points = function(points) { - this._type = "points"; - - if (points !== false) { - for (var property in points) { - if (points.hasOwnProperty(property)) { - this[property] = points[property]; - } - } - } - }; - - /** - * Draws a border around the points on screen - */ - Points.prototype.draw = function() { - this.list.forEach(function(element) { - element.draw(); - }); - }; - - /** - * Returns the point a user clicked on - * @param {number} x - The x value from the user - * @param {number} y - The y value from the user - * @returns {Point|null} The point the user clicked on - */ - Points.prototype.hitAPoint = function(x, y) { - var point = null; - - this.list.forEach(function(item) { - if (item.isOn(x, y)) { - point = item; - return false; - } - }); - return point; - }; - - /** - * Get a specific point - * @param {number} number - The number of a point - * @returns {Point|null} The requested point - */ - Points.prototype.get = function(number) { - for (var i = 0; i < this.list.length; i++) { - if (this.list[i].number == number) { - return this.list[i]; - } - } - return null; - }; - /** - * The popup class - * @class - * @param {object} popup - The json popup object - */ - var Popup = function(popup) { - this._type = "popup"; - - this.on_screen = false; - - if (popup !== false) { - for (var property in popup) { - if (popup.hasOwnProperty(property)) { - this[property] = popup[property]; - } - } - } - this.html_id = main.canvas + '-popup-' + this.number; - this.video_id = main.html_id + '-video'; - }; - - /** - * Get the api object for a popup - * - * @returns {object} The popup api object - */ - Popup.prototype.getApiObject = function() { - return { - number: this.number, - title: this.title, - info: this.info, - show: function(center) { - this.show(center); - }.bind(this), - toggle: function(center, force) { - this.toggle(center, force); - }.bind(this), - hide: function(force) { - this.hide(force); - }.bind(this) - }; - }; - - /** - * Show a popup - * - * @param {boolean} [center=false] - the the map when showing the popup - */ - Popup.prototype.show = function(center) { - if (!this.on_screen) { - // Hide all other popups (including sidebars) - main.object.popups.hideAll(true); - - // Get the clicked point - var point = main.object.levels.getCurrent().points.get(this.number); - - // Center the map - if (center === true) { - helpers.moveTo(point.position.left + (point.size.width / 2), point.position.top + (point.size.height / 2)); - } else { - var object = { - x: 0, - y: 0 - }; - - var location = point.location(); - - if (location.location.x !== "center" || location.location.y !== "center") { - // Check if popup isn't wider than the canvas - if (!(location.left < 0 && location.right < 0)) { - if (location.left < 5) { - object.x = 5 - location.left; - } else if (location.right < 5) { - object.x = -(5 - location.right); - } - } - - // Check if the popup isn't higher than the canvas - if (!(location.top < 0 && location.bottom < 0)) { - if (location.top < 5) { - object.y = 5 - location.top; - } else if (location.bottom < 5) { - object.y = -(5 - location.bottom); - } - } - - if (object.x !== 0 || object.y !== 0) { - helpers.moveBy(object.x, object.y); - } - } - } - - var wasShown = (function() { - if (main.isMobile) { - return this.onShowMobile(point); - } else { - return this.onShowDesktop(point); - } - }.bind(this))(); - - if (wasShown) { - this.startVideo(); - this.on_screen = true; - triggerEvent("popup_shown", this.getApiObject()); - } - } - }; - - /** - * Basic popup mobile show function - * - * The popup style specific show method - * To be overwritten by popup specific function - * - * @param {Element} point - * @returns {boolean} - If the popup has been shown - */ - Popup.prototype.onShowMobile = function(point) { - // Overwrite with popup specific code - return false; - }; - - /** - * Basic popup desktop show function - * - * The popup style specific show method - * To be overwritten by popup specific function - * - * @param {Element} point - * @returns {boolean} - if the popup has be shown on mobile - */ - Popup.prototype.onShowDesktop = function(point) { - // Overwrite with popup specific code - return false; - }; - - /** - * Hide a popup - * - * @param {boolean} [force=false] - force hiding the popup - * @returns {boolean} - if the popup has been hidden - */ - Popup.prototype.hide = function(force) { - if (this.on_screen) { - if (this.onHide(force)) { - this.stopVideo(); - this.on_screen = false; - triggerEvent("popup_hidden", this.getApiObject()); - } - } - }; - - /** - * Basic popup hiding - * - * The popup style specific hide method - * To be overwritten by popup specific function - * - * @param {boolean} [force=false] - force hiding the popup - * @returns {boolean} - */ - Popup.prototype.onHide = function(force) { - // Overwrite with popup specific method - return false; - }; - - /** - * Toggle a popup - * - * @param {boolean} [center=false] - center the map - * @param {boolean} [force=false] - force hiding the popup - */ - Popup.prototype.toggle = function(center, force) { - if (this.on_screen) { - this.hide(force); - } else { - this.show(center); - } - }; - - /** - * Stop the playing video - */ - Popup.prototype.stopVideo = function() { - switch (this.media_type) { - case "youtube": - if ( - this.youtube && [ - YT.PlayerState.PLAYING, - YT.PlayerState.BUFFERING - ].indexOf(this.youtube.getPlayerState()) !== -1 - ) { - this.youtube.pauseVideo(); - } - break; - case "video": - document.getElementById(this.video_id).pause(); - break; - } - }; - - /** - * Start the video inside the popup - */ - Popup.prototype.startVideo = function() { - try { // TODO fix youtube check - switch (this.media_type) { - case "youtube": - if ( - this.youtube && [ - YT.PlayerState.UNSTARTED, - YT.PlayerState.PAUSED, - YT.PlayerState.CUED, - YT.PlayerState.BUFFERING - ].indexOf(this.youtube.getPlayerState()) !== -1 - ) { - this.youtube.playVideo(); - } - break; - case "video": - document.getElementById(this.video_id).play(); - break; - } - } catch (e) { - console.warn("YouTube wasn't ready, yet!", e); - } - }; - - /** - * Generate the html for a popup - */ - Popup.prototype.generateHTML = function() { - var title = typeof this.title !== "undefined" ? this.title : ""; - var media = typeof this.media !== "undefined" ? this.media : null; - var info = typeof this.info !== "undefined" ? this.info : null; - - var popup = document.createElement("div"); - popup.id = this.html_id; - popup.style.zIndex = main.object.canvas.style.zIndex + 1; - - var title_html = helpers.createElement("div", "m4n-title"); - title_html.innerHTML = title; - - var info_html = helpers.createElement("div", "m4n-info"); - info_html.innerHTML = info; - - var media_html = helpers.createElement("div", "m4n-media"); - - switch (this.media_type) { - case "": - case "none": - case null: - case undefined: - break; - case "image": - var media_image = document.createElement("img"); - media_image.alt = this.id; - media_image.src = media; - media_html.appendChild(media_image); - break; - case "youtube": - var media_youtube = document.createElement("iframe"); - media_youtube.src = "https://www.youtube.com/embed/" + this.media + "?modestbranding=1&autohide=1&controls=2&enablejsapi=1&showinfo=0"; - media_youtube.id = this.html_id + "-youtube"; - media_youtube.frameBorder = 0; - media_youtube.allowFullscreen = 1; - media_html.appendChild(media_youtube); - break; - case "video": - var media_video = helpers.createElement("video", "m4n-video"); - media_video.src = this.media; - media_video.loop = true; - media_video.controls = true; - media_video.id = this.video_id; - media_html.appendChild(media_video); - break; - default: - throw this.media_type + " is an invalid media type"; - } - - switch (main.object.settings.placement) { - case "overlay": - popup = this.generateOverlay(popup, title_html, info_html, media_html); - break; - case "sidebar": - popup = this.generateSidebar(popup, title_html, info_html, media_html); - break; - default: - popup = this.generatePopover(popup, title_html, info_html, media_html); - } - main.object.popupContainer.appendChild(popup); - - this.onHide(true); - }; - - /** - * Generate a Popover style popup - * - * @param {Element} popup - * @param {Element} title_html - * @param {Element} info_html - * @param {Element} media_html - * @returns {Element} the popup - */ - Popup.prototype.generatePopover = function(popup, title_html, info_html, media_html) { - popup.classList.add("m4n-popover"); - - var triangle = helpers.createElement("div", "m4n-popover-triangle"); - - popup.appendChild(triangle); - popup.appendChild(title_html); - popup.appendChild(media_html); - popup.appendChild(info_html); - - this.onHide = function() { - popup.style.display = "none"; - - var triangle = popup.getElementsByClassName("m4n-popover-triangle")[0]; - triangle.classList.remove("top", "bottom", "right", "left"); - triangle.style.left = null; - triangle.style.top = null; - - return true; - }; - - this.onShowMobile = function() { - popup.style.display = "block"; - popup.style.left = (main.object.canvas.clientWidth / 2) - (popup.clientWidth / 2) - main.object.canvas.getBoundingClientRect().left + "px"; - popup.style.top = (main.object.canvas.clientHeight / 2) - (popup.clientHeight / 2) - main.object.canvas.getBoundingClientRect().top + "px"; - - return true; - }; - - this.onShowDesktop = function(point) { - popup.style.display = "block"; - var heightTriangle = 16.97056274847714; // 24 = width of a triangle plus the border - - var left = Math.max(0.15, Math.min(0.85, ((point.position.left + main.globals.offset.get().x) / main.object.canvas.clientWidth))), - top = Math.max(0.05, Math.min(0.85, ((point.position.top + main.globals.offset.get().y) / main.object.canvas.clientHeight))), - - triangle = popup.getElementsByClassName("m4n-popover-triangle")[0], - fits = { - nextTo: ( - (main.globals.offset.get().x + point.position.left + (popup.clientWidth * left) + (point.size.width / 2)) < main.object.canvas.clientWidth && - (main.globals.offset.get().x + point.position.left - (popup.clientWidth * left) + (point.size.width / 2)) > 0 - ), - above: (main.globals.offset.get().y + point.position.top - heightTriangle) > popup.clientHeight, - beneath: (main.object.canvas.clientHeight - (main.globals.offset.get().y + point.position.top + point.size.height + heightTriangle)) > popup.clientHeight, - left: (main.globals.offset.get().x + point.position.left - heightTriangle) > popup.clientWidth, - right: (main.object.canvas.clientWidth - (main.globals.offset.get().x + point.position.left + point.size.width + heightTriangle)) > popup.clientWidth - }; - - var showAbove = function() { - triangle.classList.add("bottom"); - popup.style.top = main.globals.offset.get().y + point.position.top - popup.clientHeight - heightTriangle + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left + (point.size.width / 2) - (popup.clientWidth * left) + 'px'; - triangle.style.left = (left * 100) + "%"; - }; - - var showBeneath = function() { - triangle.classList.add("top"); - popup.style.top = main.globals.offset.get().y + point.position.top + point.size.height + heightTriangle + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left + (point.size.width / 2) - (popup.clientWidth * left) + 'px'; - triangle.style.left = (left * 100) + "%"; - }; - - var showLeft = function() { - triangle.classList.add("right"); - popup.style.top = (main.globals.offset.get().y + point.position.top + (point.size.height / 2) - (popup.clientHeight * top) - 10) + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left - popup.clientWidth - heightTriangle + 'px'; - triangle.style.top = (top * 100) + "%"; - }; - - var showRight = function() { - triangle.classList.add("left"); - popup.style.top = (main.globals.offset.get().y + point.position.top + (point.size.height / 2) - (popup.clientHeight * top) - 10) + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left + point.size.width + heightTriangle + 'px'; - triangle.style.top = (top * 100) + "%"; - }; - - // TODO redo if statements; redo - if ((fits.above || !fits.beneath) && !fits.nextTo) { - showAbove(); - } else if (!fits.nextTo) { - showBeneath(); - } else if (fits.left) { - showLeft(); - } else if (fits.right) { - showRight(); - } else { - showAbove(); - } - - return true; - }; - - return popup; - }; - - /** - * Generate a Overlay style popup - * - * @param {Element} popup - * @param {Element} title_html - * @param {Element} info_html - * @param {Element} media_html - * @returns {Element} the popup - */ - Popup.prototype.generateOverlay = function(popup, title_html, info_html, media_html) { - popup.classList.add("m4n-overlay"); - - var info_container = document.createElement("div"); - info_container.appendChild(title_html); - info_container.appendChild(media_html); - info_container.appendChild(info_html); - - var cell = document.createElement("div"); - var aligner = document.createElement("div"); - - var close_button = helpers.createElement("span", "close_overlay", { - "click": function() { - this.hide(); - }.bind(this), - "touchend": function() { - this.hide(); - }.bind(this) - }); - - aligner.appendChild(info_container); - cell.appendChild(aligner); - - popup.appendChild(cell); - popup.appendChild(close_button); - - this.onHide = function() { - popup.style.display = "none"; - return true; - }; - - this.onShowDesktop = this.onShowMobile = function() { - popup.style.display = "block"; - popup.style.left = main.object.canvas.clientLeft + "px"; - popup.style.top = main.object.canvas.clientTop + "px"; - popup.style.width = main.object.canvas.clientWidth + "px"; - popup.style.height = main.object.canvas.clientHeight + "px"; - - return true; - }; - - return popup; - }; - - /** - * Generate a Popover style popup - * - * @param {Element} popup - * @param {Element} title_html - * @param {Element} info_html - * @param {Element} media_html - * @returns {Element} the popup - */ - Popup.prototype.generateSidebar = function(popup, title_html, info_html, media_html) { - - popup.classList.add("m4n-sidebar-container"); - - var sidebar = helpers.createElement("div", "m4n-sidebar"); - var header = helpers.createElement("div", "m4n-sidebar-header"); - var close = helpers.createElement("div", "m4n-sidebar-close", { - "click": function() { - this.hide(true); - }.bind(this), - "touchend": function() { - this.hide(true); - }.bind(this) - }); - - header.appendChild(close); - header.appendChild(title_html); - - var content = helpers.createElement("div", "m4n-sidebar-content"); - content.appendChild(media_html); - content.appendChild(info_html); - - var footer = helpers.createElement("div", "m4n-sidebar-footer"); - var pagination = helpers.createElement("ul", "m4n-pagination"); - - var previous = helpers.createElement("li", null, { - "click": function() { - this.hide(true); - var new_popup; - if (this.number != main.object.popups.getFirst().number) { - new_popup = main.api.popup(this.number - 1); - } else { - new_popup = main.api.popup(main.object.popups.getLast().number); - } - if (new_popup !== null) { - new_popup.show(true); - } - }.bind(this) - }); - - var next = helpers.createElement("li", null, { - "click": function() { - this.hide(true); - var new_popup; - if (this.number != main.object.popups.getLast().number) { - new_popup = main.api.popup(this.number + 1); - } else { - new_popup = main.api.popup(main.object.popups.getFirst().number); - } - if (new_popup !== null) { - new_popup.show(true); - } - }.bind(this) - }); - - var clear = document.createElement("div"); - clear.style.clear = "both"; - - pagination.appendChild(previous); - pagination.appendChild(next); - - footer.appendChild(pagination); - footer.appendChild(clear); - - sidebar.appendChild(header); - sidebar.appendChild(content); - sidebar.appendChild(footer); - - popup.appendChild(sidebar); - - this.onHide = function(force) { - if (force === true) { - popup.style.display = "none"; - return true; - } - return false; - }; - - this.onShowDesktop = this.onShowMobile = function() { - popup.style.removeProperty("display"); - return true; - }; - - return popup; - }; - /** - * The popups class - * @class - * @param {Popup[]} popups - A list of popups - */ - var Popups = function(popups) { - this._type = "popups"; - - if (popups !== false) { - for (var property in popups) { - if (popups.hasOwnProperty(property)) { - this[property] = popups[property]; - } - } - } - }; - - /** - * Popups api object - */ - Popups.prototype.getApiObject = function() { - var popups = []; - - this.list.forEach(function(item) { - popups.push(item.getApiObject()); - }); - - return popups; - }; - - /** - * Get a specific popup - * - * @param {number} number - The number of the popup - * @returns {Popup|null} The requested popup - */ - Popups.prototype.get = function(number) { - for (var i = 0; i < this.list.length; i++) { - if (this.list[i].number == number) { - return this.list[i]; - } - } - return null; - }; - - /** - * Get all popups - * - * @returns {Popup[]} - */ - Popups.prototype.getAll = function() { - return this.list; - }; - - /** - * Get the first popup - * - * @returns {Popup} - */ - Popups.prototype.getFirst = function() { - return this.list[0]; - }; - - /** - * Get the last popup - * - * @returns {Popup} - */ - Popups.prototype.getLast = function() { - return this.list[this.list.length - 1]; - }; - - /** - * Generate html for the popups - */ - Popups.prototype.generateHTML = function() { - this.list.forEach(function(element) { - element.generateHTML(); - }); - }; - - /** - * Hide all popups - */ - Popups.prototype.hideAll = function(force) { - this.list.forEach(function(element) { - element.hide(force); - }); - }; - - /** - * Get the current popup - * @returns {Popup|null} the current popup - */ - Popups.prototype.getCurrent = function() { - var current = null; - this.getAll().forEach(function(item) { - if (item.on_screen) { - current = item; - return false; - } - }); - return current; - }; - /** - * The tile class - * @class - * @param {object} tile - The tile object from json - */ - var Tile = function(tile) { - this._type = "tile"; - - this.image = new Image(); - this.state = 0; - - this.loadingStates = { - initial: 0, - loading: 1, - loaded: 2, - error: 3 - }; - - if (tile !== false) { - for (var property in tile) { - if (tile.hasOwnProperty(property)) { - this[property] = tile[property]; - } - } - } - }; - - /** - * Download the tile - */ - Tile.prototype.load = function() { - this.image.src = main.url + this.url; - this.state = 1; - this.image.onload = function() { - this.state = 2; - main.object.levels.getLevel(this.level).checkLoaded(); - }.bind(this); - this.image.onerror = function() { - this.state = 3; - main.object.levels.getLevel(this.level).checkLoaded(); - }.bind(this); - }; - - /** - * Draw the tile on screen - */ - Tile.prototype.draw = function() { - /** - * Draw a tile on screen - */ - var show = function() { - var left = this.position.left + main.globals.offset.get().x; - var top = this.position.top + main.globals.offset.get().y; - - if (this.isVisible(left, top, this.size.width, this.size.height)) { - main.object.context.drawImage(this.image, left, top, this.size.width, this.size.height); - } - }.bind(this); - - /** - * Draw an "x" when a tile is unable to load - */ - var error = function() { - var offset = main.globals.offset.get(); - - main.object.context.lineWidth = 8; - main.object.context.lineCap = "round"; - main.object.context.beginPath(); - main.object.context.moveTo(10 + this.position.left + offset.x, - 10 + this.position.top + offset.y); - main.object.context.lineTo(-10 + this.position.left + this.size.width + offset.x, -10 + this.position.top + this.size.height + offset.y); - main.object.context.stroke(); - - main.object.context.beginPath(); - main.object.context.moveTo(10 + this.position.left + offset.x, -10 + this.position.top + this.size.height + offset.y); - main.object.context.lineTo(-10 + this.position.left + this.size.width + offset.x, - 10 + this.position.top + offset.y); - main.object.context.stroke(); - this.state = 3; - }.bind(this); - - switch (this.state) { - case this.loadingStates.initial: - this.load(); - break; - case this.loadingStates.loading: - break; - case this.loadingStates.loaded: - show(); - break; - case this.loadingStates.error: - error(); - break; - } - }; - - /** - * Check if the tile will be visible on screen if drawn - * @param {number} x - The x position of the tile - * @param {number} y - The y position of the tile - * @param {number} w - The width of the tile - * @param {number} h - The height of the tile - * @returns {boolean} If the tile is visible - */ - Tile.prototype.isVisible = function(x, y, w, h) { - return (x < main.object.canvas.width && x + w > 0 && y < main.object.canvas.height && y + h > 0); - }; - /** - * The tiles class - * @class - * @param {Tile[]} tiles - A list of tiles - */ - var Tiles = function(tiles) { - this._type = "tiles"; - - if (tiles !== false) { - for (var property in tiles) { - if (tiles.hasOwnProperty(property)) { - this[property] = tiles[property]; - } - } - } - }; - - /** - * Draws every tile on screen - */ - Tiles.prototype.draw = function() { - this.list.forEach(function(element) { - element.draw(); - }); - }; - - /** - * Downloads every tile - */ - Tiles.prototype.load = function() { - this.list.forEach(function(element) { - if (element.state === element.loadingStates.initial) { - element.load(); - } - }); - }; - - /** - * Get the number of tiles on this level - * - * @returns {number} the number of tiles - */ - Tiles.prototype.count = function() { - return this.list.length; - }; - - /** - * Get all tiles - * - * @returns {Tile[]} all tile objects - */ - Tiles.prototype.getAll = function() { - return this.list; - }; - - /** - * Get a specific tile - * - * @param {number} index - the index for the popup - * @returns {Tile} the specific tile - */ - Tiles.prototype.get = function(index) { - return this.list[index]; - }; - - /** - * The user interaction events - * @type {object} - */ - var events = { - - /** - * When the canvas is clicked - * @param {object} e - The event object - */ - mouseDown: function(e) { - e.preventDefault(); - if (main.object.levels.getCurrent().isOn(e.layerX, e.layerY)) { - helpers.doubleTap(); - main.globals.clickStart = { - x: e.pageX, - y: e.pageY - }; - main.globals.dragPosition = { - x: e.pageX, - y: e.pageY - }; - if (e.which === 1) { - main.globals.isDown = true; - main.object.canvas.classList.add('grabbing'); - } - } - }, - - /** - * When the user starts touching the canvas - * @param {object} e - The event object - */ - touchStart: function(e) { - e.preventDefault(); - if (main.object.levels.getCurrent().isOn(e.touches[0].clientX, e.touches[0].clientY)) { - helpers.doubleTap(); - main.globals.isDown = true; - main.globals.dragPosition = { - x: e.touches[0].clientX, - y: e.touches[0].clientY - }; - main.globals.clickStart = { - x: e.touches[0].clientX, - y: e.touches[0].clientY - }; - } - - // Pinch to zoom - if (e.touches.length == 2) { - main.globals.isScaling = true; - // main.object.context.save(); - main.globals.startDistance = Math.sqrt( - (e.touches[0].pageX - e.touches[1].pageX) * (e.touches[0].pageX - e.touches[1].pageX) + - (e.touches[0].pageY - e.touches[1].pageY) * (e.touches[0].pageY - e.touches[1].pageY)); - } - - // Android zoom - // if(e.touches.length == 1 && main.globals.doubleTap === true) { - // main.globals.isScaling = true; - // // main.object.context.save(); - // main.globals.startDistance = 1; - // - // main.globals.lastPos = { - // x: (main.globals.clickStart.x + e.touches[0].pageX) / 2, - // y: (main.globals.clickStart.y + e.touches[0].pageY) / 2 - // }; - // } - }, - - /** - * When the user lifts the mouse - * @param e - The event object - */ - mouseUp: function(e) { - e.preventDefault(); - if (e.target.id == main.canvas) { - helpers.setInteractTime(); - main.globals.isDown = false; - main.object.canvas.classList.remove('grabbing'); - if (e.pageX == main.globals.clickStart.x && e.pageY == main.globals.clickStart.y) { - var point = main.object.levels.getCurrent().points.hitAPoint(e.layerX, e.layerY); - if (point !== null && e.which === 1) { - main.object.popups.get(point.number).show(); - } else { - if (main.globals.doubleTap === true) { - events.dblclick(e); - main.globals.doubleTap = null; - } else { - main.object.popups.hideAll(); - } - } - } - } - }, - - /** - * When the user lifts his/her finger - * @param e - The event object - */ - touchEnd: function(e) { - e.preventDefault(); - main.globals.isDown = false; - if (e.target.id == main.canvas) { - helpers.setInteractTime(); - if (helpers.validateTouchMoveClickMargin(main.globals.clickStart, main.globals.dragPosition) && !main.globals.isScaling) { - var point = main.object.levels.getCurrent() - .points.hitAPoint(main.globals.dragPosition.x, main.globals.dragPosition.y); - if (point !== null) { - main.object.popups.get(point.number).show(); - } else { - if (main.globals.doubleTap === true) { - events.dbltap(e); - main.globals.doubleTap = null; - } else { - main.object.popups.hideAll(); - } - } - } else { - if (main.globals.doubleTap === true) { - main.globals.doubleTap = null; - } - } - } - - if (main.globals.isScaling) { - var difference = main.globals.newDistance - main.globals.startDistance; - var steps = Math.round(Math.abs(difference) / 100); - - var currentLevel = main.object.levels.getCurrent(); - var newLevel = main.object.levels.getLevel(currentLevel.level + function() { - if (difference > 0) { - return steps; - } else { - return -steps; - } - }()) || currentLevel; - - if (steps > 0) { - var pinchCentre = { - x: main.globals.lastPos.x, - y: main.globals.lastPos.y - }; - - main.globals.offset.changeTo( - pinchCentre.x - (newLevel.size.width / currentLevel.size.width) * (pinchCentre.x - main.globals.offset.get().x), - pinchCentre.y - (newLevel.size.height / currentLevel.size.height) * (pinchCentre.y - main.globals.offset.get().y) - ); - main.object.levels.change(newLevel.level); - - main.globals.startDistance = 0; - main.globals.isScaling = false; - } - main.object.context.setTransform(1, 0, 0, 1, 0, 0); - newLevel.draw(); - } - }, - - /** - * When the user moves the mouse - * @param e - The event object - */ - mouseMove: function(e) { - var currentLevel = main.object.levels.getCurrent(); - if (main.globals.isDown && helpers.isInteracting()) { - helpers.setInteractTime(); - e.preventDefault(); - - main.object.canvas.classList.remove('pointing'); - main.object.canvas.classList.add('grabbing'); - - main.globals.offset.changeBy( - e.pageX - main.globals.dragPosition.x, - e.pageY - main.globals.dragPosition.y - ); - main.globals.dragPosition = { - x: e.pageX, - y: e.pageY - }; - - - main.object.context.fillRect(e.pageX - 5, e.pageY - 5, 10, 10); - - currentLevel.draw(); - } else if (e.target.id == main.canvas) { - var point = currentLevel.points.hitAPoint(e.layerX, e.layerY); - - if (point !== null) { - main.object.canvas.classList.add('pointing'); - } else { - main.object.canvas.classList.remove('pointing'); - } - - if (main.object.settings.eventType == "mouseenter") { - if (point !== null) { - main.object.popups.get(point.number).show(); - } else { - main.object.popups.hideAll(); - } - } - } - }, - - /** - * When the user moves his/her finger - * @param e - The event object - */ - touchMove: function(e) { // TODO not preventdefault when interacting - if (main.globals.isDown && helpers.isInteracting()) { - e.preventDefault(); - - helpers.setInteractTime(); - - var fingers = e.touches; - var currentLevel = main.object.levels.getCurrent(); - - var gPz; - if (fingers.length === 1) { - var finger = fingers[0]; - var new_offset = { - x: main.globals.offset.get().x + finger.clientX - main.globals.dragPosition.x, - y: main.globals.offset.get().y + finger.clientY - main.globals.dragPosition.y - }; - if (new_offset.x !== main.globals.offset.get().x && new_offset.y !== main.globals.offset.get().y) { - if (main.globals.doubleTap === true && main.globals.isScaling) { // if the user has double tapped and is holding down his/her finger - main.globals.newDistance = Math.sqrt( - (main.globals.clickStart.x - fingers[0].pageX) * (main.globals.clickStart.x - fingers[0].pageX) + - (main.globals.clickStart.y - fingers[0].pageY) * (main.globals.clickStart.y - fingers[0].pageY) - ); - - gPz = helpers.gesturePinchZoom(e) / 40; - if (gPz < 1 && gPz > -1) { - main.globals.distance = gPz; - helpers.zoom(gPz); - } - } else { // Drag the map - main.globals.offset.changeTo(new_offset.x, new_offset.y); - currentLevel.draw(); - } - main.globals.dragPosition = { - x: finger.clientX, - y: finger.clientY - }; - } - } else if (fingers.length === 2) { - if (main.globals.isScaling === true) { - // Todo: improve delta calculation - main.globals.newDistance = Math.sqrt( - (fingers[0].pageX - fingers[1].pageX) * (fingers[0].pageX - fingers[1].pageX) + - (fingers[0].pageY - fingers[1].pageY) * (fingers[0].pageY - fingers[1].pageY) - ); - main.globals.lastPos = { - x: (fingers[0].pageX + fingers[1].pageX) / 2, - y: (fingers[0].pageY + fingers[1].pageY) / 2 - }; - - gPz = helpers.gesturePinchZoom(e) / 40; - if (gPz < 1 && gPz > -1) { - main.globals.distance = gPz; - helpers.zoom(gPz); - } - } - } - } - }, - - /** - * When the user scrolls - * @param e - The event object - */ - mouseWheel: function(e) { - var willScroll = (function() { - switch (main.interact) { - case "scroll": - return !e.ctrlKey; - case "smart": - return helpers.isInteracting(); - default: - return e.ctrlKey; - } - })(); - - if (e.target.id == main.canvas && willScroll) { - helpers.setInteractTime(); - clearTimeout(main.globals.scroll.timeout); - e.preventDefault(); - - // TODO improve - main.globals.scroll.value += (function() { - var w = e.wheelDelta, - d = e.detail; - if (d) { - return w ? (w / d / 40 * d > 0 ? 1 : -1) : (-d / 3); - } - return w / 120; - })(); - - var direction = main.globals.scroll.value > 1 ? 1 : main.globals.scroll.value < -1 ? -1 : 0; - if (direction !== 0) { - main.globals.scroll.value = 0; - var levels = main.object.levels.getLevels([main.object.levels.current, main.object.levels.current + direction]); - - if (levels[1] !== null) { - main.globals.offset.changeTo( - e.layerX - (levels[1].size.width / levels[0].size.width) * (e.layerX - main.globals.offset.get().x), - e.layerY - (levels[1].size.height / levels[0].size.height) * (e.layerY - main.globals.offset.get().y) - ); - main.object.levels.change(levels[0].level + direction); - } - } - } - }, - - /** - * When the user double clicks - * @param e - The event object - */ - dblclick: function(e) { - if ( - e.target.id == main.canvas && - main.object.levels.getCurrent().isOn(e.layerX, e.layerY) && - helpers.isInteracting() - ) { - helpers.setInteractTime(); - var currentLevel = main.object.levels.getCurrent(); - var newLevel = main.object.levels.getLevel(currentLevel.level + function() { - return e.which == 1 ? 1 : -1; - }()); - - if (newLevel !== null) { - main.globals.offset.changeTo( - e.layerX - (newLevel.size.width / currentLevel.size.width) * (e.layerX - main.globals.offset.get().x), - e.layerY - (newLevel.size.height / currentLevel.size.height) * (e.layerY - main.globals.offset.get().y) - ); - main.object.levels.change(newLevel.level); - } - } - }, - - /** - * When the user double taps - * @param e - The event object - */ - dbltap: function(e) { - if (e.target.id == main.canvas && main.object.levels.isOn(main.globals.dragPosition.x, main.globals.dragPosition.y)) { - helpers.setInteractTime(); - var levels = main.object.levels.getLevels([main.object.levels.current, main.object.levels.current + 1]); - if (levels[1] !== null) { - main.globals.offset.changeTo( - main.globals.dragPosition.x - (levels[1].size.width / levels[0].size.width) * (main.globals.dragPosition.x - main.globals.offset.get().x), - main.globals.dragPosition.y - (levels[1].size.height / levels[0].size.height) * (main.globals.dragPosition.y - main.globals.offset.get().y) - ); - main.object.levels.change(main.object.levels.current + 1); - } - } - }, - - /** - * When the user triggers the context menu (right click) - * @param e - The event object - */ - contextMenu: function(e) { - e.preventDefault(); - }, - - /** - * When the document gets resized - */ - resize: function() { - var fullscreen = document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement; - if (fullscreen) { - if ([fullscreen.id.indexOf("-youtube"), fullscreen.id.indexOf("-video")].indexOf(-1) > -1) { - main.globals.videoFullscreen.value = true; - main.globals.videoFullscreen.noEvents = 0; - } - } - - if (!main.globals.videoFullscreen.value && (new Date().getTime() - main.globals.videoFullscreen.date > 3000 || main.globals.videoFullscreen.noEvents > 1)) { - var currentLevel = main.object.levels.getCurrent(); - var current = { - w: main.object.canvas.width, - h: main.object.canvas.height - }; - - main.object.canvas.height = main.object.container.clientHeight; - main.object.canvas.width = main.object.container.clientWidth; - - main.globals.offset.changeBy(-((current.w - main.object.canvas.width) / 2), -((current.h - main.object.canvas.height) / 2)); - currentLevel.draw(); - } - - if (!fullscreen) { - main.globals.videoFullscreen = { - value: false, - date: new Date().getTime(), - noEvents: main.globals.videoFullscreen.noEvents + 1 - }; - } - } - }; - - main.globals = { - // Keep track of the cursor; if it's down (clicked) - isDown: false, - // If the user is scaling - isScaling: false, - // The location of the initial click - clickStart: { - x: 0, - y: 0 - }, - // The location of the last move event - dragPosition: { - x: 0, - y: 0 - }, - // The offset of the map on screen - mapOffset: { - x: 0, - y: 0 - }, - // If the user has double tapped or clicked - doubleTap: null, - // If a video prompted the fullscreen and when - videoFullscreen: { - value: false, - date: null, - noEvents: 2 - }, - // - scroll: { - value: 0, - timeout: null - }, - // - startDistance: 0, - // - scaleFactor: 1.1, - // - lastPos: { - x: 0, - y: 0 - }, - // - interact: { - isInteracting: false, - timer: null - }, - - // mapOffset helper functions - offset: { - changeBy: function(x, y) { - main.globals.mapOffset.x += x; - main.globals.mapOffset.y += y; - }, - changeTo: function(x, y) { - main.globals.mapOffset = { - x: x, - y: y - }; - }, - get: function() { - return main.globals.mapOffset; - } - } - }; - - /** - * Helpers methods - * @type {object} - */ - var helpers = { - - /** - * Moves the canvas to a specific location - * @param {number} x - the x value (map offset) - * @param {number} y - the y value (map offset) - */ - moveTo: function(x, y) { - main.globals.offset.changeTo(-(x - (main.object.canvas.clientWidth / 2)), -(y - (main.object.canvas.clientHeight / 2))); - - main.object.levels.getCurrent().draw(); - }, - - /** - * Moves the canvas by a specific number of pixels - * @param {number} x - the x value (map offset) - * @param {number} y - the y value (map offset) - */ - moveBy: function(x, y) { - main.globals.offset.changeBy(x, y); - main.object.levels.getCurrent().draw(); - }, - - /** - * Help set value of double (tap|click) - */ - doubleTap: function() { - main.globals.doubleTap = - main.globals.doubleTap !== null && new Date().getTime() - main.globals.doubleTap <= 250 ? - true : new Date().getTime(); - }, - - /** - * Returns the distance between two numbers - * @param {object} event - the event object - * @returns {number|boolean} Distance between the fingers - */ - gesturePinchZoom: function(event) { - var zoom = false; - - if (event.targetTouches.length >= 2) { - var p1 = event.targetTouches[0]; - var p2 = event.targetTouches[1]; - var zoomScale = Math.sqrt(Math.pow(p2.pageX - p1.pageX, 2) + Math.pow(p2.pageY - p1.pageY, 2)); // Euclidean distance - - if (this.lastZoomScale) { - zoom = zoomScale - this.lastZoomScale; - } - this.lastZoomScale = zoomScale; - } - return zoom; - }, - - /** - * Zooms the map - * @param {object} distance - distance between the fingers - */ - zoom: function(distance) { - var pt = main.object.context.transformedPoint(main.globals.lastPos.x, main.globals.lastPos.y); - main.object.context.translate(pt.x, pt.y); - var factor = Math.pow(main.globals.scaleFactor, distance); - main.object.context.scale(factor, factor); - main.object.context.translate(-pt.x, -pt.y); - main.object.levels.getCurrent().draw(); - }, - - /** - * Create an html element - * @param {string} tag - the tag of the element - * @param {string|string[]} classes - the classes for the element - * @param {Object|null} [events] - the event listeners - * @returns {Element} the new element - */ - createElement: function(tag, classes, events) { - var element = document.createElement(tag); - - if (classes !== null) { - element.classList.add(classes); - } - - for (var event in events) { - if (events.hasOwnProperty(event)) { - element.addEventListener(event, events[event]); - } - } - return element; - }, - - /** - * Set the interact time - * - * @param {number} [listenerId] - */ - setInteractTime: function(listenerId) { - if (main.interact === "smart") { - var setNotInteracting = function() { - if (!main.globals.isDown) { - var popup = main.object.popups.getCurrent(); - if (popup === null) { - main.globals.interact.isInteracting = false; - helpers.showTimeoutOverlay(); - if (listenerId !== undefined) { - removeEventListener("popup_hidden", listenerId); - } - } else { - var eventId = addEventListener("popup_hidden", function() { - helpers.setInteractTime(eventId); - removeEventListener("popup_hidden", eventId); - }); - } - } else { - if (main.dev) { - console.log("Finger or mouse is down"); - } - } - }; - - clearTimeout(main.globals.interact.timer); - main.globals.interact = { - isInteracting: true, - timer: setTimeout(setNotInteracting, 3000) - }; - } - }, - - /** - * If the user has interacted with the map in the last 3 seconds - */ - isInteracting: function() { - return main.interact != "smart" || main.globals.interact.isInteracting; - }, - - /** - * Show the timeout overlay - */ - showTimeoutOverlay: function() { - main.timeoutOverlay.style.display = "block"; - }, - - /** - * Checks if the finger moved with a margin of 2 pixels - * @param {object} a - * @param {object} b - * @returns {boolean} - */ - validateTouchMoveClickMargin: function(a, b) { - return ( - (a.x > b.x - 2 && a.x < b.x + 2) && - (a.y > b.y - 2 && a.y < b.y + 2) - ); - } - }; - - /** - * The object that will be returned when the map is made. - * Write-protected - * @type {object} - */ - var returnObject = {}; - Object.defineProperties(returnObject, { - api: { - value: main.api, - writable: false - }, - addEventListener: { - value: addEventListener, - writable: false - }, - removeEventListener: { - value: removeEventListener, - writable: false - } - }); - - if (main.dev) { - returnObject.object = function() { - return main; - }; - } - return returnObject; -}); diff --git a/dist/m4n.min.js b/dist/m4n.min.js deleted file mode 100644 index e56990c..0000000 --- a/dist/m4n.min.js +++ /dev/null @@ -1,2 +0,0 @@ -var M4nInteractive=function(a,b,c){"use strict";function d(a){if(h(),m.object=g(a),m.object.levels.count()>1&&i(),!b.hasPredefinedHeight){var d=m.object.levels.getCurrent();m.object.canvas.height=b.clientWidth*(d.size.height/d.size.width)}for(var f in n)n.hasOwnProperty(f)&&n[f].checkIfNeeded();e(),m.object.popups.generateHTML(),m.api.reset(),"function"==typeof c&&c(A),m.endTime=(new Date).getTime(),m.dev&&console.info("It took "+(m.endTime-m.startTime)+"ms to start up")}function e(){m.object.canvas.addEventListener("mousedown",y.mouseDown),m.object.canvas.addEventListener("touchstart",y.touchStart),document.addEventListener("mouseup",y.mouseUp),document.addEventListener("touchend",y.touchEnd),document.addEventListener("mousemove",y.mouseMove),document.addEventListener("touchmove",y.touchMove),m.object.canvas.addEventListener("mousewheel",y.mouseWheel),m.object.canvas.addEventListener("DOMMouseScroll",y.mouseWheel),m.object.canvas.addEventListener("contextmenu",y.contextMenu),window.addEventListener("resize",y.resize),window.addEventListener("orientationchange",y.resize)}function f(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg"),c=b.createSVGMatrix();a.getTransform=function(){return c};var d=[],e=a.save;a.save=function(){return d.push(c.translate(0,0)),e.call(a)};var f=a.restore;a.restore=function(){return c=d.pop(),f.call(a)};var g=a.scale;a.scale=function(b,d){return c=c.scaleNonUniform(b,d),g.call(a,b,d)};var h=a.rotate;a.rotate=function(b){return c=c.rotate(180*b/Math.PI),h.call(a,b)};var i=a.translate;a.translate=function(b,d){return c=c.translate(b,d),i.call(a,b,d)};var j=a.transform;a.transform=function(d,e,f,g,h,i){var k=b.createSVGMatrix();return k.a=d,k.b=e,k.c=f,k.d=g,k.e=h,k.f=i,c=c.multiply(k),j.call(a,d,e,f,g,h,i)};var k=a.setTransform;a.setTransform=function(b,d,e,f,g,h){return c.a=b,c.b=d,c.c=e,c.d=f,c.e=g,c.f=h,k.call(a,b,d,e,f,g,h)};var l=b.createSVGPoint();a.transformedPoint=function(a,b){return l.x=a,l.y=b,l.matrixTransform(c.inverse())}}function g(a){var b={levels:r,level:q,tiles:x,tile:w,points:t,point:s,popup:u,popups:v},c=JSON.parse(a,function(a,c){if(null!==c){if(""===a)return new p(c);if(null!==c)return c._type?b[c._type]?new b[c._type](c):(console.error("Unknown class type in save: "+c._type),null):c}});return c.levels.list.forEach(function(a){a.tiles.list.forEach(function(b){b.level=a.level})}),c}function h(){if(m.isIframe&&(document.body.style.margin="0"),null===document.getElementById("m4n-style")){var c=document.createElement("link");c.id="m4n-style",c.rel="stylesheet",c.type="text/css",c.href=function(){switch(a.environment){case"development":return location.href.split("/").slice(0,-1).join("/")+"/style.css";case"local":return a.path+"style.css";default:return"//"+a.environment+".maps4news.com/ia/"+m.version.map+"/style.css"}}(),document.head.appendChild(c)}var d=document.getElementById("m4n-style-custom");if(null!==d){var e=document.createElement("link");e.id="m4n-style-custom",e.rel="stylesheet",e.type="text/css",e.href=d.href,document.head.removeChild(d),document.head.appendChild(e)}var f=document.getElementById(m.canvas);if(null!==f){if(f.classList.contains("m4n-canvas"))throw"Map already initialized for "+m.canvas;m.canvas=m.canvas+"-"+Math.random().toString(36).substring(7),f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas}else f=z.createElement("canvas","m4n-canvas"),f.id=m.canvas;if("smart"==m.interact){var g=z.createElement("div","timeout-overlay",{click:function(){h()},touchstart:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchmove:function(a){m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY}},touchend:function(){z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&h()}}),h=function(){g.style.display="none",z.setInteractTime()};g.style.display="block",m.timeoutOverlay=g,b.appendChild(g)}b.id=m.canvas+"-container",b.classList.add("m4n-container"),b.style.height="100%",b.style.width="100%",b.hasPredefinedHeight=0!==b.clientHeight;var i=document.createElement("div");i.id=m.canvas+"-popup-container",b.appendChild(i),b.appendChild(f),f.height=b.clientHeight,f.width=b.clientWidth}function i(){var a=z.createElement("div","m4n-zoom-container"),c=z.createElement("div","m4n-zoom-button",{click:function(){c.classList.contains("disabled")||m.api.zoom["in"]()}}),d=z.createElement("div","m4n-zoom-button",{click:function(){d.classList.contains("disabled")||m.api.zoom.out()}});j("level_changed",function(){var a=m.object.levels.getCurrent();d.classList.remove("disabled"),c.classList.remove("disabled"),a.level==m.object.levels.getHighest().level?d.classList.add("disabled"):a.level==m.object.levels.getLowest().level&&c.classList.add("disabled")}),a.style.zIndex=m.object.canvas.style.zIndex+1,a.appendChild(c),a.appendChild(d),b.appendChild(a)}function j(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("function"!=typeof b)throw"callback must be a function";return m.dispatchEvents[a]||(m.dispatchEvents[a]=[]),m.dev&&console.log('Event listener for event "'+a+'" added',b),m.dispatchEvents[a].push(b)}function k(a,b){if("string"!=typeof a)throw"event must be a string; "+a+" given";if("number"!=typeof b)throw"id must be a number; "+b+" given";if(!m.dispatchEvents[a])throw"unknown event";if(!m.dispatchEvents[a][b-1])throw"unknown listener";m.dev&&console.log('Event listener for event "'+a+'" removed',m.dispatchEvents[a][b-1]),delete m.dispatchEvents[a][b-1]}function l(a,b){m.dispatchEvents[a]&&m.dispatchEvents[a].forEach(function(a){a(b)})}var m=this;!function(a){if(m.startTime=(new Date).getTime(),!a.path)throw"M4nInteractive Parameter 'path' is missing";if(!b)throw"M4nInteractive: No container was given";switch(m.interact=a.interact||"scroll",m.environment=a.environment||"online",m.version={map:"2.0",code:"2.0.4"},m.dev="development"==m.environment||a.debug&&"true"==a.debug,m.isMobile=/Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),m.isIframe=window.location!==window.parent.location,m.canvas="m4n-"+Math.floor(65536*(1+Math.random())).toString(16).substring(1),m.url=m.json="",m.environment){case"development":m.url=location.href.split("/").slice(0,-1).join("/")+"/output/"+a.path+"/",m.json=m.url+"map.json";break;case"local":m.url=a.path.replace(/\/$/,"")+"/",m.json=m.url+"map.json";break;default:m.url="https://"+m.environment+".maps4news.com/output/"+a.path+"/",m.json="https://"+m.environment+".maps4news.com/ia/"+m.version.map+"/?id="+encodeURIComponent(a.path)}}(a);var n={youtube:{checkIfNeeded:function(){var a=!1;return m.object.popups.list.forEach(function(b){return"youtube"===b.media_type?(a=!0,n.youtube.download(),!1):void 0}),a},download:function(){if("undefined"==typeof YT){var a=document.createElement("script");a.src="//www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}},enable:function(){null!==m.object&&"undefined"!=typeof YT&&m.object.popups.list.forEach(function(a){"youtube"===a.media_type&&(a.youtube=new YT.Player(a.html_id+"-youtube"))})}}};document.addEventListener("onYouTubeIframeAPIReady",n.youtube.enable,!1),window.onYouTubeIframeAPIReady=function(){document.dispatchEvent(new CustomEvent("onYouTubeIframeAPIReady",null))};var o=new XMLHttpRequest;o.open("GET",m.json,!0),o.onreadystatechange=function(){4==o.readyState&&200==o.status?d(o.responseText):200!==o.status&&console.error("Something went wrong!",o)},o.send(),m.dispatchEvents={},m.api={popup:function(a){var b=m.object.popups.get(a);if(null===b)throw"Popup "+a+" not found";return b.getApiObject()},popups:function(){return m.object.popups.getApiObject()},level:function(a){var b=m.object.levels.getLevel(a);return b.getApiObject()||null},levels:function(){return m.object.levels.getApiObject()},reset:function(){var a=m.object.levels.getIdealLevel();m.globals.offset.changeTo(-(a.size.width/2-m.object.canvas.width/2),-(a.size.height/2-m.object.canvas.height/2)),m.object.levels.change(a.level)},refit:function(){y.resize()},zoom:{to:function(a){a="number"==typeof a?a:0;var b={x:m.object.canvas.clientWidth/2,y:m.object.canvas.clientHeight/2},c=m.object.levels.getLevels([m.object.levels.current,a]);null!==c[1]&&(m.globals.offset.changeTo(b.x-c[1].size.width/c[0].size.width*(b.x-m.globals.offset.get().x),b.y-c[1].size.height/c[0].size.height*(b.y-m.globals.offset.get().y)),m.object.levels.change(c[1].level))},"in":function(){this.to(m.object.levels.current+1)},out:function(){this.to(m.object.levels.current-1)}},move:{left:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(-40*(a||1),0),b.draw()},right:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(40*(a||1),0),b.draw()},up:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,-40*(a||1)),b.draw()},down:function(a){var b=m.object.levels.getCurrent();m.globals.offset.changeBy(0,40*(a||1)),b.draw()}}};var p=function(a){this._type="map",this.container=document.getElementById(m.canvas+"-container"),this.canvas=document.getElementById(m.canvas),this.context=this.canvas.getContext("2d"),f(this.context),this.popupContainer=document.getElementById(m.canvas+"-popup-container");for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},q=function(a){if(this._type="level",this.is_loaded=!1,this.tiles={},a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};q.prototype.getApiObject=function(){return{level:this.level,isLoaded:this.is_loaded,changeTo:function(){m.object.levels.change(this.level)}.bind(this),load:function(){this.load()}.bind(this)}},q.prototype.checkLoaded=function(){var a=0;this.tiles.list.forEach(function(b){b.state>1&&a++}),a===this.tiles.list.length&&(this.is_loaded=!0,l("level_loaded",this.getApiObject()))},q.prototype.draw=function(){m.object.popups.hideAll(),m.object.context.save(),m.object.context.setTransform(1,0,0,1,0,0),m.object.context.clearRect(0,0,m.object.canvas.width,m.object.canvas.height),m.object.context.restore(),m.globals.offset.changeTo(this.getBounds(!0,m.globals.offset.get().x),this.getBounds(!1,m.globals.offset.get().y)),this.tiles.draw(),m.dev&&this.points.draw(),m.object.levels.setCurrent(this.level),l("level_drawn",this.getApiObject())},q.prototype.load=function(){this.is_loaded||this.tiles.load()},q.prototype.isOn=function(a,b){return a>m.globals.offset.get().x&&am.globals.offset.get().y&&b=m.object.canvas.clientHeight?(c=Math.abs(m.object.canvas.width-b.requested_area.size.width),d=Math.abs(m.object.canvas.width-a.requested_area.size.width)):(c=Math.abs(m.object.canvas.height-b.requested_area.size.height),d=Math.abs(m.object.canvas.height-a.requested_area.size.height)),d>c&&(a=b)}else a=b}),a},r.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),{current:this.current,highest:this.getHighest().level,lowest:this.getLowest().level,levels:a}},r.prototype.setCurrent=function(a){this.current!==a&&(this.current=a)},r.prototype.getLevel=function(a){for(var b=0;ba.level&&(a=b)}),a},r.prototype.change=function(a){var b=this.getLevels([a,a+1,a-1]);if(null!==b[0]){var c=function(a){window.requestAnimationFrame(function(){a.draw(),l("level_changed",a.getApiObject())})};if(b[0].is_loaded)c(b[0]);else{b[0].load();var d=j("level_loaded",function(e){e.level==a&&(c(b[0]),k("level_loaded",d))})}null!==b[1]&&b[1].load(),null!==b[2]&&b[2].load()}},r.prototype.count=function(){return this.list.length};var s=function(a){if(this._type="point",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);this.position={left:Math.min.apply(null,this.shape.map(function(a){return a.x})),top:Math.min.apply(null,this.shape.map(function(a){return a.y}))},this.size={width:Math.max.apply(null,this.shape.map(function(a){return a.x}))-this.position.left,height:Math.max.apply(null,this.shape.map(function(a){return a.y}))-this.position.top}};s.prototype.draw=function(){m.object.context.strokeRect(this.position.left+m.globals.offset.get().x,this.position.top+m.globals.offset.get().y,this.size.width,this.size.height)},s.prototype.isOn=function(a,b){return a>this.position.left+m.globals.offset.get().x&&athis.position.top+m.globals.offset.get().y&&b0,above:m.globals.offset.get().y+b.position.top-c>a.clientHeight,beneath:m.object.canvas.clientHeight-(m.globals.offset.get().y+b.position.top+b.size.height+c)>a.clientHeight,left:m.globals.offset.get().x+b.position.left-c>a.clientWidth,right:m.object.canvas.clientWidth-(m.globals.offset.get().x+b.position.left+b.size.width+c)>a.clientWidth},h=function(){f.classList.add("bottom"),a.style.top=m.globals.offset.get().y+b.position.top-a.clientHeight-c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},i=function(){f.classList.add("top"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height+c+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width/2-a.clientWidth*d+"px",f.style.left=100*d+"%"},j=function(){f.classList.add("right"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left-a.clientWidth-c+"px",f.style.top=100*e+"%"},k=function(){f.classList.add("left"),a.style.top=m.globals.offset.get().y+b.position.top+b.size.height/2-a.clientHeight*e-10+"px",a.style.left=m.globals.offset.get().x+b.position.left+b.size.width+c+"px",f.style.top=100*e+"%"};return!g.above&&g.beneath||g.nextTo?g.nextTo?g.left?j():g.right?k():h():i():h(),!0},a},u.prototype.generateOverlay=function(a,b,c,d){a.classList.add("m4n-overlay");var e=document.createElement("div");e.appendChild(b),e.appendChild(d),e.appendChild(c);var f=document.createElement("div"),g=document.createElement("div"),h=z.createElement("span","close_overlay",{click:function(){this.hide()}.bind(this),touchend:function(){this.hide()}.bind(this)});return g.appendChild(e),f.appendChild(g),a.appendChild(f),a.appendChild(h),this.onHide=function(){return a.style.display="none",!0},this.onShowDesktop=this.onShowMobile=function(){return a.style.display="block",a.style.left=m.object.canvas.clientLeft+"px",a.style.top=m.object.canvas.clientTop+"px",a.style.width=m.object.canvas.clientWidth+"px",a.style.height=m.object.canvas.clientHeight+"px",!0},a},u.prototype.generateSidebar=function(a,b,c,d){a.classList.add("m4n-sidebar-container");var e=z.createElement("div","m4n-sidebar"),f=z.createElement("div","m4n-sidebar-header"),g=z.createElement("div","m4n-sidebar-close",{click:function(){this.hide(!0)}.bind(this),touchend:function(){this.hide(!0)}.bind(this)});f.appendChild(g),f.appendChild(b);var h=z.createElement("div","m4n-sidebar-content");h.appendChild(d),h.appendChild(c);var i=z.createElement("div","m4n-sidebar-footer"),j=z.createElement("ul","m4n-pagination"),k=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getFirst().number?m.api.popup(this.number-1):m.api.popup(m.object.popups.getLast().number),null!==a&&a.show(!0)}.bind(this)}),l=z.createElement("li",null,{click:function(){this.hide(!0);var a;a=this.number!=m.object.popups.getLast().number?m.api.popup(this.number+1):m.api.popup(m.object.popups.getFirst().number),null!==a&&a.show(!0)}.bind(this)}),n=document.createElement("div");return n.style.clear="both",j.appendChild(k),j.appendChild(l),i.appendChild(j),i.appendChild(n),e.appendChild(f),e.appendChild(h),e.appendChild(i),a.appendChild(e),this.onHide=function(b){return b===!0?(a.style.display="none",!0):!1},this.onShowDesktop=this.onShowMobile=function(){return a.style.removeProperty("display"),!0},a};var v=function(a){if(this._type="popups",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};v.prototype.getApiObject=function(){var a=[];return this.list.forEach(function(b){a.push(b.getApiObject())}),a},v.prototype.get=function(a){for(var b=0;b0&&b0};var x=function(a){if(this._type="tiles",a!==!1)for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])};x.prototype.draw=function(){this.list.forEach(function(a){a.draw()})},x.prototype.load=function(){this.list.forEach(function(a){a.state===a.loadingStates.initial&&a.load()})},x.prototype.count=function(){return this.list.length},x.prototype.getAll=function(){return this.list},x.prototype.get=function(a){return this.list[a]};var y={mouseDown:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&(z.doubleTap(),m.globals.clickStart={x:a.pageX,y:a.pageY},m.globals.dragPosition={x:a.pageX,y:a.pageY},1===a.which&&(m.globals.isDown=!0,m.object.canvas.classList.add("grabbing")))},touchStart:function(a){a.preventDefault(),m.object.levels.getCurrent().isOn(a.touches[0].clientX,a.touches[0].clientY)&&(z.doubleTap(),m.globals.isDown=!0,m.globals.dragPosition={x:a.touches[0].clientX,y:a.touches[0].clientY},m.globals.clickStart={x:a.touches[0].clientX,y:a.touches[0].clientY}),2==a.touches.length&&(m.globals.isScaling=!0,m.globals.startDistance=Math.sqrt((a.touches[0].pageX-a.touches[1].pageX)*(a.touches[0].pageX-a.touches[1].pageX)+(a.touches[0].pageY-a.touches[1].pageY)*(a.touches[0].pageY-a.touches[1].pageY)))},mouseUp:function(a){if(a.preventDefault(),a.target.id==m.canvas&&(z.setInteractTime(),m.globals.isDown=!1,m.object.canvas.classList.remove("grabbing"),a.pageX==m.globals.clickStart.x&&a.pageY==m.globals.clickStart.y)){var b=m.object.levels.getCurrent().points.hitAPoint(a.layerX,a.layerY);null!==b&&1===a.which?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dblclick(a),m.globals.doubleTap=null):m.object.popups.hideAll()}},touchEnd:function(a){if(a.preventDefault(),m.globals.isDown=!1,a.target.id==m.canvas)if(z.setInteractTime(),z.validateTouchMoveClickMargin(m.globals.clickStart,m.globals.dragPosition)&&!m.globals.isScaling){var b=m.object.levels.getCurrent().points.hitAPoint(m.globals.dragPosition.x,m.globals.dragPosition.y);null!==b?m.object.popups.get(b.number).show():m.globals.doubleTap===!0?(y.dbltap(a),m.globals.doubleTap=null):m.object.popups.hideAll()}else m.globals.doubleTap===!0&&(m.globals.doubleTap=null);if(m.globals.isScaling){var c=m.globals.newDistance-m.globals.startDistance,d=Math.round(Math.abs(c)/100),e=m.object.levels.getCurrent(),f=m.object.levels.getLevel(e.level+function(){return c>0?d:-d}())||e;if(d>0){var g={x:m.globals.lastPos.x,y:m.globals.lastPos.y};m.globals.offset.changeTo(g.x-f.size.width/e.size.width*(g.x-m.globals.offset.get().x),g.y-f.size.height/e.size.height*(g.y-m.globals.offset.get().y)),m.object.levels.change(f.level),m.globals.startDistance=0,m.globals.isScaling=!1}m.object.context.setTransform(1,0,0,1,0,0),f.draw()}},mouseMove:function(a){var b=m.object.levels.getCurrent();if(m.globals.isDown&&z.isInteracting())z.setInteractTime(),a.preventDefault(),m.object.canvas.classList.remove("pointing"),m.object.canvas.classList.add("grabbing"),m.globals.offset.changeBy(a.pageX-m.globals.dragPosition.x,a.pageY-m.globals.dragPosition.y),m.globals.dragPosition={x:a.pageX,y:a.pageY},m.object.context.fillRect(a.pageX-5,a.pageY-5,10,10),b.draw();else if(a.target.id==m.canvas){var c=b.points.hitAPoint(a.layerX,a.layerY);null!==c?m.object.canvas.classList.add("pointing"):m.object.canvas.classList.remove("pointing"),"mouseenter"==m.object.settings.eventType&&(null!==c?m.object.popups.get(c.number).show():m.object.popups.hideAll())}},touchMove:function(a){if(m.globals.isDown&&z.isInteracting()){a.preventDefault(),z.setInteractTime();var b,c=a.touches,d=m.object.levels.getCurrent();if(1===c.length){var e=c[0],f={x:m.globals.offset.get().x+e.clientX-m.globals.dragPosition.x,y:m.globals.offset.get().y+e.clientY-m.globals.dragPosition.y};f.x!==m.globals.offset.get().x&&f.y!==m.globals.offset.get().y&&(m.globals.doubleTap===!0&&m.globals.isScaling?(m.globals.newDistance=Math.sqrt((m.globals.clickStart.x-c[0].pageX)*(m.globals.clickStart.x-c[0].pageX)+(m.globals.clickStart.y-c[0].pageY)*(m.globals.clickStart.y-c[0].pageY)),b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b))):(m.globals.offset.changeTo(f.x,f.y),d.draw()),m.globals.dragPosition={x:e.clientX,y:e.clientY})}else 2===c.length&&m.globals.isScaling===!0&&(m.globals.newDistance=Math.sqrt((c[0].pageX-c[1].pageX)*(c[0].pageX-c[1].pageX)+(c[0].pageY-c[1].pageY)*(c[0].pageY-c[1].pageY)),m.globals.lastPos={x:(c[0].pageX+c[1].pageX)/2,y:(c[0].pageY+c[1].pageY)/2},b=z.gesturePinchZoom(a)/40,1>b&&b>-1&&(m.globals.distance=b,z.zoom(b)))}},mouseWheel:function(a){var b=function(){switch(m.interact){case"scroll":return!a.ctrlKey;case"smart":return z.isInteracting();default:return a.ctrlKey}}();if(a.target.id==m.canvas&&b){z.setInteractTime(),clearTimeout(m.globals.scroll.timeout),a.preventDefault(),m.globals.scroll.value+=function(){var b=a.wheelDelta,c=a.detail;return c?b?b/c/40*c>0?1:-1:-c/3:b/120}();var c=m.globals.scroll.value>1?1:m.globals.scroll.value<-1?-1:0;if(0!==c){m.globals.scroll.value=0;var d=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+c]);null!==d[1]&&(m.globals.offset.changeTo(a.layerX-d[1].size.width/d[0].size.width*(a.layerX-m.globals.offset.get().x),a.layerY-d[1].size.height/d[0].size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(d[0].level+c))}}},dblclick:function(a){if(a.target.id==m.canvas&&m.object.levels.getCurrent().isOn(a.layerX,a.layerY)&&z.isInteracting()){z.setInteractTime();var b=m.object.levels.getCurrent(),c=m.object.levels.getLevel(b.level+function(){return 1==a.which?1:-1}());null!==c&&(m.globals.offset.changeTo(a.layerX-c.size.width/b.size.width*(a.layerX-m.globals.offset.get().x),a.layerY-c.size.height/b.size.height*(a.layerY-m.globals.offset.get().y)),m.object.levels.change(c.level))}},dbltap:function(a){if(a.target.id==m.canvas&&m.object.levels.isOn(m.globals.dragPosition.x,m.globals.dragPosition.y)){z.setInteractTime();var b=m.object.levels.getLevels([m.object.levels.current,m.object.levels.current+1]);null!==b[1]&&(m.globals.offset.changeTo(m.globals.dragPosition.x-b[1].size.width/b[0].size.width*(m.globals.dragPosition.x-m.globals.offset.get().x),m.globals.dragPosition.y-b[1].size.height/b[0].size.height*(m.globals.dragPosition.y-m.globals.offset.get().y)),m.object.levels.change(m.object.levels.current+1))}},contextMenu:function(a){a.preventDefault()},resize:function(){var a=document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement;if(a&&[a.id.indexOf("-youtube"),a.id.indexOf("-video")].indexOf(-1)>-1&&(m.globals.videoFullscreen.value=!0,m.globals.videoFullscreen.noEvents=0),!m.globals.videoFullscreen.value&&((new Date).getTime()-m.globals.videoFullscreen.date>3e3||m.globals.videoFullscreen.noEvents>1)){var b=m.object.levels.getCurrent(),c={w:m.object.canvas.width,h:m.object.canvas.height};m.object.canvas.height=m.object.container.clientHeight,m.object.canvas.width=m.object.container.clientWidth,m.globals.offset.changeBy(-((c.w-m.object.canvas.width)/2),-((c.h-m.object.canvas.height)/2)), -b.draw()}a||(m.globals.videoFullscreen={value:!1,date:(new Date).getTime(),noEvents:m.globals.videoFullscreen.noEvents+1})}};m.globals={isDown:!1,isScaling:!1,clickStart:{x:0,y:0},dragPosition:{x:0,y:0},mapOffset:{x:0,y:0},doubleTap:null,videoFullscreen:{value:!1,date:null,noEvents:2},scroll:{value:0,timeout:null},startDistance:0,scaleFactor:1.1,lastPos:{x:0,y:0},interact:{isInteracting:!1,timer:null},offset:{changeBy:function(a,b){m.globals.mapOffset.x+=a,m.globals.mapOffset.y+=b},changeTo:function(a,b){m.globals.mapOffset={x:a,y:b}},get:function(){return m.globals.mapOffset}}};var z={moveTo:function(a,b){m.globals.offset.changeTo(-(a-m.object.canvas.clientWidth/2),-(b-m.object.canvas.clientHeight/2)),m.object.levels.getCurrent().draw()},moveBy:function(a,b){m.globals.offset.changeBy(a,b),m.object.levels.getCurrent().draw()},doubleTap:function(){m.globals.doubleTap=null!==m.globals.doubleTap&&(new Date).getTime()-m.globals.doubleTap<=250?!0:(new Date).getTime()},gesturePinchZoom:function(a){var b=!1;if(a.targetTouches.length>=2){var c=a.targetTouches[0],d=a.targetTouches[1],e=Math.sqrt(Math.pow(d.pageX-c.pageX,2)+Math.pow(d.pageY-c.pageY,2));this.lastZoomScale&&(b=e-this.lastZoomScale),this.lastZoomScale=e}return b},zoom:function(a){var b=m.object.context.transformedPoint(m.globals.lastPos.x,m.globals.lastPos.y);m.object.context.translate(b.x,b.y);var c=Math.pow(m.globals.scaleFactor,a);m.object.context.scale(c,c),m.object.context.translate(-b.x,-b.y),m.object.levels.getCurrent().draw()},createElement:function(a,b,c){var d=document.createElement(a);null!==b&&d.classList.add(b);for(var e in c)c.hasOwnProperty(e)&&d.addEventListener(e,c[e]);return d},setInteractTime:function(a){if("smart"===m.interact){var b=function(){if(m.globals.isDown)m.dev&&console.log("Finger or mouse is down");else{var b=m.object.popups.getCurrent();if(null===b)m.globals.interact.isInteracting=!1,z.showTimeoutOverlay(),void 0!==a&&k("popup_hidden",a);else var c=j("popup_hidden",function(){z.setInteractTime(c),k("popup_hidden",c)})}};clearTimeout(m.globals.interact.timer),m.globals.interact={isInteracting:!0,timer:setTimeout(b,3e3)}}},isInteracting:function(){return"smart"!=m.interact||m.globals.interact.isInteracting},showTimeoutOverlay:function(){m.timeoutOverlay.style.display="block"},validateTouchMoveClickMargin:function(a,b){return a.x>b.x-2&&a.xb.y-2&&a.y Date: Wed, 4 May 2016 16:39:45 +0200 Subject: [PATCH 11/27] Removed style from dist --- .gitignore | 3 +- dist/.gitignore | 2 - dist/style.css | 312 ------------------------------------------------ 3 files changed, 2 insertions(+), 315 deletions(-) delete mode 100644 dist/.gitignore delete mode 100644 dist/style.css diff --git a/.gitignore b/.gitignore index 34977ee..d4e0572 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.idea \ No newline at end of file +.idea +dist \ No newline at end of file diff --git a/dist/.gitignore b/dist/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/dist/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/dist/style.css b/dist/style.css deleted file mode 100644 index e95bfa9..0000000 --- a/dist/style.css +++ /dev/null @@ -1,312 +0,0 @@ -.m4n-container *, -.m4n-container *:after, -.m4n-container *:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.m4n-container { - position: relative; - display: inline-block; -} -.m4n-container::after { - clear: both; -} -.m4n-canvas { - float: left; - cursor: grab; - cursor: -moz-grab; - cursor: -webkit-grab; -} -.m4n-canvas.grabbing { - cursor: grabbing; - cursor: -moz-grabbing; - cursor: -webkit-grabbing; -} -.m4n-canvas.pointing { - cursor: pointer; -} -.m4n-video::-webkit-media-controls-current-time-display, -.m4n-video::-webkit-media-controls-time-remaining-display, -.m4n-video::-webkit-media-controls-toggle-closed-captions-button, -.m4n-video::-webkit-media-controls-volume-slider { - display: none; -} -.timeout-overlay { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: rgba(0, 0, 0, 0.3); - z-index: 2; - cursor: pointer; - display: none; -} -.m4n-popover { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: absolute; - max-width: 200px; - text-align: left; - color: black; - border: 0.5px solid #DDDDDD; - border-radius: 5px; - background-color: white; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.4); - z-index: 10; - display: none; -} -.m4n-popover .m4n-title { - font-size: 14px; - line-height: 1.5; - padding: 10px; - background: #f0f0f0; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} -.m4n-popover .m4n-media { - min-height: 1px; - width: 200px; -} -.m4n-popover .m4n-media img, -.m4n-popover .m4n-media embed, -.m4n-popover .m4n-media object, -.m4n-popover .m4n-media video, -.m4n-popover .m4n-media iframe { - max-width: 100%; -} -.m4n-popover .m4n-info { - font-size: 12px; - line-height: 1.5; - padding: 5px 10px 10px 10px; - z-index: 1; -} -.m4n-popover-triangle, -.m4n-popover-triangle { - content: ''; - position: absolute; - display: block; - width: 22px; - height: 22px; - margin-left: -12px; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); -} -.m4n-popover-triangle.bottom { - bottom: -11px; - background: white; - box-shadow: 1.5px 1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-popover-triangle.top { - top: -11px; - background: #f0f0f0; - box-shadow: -1.5px -1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-popover-triangle.right { - right: -11px; - background: white; - box-shadow: 1.5px -1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-popover-triangle.left { - left: 1px; - background: white; - box-shadow: -1.5px 1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-sidebar-container { - display: inline-block; - position: absolute; - pointer-events: none; - width: 230px; - top: 20px; - bottom: 20px; - left: 20px; - font-size: 12px; - max-height: 100%; - z-index: 10; -} -.m4n-sidebar { - max-height: inherit; - position: relative; - background: white; - box-shadow: 0 0 4px 0 #aaa; - pointer-events: auto; -} -.m4n-sidebar > div { - display: inline-block; -} -.m4n-sidebar-header { - top: 0; - font-size: 16px; - font-weight: bold; - width: 100%; - padding: 10px 10px; - background: inherit; -} -.m4n-sidebar-footer { - height: 40px; - background: #ddd; - width: 100%; - padding: 0; -} -.m4n-sidebar-content { - overflow-y: auto; - overflow-x: hidden; - max-height: calc(100% - 119px); - padding: 10px; - width: 100%; - background: inherit; - word-break: break-all; -} -.m4n-sidebar .m4n-title { - margin-top: 4px; -} -.m4n-sidebar .m4n-media { - margin-bottom: 10px; -} -.m4n-sidebar .m4n-media iframe, -.m4n-sidebar .m4n-media img { - max-width: 100%; - margin-bottom: 5px; -} -.m4n-sidebar-close { - float: right; - color: #ccc; - text-align: center; - font-family: "Arial", serif; - font-weight: bold; - font-size: 20px; - cursor: pointer; - top: 0; -} -.m4n-sidebar-close:hover { - color: #aaa; -} -.m4n-sidebar-close::before { - content: '✕'; -} -.m4n-pagination { - margin: 0; - padding: 0; - list-style: none; - color: #333; -} -.m4n-pagination li { - display: inline-block; - cursor: pointer; - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAAAoCAYAAADqiIZ/AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAT9JREFUeNrs3Mtpw0AUBVBJFbgEl+ASrBK0DJgUFwJZTglJCS7BJbgES2YCIUTIiwRe5p0Dwsg7c+cyHyx1HQAAAAAAAAAA8P/0mX7sy+vbbv44ztfH8+npKn6ZRTUkC/h9vsryWe+RmRkzQMCHL1+f52s0c8rMjBkn4K7eFxUIq6xklmLmHJKW8tPe+A9rLZsU5RwSl3JZDk3Gf1hTzShlOfvEpVz2KmfjP3SOh5rjWgGb3XP2SolyKqZSopwJ95hFKdtTMxs39pxNnbAPYgfF/GtTXdb85L7Mrcsi2lvKNnXC7vAH+0vFVE6UMm0xlVMp7TGDqoGNG3tO/5WNq2QtZdPFfLCcF+M/rEvWUjZfzI1yNneS15hpJbMUj32leYPBtz2nZzFlppjBgj52Xi0iMwAAAAAAAAAAgF93E2AAKdG+bRyMOEsAAAAASUVORK5CYII=") no-repeat; - width: 50%; - height: 40px; -} -.m4n-pagination li:hover { - background-color: #e6e6e6; -} -.m4n-pagination li:first-child { - background-position: 0 0; -} -.m4n-pagination li:last-child { - background-position: -115px 0; -} -.m4n-overlay { - position: absolute; - top: 0; - background: rgba(0, 0, 0, 0.8); - color: white; - text-align: center; - width: 100%; - height: 100%; - z-index: 10; - overflow-y: auto; - display: none; -} -.m4n-overlay > div { - display: table; - width: 100%; - height: 100%; -} -.m4n-overlay > div > div { - display: table-cell; - vertical-align: middle; -} -.m4n-overlay > div > div > div { - margin-left: auto; - margin-right: auto; -} -.m4n-overlay .m4n-title, -.m4n-overlay .m4n-media, -.m4n-overlay .m4n-info { - max-width: 90%; - margin: 0 auto; -} -.m4n-overlay .m4n-title { - font-size: 13px; - font-weight: bold; - line-height: 1.5; - padding-bottom: 8px; -} -.m4n-overlay .m4n-media img, -.m4n-overlay .m4n-media iframe { - max-width: 100%; - max-height: 100%; -} -.m4n-overlay .m4n-info { - font-size: 12px; - font-weight: normal; - line-height: 1.5; -} -.close_overlay::before { - content: '✕'; -} -.close_overlay { - position: absolute; - top: 0; - right: 5px; - font-weight: bold; - font-size: 20px; - cursor: pointer; -} -.close_overlay:hover { - color: grey; -} -.m4n-zoom-container { - position: absolute; - top: 20px; - right: 10px; - background: white; - font-size: 15px; - font-weight: bold; - font-family: "Arial", serif; - color: #555; - text-align: center; -} -.m4n-zoom-button { - width: 20px; - height: 20px; - line-height: 20px; - cursor: pointer; - border: 1px solid #ccc; -} -.m4n-zoom-button:hover { - background: #efefef; -} -.m4n-zoom-container div:first-child { - border-bottom: 0; -} -.m4n-zoom-container div:first-child::before { - content: '+'; -} -.m4n-zoom-container div:last-child::before { - content: '\2013'; -} -.m4n-zoom-button.disabled { - background: #ddd; - color: #aaa; - cursor: not-allowed; -} From ecae9cbf07d67202276562f63182572f15299c30 Mon Sep 17 00:00:00 2001 From: shodan Date: Fri, 20 May 2016 10:32:08 +0200 Subject: [PATCH 12/27] Report gziped size --- gruntfile.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gruntfile.js b/gruntfile.js index ac67867..6e7cf7e 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -48,10 +48,13 @@ module.exports = function(grunt) { }, uglify: { + options: { + report: 'gzip' + }, default: { files: { 'prod/m4n.min.js': ['prod/m4n.js'] - } + }, } } }); @@ -64,4 +67,4 @@ module.exports = function(grunt) { grunt.registerTask('default', ['template:dev', 'jsbeautifier', 'less:dev', 'watch']); grunt.registerTask('production', ['template:prod', 'jsbeautifier', 'uglify', 'less:prod']); -}; \ No newline at end of file +}; From 952bc373a9609a53484ecff1f9ea748877105e82 Mon Sep 17 00:00:00 2001 From: shodan Date: Fri, 3 Jun 2016 08:51:12 +0200 Subject: [PATCH 13/27] Import from old repo --- include/acbj-interactive-overrule.css | 45 ++++ include/iframe/index.php | 46 ++++ include/index.php | 46 ++++ include/style.css | 312 ++++++++++++++++++++++++++ 4 files changed, 449 insertions(+) create mode 100644 include/acbj-interactive-overrule.css create mode 100644 include/iframe/index.php create mode 100644 include/index.php create mode 100644 include/style.css diff --git a/include/acbj-interactive-overrule.css b/include/acbj-interactive-overrule.css new file mode 100644 index 0000000..c97b1f5 --- /dev/null +++ b/include/acbj-interactive-overrule.css @@ -0,0 +1,45 @@ +.m4n-sidebar-content{ + padding: 15px; +} +.m4n-sidebar-header{ + padding: 10px 15px 0; +} +.m4n-sidebar-footer{ + padding: 10px 15px 15px; + height: auto; + border: none; + background: none; +} +.m4n-sidebar .m4n-title{ + margin-top: 30px; +} + +.m4n-sidebar-close { + font-size: 10px; + width: 15px; + border: 1px solid #ccc; +} +.m4n-pagination li { + background: none; + padding: 2px 10px; + border: 1px solid #982a2d; + width: auto; + height: auto; + color: #982a2d; +} +.m4n-pagination li:first-child{ + background-position: 0 0px; +} +.m4n-pagination li:last-child{ + background: #982a2d; + color: white; +} +.m4n-pagination li:last-child { + margin-left: 10px; +} +.m4n-pagination li:first-child::before { + content: 'Previous <'; +} +.m4n-pagination li:last-child::before { + content: 'Next >'; +} \ No newline at end of file diff --git a/include/iframe/index.php b/include/iframe/index.php new file mode 100644 index 0000000..ed46657 --- /dev/null +++ b/include/iframe/index.php @@ -0,0 +1,46 @@ + + + + + + + + + +
+
+ + +
+
+ + diff --git a/include/index.php b/include/index.php new file mode 100644 index 0000000..ed46657 --- /dev/null +++ b/include/index.php @@ -0,0 +1,46 @@ + + + + + + + + + +
+
+ + +
+
+ + diff --git a/include/style.css b/include/style.css new file mode 100644 index 0000000..e95bfa9 --- /dev/null +++ b/include/style.css @@ -0,0 +1,312 @@ +.m4n-container *, +.m4n-container *:after, +.m4n-container *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.m4n-container { + position: relative; + display: inline-block; +} +.m4n-container::after { + clear: both; +} +.m4n-canvas { + float: left; + cursor: grab; + cursor: -moz-grab; + cursor: -webkit-grab; +} +.m4n-canvas.grabbing { + cursor: grabbing; + cursor: -moz-grabbing; + cursor: -webkit-grabbing; +} +.m4n-canvas.pointing { + cursor: pointer; +} +.m4n-video::-webkit-media-controls-current-time-display, +.m4n-video::-webkit-media-controls-time-remaining-display, +.m4n-video::-webkit-media-controls-toggle-closed-captions-button, +.m4n-video::-webkit-media-controls-volume-slider { + display: none; +} +.timeout-overlay { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.3); + z-index: 2; + cursor: pointer; + display: none; +} +.m4n-popover { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + position: absolute; + max-width: 200px; + text-align: left; + color: black; + border: 0.5px solid #DDDDDD; + border-radius: 5px; + background-color: white; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.4); + z-index: 10; + display: none; +} +.m4n-popover .m4n-title { + font-size: 14px; + line-height: 1.5; + padding: 10px; + background: #f0f0f0; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} +.m4n-popover .m4n-media { + min-height: 1px; + width: 200px; +} +.m4n-popover .m4n-media img, +.m4n-popover .m4n-media embed, +.m4n-popover .m4n-media object, +.m4n-popover .m4n-media video, +.m4n-popover .m4n-media iframe { + max-width: 100%; +} +.m4n-popover .m4n-info { + font-size: 12px; + line-height: 1.5; + padding: 5px 10px 10px 10px; + z-index: 1; +} +.m4n-popover-triangle, +.m4n-popover-triangle { + content: ''; + position: absolute; + display: block; + width: 22px; + height: 22px; + margin-left: -12px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); +} +.m4n-popover-triangle.bottom { + bottom: -11px; + background: white; + box-shadow: 1.5px 1.5px 3px 0 rgba(0, 0, 0, 0.2); + z-index: -1; +} +.m4n-popover-triangle.top { + top: -11px; + background: #f0f0f0; + box-shadow: -1.5px -1.5px 3px 0 rgba(0, 0, 0, 0.2); + z-index: -1; +} +.m4n-popover-triangle.right { + right: -11px; + background: white; + box-shadow: 1.5px -1.5px 3px 0 rgba(0, 0, 0, 0.2); + z-index: -1; +} +.m4n-popover-triangle.left { + left: 1px; + background: white; + box-shadow: -1.5px 1.5px 3px 0 rgba(0, 0, 0, 0.2); + z-index: -1; +} +.m4n-sidebar-container { + display: inline-block; + position: absolute; + pointer-events: none; + width: 230px; + top: 20px; + bottom: 20px; + left: 20px; + font-size: 12px; + max-height: 100%; + z-index: 10; +} +.m4n-sidebar { + max-height: inherit; + position: relative; + background: white; + box-shadow: 0 0 4px 0 #aaa; + pointer-events: auto; +} +.m4n-sidebar > div { + display: inline-block; +} +.m4n-sidebar-header { + top: 0; + font-size: 16px; + font-weight: bold; + width: 100%; + padding: 10px 10px; + background: inherit; +} +.m4n-sidebar-footer { + height: 40px; + background: #ddd; + width: 100%; + padding: 0; +} +.m4n-sidebar-content { + overflow-y: auto; + overflow-x: hidden; + max-height: calc(100% - 119px); + padding: 10px; + width: 100%; + background: inherit; + word-break: break-all; +} +.m4n-sidebar .m4n-title { + margin-top: 4px; +} +.m4n-sidebar .m4n-media { + margin-bottom: 10px; +} +.m4n-sidebar .m4n-media iframe, +.m4n-sidebar .m4n-media img { + max-width: 100%; + margin-bottom: 5px; +} +.m4n-sidebar-close { + float: right; + color: #ccc; + text-align: center; + font-family: "Arial", serif; + font-weight: bold; + font-size: 20px; + cursor: pointer; + top: 0; +} +.m4n-sidebar-close:hover { + color: #aaa; +} +.m4n-sidebar-close::before { + content: '✕'; +} +.m4n-pagination { + margin: 0; + padding: 0; + list-style: none; + color: #333; +} +.m4n-pagination li { + display: inline-block; + cursor: pointer; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAAAoCAYAAADqiIZ/AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAT9JREFUeNrs3Mtpw0AUBVBJFbgEl+ASrBK0DJgUFwJZTglJCS7BJbgES2YCIUTIiwRe5p0Dwsg7c+cyHyx1HQAAAAAAAAAA8P/0mX7sy+vbbv44ztfH8+npKn6ZRTUkC/h9vsryWe+RmRkzQMCHL1+f52s0c8rMjBkn4K7eFxUIq6xklmLmHJKW8tPe+A9rLZsU5RwSl3JZDk3Gf1hTzShlOfvEpVz2KmfjP3SOh5rjWgGb3XP2SolyKqZSopwJ95hFKdtTMxs39pxNnbAPYgfF/GtTXdb85L7Mrcsi2lvKNnXC7vAH+0vFVE6UMm0xlVMp7TGDqoGNG3tO/5WNq2QtZdPFfLCcF+M/rEvWUjZfzI1yNneS15hpJbMUj32leYPBtz2nZzFlppjBgj52Xi0iMwAAAAAAAAAAgF93E2AAKdG+bRyMOEsAAAAASUVORK5CYII=") no-repeat; + width: 50%; + height: 40px; +} +.m4n-pagination li:hover { + background-color: #e6e6e6; +} +.m4n-pagination li:first-child { + background-position: 0 0; +} +.m4n-pagination li:last-child { + background-position: -115px 0; +} +.m4n-overlay { + position: absolute; + top: 0; + background: rgba(0, 0, 0, 0.8); + color: white; + text-align: center; + width: 100%; + height: 100%; + z-index: 10; + overflow-y: auto; + display: none; +} +.m4n-overlay > div { + display: table; + width: 100%; + height: 100%; +} +.m4n-overlay > div > div { + display: table-cell; + vertical-align: middle; +} +.m4n-overlay > div > div > div { + margin-left: auto; + margin-right: auto; +} +.m4n-overlay .m4n-title, +.m4n-overlay .m4n-media, +.m4n-overlay .m4n-info { + max-width: 90%; + margin: 0 auto; +} +.m4n-overlay .m4n-title { + font-size: 13px; + font-weight: bold; + line-height: 1.5; + padding-bottom: 8px; +} +.m4n-overlay .m4n-media img, +.m4n-overlay .m4n-media iframe { + max-width: 100%; + max-height: 100%; +} +.m4n-overlay .m4n-info { + font-size: 12px; + font-weight: normal; + line-height: 1.5; +} +.close_overlay::before { + content: '✕'; +} +.close_overlay { + position: absolute; + top: 0; + right: 5px; + font-weight: bold; + font-size: 20px; + cursor: pointer; +} +.close_overlay:hover { + color: grey; +} +.m4n-zoom-container { + position: absolute; + top: 20px; + right: 10px; + background: white; + font-size: 15px; + font-weight: bold; + font-family: "Arial", serif; + color: #555; + text-align: center; +} +.m4n-zoom-button { + width: 20px; + height: 20px; + line-height: 20px; + cursor: pointer; + border: 1px solid #ccc; +} +.m4n-zoom-button:hover { + background: #efefef; +} +.m4n-zoom-container div:first-child { + border-bottom: 0; +} +.m4n-zoom-container div:first-child::before { + content: '+'; +} +.m4n-zoom-container div:last-child::before { + content: '\2013'; +} +.m4n-zoom-button.disabled { + background: #ddd; + color: #aaa; + cursor: not-allowed; +} From 5cc06af0f6f8c99cf797e765f66fa7563635c746 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Fri, 3 Jun 2016 10:21:41 +0200 Subject: [PATCH 14/27] Move files from maponline & optimize build script --- app/js/classes/popup.js | 119 ++++++---- gruntfile.js | 38 ++-- include/acbj-interactive-overrule.css | 45 ---- include/iframe/index.php | 12 +- include/index.php | 49 +--- include/style.css | 312 -------------------------- package.json | 3 +- 7 files changed, 108 insertions(+), 470 deletions(-) delete mode 100644 include/acbj-interactive-overrule.css delete mode 100644 include/style.css diff --git a/app/js/classes/popup.js b/app/js/classes/popup.js index 2fc4cb9..bd2da38 100644 --- a/app/js/classes/popup.js +++ b/app/js/classes/popup.js @@ -64,7 +64,7 @@ Popup.prototype.show = function(center) { if(location.location.x !== "center" || location.location.y !== "center") { // Check if popup isn't wider than the canvas - if(!(location.left < 0 && location.right < 0)) { + if(!(location.left <= 5 && location.right <= 5)) { if(location.left < 5) { object.x = 5 - location.left; } else if(location.right < 5) { @@ -73,7 +73,7 @@ Popup.prototype.show = function(center) { } // Check if the popup isn't higher than the canvas - if(!(location.top < 0 && location.bottom < 0)) { + if(!(location.top <= 5 && location.bottom <= 5)) { if(location.top < 5) { object.y = 5 - location.top; } else if(location.bottom < 5) { @@ -330,62 +330,85 @@ Popup.prototype.generatePopover = function(popup, title_html, info_html, media_h this.onShowDesktop = function(point) { popup.style.display = "block"; + + // Triangle var heightTriangle = 16.97056274847714; // 24 = width of a triangle plus the border + var triangle = popup.getElementsByClassName("m4n-popover-triangle")[0]; - var left = Math.max(0.15, Math.min(0.85, ((point.position.left + main.globals.offset.get().x) / main.object.canvas.clientWidth))), - top = Math.max(0.05, Math.min(0.85, ((point.position.top + main.globals.offset.get().y) / main.object.canvas.clientHeight))), - - triangle = popup.getElementsByClassName("m4n-popover-triangle")[0], - fits = { - nextTo: ( - (main.globals.offset.get().x + point.position.left + (popup.clientWidth * left) + (point.size.width / 2)) < main.object.canvas.clientWidth && - (main.globals.offset.get().x + point.position.left - (popup.clientWidth * left) + (point.size.width / 2)) > 0 - ), - above: (main.globals.offset.get().y + point.position.top - heightTriangle) > popup.clientHeight, - beneath: (main.object.canvas.clientHeight - (main.globals.offset.get().y + point.position.top + point.size.height + heightTriangle)) > popup.clientHeight, - left: (main.globals.offset.get().x + point.position.left - heightTriangle) > popup.clientWidth, - right: (main.object.canvas.clientWidth - (main.globals.offset.get().x + point.position.left + point.size.width + heightTriangle)) > popup.clientWidth - }; - - var showAbove = function() { - triangle.classList.add("bottom"); - popup.style.top = main.globals.offset.get().y + point.position.top - popup.clientHeight - heightTriangle + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left + (point.size.width / 2) - (popup.clientWidth * left) + 'px'; - triangle.style.left = (left * 100) + "%"; - }; + // Position for triangle + var left = Math.max(0.15, Math.min(0.85, ((point.position.left + main.globals.offset.get().x) / main.object.canvas.clientWidth))); + var top = Math.max(0.05, Math.min(0.85, ((point.position.top + main.globals.offset.get().y) / main.object.canvas.clientHeight))); - var showBeneath = function() { - triangle.classList.add("top"); - popup.style.top = main.globals.offset.get().y + point.position.top + point.size.height + heightTriangle + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left + (point.size.width / 2) - (popup.clientWidth * left) + 'px'; - triangle.style.left = (left * 100) + "%"; + // Bounding Client Rect of the canvas + var boundingRect = main.object.canvas.getBoundingClientRect(); + + // Formulas for where the popup fits + var formulas = { + above: main.globals.offset.get().y + point.position.top - heightTriangle, + beneath: boundingRect.height - (main.globals.offset.get().y + point.position.top + point.size.height) - heightTriangle, + left: main.globals.offset.get().x + point.position.left - heightTriangle, + right: boundingRect.width - (main.globals.offset.get().x + point.position.left + point.size.width) - heightTriangle }; - var showLeft = function() { - triangle.classList.add("right"); - popup.style.top = (main.globals.offset.get().y + point.position.top + (point.size.height / 2) - (popup.clientHeight * top) - 10) + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left - popup.clientWidth - heightTriangle + 'px'; - triangle.style.top = (top * 100) + "%"; + // Booleans for where the popup fits + var fits = { + onCanvas: { + above: formulas.above > popup.clientHeight, + beneath: formulas.beneath > popup.clientHeight, + left: formulas.left > popup.clientWidth, + right: formulas.right > popup.clientWidth + }, + onScreen: { + above: (formulas.above + boundingRect.top) > popup.clientHeight, + beneath: (formulas.beneath + (window.innerHeight - boundingRect.height - boundingRect.top)) > popup.clientHeight, + left: (formulas.left + boundingRect.left) > popup.clientWidth, + right: (formulas.right + (window.innerWidth - boundingRect.width - boundingRect.left)) > popup.clientWidth + } }; - var showRight = function() { - triangle.classList.add("left"); - popup.style.top = (main.globals.offset.get().y + point.position.top + (point.size.height / 2) - (popup.clientHeight * top) - 10) + 'px'; - popup.style.left = main.globals.offset.get().x + point.position.left + point.size.width + heightTriangle + 'px'; - triangle.style.top = (top * 100) + "%"; + console.log(formulas, "\n", fits.onCanvas, "\n", fits.onScreen); + + var show = { + above: function() { + triangle.classList.add("bottom"); + popup.style.top = main.globals.offset.get().y + point.position.top - popup.clientHeight - heightTriangle + 'px'; + popup.style.left = main.globals.offset.get().x + point.position.left + (point.size.width / 2) - (popup.clientWidth * left) + 'px'; + triangle.style.left = (left * 100) + "%"; + }, + beneath: function() { + triangle.classList.add("top"); + popup.style.top = main.globals.offset.get().y + point.position.top + point.size.height + heightTriangle + 'px'; + popup.style.left = main.globals.offset.get().x + point.position.left + (point.size.width / 2) - (popup.clientWidth * left) + 'px'; + triangle.style.left = (left * 100) + "%"; + }, + left: function() { + triangle.classList.add("right"); + popup.style.top = (main.globals.offset.get().y + point.position.top + (point.size.height / 2) - (popup.clientHeight * top) - 10) + 'px'; + popup.style.left = main.globals.offset.get().x + point.position.left - popup.clientWidth - heightTriangle + 'px'; + triangle.style.top = (top * 100) + "%"; + }, + right: function() { + triangle.classList.add("left"); + popup.style.top = (main.globals.offset.get().y + point.position.top + (point.size.height / 2) - (popup.clientHeight * top) - 10) + 'px'; + popup.style.left = main.globals.offset.get().x + point.position.left + point.size.width + heightTriangle + 'px'; + triangle.style.top = (top * 100) + "%"; + } }; - // TODO redo if statements; redo - if((fits.above || !fits.beneath) && !fits.nextTo) { - showAbove(); - } else if(!fits.nextTo) { - showBeneath(); - } else if(fits.left) { - showLeft(); - } else if(fits.right) { - showRight(); + if(fits.onCanvas.above && fits.onScreen.above) { + show.above(); + } else if(fits.onCanvas.beneath && fits.onScreen.beneath) { + show.beneath(); } else { - showAbove(); + + if(fits.onCanvas.left && fits.onScreen.left) { + show.left(); + } else if(fits.onCanvas.right && fits.onScreen.right) { + show.right(); + } else { + show.above(); + } + } return true; diff --git a/gruntfile.js b/gruntfile.js index 6e7cf7e..c90532e 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -18,32 +18,22 @@ module.exports = function(grunt) { }, jsbeautifier: { - files : ['dist/m4n.js', 'prod/m4n.js'] + files : ['dist/m4n.js'] }, less: { - dev: { + default: { options: { cleancss: true }, files: { "dist/style.css": "app/less/main.less" } - }, - prod: { - options: { - cleancss: true - }, - files: { "prod/style.css": "app/less/main.less" } } }, template: { - dev: { + default: { template: "app/js/main.js", dest: "dist/m4n.js" - }, - prod: { - template: "app/js/main.js", - dest: "prod/m4n.js" } }, @@ -53,8 +43,21 @@ module.exports = function(grunt) { }, default: { files: { - 'prod/m4n.min.js': ['prod/m4n.js'] - }, + 'dist/m4n.min.js': ['dist/m4n.js'] + } + } + }, + + copy: { + default: { + files: [ + { + expand: true, + cwd: 'include/', + src: '**', + dest: 'dist/' + } + ] } } }); @@ -64,7 +67,8 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-less'); + grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.registerTask('default', ['template:dev', 'jsbeautifier', 'less:dev', 'watch']); - grunt.registerTask('production', ['template:prod', 'jsbeautifier', 'uglify', 'less:prod']); + grunt.registerTask('default', ['template', 'jsbeautifier', 'less', 'watch']); + grunt.registerTask('production', ['template', 'jsbeautifier', 'uglify', 'less', 'copy']); }; diff --git a/include/acbj-interactive-overrule.css b/include/acbj-interactive-overrule.css deleted file mode 100644 index c97b1f5..0000000 --- a/include/acbj-interactive-overrule.css +++ /dev/null @@ -1,45 +0,0 @@ -.m4n-sidebar-content{ - padding: 15px; -} -.m4n-sidebar-header{ - padding: 10px 15px 0; -} -.m4n-sidebar-footer{ - padding: 10px 15px 15px; - height: auto; - border: none; - background: none; -} -.m4n-sidebar .m4n-title{ - margin-top: 30px; -} - -.m4n-sidebar-close { - font-size: 10px; - width: 15px; - border: 1px solid #ccc; -} -.m4n-pagination li { - background: none; - padding: 2px 10px; - border: 1px solid #982a2d; - width: auto; - height: auto; - color: #982a2d; -} -.m4n-pagination li:first-child{ - background-position: 0 0px; -} -.m4n-pagination li:last-child{ - background: #982a2d; - color: white; -} -.m4n-pagination li:last-child { - margin-left: 10px; -} -.m4n-pagination li:first-child::before { - content: 'Previous <'; -} -.m4n-pagination li:last-child::before { - content: 'Next >'; -} \ No newline at end of file diff --git a/include/iframe/index.php b/include/iframe/index.php index ed46657..5aaa507 100644 --- a/include/iframe/index.php +++ b/include/iframe/index.php @@ -6,18 +6,14 @@ $path = htmlentities($_GET['path']); } -if(!isset($_GET['id'])) { - $id = "m4n-" . str_shuffle("withlovefrommaps4news"); -} else { - $id = htmlentities($_GET['id']); -} - -$env = isset($_GET['env']) ? htmlentities($_GET['env']) : "online"; - if(isset($_GET['style'])) { $style = htmlentities($_GET['style']); } +$id = isset($_GET['id']) ? htmlentities($_GET['id']) : "m4n-" . str_shuffle("withlovefrommaps4news"); + +$env = isset($_GET['env']) ? htmlentities($_GET['env']) : "online"; + ?> diff --git a/include/index.php b/include/index.php index ed46657..3092985 100644 --- a/include/index.php +++ b/include/index.php @@ -1,46 +1,17 @@ - - - - - - - - -
-
- - -
-
- - +print($data); \ No newline at end of file diff --git a/include/style.css b/include/style.css deleted file mode 100644 index e95bfa9..0000000 --- a/include/style.css +++ /dev/null @@ -1,312 +0,0 @@ -.m4n-container *, -.m4n-container *:after, -.m4n-container *:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.m4n-container { - position: relative; - display: inline-block; -} -.m4n-container::after { - clear: both; -} -.m4n-canvas { - float: left; - cursor: grab; - cursor: -moz-grab; - cursor: -webkit-grab; -} -.m4n-canvas.grabbing { - cursor: grabbing; - cursor: -moz-grabbing; - cursor: -webkit-grabbing; -} -.m4n-canvas.pointing { - cursor: pointer; -} -.m4n-video::-webkit-media-controls-current-time-display, -.m4n-video::-webkit-media-controls-time-remaining-display, -.m4n-video::-webkit-media-controls-toggle-closed-captions-button, -.m4n-video::-webkit-media-controls-volume-slider { - display: none; -} -.timeout-overlay { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: rgba(0, 0, 0, 0.3); - z-index: 2; - cursor: pointer; - display: none; -} -.m4n-popover { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: absolute; - max-width: 200px; - text-align: left; - color: black; - border: 0.5px solid #DDDDDD; - border-radius: 5px; - background-color: white; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.4); - z-index: 10; - display: none; -} -.m4n-popover .m4n-title { - font-size: 14px; - line-height: 1.5; - padding: 10px; - background: #f0f0f0; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} -.m4n-popover .m4n-media { - min-height: 1px; - width: 200px; -} -.m4n-popover .m4n-media img, -.m4n-popover .m4n-media embed, -.m4n-popover .m4n-media object, -.m4n-popover .m4n-media video, -.m4n-popover .m4n-media iframe { - max-width: 100%; -} -.m4n-popover .m4n-info { - font-size: 12px; - line-height: 1.5; - padding: 5px 10px 10px 10px; - z-index: 1; -} -.m4n-popover-triangle, -.m4n-popover-triangle { - content: ''; - position: absolute; - display: block; - width: 22px; - height: 22px; - margin-left: -12px; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); -} -.m4n-popover-triangle.bottom { - bottom: -11px; - background: white; - box-shadow: 1.5px 1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-popover-triangle.top { - top: -11px; - background: #f0f0f0; - box-shadow: -1.5px -1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-popover-triangle.right { - right: -11px; - background: white; - box-shadow: 1.5px -1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-popover-triangle.left { - left: 1px; - background: white; - box-shadow: -1.5px 1.5px 3px 0 rgba(0, 0, 0, 0.2); - z-index: -1; -} -.m4n-sidebar-container { - display: inline-block; - position: absolute; - pointer-events: none; - width: 230px; - top: 20px; - bottom: 20px; - left: 20px; - font-size: 12px; - max-height: 100%; - z-index: 10; -} -.m4n-sidebar { - max-height: inherit; - position: relative; - background: white; - box-shadow: 0 0 4px 0 #aaa; - pointer-events: auto; -} -.m4n-sidebar > div { - display: inline-block; -} -.m4n-sidebar-header { - top: 0; - font-size: 16px; - font-weight: bold; - width: 100%; - padding: 10px 10px; - background: inherit; -} -.m4n-sidebar-footer { - height: 40px; - background: #ddd; - width: 100%; - padding: 0; -} -.m4n-sidebar-content { - overflow-y: auto; - overflow-x: hidden; - max-height: calc(100% - 119px); - padding: 10px; - width: 100%; - background: inherit; - word-break: break-all; -} -.m4n-sidebar .m4n-title { - margin-top: 4px; -} -.m4n-sidebar .m4n-media { - margin-bottom: 10px; -} -.m4n-sidebar .m4n-media iframe, -.m4n-sidebar .m4n-media img { - max-width: 100%; - margin-bottom: 5px; -} -.m4n-sidebar-close { - float: right; - color: #ccc; - text-align: center; - font-family: "Arial", serif; - font-weight: bold; - font-size: 20px; - cursor: pointer; - top: 0; -} -.m4n-sidebar-close:hover { - color: #aaa; -} -.m4n-sidebar-close::before { - content: '✕'; -} -.m4n-pagination { - margin: 0; - padding: 0; - list-style: none; - color: #333; -} -.m4n-pagination li { - display: inline-block; - cursor: pointer; - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOYAAAAoCAYAAADqiIZ/AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAT9JREFUeNrs3Mtpw0AUBVBJFbgEl+ASrBK0DJgUFwJZTglJCS7BJbgES2YCIUTIiwRe5p0Dwsg7c+cyHyx1HQAAAAAAAAAA8P/0mX7sy+vbbv44ztfH8+npKn6ZRTUkC/h9vsryWe+RmRkzQMCHL1+f52s0c8rMjBkn4K7eFxUIq6xklmLmHJKW8tPe+A9rLZsU5RwSl3JZDk3Gf1hTzShlOfvEpVz2KmfjP3SOh5rjWgGb3XP2SolyKqZSopwJ95hFKdtTMxs39pxNnbAPYgfF/GtTXdb85L7Mrcsi2lvKNnXC7vAH+0vFVE6UMm0xlVMp7TGDqoGNG3tO/5WNq2QtZdPFfLCcF+M/rEvWUjZfzI1yNneS15hpJbMUj32leYPBtz2nZzFlppjBgj52Xi0iMwAAAAAAAAAAgF93E2AAKdG+bRyMOEsAAAAASUVORK5CYII=") no-repeat; - width: 50%; - height: 40px; -} -.m4n-pagination li:hover { - background-color: #e6e6e6; -} -.m4n-pagination li:first-child { - background-position: 0 0; -} -.m4n-pagination li:last-child { - background-position: -115px 0; -} -.m4n-overlay { - position: absolute; - top: 0; - background: rgba(0, 0, 0, 0.8); - color: white; - text-align: center; - width: 100%; - height: 100%; - z-index: 10; - overflow-y: auto; - display: none; -} -.m4n-overlay > div { - display: table; - width: 100%; - height: 100%; -} -.m4n-overlay > div > div { - display: table-cell; - vertical-align: middle; -} -.m4n-overlay > div > div > div { - margin-left: auto; - margin-right: auto; -} -.m4n-overlay .m4n-title, -.m4n-overlay .m4n-media, -.m4n-overlay .m4n-info { - max-width: 90%; - margin: 0 auto; -} -.m4n-overlay .m4n-title { - font-size: 13px; - font-weight: bold; - line-height: 1.5; - padding-bottom: 8px; -} -.m4n-overlay .m4n-media img, -.m4n-overlay .m4n-media iframe { - max-width: 100%; - max-height: 100%; -} -.m4n-overlay .m4n-info { - font-size: 12px; - font-weight: normal; - line-height: 1.5; -} -.close_overlay::before { - content: '✕'; -} -.close_overlay { - position: absolute; - top: 0; - right: 5px; - font-weight: bold; - font-size: 20px; - cursor: pointer; -} -.close_overlay:hover { - color: grey; -} -.m4n-zoom-container { - position: absolute; - top: 20px; - right: 10px; - background: white; - font-size: 15px; - font-weight: bold; - font-family: "Arial", serif; - color: #555; - text-align: center; -} -.m4n-zoom-button { - width: 20px; - height: 20px; - line-height: 20px; - cursor: pointer; - border: 1px solid #ccc; -} -.m4n-zoom-button:hover { - background: #efefef; -} -.m4n-zoom-container div:first-child { - border-bottom: 0; -} -.m4n-zoom-container div:first-child::before { - content: '+'; -} -.m4n-zoom-container div:last-child::before { - content: '\2013'; -} -.m4n-zoom-button.disabled { - background: #ddd; - color: #aaa; - cursor: not-allowed; -} diff --git a/package.json b/package.json index 08254ef..8340efb 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,11 @@ "grunt": "^1.0.1" }, "devDependencies": { + "grunt-contrib-copy": "^1.0.0", "grunt-contrib-less": "^1.2.0", + "grunt-contrib-template": "^1.0", "grunt-contrib-uglify": "^1.0.1", "grunt-contrib-watch": "^1.0.0", - "grunt-contrib-template": "^1.0", "grunt-jsbeautifier": "^0.2.10" } } From e43e0617ae2ef15e4951c1338c249a641150e4c7 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Thu, 9 Jun 2016 10:56:31 +0200 Subject: [PATCH 15/27] Make hitbox 5px bigger on each side --- app/js/classes/point.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/js/classes/point.js b/app/js/classes/point.js index 8176ce1..9ea539c 100644 --- a/app/js/classes/point.js +++ b/app/js/classes/point.js @@ -15,12 +15,12 @@ var Point = function(point) { } // TODO refactor to support all formats this.position = { - left: Math.min.apply(null, this.shape.map(function(item) { return item.x })), - top: Math.min.apply(null, this.shape.map(function(item) { return item.y })) + left: Math.min.apply(null, this.shape.map(function(item) { return item.x })) - 5, + top: Math.min.apply(null, this.shape.map(function(item) { return item.y })) - 5 }; this.size = { - width: Math.max.apply(null, this.shape.map(function(item) { return item.x })) - this.position.left, - height: Math.max.apply(null, this.shape.map(function(item) { return item.y })) - this.position.top + width: Math.max.apply(null, this.shape.map(function(item) { return item.x })) - this.position.left + 10, + height: Math.max.apply(null, this.shape.map(function(item) { return item.y })) - this.position.top + 10 }; }; From c4d5012beb3795347da01602fe15cdf1936bb25b Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Wed, 22 Jun 2016 09:02:18 +0200 Subject: [PATCH 16/27] Fixed grammar --- docs.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs.md b/docs.md index 0c3c26f..e279288 100644 --- a/docs.md +++ b/docs.md @@ -122,7 +122,7 @@ In the API you will find a number of functions which can be used to interact wit level: function() {}, /** * Will return all levels - * @returns {level[]} + * @returns {levels} */ levels: function() {}, /** @@ -246,7 +246,7 @@ The API `level` function will return a specific level, its structure is as follo ``` #### levels -The API `levels` function will return an array of all `level` objects as described above as well as the current level. +The API `levels` function will return an array of all `level` objects as described above as well as the highest, lowest and the current level. ```js { @@ -263,7 +263,7 @@ The API `levels` function will return an array of all `level` objects as describ */ lowest: 2, /** - * All level object as described above + * All level objects as described above */ levels: [] } @@ -295,14 +295,14 @@ Since it’s possible to have multiple maps run on one page we have implemented `“level_loaded”` This event will be called when all tiles (images) of a level have been downloaded. -One argument will be passed to the listener, the level object of the level that has been loaded. +One argument will be passed to the listener, the `level` object of the level that has been loaded. -------- `“level_drawn”` This event will be called when a level has been drawn on the canvas. -One argument will be passed to the listener, the level object of the level that has been drawn. +One argument will be passed to the listener, the `level` object of the level that has been drawn. Note: this will be called on every move made by the user and/or API. @@ -311,21 +311,21 @@ Note: this will be called on every move made by the user and/or API. `“level_changed”` This event will be called when the currently displayed level has changed. -One argument will be passed to the listener, the level object of the level that the map has changed to. +One argument will be passed to the listener, the `level` object of the level that the map has changed to. ------- `“popup_shown”` This event will be called when a popup has been displayed on screen. -One argument will be passed to the listener, the popup object of the popup that has been shown. +One argument will be passed to the listener, the `popup` object of the popup that has been shown. ------- `“popup_hidden”` This event will be called when a popup has been hidden. -One argument will be passed to the listener, the popup object of the popup that has been hidden. +One argument will be passed to the listener, the `popup` object of the popup that has been hidden. ## Misc @@ -337,7 +337,7 @@ It's also possible to generate an iframe version of the map via the Maps4News to ``` Customization of the iframe map is done via the get variables in the url. There are a total of 4 parameters that can be added to the url. -1. __path__. Same of the inline version. +1. __path__. Same as the inline version. 2. __env__. (optional; default "online") Same as the environment for the inline version (note that you should also change the subdomain). - The download environment is not available for iframe maps, if you wish to host your own iframe map you should create your own HTML document with an inline map inside, as described above. 3. __id__. (optional) A specific id for the container. @@ -347,7 +347,7 @@ The iframe map does not allow eventListeners due to limitations with DOM. ### Style Overwriting -The Interactive Map adds its own `style.css` file to your page head, if you wish to overwrite certain styles used in the map. you can add a `link` tag to your head with the id `m4n-style-custom`. The map will look for this id when setting up its HTML elements and will remove and re-add this tag so that the styles defined in your css file will have priority over the ones in our main `style.css` file. +The Interactive Map adds its own `style.css` file to your page head. If you wish to overwrite certain styles used in the map, you can add a `link` tag to your head with the id `m4n-style-custom`. The map will look for this id when setting up its HTML elements and will remove and re-add this tag so that the styles defined in your css file will have priority over the ones in our main `style.css` file. ```html From 887fe63bddac3906b5d3cb5eb28fde2fdf6c7ad4 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Tue, 28 Jun 2016 16:41:43 +0200 Subject: [PATCH 17/27] Fix mouseout bug --- app/js/events.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/app/js/events.js b/app/js/events.js index d882247..40e3743 100644 --- a/app/js/events.js +++ b/app/js/events.js @@ -62,21 +62,19 @@ var events = { */ mouseUp: function(e) { e.preventDefault(); - if(e.target.id == main.canvas) { - helpers.setInteractTime(); - main.globals.isDown = false; - main.object.canvas.classList.remove('grabbing'); - if(e.pageX == main.globals.clickStart.x && e.pageY == main.globals.clickStart.y) { - var point = main.object.levels.getCurrent().points.hitAPoint(e.layerX, e.layerY); - if(point !== null && e.which === 1) { - main.object.popups.get(point.number).show(); + helpers.setInteractTime(); + main.globals.isDown = false; + main.object.canvas.classList.remove('grabbing'); + if(e.pageX == main.globals.clickStart.x && e.pageY == main.globals.clickStart.y) { + var point = main.object.levels.getCurrent().points.hitAPoint(e.layerX, e.layerY); + if(point !== null && e.which === 1) { + main.object.popups.get(point.number).show(); + } else { + if(main.globals.doubleTap === true) { + events.dblclick(e); + main.globals.doubleTap = null; } else { - if(main.globals.doubleTap === true) { - events.dblclick(e); - main.globals.doubleTap = null; - } else { - main.object.popups.hideAll(); - } + main.object.popups.hideAll(); } } } From 6901a216f8c22518e3b527165eed9b3b898e2b88 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Wed, 29 Jun 2016 10:11:43 +0200 Subject: [PATCH 18/27] Flag for enabling and disabling zoom controls --- app/js/init.js | 1 + app/js/setup.js | 2 +- docs.md | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/js/init.js b/app/js/init.js index bc4f01a..922ba48 100644 --- a/app/js/init.js +++ b/app/js/init.js @@ -9,6 +9,7 @@ main.interact = options.interact || "scroll"; main.environment = options.environment || "online"; + main.zoomControls = typeof options.zoomControls !== 'undefined' ? options.zoomControls : true; main.version = { map: '2.0', code: '2.0.4' }; // TODO Add version to json for verification diff --git a/app/js/setup.js b/app/js/setup.js index e11945d..266a926 100644 --- a/app/js/setup.js +++ b/app/js/setup.js @@ -22,7 +22,7 @@ function initializeM4n(mapJson) { main.object = revive(mapJson); - if(main.object.levels.count() > 1) { + if(main.object.levels.count() > 1 && main.zoomControls) { createZoomControls(); } diff --git a/docs.md b/docs.md index e279288..229d572 100644 --- a/docs.md +++ b/docs.md @@ -69,6 +69,8 @@ The M4nInteractive class accepts the following parameters: | controls | use the on-screen controls and the mouse buttons to zoom in or out (holding ctrl will __enable__ scroll zooming) | | smart | an overlay will be placed over the map when the user is not working with the map and disables the events to the map (timeout of 3 seconds; will not disable when a popup is active) | + - __zoomControls__. (optional; default true) Enable or disable the zoom controls for maps with more than 1 level. + - __debug__. (not recommended) true or false, this allows the map object to be returned from the browser's console. 2. The div container node (in this case the `div` with id `m4n-map`). From 9c4a692bf7e7c3ec05ae92119d7f2c4265b42a41 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Wed, 29 Jun 2016 13:53:47 +0200 Subject: [PATCH 19/27] More modular map controls, and home button --- app/js/home_button.js | 17 +++++++++++ app/js/init.js | 1 + app/js/setup.js | 13 ++++++++- app/js/zoom_controls.js | 13 ++++----- app/less/controls.less | 57 +++++++++++++++++++++++++++++++++++++ app/less/main.less | 2 +- app/less/zoom_controls.less | 41 -------------------------- docs.md | 3 +- 8 files changed, 96 insertions(+), 51 deletions(-) create mode 100644 app/js/home_button.js create mode 100644 app/less/controls.less delete mode 100644 app/less/zoom_controls.less diff --git a/app/js/home_button.js b/app/js/home_button.js new file mode 100644 index 0000000..5e43230 --- /dev/null +++ b/app/js/home_button.js @@ -0,0 +1,17 @@ +/** + + **/ +function createHomeButton(control_container) { + + var home_container = helpers.createElement('div', 'm4n-home-container'); + var home_button = helpers.createElement('div', ['m4n-control-button'], { + 'click': function() { + main.api.reset(); + } + }); + + home_container.appendChild(home_button); + + control_container.appendChild(home_container); + control_container.appendChild(helpers.createElement('div', 'm4n-control-separator')); +} diff --git a/app/js/init.js b/app/js/init.js index 922ba48..bebbb4c 100644 --- a/app/js/init.js +++ b/app/js/init.js @@ -10,6 +10,7 @@ main.interact = options.interact || "scroll"; main.environment = options.environment || "online"; main.zoomControls = typeof options.zoomControls !== 'undefined' ? options.zoomControls : true; + main.homeButton = typeof options.homeButton !== 'undefined' ? options.homeButton : true; main.version = { map: '2.0', code: '2.0.4' }; // TODO Add version to json for verification diff --git a/app/js/setup.js b/app/js/setup.js index 266a926..6193d8c 100644 --- a/app/js/setup.js +++ b/app/js/setup.js @@ -22,10 +22,19 @@ function initializeM4n(mapJson) { main.object = revive(mapJson); + var controlContainer = helpers.createElement('div', 'm4n-control-container'); + if(main.object.levels.count() > 1 && main.zoomControls) { - createZoomControls(); + createZoomControls(controlContainer); + } + + if(main.homeButton) { + createHomeButton(controlContainer); } + controlContainer.style.zIndex = main.object.canvas.style.zIndex +1; + container.appendChild(controlContainer); + if(!container.hasPredefinedHeight) { var level = main.object.levels.getCurrent(); main.object.canvas.height = container.clientWidth * (level.size.height / level.size.width); @@ -234,4 +243,6 @@ function createHtmlElements() { ""; +""; + ""; \ No newline at end of file diff --git a/app/js/zoom_controls.js b/app/js/zoom_controls.js index a43b086..d325f15 100644 --- a/app/js/zoom_controls.js +++ b/app/js/zoom_controls.js @@ -1,17 +1,17 @@ /** * Create the zoom controls */ -function createZoomControls() { +function createZoomControls(control_container) { // Zoom controls var zoom_container = helpers.createElement('div', 'm4n-zoom-container'); - var zoom_control_in = helpers.createElement('div', 'm4n-zoom-button', { + var zoom_control_in = helpers.createElement('div', 'm4n-control-button', { 'click': function() { if(!zoom_control_in.classList.contains('disabled')) { main.api.zoom.in(); } } }); - var zoom_control_out = helpers.createElement('div', 'm4n-zoom-button', { + var zoom_control_out = helpers.createElement('div', 'm4n-control-button', { 'click': function() { if(!zoom_control_out.classList.contains('disabled')) { main.api.zoom.out(); @@ -32,10 +32,9 @@ function createZoomControls() { } }); - zoom_container.style.zIndex = main.object.canvas.style.zIndex +1; - zoom_container.appendChild(zoom_control_in); zoom_container.appendChild(zoom_control_out); - container.appendChild(zoom_container); -} \ No newline at end of file + control_container.appendChild(zoom_container); + control_container.appendChild(helpers.createElement('div', 'm4n-control-separator')); +} diff --git a/app/less/controls.less b/app/less/controls.less new file mode 100644 index 0000000..3bdbf3b --- /dev/null +++ b/app/less/controls.less @@ -0,0 +1,57 @@ +// Icon container position and styling +.m4n-control-container { + position: absolute; + top: 20px; + right: 10px; + font-size: 15px; + font-weight: bold; + font-family: "Arial", serif; + color: #555555; + text-align: center; + pointer-events: none; +} + +.m4n-control-container > div:not(.m4n-control-separator) { + border-bottom: 0; +} + +// Separator +.m4n-control-container .m4n-control-separator { + height: 10px; + pointer-events: none; +} + +.m4n-control-button { + width: 20px; + height: 20px; + line-height: 20px; + cursor: pointer; + border: 1px solid #CCCCCC; + background-color: #FFFFFF; + pointer-events: all; +} + +.m4n-control-button:hover { + background: #EFEFEF; +} + +.m4n-control-button.disabled { + background: #DDDDDD; + color: #AAAAAA; + cursor: not-allowed; +} + +//// +// Button icons + +.m4n-zoom-container div:first-child::before { + content: '+'; +} + +.m4n-zoom-container div:last-child::before { + content: '\2013'; +} + +.m4n-home-container div:first-child::before { + content: '\2302'; +} \ No newline at end of file diff --git a/app/less/main.less b/app/less/main.less index b891744..43c119c 100644 --- a/app/less/main.less +++ b/app/less/main.less @@ -53,4 +53,4 @@ @import "popups/sidebar"; @import "popups/overlay"; -@import "zoom_controls"; \ No newline at end of file +@import "controls"; \ No newline at end of file diff --git a/app/less/zoom_controls.less b/app/less/zoom_controls.less deleted file mode 100644 index ae7bedd..0000000 --- a/app/less/zoom_controls.less +++ /dev/null @@ -1,41 +0,0 @@ -.m4n-zoom-container { - position: absolute; - top: 20px; - right: 10px; - background: white; - font-size: 15px; - font-weight: bold; - font-family: "Arial", serif; - color: #555; - text-align: center; -} - -.m4n-zoom-button { - width: 20px; - height: 20px; - line-height: 20px; - cursor: pointer; - border: 1px solid #ccc; -} - -.m4n-zoom-button:hover { - background: #efefef; -} - -.m4n-zoom-container div:first-child { - border-bottom: 0; -} - -.m4n-zoom-container div:first-child::before { - content: '+'; -} - -.m4n-zoom-container div:last-child::before { - content: '\2013'; -} - -.m4n-zoom-button.disabled { - background: #ddd; - color: #aaa; - cursor: not-allowed; -} \ No newline at end of file diff --git a/docs.md b/docs.md index 229d572..850b945 100644 --- a/docs.md +++ b/docs.md @@ -60,7 +60,6 @@ The M4nInteractive class accepts the following parameters: | bleeding | For maps generated with the M4N bleeding tool. | | download | This should be used when a user wants to self-host their map. | | development | Used by M4N employees during development. (will enable debugging mode) | - - __interact__. (optional; default "scroll") The way interaction with the map works. | Name | Description | @@ -71,6 +70,8 @@ The M4nInteractive class accepts the following parameters: - __zoomControls__. (optional; default true) Enable or disable the zoom controls for maps with more than 1 level. + - __homeButton__. (optional; default true) Enable or disable the home button + - __debug__. (not recommended) true or false, this allows the map object to be returned from the browser's console. 2. The div container node (in this case the `div` with id `m4n-map`). From cf01ad19e8b1da84ececd71c71724262e246add0 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Wed, 29 Jun 2016 14:01:24 +0200 Subject: [PATCH 20/27] bug fixes and gruntfile cleanup --- app/js/events.js | 22 ++++++++++++---------- gruntfile.js | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/js/events.js b/app/js/events.js index 40e3743..7235c66 100644 --- a/app/js/events.js +++ b/app/js/events.js @@ -62,19 +62,21 @@ var events = { */ mouseUp: function(e) { e.preventDefault(); - helpers.setInteractTime(); main.globals.isDown = false; main.object.canvas.classList.remove('grabbing'); - if(e.pageX == main.globals.clickStart.x && e.pageY == main.globals.clickStart.y) { - var point = main.object.levels.getCurrent().points.hitAPoint(e.layerX, e.layerY); - if(point !== null && e.which === 1) { - main.object.popups.get(point.number).show(); - } else { - if(main.globals.doubleTap === true) { - events.dblclick(e); - main.globals.doubleTap = null; + if(e.target.id == main.canvas) { + helpers.setInteractTime(); + if(e.pageX == main.globals.clickStart.x && e.pageY == main.globals.clickStart.y) { + var point = main.object.levels.getCurrent().points.hitAPoint(e.layerX, e.layerY); + if(point !== null && e.which === 1) { + main.object.popups.get(point.number).show(); } else { - main.object.popups.hideAll(); + if(main.globals.doubleTap === true) { + events.dblclick(e); + main.globals.doubleTap = null; + } else { + main.object.popups.hideAll(); + } } } } diff --git a/gruntfile.js b/gruntfile.js index c90532e..eec0f22 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -7,7 +7,7 @@ module.exports = function(grunt) { files: [ 'app/**/*.js' ], - tasks: ['template', 'jsbeautifier', 'uglify'] + tasks: ['template', 'jsbeautifier'] }, less: { files: [ From 2ad31a0c5e64ea11249b7b58f44a1f566671a9ad Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Wed, 29 Jun 2016 15:34:38 +0200 Subject: [PATCH 21/27] Custom controls api --- app/js/api.js | 21 ++++++++++++++++++ app/js/home_button.js | 6 ++--- app/js/setup.js | 10 ++++----- app/js/zoom_controls.js | 6 ++--- app/less/controls.less | 4 ++++ docs.md | 49 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 11 deletions(-) diff --git a/app/js/api.js b/app/js/api.js index 344e201..d1c9837 100644 --- a/app/js/api.js +++ b/app/js/api.js @@ -148,5 +148,26 @@ main.api = { main.globals.offset.changeBy(0, 40 * (factor || 1)); level.draw(); } + }, + + controls: { + + /** + * Array of controls to add + * @param {Array} objects + */ + add: function(objects) { + var control_container = helpers.createElement('div', 'm4n-custom-control-container'); + objects.forEach(function(object) { + var control = helpers.createElement('div', 'm4n-control-button', { + 'click': object.click + }); + control.setAttribute('data-content', object.text); + control_container.appendChild(control); + }); + control_container.appendChild(helpers.createElement('div', 'm4n-control-separator')); + + main.controlContainer.appendChild(control_container); + } } }; \ No newline at end of file diff --git a/app/js/home_button.js b/app/js/home_button.js index 5e43230..9b8663d 100644 --- a/app/js/home_button.js +++ b/app/js/home_button.js @@ -1,7 +1,7 @@ /** **/ -function createHomeButton(control_container) { +function createHomeButton() { var home_container = helpers.createElement('div', 'm4n-home-container'); var home_button = helpers.createElement('div', ['m4n-control-button'], { @@ -11,7 +11,7 @@ function createHomeButton(control_container) { }); home_container.appendChild(home_button); + home_container.appendChild(helpers.createElement('div', 'm4n-control-separator')); - control_container.appendChild(home_container); - control_container.appendChild(helpers.createElement('div', 'm4n-control-separator')); + main.controlContainer.appendChild(home_container); } diff --git a/app/js/setup.js b/app/js/setup.js index 6193d8c..2b9c41f 100644 --- a/app/js/setup.js +++ b/app/js/setup.js @@ -22,18 +22,18 @@ function initializeM4n(mapJson) { main.object = revive(mapJson); - var controlContainer = helpers.createElement('div', 'm4n-control-container'); + main.controlContainer = helpers.createElement('div', 'm4n-control-container'); if(main.object.levels.count() > 1 && main.zoomControls) { - createZoomControls(controlContainer); + createZoomControls(); } if(main.homeButton) { - createHomeButton(controlContainer); + createHomeButton(); } - controlContainer.style.zIndex = main.object.canvas.style.zIndex +1; - container.appendChild(controlContainer); + main.controlContainer.style.zIndex = main.object.canvas.style.zIndex +1; + container.appendChild(main.controlContainer); if(!container.hasPredefinedHeight) { var level = main.object.levels.getCurrent(); diff --git a/app/js/zoom_controls.js b/app/js/zoom_controls.js index d325f15..5c061ae 100644 --- a/app/js/zoom_controls.js +++ b/app/js/zoom_controls.js @@ -1,7 +1,7 @@ /** * Create the zoom controls */ -function createZoomControls(control_container) { +function createZoomControls() { // Zoom controls var zoom_container = helpers.createElement('div', 'm4n-zoom-container'); var zoom_control_in = helpers.createElement('div', 'm4n-control-button', { @@ -34,7 +34,7 @@ function createZoomControls(control_container) { zoom_container.appendChild(zoom_control_in); zoom_container.appendChild(zoom_control_out); + zoom_container.appendChild(helpers.createElement('div', 'm4n-control-separator')); - control_container.appendChild(zoom_container); - control_container.appendChild(helpers.createElement('div', 'm4n-control-separator')); + main.controlContainer.appendChild(zoom_container); } diff --git a/app/less/controls.less b/app/less/controls.less index 3bdbf3b..815a112 100644 --- a/app/less/controls.less +++ b/app/less/controls.less @@ -54,4 +54,8 @@ .m4n-home-container div:first-child::before { content: '\2302'; +} + +.m4n-custom-control-container div::before { + content: attr(data-content); } \ No newline at end of file diff --git a/docs.md b/docs.md index 850b945..0ac94c5 100644 --- a/docs.md +++ b/docs.md @@ -178,6 +178,14 @@ In the API you will find a number of functions which can be used to interact wit * @param {number} [factor=1] */ down: function(factor) {} + }, + + controls: { + /** + * Array of controls to add + * @param {Array} objects + */ + add: function(objects) {} } } ``` @@ -272,6 +280,47 @@ The API `levels` function will return an array of all `level` objects as describ } ``` +#### controls +The API `controls` namespace has one method: `add`, this method can be used to add clusters of icons to the control container. + +The `add` method accepts an array of objects with this following properties. + +```js +[ + { + /** + * The text for the button, css compatible. + **/ + text: '1', + /** + * The method called when the button is clicked. + **/ + click: function() {} + }, + { + text: '2', + click: function() { + console.log('2'); + } + } +] +``` +each array of objects will form a cluster onderneath the zoom or home controls. + +#####example + +```js +var levels = []; +map.api.levels().levels.forEach(function(level) { + levels.push({ + 'text': level.level, + 'click': level.changeTo + }); +}); +map.api.controls.add(levels); +``` +This will add a cluster of all levels to the control container and when they're clicked the map will change to that level. + ### addEventListener The `addEventListener` method is used to add an eventListener to an event. From 6054867d5c7658c914a5bd27a911d5e609c8eebd Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Thu, 30 Jun 2016 09:59:07 +0200 Subject: [PATCH 22/27] Cleanup --- app/js/home_button.js | 2 +- app/less/controls.less | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/js/home_button.js b/app/js/home_button.js index 9b8663d..ffdd42e 100644 --- a/app/js/home_button.js +++ b/app/js/home_button.js @@ -4,7 +4,7 @@ function createHomeButton() { var home_container = helpers.createElement('div', 'm4n-home-container'); - var home_button = helpers.createElement('div', ['m4n-control-button'], { + var home_button = helpers.createElement('div', 'm4n-control-button', { 'click': function() { main.api.reset(); } diff --git a/app/less/controls.less b/app/less/controls.less index 815a112..dd27033 100644 --- a/app/less/controls.less +++ b/app/less/controls.less @@ -44,18 +44,18 @@ //// // Button icons -.m4n-zoom-container div:first-child::before { +.m4n-zoom-container div.m4n-control-button:nth-child(1)::before { content: '+'; } -.m4n-zoom-container div:last-child::before { +.m4n-zoom-container div.m4n-control-button:nth-child(2)::before { content: '\2013'; } -.m4n-home-container div:first-child::before { +.m4n-home-container div.m4n-control-button:first-child::before { content: '\2302'; } -.m4n-custom-control-container div::before { +.m4n-custom-control-container div.m4n-control-button::before { content: attr(data-content); } \ No newline at end of file From 272e98568e332e17d972195a1cab4c6ef0ec9133 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Thu, 30 Jun 2016 13:55:33 +0200 Subject: [PATCH 23/27] Fixes, cleanup & WIP --- app/js/classes/point.js | 6 +++--- app/js/classes/points.js | 13 +++++-------- app/js/classes/popup.js | 2 +- app/js/classes/popups.js | 12 +++++------- app/js/events.js | 19 +++++++++++++++---- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/app/js/classes/point.js b/app/js/classes/point.js index 9ea539c..93879a8 100644 --- a/app/js/classes/point.js +++ b/app/js/classes/point.js @@ -13,10 +13,10 @@ var Point = function(point) { } } } - // TODO refactor to support all formats + this.position = { - left: Math.min.apply(null, this.shape.map(function(item) { return item.x })) - 5, - top: Math.min.apply(null, this.shape.map(function(item) { return item.y })) - 5 + left: Math.min.apply(null, this.shape.map(function(item) { return item.x })) - 10, + top: Math.min.apply(null, this.shape.map(function(item) { return item.y })) - 10 }; this.size = { width: Math.max.apply(null, this.shape.map(function(item) { return item.x })) - this.position.left + 10, diff --git a/app/js/classes/points.js b/app/js/classes/points.js index 3b53828..1eeb1ad 100644 --- a/app/js/classes/points.js +++ b/app/js/classes/points.js @@ -31,15 +31,12 @@ Points.prototype.draw = function() { * @returns {Point|null} The point the user clicked on */ Points.prototype.hitAPoint = function(x, y) { - var point = null; - - this.list.forEach(function(item) { - if(item.isOn(x, y)) { - point = item; - return false; + for(var i = 0; i < this.list.length; i++) { + if(this.list[i].isOn(x, y)) { + return this.list[i]; } - }); - return point; + } + return null; }; /** diff --git a/app/js/classes/popup.js b/app/js/classes/popup.js index bd2da38..bb18e0a 100644 --- a/app/js/classes/popup.js +++ b/app/js/classes/popup.js @@ -366,7 +366,7 @@ Popup.prototype.generatePopover = function(popup, title_html, info_html, media_h } }; - console.log(formulas, "\n", fits.onCanvas, "\n", fits.onScreen); + // console.log(formulas, "\n", fits.onCanvas, "\n", fits.onScreen); var show = { above: function() { diff --git a/app/js/classes/popups.js b/app/js/classes/popups.js index e23ecdb..8f5b30d 100644 --- a/app/js/classes/popups.js +++ b/app/js/classes/popups.js @@ -93,12 +93,10 @@ Popups.prototype.hideAll = function(force) { * @returns {Popup|null} the current popup */ Popups.prototype.getCurrent = function() { - var current = null; - this.getAll().forEach(function(item) { - if(item.on_screen) { - current = item; - return false; + for(var i = 0; i < this.list.length; i++) { + if(this.list[i].on_screen) { + return this.list[i]; } - }); - return current; + } + return null; }; \ No newline at end of file diff --git a/app/js/events.js b/app/js/events.js index 7235c66..0fd46e1 100644 --- a/app/js/events.js +++ b/app/js/events.js @@ -94,7 +94,7 @@ var events = { if(helpers.validateTouchMoveClickMargin(main.globals.clickStart, main.globals.dragPosition) && !main.globals.isScaling) { var point = main.object.levels.getCurrent() .points.hitAPoint(main.globals.dragPosition.x, main.globals.dragPosition.y); - if(point !== null) { + if(point !== null && !main.globals.isScaling) { main.object.popups.get(point.number).show(); } else { if(main.globals.doubleTap === true) { @@ -221,16 +221,25 @@ var events = { } else if(fingers.length === 2) { if(main.globals.isScaling === true) { // Todo: improve delta calculation - main.globals.newDistance = Math.sqrt( + var newDistance = Math.sqrt( (fingers[0].pageX - fingers[1].pageX) * (fingers[0].pageX - fingers[1].pageX) + (fingers[0].pageY - fingers[1].pageY) * (fingers[0].pageY - fingers[1].pageY) ); + + var pinching = newDistance < main.globals.newDistance; + + main.globals.newDistance = newDistance; main.globals.lastPos = { x: (fingers[0].pageX + fingers[1].pageX) / 2, y: (fingers[0].pageY + fingers[1].pageY) / 2 }; - gPz = helpers.gesturePinchZoom(e) / 40; + if(!( + (currentLevel.level == main.object.levels.getLowest().level && !pinching) || + (currentLevel.level == main.object.levels.getHighest().level && pinching) + )) { + gPz = helpers.gesturePinchZoom(e) / 40; + } if(gPz < 1 && gPz > -1) { main.globals.distance = gPz; helpers.zoom(gPz); @@ -342,7 +351,9 @@ var events = { * When the document gets resized */ resize: function() { - var fullscreen = document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement; + var fullscreen = + document.fullscreenElement || document.webkitFullscreenElement || + document.msFullscreenElement || document.mozFullScreenElement; if(fullscreen) { if([fullscreen.id.indexOf("-youtube"), fullscreen.id.indexOf("-video")].indexOf(-1) > -1) { main.globals.videoFullscreen.value = true; From a7a9ac985c80e5dd79758366d6c111ec7838b628 Mon Sep 17 00:00:00 2001 From: Kevin Richter Date: Thu, 30 Jun 2016 14:26:38 +0200 Subject: [PATCH 24/27] cleanup docs --- docs.md | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs.md b/docs.md index 0ac94c5..6012f8a 100644 --- a/docs.md +++ b/docs.md @@ -29,7 +29,7 @@ Here we’ll talk a bit about the boilerplate code that the tool will provide. Example -```js +```html