{"version":3,"file":"js/decidim_homepage_interactive_map.js","mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAiBA;AAGA;AACA;AACA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AC7WA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;;;;;;;;;;AClBA;;AAEA;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAEA;;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxGA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AAGA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAGA;AACA;AAAA;AAAA;AAAA;AAGA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAGA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAKA;AACA;AAEA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;;;;;ACzPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACPA;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AElDA;AACA;AACA;AACA;AACA","sources":["webpack://code/./vendor/decidim-gems/decidim-module-homepage_interactive_map-master/app/packs/entrypoints/decidim_homepage_interactive_map.js","webpack://code/./vendor/decidim-gems/decidim-module-homepage_interactive_map-master/app/packs/src/decidim/homepage_interactive_map/interactive_map.js","webpack://code/./vendor/decidim-gems/decidim-module-homepage_interactive_map-master/app/packs/src/decidim/homepage_interactive_map/scope.js","webpack://code/./vendor/decidim-gems/decidim-module-homepage_interactive_map-master/app/packs/src/vendor/jquery.truncate.js","webpack://code/./vendor/decidim-gems/decidim-module-homepage_interactive_map-master/app/packs/src/vendor/leaflet-polylabel-centroid.js","webpack://code/webpack/bootstrap","webpack://code/webpack/runtime/chunk loaded","webpack://code/webpack/runtime/compat get default export","webpack://code/webpack/runtime/define property getters","webpack://code/webpack/runtime/hasOwnProperty shorthand","webpack://code/webpack/runtime/make namespace object","webpack://code/webpack/runtime/jsonp chunk loading","webpack://code/webpack/before-startup","webpack://code/webpack/startup","webpack://code/webpack/after-startup"],"sourcesContent":["import \"leaflet\"\nimport \"leaflet-tilelayer-here\"\nimport \"leaflet-svgicon\"\nimport \"leaflet.markercluster\"\nimport \"src/decidim/homepage_interactive_map/interactive_map\"\nimport \"src/decidim/homepage_interactive_map/scope\"\n","import * as L from \"leaflet\";\nimport \"src/decidim/vendor/leaflet-tilelayer-here\"\nimport \"src/decidim/map/icon.js\" // comes with Decidim\nimport \"leaflet.markercluster\"; // Comes with Decidim\nimport \"leaflet.featuregroup.subgroup\" // included in this package.json\nimport \"src/vendor/jquery.truncate\"\n\nimport \"src/vendor/leaflet-polylabel-centroid\";\n\nL.DivIcon.SVGIcon.DecidimIcon = L.DivIcon.SVGIcon.extend({\n options: {\n iconSize: L.point(24,34),\n fillColor: getComputedStyle(document.documentElement).getPropertyValue('--primary'),\n fillOpacity: 1,\n opacity: 0,\n },\n _createPathDescription: function() {\n return \"M12,0.17 C5.5465527,0.17 0.315,5.4015527 0.315,11.855 C0.315,23.105 10.545,32.465 10.98,32.855 C11.5531636,33.3793645 12.4318364,33.3793645 13.005,32.855 C13.44,32.42 23.67,23.045 23.67,11.855 C23.67,5.40740603 18.4475887,0.178276757 12,0.17 Z M12,17.585 C9.19163205,17.585 6.915,15.308368 6.915,12.5 C6.915,9.69163205 9.19163205,7.415 12,7.415 C14.808368,7.415 17.085,9.69163205 17.085,12.5 C17.085,15.308368 14.808368,17.585 12,17.585 L12,17.585 Z\";\n },\n _createCircle: function() {\n return \"\"\n }\n});\n\n(() => {\n $(document).ready(() => {\n const here_api_key = $(\"#interactive_map\").data(\"here-api-key\");\n const geoJson = $(\"#interactive_map\").data(\"geojson-data\");\n const $viewParticipatoryProcess = $(\"#view-participatory-process\");\n\n // Used to prevent click event when double click navigating\n const clickDelay = 500;\n let clickTimer = 0;\n let clickPrevent = false;\n\n // Style options\n const colorOpacity = 0.5;\n const hoverColorOpacity = 0.8;\n const strokeWeight = 1.5;\n const polyLineColor = 1;\n const strokeColor = \"#8a8a8a\";\n const iconSize = 28;\n\n const map = L.map('interactive_map', {scrollWheelZoom: false});\n\n let zoomOrigin = map.getZoom();\n let allZonesLayer = L.featureGroup();\n let allZonesMarkers = [];\n let allProcessesLinks = {};\n\n function zoneMarkerIconCSS(size) {\n return {\n 'font-size': `${(size / 2) - 2}px`,\n 'width' : `${size - 2}px`,\n 'height' : `${size - 2}px`,\n 'line-height' : `${size - 2}px`,\n 'border-radius' : `${size / 2}px`\n }\n }\n\n function processMarkerIconCSS(size) {\n return {\n 'font-size': `${Math.round(size / 3)}px`,\n 'width' : `${size / 2}px`,\n 'height' : `${size / 2}px`,\n 'line-height' : `${size / 2}px`,\n 'border-radius' : `${size / 4}px`\n }\n }\n\n function popupMaxwidth() {\n if ($(window).width() < 600) {\n return 260\n } else {\n return 640\n }\n }\n\n function popupMinwidth() {\n if ($(window).width() < 600) {\n return 204\n } else {\n return 500\n }\n }\n\n function isCoordinates(value, length) {\n return Array.isArray(value) && (value.length === length) && !!value.reduce((a, v) => (a && (a !== null)));\n }\n\n function hasLocation(participatory_process) {\n return (participatory_process.location !== undefined) && isCoordinates(participatory_process.location, 2);\n }\n\n function updateProcessMarkerPosition(marker, delta, zoom) {\n if (marker.origin === undefined) {\n return;\n }\n let oldPoint = map.project(L.latLng(marker.origin), zoom);\n\n let radius = ( delta / 2.5 ) + ( marker.getRadius() / 1.75 ) ;\n let newPoint = L.point(\n oldPoint.x + ( radius * Math.cos( Math.PI / 4 ) ),\n oldPoint.y - ( radius * Math.sin( Math.PI / 4 ) )\n );\n marker._latlng = map.unproject(newPoint, zoom);\n }\n\n function calculateIconSize() {\n const delta = Math.round(1.75 * (map.getZoom()));\n return (delta + 2) * 2;\n }\n\n function tmpl(participatoryProcess, linkTxt) {\n return `\n
\n

${participatoryProcess.title}

\n
\n
\n
\n ${participatoryProcess.start_date} - ${participatoryProcess.end_date}\n
\n
\n \n
\n
\n `\n }\n\n\n L.tileLayer.here({\n apiKey: here_api_key,\n scheme: \"normal.day.grey\"\n }, {continuousWorld: true}).addTo(map);\n\n map.createPane(\"processPane\").style.zIndex = 610;\n let allProcessesLayer = L.markerClusterGroup({\n clusterPane: \"processPane\",\n zoomToBoundsOnClick: false,\n removeOutsideVisibleBounds: true,\n spiderfyDistanceMultiplier: 2,\n chunkedLoading: true,\n showCoverageOnHover: false,\n maxClusterRadius: 40,\n spiderLegPolylineOptions: {\n weight: 2,\n color: getComputedStyle(document.documentElement).getPropertyValue('--primary'),\n opacity: polyLineColor\n },\n iconCreateFunction: (cluster) => {\n let actualIconSize = ( map.getZoom() > zoomOrigin ) ? calculateIconSize() : iconSize;\n\n let style = Object.entries(processMarkerIconCSS(actualIconSize)).map(\n (v) => `${v[0]}: ${v[1]};`\n ).join(\" \");\n\n return new L.DivIcon({\n html: '
' + cluster.getChildCount() + '
',\n className: 'marker-cluster',\n iconSize: new L.Point(actualIconSize / 2, actualIconSize / 2)\n });\n }\n });\n\n // Convert data from GeoJSON\n const geoJsonLayer = L.geoJson(geoJson, {\n style: (feature) => {\n return {\n interactive: false,\n stroke: true,\n color: strokeColor,\n weight: strokeWeight,\n fillColor: feature.color,\n fillOpacity: colorOpacity\n }\n }\n });\n\n // We parsed the data to generate advanced layers configuration\n geoJsonLayer.eachLayer((layer) => {\n let { feature } = layer;\n let zoneLayer = L.featureGroup();\n\n // Zone = Assembly with scope\n\n // Base zone polygon\n zoneLayer.addLayer(layer);\n\n zoneLayer.on(\"mouseover\", function() {\n this.setStyle({\n fillOpacity: hoverColorOpacity\n });\n });\n\n zoneLayer.on(\"mouseout\", function() {\n this.setStyle({\n fillOpacity: colorOpacity\n });\n });\n\n\n // Zone label\n const icon = L.divIcon({\n className: 'district-number',\n html: feature.code,\n iconSize: new L.Point(iconSize, iconSize)\n });\n const centroid = L.PolylabelCentroid(L.GeoJSON.latLngsToCoords(layer._latlngs[0], 1), 1/1000);\n\n let zoneMarker = L.marker(centroid, { icon });\n\n allZonesMarkers.push(zoneMarker);\n zoneLayer.addLayer(zoneMarker);\n\n // Navigate to target page\n zoneMarker.on(\"keypress\", (e) => {\n if( e.originalEvent.key === \"Enter\" ) {\n return window.location = feature.link;\n }\n });\n\n // Navigate to target page if not double click\n zoneMarker.on(\"click\", (e) => {\n clickTimer = setTimeout(() => {\n if (!clickPrevent) {\n return window.location = feature.link;\n }\n clickPrevent = false;\n }, clickDelay);\n });\n\n // Zoom to Polygone / Zone\n zoneMarker.on(\"dblclick\", (e) => {\n clearTimeout(clickTimer);\n clickPrevent = true;\n map.fitBounds(zoneLayer.getBounds(), {\n padding: [25, 25]\n });\n });\n\n // Manage linked participatory processes\n feature.participatory_processes.forEach((participatory_process) => {\n\n // Filling the registry links\n if(Object.keys(allProcessesLinks).includes(participatory_process.id.toString())) {\n allProcessesLinks[participatory_process.id.toString()].push(layer);\n // Process with location are only displayed once\n if( hasLocation(participatory_process) ) { return }\n } else {\n allProcessesLinks[participatory_process.id.toString()] = [layer];\n }\n\n let marker = new L.circleMarker(\n // marker is placed on its location or the center of the assembly\n hasLocation(participatory_process) ? participatory_process.location : centroid,\n {\n pane: \"processPane\",\n radius: Math.round(iconSize / 4),\n weight: 0,\n fillOpacity: 1,\n fillColor: getComputedStyle(document.documentElement).getPropertyValue('--primary'),\n }\n );\n\n let node = document.createElement(\"div\");\n $(node).html((tmpl(participatory_process, $viewParticipatoryProcess.val())));\n\n marker.bindPopup(node, {\n maxwidth: popupMaxwidth(),\n minWidth: popupMinwidth(),\n keepInView: true,\n className: \"interactive-map-info\"\n }).openPopup();\n\n marker.participatory_process_data = participatory_process;\n marker.origin = centroid;\n\n // Add marker to marker cluster group\n allProcessesLayer.addLayer(marker);\n });\n\n // Add zone to layer group\n allZonesLayer.addLayer(zoneLayer);\n });\n\n // Add zones to map\n allZonesLayer.addTo(map);\n\n // Map is centered on all the zone\n map.fitBounds(allZonesLayer.getBounds(), {\n padding: [25, 25]\n });\n\n // Update the starting zoom\n zoomOrigin = map.getZoom();\n\n\n // Now, all the element are actually projected on the map\n allProcessesLayer.eachLayer((marker) => {\n\n // Each participatory process should highlight its linked assemblies / zones\n let linked = allProcessesLinks[marker.participatory_process_data.id.toString()];\n\n linked.forEach((layer) => {\n marker.on(\"mouseover\", function() {\n layer.bringToFront().setStyle({\n fillOpacity: hoverColorOpacity,\n color: getComputedStyle(document.documentElement).getPropertyValue('--primary'),\n weight: 2\n });\n });\n\n marker.on(\"mouseout\", function() {\n layer.bringToBack().setStyle({\n fillOpacity: colorOpacity,\n color: strokeColor,\n weight: strokeWeight\n });\n });\n });\n\n // Translate the marker centered on the zone outside the zone label\n // ( like an notification badge )\n if(!hasLocation(marker.participatory_process_data)) {\n updateProcessMarkerPosition(marker, iconSize, map.getZoom());\n }\n });\n\n // Map zoom events\n map.on('zoomstart', (e) => {\n $('#interactive_map .leaflet-process-pane').hide();\n });\n\n map.on('zoomend', (e) => {\n let actualIconSize = iconSize;\n\n if (map.getZoom() > zoomOrigin) {\n actualIconSize = calculateIconSize()\n $('#interactive_map .district-number').css(zoneMarkerIconCSS(actualIconSize));\n } else {\n $('#interactive_map .district-number').css(zoneMarkerIconCSS(iconSize));\n }\n\n allZonesMarkers.forEach((marker) => {\n let icon = marker.options.icon;\n icon.options.iconSize = new L.Point(actualIconSize, actualIconSize);\n marker.setIcon(icon);\n });\n\n allProcessesLayer.eachLayer((marker) => {\n if(!hasLocation(marker.participatory_process_data)) {\n updateProcessMarkerPosition(marker, actualIconSize, map.getZoom());\n }\n });\n\n allProcessesLayer.refreshClusters();\n $('#interactive_map .leaflet-process-pane').show();\n });\n // Add markers to map\n allProcessesLayer.addTo(map);\n });\n})(window);\n","$(document).ready(() => {\n let $geolocalized = $(\"#scope_geolocalized\");\n let $geojson = $(\"#geojson\");\n\n function toggleSubField(field, subfield) {\n if (field.is(\":checked\")) {\n subfield.show();\n } else {\n subfield.hide();\n }\n }\n\n $geolocalized.on(\"click\", function () {\n toggleSubField($geolocalized, $geojson);\n }\n );\n\n toggleSubField($geolocalized, $geojson);\n});\n","// From https://github.com/pathable/truncate/\n\n(function($) {\n\n // Matches trailing non-space characters.\n var chop = /(\\s*\\S+|\\s)$/;\n\n // Matches the first word in the string.\n var start = /^(\\S*)/;\n\n // Return a truncated html string. Delegates to $.fn.truncate.\n $.truncate = function(html, options) {\n return $('
').append(html).truncate(options).html();\n };\n\n // Truncate the contents of an element in place.\n $.fn.truncate = function(options) {\n if ($.isNumeric(options)) options = { length: options };\n var o = $.extend({}, $.truncate.defaults, options);\n\n return this.each(function() {\n var self = $(this);\n\n if (o.noBreaks) self.find('br').replaceWith(' ');\n\n var text = self.text();\n var excess = text.length - o.length;\n\n if (o.stripTags) self.text(text);\n\n // Chop off any partial words if appropriate.\n if (o.words && excess > 0) {\n var truncated = text.slice(0, o.length).replace(chop, '').length;\n\n if (o.keepFirstWord && truncated === 0) {\n excess = text.length - start.exec(text)[0].length - 1;\n } else {\n excess = text.length - truncated - 1;\n }\n }\n\n if (excess < 0 || !excess && !o.truncated) return;\n\n // Iterate over each child node in reverse, removing excess text.\n $.each(self.contents().get().reverse(), function(i, el) {\n var $el = $(el);\n var text = $el.text();\n var length = text.length;\n\n // If the text is longer than the excess, remove the node and continue.\n if (length <= excess) {\n o.truncated = true;\n excess -= length;\n $el.remove();\n return;\n }\n\n // Remove the excess text and append the ellipsis.\n if (el.nodeType === 3) {\n // should we finish the block anyway?\n if (o.finishBlock) {\n $(el.splitText(length)).replaceWith(o.ellipsis);\n } else {\n $(el.splitText(length - excess - 1)).replaceWith(o.ellipsis);\n }\n return false;\n }\n\n // Recursively truncate child nodes.\n $el.truncate($.extend(o, { length: length - excess }));\n return false;\n });\n });\n };\n\n $.truncate.defaults = {\n\n // Strip all html elements, leaving only plain text.\n stripTags: false,\n\n // Only truncate at word boundaries.\n words: false,\n\n // When 'words' is active, keeps the first word in the string\n // even if it's longer than a target length.\n keepFirstWord: false,\n\n // Replace instances of
with a single space.\n noBreaks: false,\n\n // if true always truncate the content at the end of the block.\n finishBlock: false,\n\n // The maximum length of the truncated html.\n length: Infinity,\n\n // The character to use as the ellipsis. The word joiner (U+2060) can be\n // used to prevent a hanging ellipsis, but displays incorrectly in Chrome\n // on Windows 7.\n // http://code.google.com/p/chromium/issues/detail?id=68323\n ellipsis: '\\u2026' // '\\u2060\\u2026'\n\n };\n\n})(jQuery);\n","// Leaflet Polylabel Centroid\n// USAGE : L.PolylabelCentroid(coordinates, precision, debug)\n// + coordinates (required) : GeoJSON Polygon coordinates\n// + precision (optional) : default to 1.0, decrease for better precision (like 1/1000)\n// + debug (optional) : activate debug coinsole output\n\n// ----------------------------------------------------------------------------\n\n// TinyQueue\n// source : https://github.com/mourner/tinyqueue/blob/3a212a4f73ad9c39caeb27922c86ff4115e59c66/index.js\n\nclass Queue {\n constructor(data = [], compare = defaultCompare) {\n this.data = data;\n this.length = this.data.length;\n this.compare = compare;\n\n if (this.length > 0) {\n for (let i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);\n }\n }\n\n push(item) {\n this.data.push(item);\n this.length++;\n this._up(this.length - 1);\n }\n\n pop() {\n if (this.length === 0) return undefined;\n\n const top = this.data[0];\n const bottom = this.data.pop();\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = bottom;\n this._down(0);\n }\n\n return top;\n }\n\n peek() {\n return this.data[0];\n }\n\n _up(pos) {\n const {data, compare} = this;\n const item = data[pos];\n\n while (pos > 0) {\n const parent = (pos - 1) >> 1;\n const current = data[parent];\n if (compare(item, current) >= 0) break;\n data[pos] = current;\n pos = parent;\n }\n\n data[pos] = item;\n }\n\n _down(pos) {\n const {data, compare} = this;\n const halfLength = this.length >> 1;\n const item = data[pos];\n\n while (pos < halfLength) {\n let left = (pos << 1) + 1;\n let best = data[left];\n const right = left + 1;\n\n if (right < this.length && compare(data[right], best) < 0) {\n left = right;\n best = data[right];\n }\n if (compare(best, item) >= 0) break;\n\n data[pos] = best;\n pos = left;\n }\n\n data[pos] = item;\n }\n}\n\n// ----------------------------------------------------------------------------\n\n// Polylabel\n// source : https://github.com/mapbox/polylabel/blob/6854a05e221fac42b9e025cbf356b2a057f212aa/polylabel.js\n\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nfunction polylabel(polygon, precision, debug) {\n precision = precision || 1.0;\n\n // find the bounding box of the outer ring\n var minX, minY, maxX, maxY;\n for (var i = 0; i < polygon[0].length; i++) {\n var p = polygon[0][i];\n if (!i || p[0] < minX) minX = p[0];\n if (!i || p[1] < minY) minY = p[1];\n if (!i || p[0] > maxX) maxX = p[0];\n if (!i || p[1] > maxY) maxY = p[1];\n }\n\n var width = maxX - minX;\n var height = maxY - minY;\n var cellSize = Math.min(width, height);\n var h = cellSize / 2;\n\n if (cellSize === 0) return [minX, minY];\n\n // a priority queue of cells in order of their \"potential\" (max distance to polygon)\n var cellQueue = new Queue(undefined, compareMax);\n\n // cover polygon with initial cells\n for (var x = minX; x < maxX; x += cellSize) {\n for (var y = minY; y < maxY; y += cellSize) {\n cellQueue.push(new Cell(x + h, y + h, h, polygon));\n }\n }\n\n // take centroid as the first best guess\n var bestCell = getCentroidCell(polygon);\n\n // special case for rectangular polygons\n var bboxCell = new Cell(minX + width / 2, minY + height / 2, 0, polygon);\n if (bboxCell.d > bestCell.d) bestCell = bboxCell;\n\n var numProbes = cellQueue.length;\n\n while (cellQueue.length) {\n // pick the most promising cell from the queue\n var cell = cellQueue.pop();\n\n // update the best cell if we found a better one\n if (cell.d > bestCell.d) {\n bestCell = cell;\n if (debug) console.log('found best %d after %d probes', Math.round(1e4 * cell.d) / 1e4, numProbes);\n }\n\n // do not drill down further if there's no chance of a better solution\n if (cell.max - bestCell.d <= precision) continue;\n\n // split the cell into four cells\n h = cell.h / 2;\n cellQueue.push(new Cell(cell.x - h, cell.y - h, h, polygon));\n cellQueue.push(new Cell(cell.x + h, cell.y - h, h, polygon));\n cellQueue.push(new Cell(cell.x - h, cell.y + h, h, polygon));\n cellQueue.push(new Cell(cell.x + h, cell.y + h, h, polygon));\n numProbes += 4;\n }\n\n if (debug) {\n console.log('num probes: ' + numProbes);\n console.log('best distance: ' + bestCell.d);\n }\n\n return [bestCell.x, bestCell.y];\n}\n\nfunction compareMax(a, b) {\n return b.max - a.max;\n}\n\nfunction Cell(x, y, h, polygon) {\n this.x = x; // cell center x\n this.y = y; // cell center y\n this.h = h; // half the cell size\n this.d = pointToPolygonDist(x, y, polygon); // distance from cell center to polygon\n this.max = this.d + this.h * Math.SQRT2; // max distance to polygon within a cell\n}\n\n// signed distance from point to polygon outline (negative if point is outside)\nfunction pointToPolygonDist(x, y, polygon) {\n var inside = false;\n var minDistSq = Infinity;\n\n for (var k = 0; k < polygon.length; k++) {\n var ring = polygon[k];\n\n for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {\n var a = ring[i];\n var b = ring[j];\n\n if ((a[1] > y !== b[1] > y) &&\n (x < (b[0] - a[0]) * (y - a[1]) / (b[1] - a[1]) + a[0])) inside = !inside;\n\n minDistSq = Math.min(minDistSq, getSegDistSq(x, y, a, b));\n }\n }\n\n return (inside ? 1 : -1) * Math.sqrt(minDistSq);\n}\n\n// get polygon centroid\nfunction getCentroidCell(polygon) {\n var area = 0;\n var x = 0;\n var y = 0;\n var points = polygon[0];\n\n for (var i = 0, len = points.length, j = len - 1; i < len; j = i++) {\n var a = points[i];\n var b = points[j];\n var f = a[0] * b[1] - b[0] * a[1];\n x += (a[0] + b[0]) * f;\n y += (a[1] + b[1]) * f;\n area += f * 3;\n }\n if (area === 0) return new Cell(points[0][0], points[0][1], 0, polygon);\n return new Cell(x / area, y / area, 0, polygon);\n}\n\n// get squared distance from a point to a segment\nfunction getSegDistSq(px, py, a, b) {\n\n var x = a[0];\n var y = a[1];\n var dx = b[0] - x;\n var dy = b[1] - y;\n\n if (dx !== 0 || dy !== 0) {\n\n var t = ((px - x) * dx + (py - y) * dy) / (dx * dx + dy * dy);\n\n if (t > 1) {\n x = b[0];\n y = b[1];\n\n } else if (t > 0) {\n x += dx * t;\n y += dy * t;\n }\n }\n\n dx = px - x;\n dy = py - y;\n\n return dx * dx + dy * dy;\n}\n\n// ----------------------------------------------------------------------------\n\nL.PolylabelCentroid = function(polygon, precision, debug) {\n return polylabel(polygon, precision, debug).reverse();\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"decidim_homepage_interactive_map\": 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkcode\"] = self[\"webpackChunkcode\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [\"vendors-node_modules_leaflet_markercluster_dist_leaflet_markercluster-src_js-node_modules_lea-91385c\",\"vendors-node_modules_leaflet-svgicon_index_js-node_modules_leaflet-tilelayer-here_leaflet-til-f2b2f4\",\"vendor_decidim-gems_decidim-core_app_packs_src_decidim_map_icon_js-vendor_decidim-gems_decidi-12c72d\"], function() { return __webpack_require__(\"./vendor/decidim-gems/decidim-module-homepage_interactive_map-master/app/packs/entrypoints/decidim_homepage_interactive_map.js\"); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n",""],"names":[],"sourceRoot":""}