\\n Are you sure ? You want to delete the point !\\n
\\n \"+point.getName()+\" is reserved keyword
\" );\n $( '.validation.point-name' ).parent().addClass('validation-beco');\n return;\n }\n\n if(this.editMode && this.editNode == point.getName()){\n this.editNode = '';\n }else if(this.menu.isPointExist(point.getName())){\n $( \".validation.point-name\" ).html(\"
\"+point.getName()+\" already exist in this floor
\" );\n $( '.validation.point-name' ).parent().addClass('validation-beco');\n return;\n }else if(this.editMode){\n this.menu.removePoint(this.editNode);\n }\n\n this.selectedPoint = point;\n $(\"#selected-point\").show(); // Show point selected\n $(\"#pointManuallySection\").slideToggle(500); // Hide point add form\n $(\"#selected-point-name\").text(this.selectedPoint.name);\n $( \"#edit-point\" ).show();\n this.configRuleSection();\n this.menu.addPoint(this.selectedPoint.name);\n \n\n } else {\n\n if(errors && errors['name']){\n $( \".validation.point-name\" ).html(\"
\"+errors['name'].toString()+\"
\" );\n $( '.validation.point-name' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.point-name p\" ).remove();\n $( '.validation.point-name' ).parent().removeClass('validation-beco');\n }\n\n if(errors && errors['category']){\n $( \".validation.category-sec\" ).html(\"
\"+errors['category'].toString()+\"
\");\n $( '.validation.category-sec' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.category-sec p\" ).remove();\n $( '.validation.category-sec' ).parent().removeClass('validation-beco');\n }\n\n if(errors && errors['description']){\n $( \".validation.point-description\" ).html(\"
\"+errors['description'].toString()+\"
\");\n $( '.validation.point-description' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.point-description p\" ).remove();\n $( '.validation.point-description' ).parent().removeClass('validation-beco');\n }\n\n if(errors && errors['name_ar']){\n $( \".validation.point-name-ar\" ).html(\"
\"+errors['name_ar'].toString()+\"
\");\n $( '.validation.point-name-ar' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.point-name-ar p\" ).remove();\n $( '.validation.point-name-ar' ).parent().removeClass('validation-beco');\n }\n\n\n if(errors && errors['description_ar']){\n $( \".validation.point-description-ar\" ).html(\"
\"+errors['description_ar'].toString()+\"
\");\n $( '.validation.point-description-ar' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.point-description-ar p\" ).remove();\n $( '.validation.point-description-ar' ).parent().removeClass('validation-beco');\n }\n\n\n if(errors && (errors['name'] || errors['description'])){\n $( '#nav-eng-tab' ).addClass('active');\n $( '#nav-ar-tab' ).removeClass('active');\n \n $( '#point-eng' ).addClass('show active');\n $( '#point-arab' ).removeClass('show active');\n } else {\n $( '#nav-ar-tab' ).addClass('active');\n $( '#nav-eng-tab' ).removeClass('active');\n\n $( '#point-eng' ).removeClass('show active');\n $( '#point-arab' ).addClass('show active');\n }\n }\n \n }\n\n cancelAddPoint(){\n $(\"#pointManuallySection\").slideToggle(500);\n $(\"#selected-point\").show();\n }\n\n \n getMenu() {\n return this;\n }\n\n open(feature, rule, menu){\n this.initMenu();\n this.selectedFeature = feature;\n this.rule = rule;\n this.menu = menu;\n if(feature.getProperties() && feature.getProperties().location){\n this.selectedPoint = this.getOrCreatePoint(feature.getProperties().location);\n this.onEditNode();\n }\n this.editMode = false;\n }\n\n save(){\n let props = {};\n\n if(this.selectedFeature) props['location'] = this.selectedPoint;\n this.selectedFeature.setProperties(props);\n\n var type;\n if(this.selectedPoint && this.selectedPoint.isLift()){\n type = NodeType.LIFT;\n }\n\n this.selectedFeature = null;\n this.selectedPoint = null;\n $(\"#point-side-menu\").remove();\n\n return type;\n }\n\n configRuleSection(){\n if(this.selectedPoint && this.selectedPoint.isLift()){\n this.rule.showLifteRule();\n this.rule.hideEscalatorRule();\n this.rule.hideEmptyView();\n } else {\n this.rule.hideLifteRule();\n this.rule.hideEscalatorRule();\n this.rule.showEmptyView();\n }\n }\n\n removePoint(){\n if(this.selectedPoint){\n this.menu.removePoint(this.selectedPoint.name);\n this.selectedPoint = null;\n $(\"#point-cancel\").hide();\n $(\"#pointManuallySection\").show();\n // If selected point is not in server show the add point form else the search\n\n $(\"#selected-point-name\").text(\"\"); // Reset the point name\n $(\"#selected-point\").hide(); // Hide point selected\\\n\n $(\"#InputPointName\").val(\"\"); // Reset textbox value\n this.configRuleSection();\n \n }\n }\n\n editPoint(){\n if(this.selectedPoint){\n $(\"#selected-point\").hide(); // Hide point selected\n $(\"#pointManuallySection\").slideToggle(500);\n $(\"#selected-point-name\").text(this.selectedPoint.name);\n $(\"#InputPointName\").val(this.selectedPoint.name);\n $(\"#InputPointDescription\").val(this.selectedPoint.description);\n $(\"#InputPointNameAr\").val(this.selectedPoint.name_ar);\n $(\"#InputPointDescriptionAr\").val(this.selectedPoint.description_ar);\n this.editNode = this.selectedPoint.name;\n this.configRuleSection();\n }\n }\n \n\n static get getPointVariable() {\n return POINT;\n }\n\n getOrCreatePoint(params){\n console.log(params);\n var props = {\n category : params.category,\n visible : params.visible,\n searchable : params.searchable,\n clickable : params.clickable,\n name : params.name,\n name_ar : params.name_ar,\n description : params.description,\n description_ar : params.description_ar,\n label : params.categoryLabel\n };\n\n let point = new Point(props);\n\n return point;\n }\n\n\n \n}","\n\nconst NodeType = Object.freeze({\n LIFT: \"lift\",\n});\n\nclass Rules {\n\n\tconstructor() {\n \tthis.name = 'Rules';\n \tthis.type;\n \tthis.selectedFloors;\n \tthis.escalator;\n \t}\n\n\n \ttoString() {\n return this.name;\n }\n\n setFloors(floors){\n \t this.selectedFloors = floors;\n }\n\n getFloors(){\n return this.selectedFloors;\n }\n\n setType(type){\n \t this.type = type;\n }\n\n isLift(){\n return this.type == \"lift\" ? true:false;\n }\n\n \n\n}\n\n\nexport { Rules , NodeType};","var validate = require(\"validate.js\");\nvar uuidValidate = require('uuid-validate');\n\n\nexport default class Beacon {\n\n\tconstructor(params) {\n \tthis.name = params.name;\n this.major = params.major;\n this.minor = params.minor;\n this.uuid = params.uuid;\n \n //this.uuid = \"95ecc380-afe9-11e4-9b6c-751b66dd541e\";\n \t}\n\n\n \ttoString() {\n return this.name;\n }\n\n getName(){\n \t return this.name;\n }\n\n validateUUID(){\n return uuidValidate(this.uuid); \n }\n\n isEqual(beacon){\n if(this.name.toLowerCase() == beacon.name.toLowerCase() || (this.major == beacon.major && this.minor == beacon.minor)){\n return true;\n }\n return false;\n }\n\n editIsEqual(beacon){\n if(this.name.toLowerCase() == beacon.name.toLowerCase() && (this.major == beacon.major && this.minor == beacon.minor)){\n return true;\n }\n return false;\n }\n \n validate(){\n var constraints = {\n major: {\n numericality: {\n onlyInteger: true,\n greaterThan: 0\n }\n },\n minor: {\n numericality: {\n onlyInteger: true,\n greaterThan: 0\n }\n },\n uuid: {\n presence: {\n allowEmpty: false\n },\n },\n name: {\n presence: true,\n length: {\n minimum: 2,\n message: \"must be at least 2 characters\"\n }\n }\n };\n\n return validate({\n major: this.major,\n minor: this.minor,\n uuid: this.uuid,\n name:this.name\n }, \n constraints\n );\n }\n}","import '../styles/index.scss';\n\n\nimport { getSiteIdentifier } from './network/util.js';\n\nimport Application from './app.js';\n\n\nlet app;\n\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n\n\tapp = new Application();\n\tapp.init();\n});\n\n\n\n\n\n","import BeCoMap from './map/map.js';\nimport $ from 'jquery';\nimport Observable from './observer.js';\nimport API from './network/network.js';\nimport { getSiteIdentifier, getFloorIdentifier } from './network/util.js';\nimport { t } from './i18n/i18n.js';\nimport { toLocalTimeZone } from './utils.js';\n//import 'script-loader!./externaljs/ms-dropdown/jquery.dd.min.js';\n\n\n\n//Styles\nimport 'bootstrap';\nimport 'bootstrap/dist/css/bootstrap.min.css';\n\n//Driver js\nimport Driver from 'driver.js';\nimport 'driver.js/dist/driver.min.css';\nimport '../styles/tutorial/tutorial.scss';\n\nvar mapTemplate = require(\"../templates/map.handlebars\");\nvar loaderTemplate = require(\"../templates/loader.handlebars\");\nvar legendTemplate = require(\"../templates/map-legend.handlebars\");\nvar headerTemplate = require(\"../templates/header.handlebars\");\nvar feedBackTemplate = require(\"../templates/feedback.handlebars\");\nconst updateMap = app => app.saveData();\nconst drawObserver = new Observable();\n\nconst menu = {\n\taccount :{\n\t\tname : \"My Account\",\n\t\turl : SERVICE_URL \n\t},\n\tsites :{\n\t\tname : \"Sites\",\n\t\turl : SERVICE_URL\n\t},\n\tdocs :{\n\t\tname : \"Docs\",\n\t\turl : SERVICE_URL\n\t},\n\tsupport :{\n\t\tname : \"Support\",\n\t\turl : SERVICE_URL\n\t},\n\tlogout :{\n\t\tname : \"Sign out\",\n\t\turl : SERVICE_URL\n\t}\n};\n\n\nexport default class Application {\n\n\tconstructor() {\n\t\tthis.map;\n\t\tthis.siteIdentifier;\n\t\tthis.floorIdentifier;\n\t\tthis.api = new API();\n\t\tthis.buildInFlight;\n\n\t}\n\n\tinit(){\n\t\t$( \"body\" ).append(loaderTemplate);\n\t\t\n\t\t\n\t\tif(!this.checkRequestparams()){\n\t\t\t$(\"#beco-loader\").hide();\n\t\t\t$(\"#beco-error\").show();\n\t\t\t$(\"#beco-text\").text(t('site-conf-missing'));\n\t\t}else {\n\t\t\t// Check session \n\t\t\t$(\"#beco-loader\").show();\n\t\t\t$(\"#beco-error\").hide();\n\t\t\t$(\"#beco-text\").text(t('cheking-auth'));\n\t\t\tlet _this = this;\n\t\t\tthis.api.checkSession().then(function (response) {\n\t\t\t $(\"#beco-text\").text(t('fetching-map-data'));\n\t\t\t // Load Data \n\t\t\t _this.api.getSiteData(_this.siteIdentifier, _this.floorIdentifier).then(function (response) {\n\t\t\t \t//Init map\n\t\t\t\t\t$(\".container-loader\").hide();\n\t\t\t\t\t$(\"#beco-wrapper\").append(mapTemplate);\n\t\t\t\t\t//$(\"#beco-wrapper\").append(menuTemplate);\n\t\t\t\t\t_this.initMap(response.data);\n\t\t\t\t\t$( \"body\" ).append(legendTemplate);\n\t\t\t\t\t$( \"body\" ).append(headerTemplate);\n\t\t\t\t\t$( \"body\" ).append(feedBackTemplate);\n\t\t\t\t\t$(\".error-parent\").hide();\n\t\t\t\t\t$(\".success-or-error\").hide();\n\t\t\t\t\t_this.buildAccountMenu();\n\n\t\t\t\t\tif (response.data.write){\n\t\t\t\t $( \"#save-data\" ).bind( \"click\", function(event) {\n\t\t\t\t event.preventDefault();\n\t\t\t\t _this.saveData();\n\t\t\t\t });\n\t\t\t \t} else {\n\t\t\t \t\t$( \"#save-data\" ).hide();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t$(\"#feedbackSubmit\").bind( \"click\" ,function(event){\n\t\t\t\t\t\tvar data = $(\"#message-text\").val();\n\t\t\t\t\t\t_this.saveFeedback(data);\n\t\t\t\t\t});\t\n\n\t\t\t\t\tsetTimeout(function(){ \n\t\t\t\t\t\tif(localStorage.getItem('guideUIcompleted')){\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t_this.showTutorial();\n\t\t\t\t\t\t} \n\t\t\t\t\t}, 1000);\n\t\t\t\t\t\n\t\t\t\t\t$(document).on('click',\".driver-close-btn\", function(){\n\t\t\t\t\t\tlocalStorage.setItem('guideUIcompleted',true);\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t }).catch(function (error) {\n\t\t\t\t $(\"#beco-loader\").hide();\n\t\t\t\t\t$(\"#beco-error\").show();\n\t\t\t\t\tif(error.status = 403){\n\t\t\t\t\t\t$(\"#beco-text\").text(t('permission-failed'));\n\t\t\t\t\t}else {\n\t\t\t\t\t\t$(\"#beco-text\").text(t('invalid-site-config'));\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t});\n\n\t\t\t\t\n\n\t\t\t});\n\t\t\t \n\t\t\t\n\t\t\t\n\t\t}\n\t}\n\n\tinitMap(siteData) {\n\t\tthis.map = new BeCoMap(siteData,this.api);\n\t\tthis.map.init();\n\t\tthis.getData(siteData);\n\t\t//this.attachObserver(); This need to sync data to firebase\n\t}\n\n\tcheckRequestparams(){\n\t\t \n\t\ttry {\n \t\t\tthis.siteIdentifier = getSiteIdentifier();\n\t\t}\n\t\tcatch(err) {\n\t \t\tconsole.log(err);\n\t\t} \n\n\t\ttry {\n \t\t\tthis.floorIdentifier = getFloorIdentifier();\n\t\t}\n\t\tcatch(err) {\n\t \t\tconsole.log(err);\n\t\t} \n\n\t\treturn this.siteIdentifier && this.floorIdentifier;\n\t}\n\n\tgetMap(){\n\t\treturn this.map;\n\t}\n\n\tsaveData(){\n\t\tif (this.buildInFlight) return;\n\t\tthis.buildInFlight = true;\n\t\t$(\"#save-data\").removeClass('btn-beco-save');\n\t\t$(\"#save-data\").addClass('btn-beco-saved');\n\n\t\tlet data = this.map.getFeatures();\n\t\tvar _this = this;\n\t\tthis.api.saveMapData(this.siteIdentifier, this.floorIdentifier,data).then(function (response) {\n\t\t\t\n\t\t\tif(response.status==210){\n\t\t\t\t$(\"#save-error\").append(\"
\"+t('connected-floor-save-error')+\"
\");\n\t\t\t\t// alert(t('connected-floor-save-error'));\n\t\t\t} else if(response.status==211){\n\t\t\t\t$(\"#save-error\").append(\"\"+t('floor-build-in-progrss')+\"
\");\n\t\t\t\t// alert(t('floor-build-in-progrss'));\n\t\t\t} else if(response.status==212){\n\t\t\t\t$(\"#save-error\").append(\"\"+t('save-error-invalid-floor')+\"
\");\n\t\t\t\t// alert(t('save-error-invalid-floor'));\n\t\t\t} else if(response.status==209){\n\t\t\t\t$(\"#save-error\").append(\"\"+result.data.email+\" is editing this floor
\");\n\t\t\t\t// alert(result.data.email+\" is editing this floor\");\n\t\t\t}else if(response.status==200){\n\t\t\t\t$(\"#update_text\").html(\"Last saved by \"+response.data.updated_by_user+\" at \");\n\t\t\t\t$(\"#update_time\").html(toLocalTimeZone( Date.now() ));\n\t\t\t}\n\t\t\t_this.buildInFlight = false;\n\n\t\t\t$(\"#save-data\").removeClass('btn-beco-saved');\n\t\t\t$(\"#save-data\").addClass('btn-beco-save');\t\n\t\t\tsetTimeout(function() {\n\t\t \t$(\"#save-error\").children().first().remove();\n\t\t\t}, 5000);\n\t\t\t\t\t\n\t }).catch(function (error) {\n\t\t\t_this.buildInFlight = false;\n\t\t\t$(\"#save-error\").append(\"\"+t('save-error-exception')+\"
\");\n\t\t\t$(\"#save-data\").removeClass('btn-beco-saved');\n\t\t\t$(\"#save-data\").addClass('btn-beco-save');\n\t\t\tsetTimeout(function() {\n\t\t \t$(\"#save-error\").children().first().remove();\n\t\t\t}, 5000);\n\t\t});\n\n\n\t\t\n\t\t//const result = await this.api.saveData(this.siteIdentifier, this.floorIdentifier, data);\n\t\t\n\t\t\n\t\t \n\t\t// this.buildInFlight = false;\n\n\t\t// $(\"#save-data\").removeClass('btn-beco-saved');\n\t\t// $(\"#save-data\").addClass('btn-beco-save');\n\t}\n\n\tasync saveFeedback(feedback){\n\t\tconst result = await this.api.saveFeedback(this.siteIdentifier, feedback);\n\t\t$(\"#message-text\").val('');\n\t\t$(\".feedback-form\").hide();\n\t\t$(\".success-or-error\").show();\n\t\tif(result == 200){\n\t\t\t$(\".success-parent\").show();\n\t\t\tsetTimeout(function(){ \n\t\t\t\t$(\"#myModal\").modal('toggle');\n\t\t\t\t$(\".success-parent\").hide();\n\t\t\t\t$(\".feedback-form\").show();\n\t\t\t\t$(\".success-or-error\").hide();\n\t\t\t}, 2000);\n\t\t}else{\n\t\t\t$(\".success-parent\").hide();\n\t\t\t$(\".error-parent\").show();\n\t\t\tsetTimeout(function(){ \n\t\t\t\t$(\"#myModal\").modal('toggle');\n\t\t\t\t$(\".error-parent\").hide();\n\t\t\t\t$(\".feedback-form\").show();\n\t\t\t\t$(\".success-or-error\").hide();\n\t\t\t}, 2000);\n\n\t\t}\n\t\t\n\t}\n\n\tasync getData(siteData){\n\t\tconst result = await this.api.getData(this.siteIdentifier, this.floorIdentifier);\n\t\tif(result.map_data) this.map.setData(result.map_data);\n\t\tif(result.mod_time){\n\t\t\t(result.build_status) ? $(\"#update_text\").html(\"Last built by \"+result.updated_by_user+\" at \") : $(\"#update_text\").html(\"Last saved by \"+result.updated_by_user+\" at \");\n\t\t\t$(\"#update_time\").html(toLocalTimeZone(result.mod_time));\n\t\t}\n\t\telse{\n\t\t\t$(\"#update_text\").html();\n\t\t\t$(\"#update_time\").html();\n\t\t}\n\t\t\n\t\tif (siteData.write) this.map.initControls();\n\n\t}\n\n\tbuildAccountMenu(){\n\t\tconst markup = `\n\t\t\t${menu.account.name}\n ${menu.sites.name}\n ${menu.docs.name}\n \n ${menu.support.name}\n ${menu.logout.name}\n\t\t\t`;\n\t\t$(\"#accounts-menu\").html(markup);\n\n\t}\n\n\tattachObserver(){\n\t\tdrawObserver.subscribe(updateMap);\n\t\tvar app = this;\n\t\twindow.setInterval(function(){\n\t\t\tdrawObserver.notify(app);\n\t\t},30000); \n\t}\n\n\tshowTutorial(){\n\t\tconst driver = new Driver({allowClose: false,animate: true,closeBtnText: '',nextBtnText: 'Next »',prevBtnText: '« Previous',});\n\t\t$('#select-button').parent().attr('id','select-c');\n\t\t$('#modify-button').parent().attr('id','modify-c');\n\t\t$('#node-config-button').parent().attr('id','node-config-c');\n\t\t$('#draw-route-button').parent().attr('id','draw-route-c');\n\t\t$('#draw-poly-button').parent().attr('id','draw-poly-c');\n\t\t$('#split-button').parent().attr('id','split-c');\n\n\t\t\n\t\t// Define the steps for introduction\n\t\tdriver.defineSteps([\n\t\t\t{\n\t\t\telement: '#select-c',\n\t\t\tstageBackground: 'transparent',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'first-step-popover-class select-c',\n\t\t\t\ttitle: 'Select',\n\t\t\t\tdescription: 'Select routes and delete routes',\n\t\t\t\tposition: 'right'\n\t\t\t},\n\t\t\tonClose: () => {localStorage.setItem('guideUIcompleted',true);},\n\t\t\t},\n\t\t\t{\n\t\t\telement: '#modify-c',\n\t\t\tstageBackground: 'transparent',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'modify-c',\n\t\t\t\ttitle: 'Modify',\n\t\t\t\tdescription: 'Click and drag to change or modify position of nodes.',\n\t\t\t\tposition: 'right'\n\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\telement: '#node-config-c',\n\t\t\tstageBackground: 'transparent',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'node-config-c',\n\t\t\t\ttitle: 'Node Config',\n\t\t\t\tdescription: 'Configure nodes. Attribute point, becon or both to the respective node.',\n\t\t\t\tposition: 'right'\n\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\telement: '#draw-route-c',\n\t\t\tstageBackground: 'transparent',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'draw-route-c',\n\t\t\t\ttitle: 'Draw Route',\n\t\t\t\tdescription: 'Plot routes on the given map.',\n\t\t\t\tposition: 'right'\n\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\telement: '#draw-poly-c',\n\t\t\tstageBackground: 'transparent',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'draw-poly-c',\n\t\t\t\ttitle: 'Polygon',\n\t\t\t\tdescription: 'Draw and mark areas.',\n\t\t\t\tposition: 'right'\n\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\telement: '#split-c',\n\t\t\tstageBackground: 'transparent',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'split-c',\n\t\t\t\ttitle: 'Route Points',\n\t\t\t\tdescription: 'Add additional points between two nodes.',\n\t\t\t\tposition: 'right'\n\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\telement: '#save-data',\n\t\t\tstageBackground: '#fff',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'save-data-c',\n\t\t\t\ttitle: 'Save',\n\t\t\t\tdescription: 'Save current modification on the map apart from auto save.',\n\t\t\t\tposition: 'left'\n\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\telement: '#profile-c',\n\t\t\tstageBackground: '#fff',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'profile-c',\n\t\t\t\ttitle: 'Profile',\n\t\t\t\tdescription: 'User/organisation infromations.',\n\t\t\t\tposition: 'left'\n\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\telement: '.map-legend',\n\t\t\tstageBackground: 'transparent',\n\t\t\tpopover: {\n\t\t\t\tclassName: 'map-legend-c',\n\t\t\t\ttitle: 'Map Legend',\n\t\t\t\tdescription: 'Map style and icon information.',\n\t\t\t\tposition: 'left'\n\t\t\t},\n\t\t\tonNext: () => {localStorage.setItem('guideUIcompleted',true);},\n\t\t\t},\n\t\t]);\n\t\t\n\t\t// Start the introduction\n\t\tdriver.start();\n\n\t}\n\n}","import _ from 'underscore';\nimport Map from 'ol/Map.js';\nimport {defaults as defaultControls, Attribution} from 'ol/control.js';\nimport {Vector as VectorLayer} from 'ol/layer.js';\nimport VectorSource from 'ol/source/Vector.js';\nimport GeoJSON from 'ol/format/GeoJSON';\nimport LineString from 'ol/geom/LineString';\nimport Projection from 'ol/proj/Projection.js';\nimport View from 'ol/View.js';\nimport {getCenter} from 'ol/extent.js';\n\nimport LayerSwitcher from 'ol-ext/control/LayerSwitcher';\nimport '../../styles/switcher/switcher.scss';\n\nimport Floors from '../models/floor/model.js';\nimport DrawControl from '../models/layer/control/model.js';\nimport Menu from '../models/layer/menu/model.js';\nimport LineMenu from '../models/layer/menu/lineConfigMenu.js';\nimport Grid from '../models/grid/model.js';\nimport { target, toolbarConfig } from './projection.js';\nimport Beacon from '../models/layer/menu/beacon.js';\n\n\nexport default class BeCoMap {\n\n\tconstructor(siteData, api){\n \n \n \n this.map = null;\n this.menu;\n this.lineMenu;\n this.projection;\n this.view;\n this.vectorDrawLayer = null;\n this.vectorNodeLayer = null;\n this.vectorPolygonLayer = null;\n this.defaultControl = new DrawControl();\n this.siteData = siteData;\n this.api = api;\n this.extent = siteData.extent;\n this.imageSize = siteData.img_size;\n this.initProjection();\n this.initView();\n this.floors = new Floors(siteData['floors'],siteData['current_map'],siteData['floor_identifier'],\n this.projection,this.imageSize,this.extent);\n this.grid = new Grid(this.projection,this.imageSize,this.extent);\n this.floors.init();\n }\n\n initProjection(){\n this.projection = new Projection({\n code: 'xkcd-image',\n units: 'pixels',\n extent: this.extent,\n axisOrientation:'ene'\n });\n }\n\n initView(){\n this.view = new View({\n projection: this.projection,\n center: getCenter(this.extent),\n extent: this.extent,\n zoom: 2,\n minZoom: 2,\n maxZoom: 8\n });\n }\n\n // initialize plugin\n init() {\n $(\"#beco-container\").css(\"background-color\",this.siteData['bg_color']);\n var defaultControl = this.defaultControl;\n this.vectorDrawLayer = new VectorLayer({\n title : \"Draw Layer\",\n displayInLayerSwitcher: false,\n source: new VectorSource({\n features: []\n }),\n style: function(f) {\n return defaultControl.getStyle(f);\n }\n });\n\n this.vectorPolygonLayer = new VectorLayer({\n title : \"Polygon Layer\",\n displayInLayerSwitcher: false,\n opacity : 0.5,\n source: new VectorSource({\n features: []\n }),\n style: function(f) {\n return defaultControl.getAreaStyle(f);\n }\n });\n\n this.vectorNodeLayer = new VectorLayer({\n title : \"Node Layer\",\n displayInLayerSwitcher: false,\n source: new VectorSource({\n features: []\n }),\n style: function(f) {\n return defaultControl.getNodeStyle(f);\n }\n });\n\n\n \n \tthis.map = new Map({\n layers : this.getLayers(),\n\t\t target: target,\n\t\t view: this.view,\n \t\tcontrols: this.showButtons(),\n \t});\n\n \n this.map.once('rendercomplete', function(event) {\n //console.log(event);\n //console.log(\"rendercomplete\");\n });\n if(this.siteData.write ) {\n var ctrl = new LayerSwitcher();\n this.map.addControl(ctrl);\n }\n \n\n this.menu = new Menu(this.map, this.api, this.siteData);\n this.lineMenu = new LineMenu();\n \n this.map.on('singleclick', function (evt) {\n console.log(evt.coordinate);\n\n // convert coordinate to EPSG-4326\n });\n\n }\n\n initControls(){\n this.defaultControl.addControls(Object.assign({\n layer : this.vectorDrawLayer,\n nodeLayer : this.vectorNodeLayer,\n polygonLayer : this.vectorPolygonLayer,\n map : this.map,\n menu : this.menu,\n lineMenu : this.lineMenu,\n },toolbarConfig(this.siteData['plan'])));\n }\n\n getLayers() {\n var tileSource = Object.assign([],[this.floors.getTileSource()]);\n tileSource.push(this.vectorDrawLayer,this.vectorNodeLayer,this.vectorPolygonLayer);\n //if(this.siteData.write ) tileSource.push(this.grid.getGridLayer());\n\n return tileSource;\n }\n\n getMapTileLabels(){\n var layerArray = this.map.getLayers().getArray();\n var mapTile = [];\n _(layerArray).each(function (layer) {\n if(layer.getProperties().displayInLayerSwitcher){\n mapTile.push(layer.getProperties());\n }\n });\n return mapTile;\n }\n\n showButtons() {\n \tvar control = defaultControls({\n\t attributionOptions: ({\n\t collapsible: false\n\t })\n \t});\n \treturn control;\n }\n\n getMap() {\n \treturn this.map;\n }\n\n \n setData(mapData){\n let line = this.vectorDrawLayer.getSource();\n let node = this.vectorNodeLayer.getSource();\n let polygon = this.vectorPolygonLayer.getSource();\n var nodePoints = [];\n var becons = [];\n var format = new GeoJSON({\n featureProjection: this.projection,\n extractGeometryName : true\n });\n line.addFeatures(format.readFeatures(mapData.line));\n node.addFeatures(format.readFeatures(mapData.node));\n if(mapData.polygon){\n polygon.addFeatures(format.readFeatures(mapData.polygon));\n }\n _(format.readFeatures(mapData.node)).each(function (feature) { \n if(feature.getProperties() && feature.getProperties().location){\n nodePoints.push(feature.getProperties().location.name); \n }\n\n if(feature.getProperties() && feature.getProperties().beacon){\n var props = {\n name : feature.getProperties().beacon.name,\n major : feature.getProperties().beacon.major,\n minor : feature.getProperties().beacon.minor,\n uuid : feature.getProperties().beacon.uuid\n };\n \n let beacon = new Beacon(props);\n becons.push(beacon);\n }\n });\n\n this.menu.setPoints(nodePoints);\n this.menu.setBeacon(becons);\n }\n\n getFeatures() {\n const format = new GeoJSON({featureProjection: this.projection});\n\n let line = this.vectorDrawLayer.getSource().getFeatures();\n let node = this.vectorNodeLayer.getSource().getFeatures();\n let polygon = this.vectorPolygonLayer.getSource().getFeatures();\n _(node).each(function(feature){\n if(feature.getProperties().geometry){\n feature.unset('undefined');\n }\n });\n\n\n \n return ({\n \"line\" : format.writeFeatures(line, {decimals: 10}),\n \"node\" : format.writeFeatures(node, {decimals: 10}),\n \"polygon\" : format.writeFeatures(polygon,{decimals:10}),\n });\n }\n\n}\n\n","import _ from 'underscore';\nimport ImageLayer from 'ol/layer/Image.js';\nimport Static from 'ol/source/ImageStatic.js';\nimport { attributionHtml } from '../../map/projection.js';\n\nexport default class Floors {\n\n\t constructor(floors, floorTile, currentFloor,projection,imageSize,extent) {\n\n \t this.name = 'Floors';\n this.floors = floors;\n this.projection = projection;\n this.extent = extent;\n this.imageSize = imageSize;\n this.floor = currentFloor;\n this.floorTileSource;\n this.floorTile = floorTile;\n this.floorMap = new Map();\n var _this = this;\n _(floors).each(function(floor){\n _this.floorMap.set(floor.value,floor);\n }); \n\n \t}\n\n \ttoString() {\n return this.name;\n }\n\n \tinit() {\n var floor = this.floorMap.get(this.floor);\n this.floorTileSource = new ImageLayer({\n title: floor.label,\n displayInLayerSwitcher: false,\n tileId : floor.value,\n source: new Static({\n attributions: attributionHtml(),\n url: this.floorTile,\n imageSize: this.imageSize,\n projection: this.projection,\n imageExtent: this.extent,\n })\n });\n\n \t}\n\n \tgetFloors() {\n return this.floors;\n \t}\n\n getFloor(floorIdentifier) {\n return this.floorMap.get(floorIdentifier);\n }\n\n getTileSource(){\n return this.floorTileSource;\n }\n\n\n}","import _ from 'underscore';\n\nimport {Circle as CircleStyle , Style, Fill, Stroke, RegularShape, Text, Icon} from 'ol/style.js';\nimport Select from 'ol/interaction/Select';\nimport click from 'ol/events/condition';\nimport Draw from 'ol/interaction/Draw';\nimport Modify from 'ol/interaction/Modify';\nimport LineString from 'ol/geom/LineString';\nimport Polygon from 'ol/geom/Polygon';\nimport Snap from 'ol/interaction/Snap';\nimport MultiPoint from 'ol/geom/MultiPoint';\nimport Feature from 'ol/Feature';\nimport Point from 'ol/geom/Point';\nimport doubleClick from 'ol/events/condition';\n\nimport Bar from 'ol-ext/control/Bar';\nimport EditBar from 'ol-ext/control/EditBar';\nimport Delete from 'ol-ext/interaction/Delete';\nimport Button from 'ol-ext/control/Button';\nimport Toggle from 'ol-ext/control/Toggle';\nimport TextButton from 'ol-ext/control/TextButton';\nimport Split from 'ol-ext/interaction/Split';\nimport UndoRedo from './undoredo';\nimport ModifyFeature from 'ol-ext/interaction/ModifyFeature';\nimport Splitter from 'ol-ext/interaction/Splitter';\n\nimport Menu from '../menu/model.js';\nimport PointMenu from '../menu/pointMenu.js';\n\n\nimport '../../../../styles/bar/bar.css';\nimport '../../../../styles/bar/edit.css';\nimport '../../../../styles/icomoon/style.css';\n\nconst uniqueArray = a => [...new Set(a.map(o => JSON.stringify(o)))].map(s => JSON.parse(s));\n\nexport default class DrawControl {\n\n\t constructor() {\n this.name = 'DrawControl';\n this.mainbar = new Bar({\n className : 'ol-editbar',\n toggleOne : true\n });\n this.position = \"top-left\";\n this.map;\n this._source;\n this._nodeSource;\n this._layer;\n this._menu;\n this._nodeLayer;\n this._interactions = {};\n this.pointmap = new Map();\n \t}\n\n \ttoString() {\n return this.name;\n }\n\n getMap() {\n return this.map;\n }\n\n\n addPointControl(){\n this._interactions.DrawPoint = new Draw({\n type: 'Point',\n source: this._source\n });\n\n var pedit = new Toggle({\n html: 'Asset',\n title: 'Asset',\n interaction: this._interactions.DrawPoint\n });\n this.mainbar.addControl(pedit);\n }\n\n getCoordinateIdentifier(x,y){\n return x>=y ? ((x * x)+x+y) :(x+(y * y));\n }\n\n addModifyControl(){\n this._interactions.Modify = new Modify({\n source: this._source,\n });\n\n this._interactions.Modify.on('modifyend', function(e) {\n //TODO update time\n //https://gis.stackexchange.com/questions/175784/openlayers-3-how-to-get-only-the-modified-feature\n });\n\n var pmodify = new Toggle({\n html: 'Modify',\n //className: 'ol-drawhole',\n title: 'Modify',\n interaction: this._interactions.Modify\n });\n this.mainbar.addControl(pmodify);\n }\n\n addPropertiesControl(){\n \n var _this = this;\n this._interactions.NodeSelect = new Select({\n condition: doubleClick,\n style : this.getSelectedNodeStyle(),\n layers : [this._nodeLayer]\n });\n var sel = this._interactions.NodeSelect;\n var selectCtrl = new Toggle({\n html: 'Node Config',\n title: \"Node Config\",\n interaction: sel\n });\n\n sel.on('change:active', function() {\n sel.getFeatures().clear();\n });\n\n sel.on('select', function(evt){\n if(evt.selected.length > 0){\n _this._menu.open(evt.selected[0], sel); }\n });\n\n this.mainbar.addControl(selectCtrl);\n }\n\n addLinepropertiesControl(){\n \n var _this = this;\n this._interactions.LineSelect = new Select({\n condition: doubleClick,\n style : this.getSelectedStyle(),\n layers : [this._layer]\n });\n var sel = this._interactions.LineSelect;\n var selectCtrl = new Toggle({\n html: 'Route Config',\n title: \"Route Config\",\n interaction: sel\n });\n\n sel.on('change:active', function() {\n sel.getFeatures().clear();\n });\n\n sel.on('select', function(evt){\n if(evt.selected.length > 0){\n _this._lineMenu.open(evt.selected[0], sel); }\n });\n\n this.mainbar.addControl(selectCtrl);\n }\n\n addSelectControl(){\n // Sub bar\n var sbar = new Bar();\n var selectCtrl;\n this._interactions.Delete = new Delete();\n var del = this._interactions.Delete;\n del.setActive(false);\n if (this.getMap()) this.getMap().addInteraction(del);\n\n sbar.addControl (new Button({\n html: '',\n // className: 'ol-delete',\n title: \"Delete\",\n handleClick: function(e) {\n // Delete selection\n del.delete(selectCtrl.getInteraction().getFeatures());\n var evt = {\n type: 'select',\n selected: [],\n deselected: selectCtrl.getInteraction().getFeatures().getArray().slice(),\n mapBrowserEvent: e.mapBrowserEvent\n };\n selectCtrl.getInteraction().getFeatures().clear();\n selectCtrl.getInteraction().dispatchEvent(evt);\n }\n }));\n\n\n this._interactions.Select = new Select({\n condition: click,\n style : this.getSelectedStyle(),\n layers : [this._layer,this._polygonLayer]\n });\n var sel = this._interactions.Select;\n selectCtrl = new Toggle({\n className: 'have-submenu',\n html: 'Select',\n title: \"Select\",\n interaction: sel,\n bar: sbar.getControls().length ? sbar : undefined,\n autoActivate:true,\n active:true\n });\n\n sel.on('change:active', function() {\n sel.getFeatures().clear();\n });\n\n this.mainbar.addControl(selectCtrl);\n }\n\n _setModifyInteraction(){\n this._interactions.ModifySelect = new ModifyFeature({\n features: this.getInteraction('Select').getFeatures()\n });\n \n if (this.getMap()) this.getMap().addInteraction(this._interactions.ModifySelect);\n // Activate with select\n this._interactions.ModifySelect.setActive(this._interactions.Select.getActive());\n this._interactions.Select.on('change:active', function() {\n this._interactions.ModifySelect.setActive(this._interactions.Select.getActive());\n }.bind(this));\n }\n\n addLineControl(){\n\n this._interactions.DrawLine = new Draw ({\n type: 'LineString',\n source: this._source,\n geometryName : 'LineString',\n // Count inserted points\n geometryFunction: function(coordinates, geometry) {\n if (geometry) geometry.setCoordinates(coordinates);\n else geometry = new LineString(coordinates);\n this.nbpts = geometry.getCoordinates().length;\n return geometry;\n }\n });\n\n var ledit = new Toggle({\n className: 'have-submenu',\n html: 'Draw Route',\n title: 'Draw Route',\n interaction: this._interactions.DrawLine,\n // Options bar associated with the control\n bar: new Bar ({\n controls:[ \n new TextButton({\n html: '',\n // className: 'ol-undo',\n title: \"delete last point\",\n handleClick: function() {\n if (ledit.getInteraction().nbpts>1) ledit.getInteraction().removeLastPoint();\n }\n }),\n new TextButton ({\n // className: 'ol-finish',\n html: '',\n title: \"finish\",\n handleClick: function() {\n // Prevent null objects on finishDrawing\n if (ledit.getInteraction().nbpts>2) ledit.getInteraction().finishDrawing();\n }\n })\n ]\n }) \n });\n\n this.mainbar.addControl(ledit);\n }\n\n _setDrawPolygon(className, interaction, title){\n var fedit = new Toggle ({\n className: 'have-submenu',\n html: 'Polygon',\n title: title,\n interaction: interaction,\n // Options bar associated with the control\n bar: new Bar({\n controls:[ \n new TextButton ({\n html: '',\n title: 'undo last point',\n handleClick: function(){\n if (fedit.getInteraction().nbpts>1) fedit.getInteraction().removeLastPoint();\n }\n }),\n new TextButton({\n html: '',\n title: 'finish',\n handleClick: function() {\n // Prevent null objects on finishDrawing\n if (fedit.getInteraction().nbpts>3) fedit.getInteraction().finishDrawing();\n }\n })\n ]\n }) \n });\n this.mainbar.addControl(fedit);\n }\n\n addPolygonControl(){\n this._interactions.DrawPolygon = new Draw ({\n type: 'Polygon',\n source: this._polygonSource,\n // Count inserted points\n geometryFunction: function(coordinates, geometry) {\n this.nbpts = coordinates[0].length;\n if (geometry) geometry.setCoordinates([coordinates[0].concat([coordinates[0][0]])]);\n else geometry = new Polygon(coordinates);\n return geometry;\n }\n });\n this._setDrawPolygon(\n 'ol-drawpolygon', \n this._interactions.DrawPolygon, \n 'Polygon'\n );\n }\n\n\n addSplitControl(){\n this._interactions.Split = new Split ({\n sources: this._source\n });\n var split = new Toggle ({\n // className: 'ol-split',\n html: 'Route Points',\n title: 'Route Points',\n interaction: this._interactions.Split\n });\n this.mainbar.addControl(split);\n }\n\n getInteraction(name){\n return this._interactions[name];\n }\n\n \taddUndoRedoControl(){\n var _this = this;\n \t this._interactions.UndoRedo = new UndoRedo ();\n if (this.getMap()) this.getMap().addInteraction(this._interactions.UndoRedo);\n // Prevent selection of a deleted feature\n this._interactions.UndoRedo.on('undo', function(e) {\n // console.log(e);\n if (e.action.type === 'addfeature') {\n _this.getInteraction('Select').getFeatures().clear();\n //_this.getInteraction('Transform').select();\n }\n });\n\n // Add buttons to the bar\n var bar = new Bar({ \n group: true,\n controls: [\n new Button({\n html: 'Undo',\n title: 'undo...',\n handleClick: function() {\n _this._interactions.UndoRedo.undo();\n }\n }),\n new Button({\n html: 'Redo',\n title: 'redo...',\n handleClick: function() {\n _this._interactions.UndoRedo.redo();\n }\n })\n ]\n });\n this.mainbar.addControl(bar);\n }\n \n getNodeStyle(feature){\n\n var fillColor = \"#26ace3\";\n if(feature.getProperties()){\n if(feature.getProperties().location && feature.getProperties().beacon){\n fillColor = \"#4A8C7A\";\n } else {\n if(feature.getProperties().location){\n fillColor = \"#546EB3\";\n }else if(feature.getProperties().beacon){\n fillColor = \"#8F7E8C\";\n }\n }\n }\n \n var pointName = \"\";\n if(feature.get(PointMenu.getPointVariable) && feature.get(PointMenu.getPointVariable).visible){\n pointName = feature.get(PointMenu.getPointVariable).name ;\n }\n return new Style({\n image: new CircleStyle({\n radius: 6,\n fill: new Fill({ color: fillColor }),\n stroke: new Stroke({\n color: '#adccd9',\n width: 1.5\n })\n }),\n text: new Text({\n offsetY: 13,\n text: pointName,\n font: 'bold 10px Open Sans,sans-serif',\n fill: new Fill({ color: '#666666' }),\n stroke: new Stroke({ color: '#666666', width: 0.5 })\n })\n });\n }\n\n getLabelstyle() {\n return new Style({\n text: new Text({\n font: 'normal 12px \"Open Sans\", \"Arial\", \"sans-serif\"',\n placement: 'line',\n fill: new Fill({\n color: '#FFFFFF'\n }),\n stroke: new Stroke({color: \"#5D5755\", width: 3}),\n overflow: true,\n })\n });\n }\n\n getSelectedNodeStyle(){\n return new Style({\n image: new CircleStyle({\n radius: 8,\n fill: new Fill({ color: '#de837a' }),\n stroke: new Stroke({\n color: '#de837a',\n width: 1\n })\n })\n });\n }\n\n getStyle(feature){\n var geometry = feature.getGeometry();\n var styles = [\n new Style({\n stroke: new Stroke({ color: '#adccd9',width: 6 }),\n fill: new Fill({ color: '#adccd9' }),\n })\n ];\n\n if(feature.getProperties().label){\n if(geometry.getType() == 'LineString'){\n styles.push(new Style({\n geometry: geometry,\n text: new Text({\n font: 'normal '+feature.getProperties().labelTextSize+'px \"Open Sans\", \"Arial\", \"sans-serif\"',\n placement: 'line',\n text:feature.getProperties().label,\n fill: new Fill({\n color: feature.getProperties().labelTextColor\n }),\n stroke: new Stroke({color: feature.getProperties().labelBorderColor, width: 3}),\n overflow: true,\n })\n }));\n }\n \n }\n if(feature.getProperties().direction){\n geometry.forEachSegment(function(start, end) {\n\n var dx, dy;\n if(feature.getProperties().direction == 1){\n dx = end[0] - start[0];\n dy = end[1] - start[1];\n }else {\n dx = start[0] - end[0];\n dy = start[1] - end[1];\n }\n \n var rotation = Math.atan2(dy, dx);\n\n var midPoint = [((start[0] + end[0]) / 2), ((start[1] + end[1]) / 2)];\n // arrows\n styles.push(new Style({\n geometry: new Point(midPoint),\n image: new Icon({\n src: 'public/images/arrow.png',\n anchor: [0.75, 0.5],\n rotateWithView: true,\n rotation: -rotation\n })\n }));\n });\n }\n\n return styles;\n }\n\n getAreaStyle(feature){\n return [\n new Style({\n stroke: new Stroke({ color: '#adccd9',width: 6 }),\n fill: new Fill({ color: '#df4a43' }),\n }),\n ];\n }\n\n getSelectedStyle(){\n return [\n new Style({\n stroke: new Stroke({ color: '#de837a',width: 6 }),\n fill: new Fill({ color: '#de837a' }),\n }),\n ];\n }\n\n /**\n * Add different draw controls to the Map.\n * First 2 only for reference : TODO remove on final build\n * @param {import {Vector as VectorLayer} from 'ol/layer.js';} Vector\n * Vector data that is rendered client-side.\n * @param {import Map from 'ol/Map.js';} map\n * Core Map layer.\n * @param {options} map\n * Settings for the draw controls.\n */\n addControls(options){\n options = options || {};\n this.map = options.map;\n this._layer = options.layer;\n this._nodeLayer = options.nodeLayer;\n this._source = options.layer.getSource();\n this._polygonSource = options.polygonLayer.getSource();\n this._polygonLayer = options.polygonLayer;\n this._nodeSource = options.nodeLayer.getSource();\n this._menu = options.menu;\n this._lineMenu = options.lineMenu;\n\n this.mainbar.setPosition(this.position);\n \n if (options.select == true) { \n this.addSelectControl();\n this._setModifyInteraction();\n }\n if (options.modify == true) { \n this.addModifyControl();\n }\n if (options.point == true) { \n //this.addPointControl();\n }\n this.addPropertiesControl();\n this.addLinepropertiesControl();\n if (options.line == true) { \n this.addLineControl();\n }\n if (options.polygon == true) { \n this.addPolygonControl();\n }\n if (options.split == true) { \n this.addSplitControl();\n }\n if (options.undo == true) { \n this.addUndoRedoControl();\n }\n\n\n var _this = this;\n this._source.on('change', function(event) {\n //console.log(\"change: \", event.target.getFeatures());\n const points = [];\n\n _(_this._nodeSource.getFeatures()).each(function (feature) {\n if(feature.getProperties()){\n if(feature.getProperties().location || feature.getProperties().beacon){\n var pt = feature.getGeometry().getCoordinates();\n var id = _this.getCoordinateIdentifier(pt[0], pt[1]);\n _this.pointmap.set(id,feature.getProperties());\n }\n }\n \n });\n\n _this._nodeSource.clear();\n _(event.target.getFeatures()).each(function (feature) {\n if(feature.getGeometry().getType() == 'LineString'){\n points.push(...feature.getGeometry().getCoordinates());\n }\n });\n\n \n\n _(uniqueArray(points)).each(function (point) {\n var feature = new Feature(\n new Point(point)\n );\n var id = _this.getCoordinateIdentifier(point[0], point[1]);\n if(_this.pointmap.get(id)){\n feature.setProperties(_this.pointmap.get(id));\n }\n _this._nodeSource.addFeature(feature);\n });\n\n\n });\n \t\n //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set\n // Add splitter before other interaction\n var splitter = new Splitter({ source: this._source });\n this.map.addInteraction(splitter);\n\n\n this.map.addControl(this.mainbar);\n\n this.map.addInteraction(new Snap({ \n source: options.layer.getSource() \n }));\n\n this.map.on('pointermove', function(event) {\n var hasFeature = _this.map.forEachFeatureAtPixel(_this.map.getEventPixel(event.originalEvent), function(feature) {\n return true ;\n });\n\n this.getTargetElement().style.cursor = hasFeature ? 'pointer' : '';\n });\n\n }\n\n\n}","import ol_ext_inherits from 'ol-ext/util/ext';\nimport ol_interaction_Interaction from 'ol/interaction/Interaction';\nimport ol_layer_Vector from 'ol/layer/Vector';\nimport {unByKey as ol_Observable_unByKey} from 'ol/Observable';\nimport 'ol-ext/source/Vector';\n\n/** Undo/redo interaction\n * @constructor\n * @extends {ol_interaction_Interaction}\n * @fires undo\n * @fires redo\n * @param {*} options\n */\nvar ol_interaction_UndoRedo = function(options) {\n if (!options) options = {};\n\n\tol_interaction_Interaction.call(this, {\t\n handleEvent: function() { \n return true; \n }\n });\n\n this._undoStack = [];\n this._redoStack = [];\n // Block counter\n this._block = 0;\n // Start recording\n this._record = true;\n // Custom definitions\n this._defs = {};\n};\nol_ext_inherits(ol_interaction_UndoRedo, ol_interaction_Interaction);\n\n/** Add a custom undo/redo\n * @param {string} action the action key name\n * @param {function} undoFn function called when undoing\n * @param {function} redoFn function called when redoing\n * @api\n */\nol_interaction_UndoRedo.prototype.define = function(action, undoFn, redoFn) {\n this._defs['_'+action] = { undo: undoFn, redo: redoFn };\n};\n\n/** Set a custom undo/redo\n * @param {string} action the action key name\n * @param {any} prop an object that will be passed in the undo/redo fucntions of the action\n * @return {boolean} true if the action is defined\n */\nol_interaction_UndoRedo.prototype.push = function(action, prop) {\n if (this._defs['_'+action]) {\n this._undoStack.push({type: '_'+action, prop: prop });\n return true;\n } else {\n return false;\n }\n};\n\n/** Activate or deactivate the interaction, ie. records or not events on the map.\n * @param {boolean} active\n * @api stable\n */\nol_interaction_UndoRedo.prototype.setActive = function(active) {\n ol_interaction_Interaction.prototype.setActive.call (this, active);\n this._record = active;\n};\n\n/**\n * Remove the interaction from its current map, if any, and attach it to a new\n * map, if any. Pass `null` to just remove the interaction from the current map.\n * @param {ol.Map} map Map.\n * @api stable\n */\nol_interaction_UndoRedo.prototype.setMap = function(map) {\n ol_interaction_Interaction.prototype.setMap.call (this, map);\n // Watch sources\n this._watchSources();\n this._watchInteractions();\n};\n\n/** Watch for changes in the map sources\n * @private\n */\nol_interaction_UndoRedo.prototype._watchSources = function() {\n var map = this.getMap();\n // Clear listeners\n if (this._sourceListener) {\n this._sourceListener.forEach(function(l) { ol_Observable_unByKey(l); });\n }\n this._sourceListener = [];\n\n // Ges vector layers \n function getVectorLayers(layers, init) {\n if (!init) init = [];\n layers.forEach(function(l) {\n if (l.values_.title != \"Node Layer\"){\n if (l instanceof ol_layer_Vector) {\n init.push(l);\n } else if (l.getLayers) {\n getVectorLayers(l.getLayers(), init);\n }\n }\n \n });\n return init;\n }\n\n if (map) {\n // Watch the vector sources in the map \n var vectors = getVectorLayers(map.getLayers());\n vectors.forEach((function(l) {\n var s = l.getSource();\n this._sourceListener.push( s.on(['addfeature', 'removefeature'], this._onAddRemove.bind(this)) );\n this._sourceListener.push( s.on('clearstart', this.blockStart.bind(this)) );\n this._sourceListener.push( s.on('clearend', this.blockEnd.bind(this)) );\n }).bind(this));\n\n // Watch new inserted/removed\n this._sourceListener.push( map.getLayers().on(['add', 'remove'], this._watchSources.bind(this) ) );\n }\n};\n\n/** Watch for interactions\n * @private\n */\nol_interaction_UndoRedo.prototype._watchInteractions = function() {\n var map = this.getMap();\n // Clear listeners\n if (this._interactionListener) {\n this._interactionListener.forEach(function(l) { ol_Observable_unByKey(l); });\n }\n this._interactionListener = [];\n\n if (map) {\n // Watch the interactions in the map \n map.getInteractions().forEach((function(i) {\n this._interactionListener.push(i.on(\n ['setattributestart', 'modifystart', 'rotatestart', 'translatestart', 'scalestart', 'deletestart', 'deleteend', 'beforesplit', 'aftersplit'], \n this._onInteraction.bind(this)\n ));\n }).bind(this));\n\n // Watch new inserted / unwatch removed\n this._interactionListener.push( map.getInteractions().on(\n ['add', 'remove'], \n this._watchInteractions.bind(this)\n ));\n }\n};\n\n/** A feature is added / removed\n */\nol_interaction_UndoRedo.prototype._onAddRemove = function(e) {\n if (this._record) {\n this._undoStack.push({type: e.type, source: e.target, feature: e.feature });\n this._redoStack = [];\n }\n};\n\nol_interaction_UndoRedo.prototype._onInteraction = function(e) {\n var fn = this._onInteraction[e.type];\n if (fn) fn.call(this,e);\n};\n\n/** Set attribute\n * @private\n */\nol_interaction_UndoRedo.prototype._onInteraction.setattributestart = function(e) {\n this.blockStart();\n var newp = Object.assign({}, e.properties);\n e.features.forEach(function(f) {\n var oldp = {};\n for (var p in newp) {\n oldp[p] = f.get(p);\n }\n this._undoStack.push({\n type: 'changeattribute', \n feature: f, \n newProperties: newp,\n oldProperties: oldp\n });\n }.bind(this));\n this.blockEnd();\n};\n\nol_interaction_UndoRedo.prototype._onInteraction.rotatestart = \nol_interaction_UndoRedo.prototype._onInteraction.translatestart = \nol_interaction_UndoRedo.prototype._onInteraction.scalestart = \nol_interaction_UndoRedo.prototype._onInteraction.modifystart = function (e) {\n this.blockStart();\n e.features.forEach(function(m) {\n this._undoStack.push({type: 'changefeature', feature: m, oldFeature: m.clone() });\n }.bind(this));\n this.blockEnd();\n};\n\n/** Start an undo block\n * @api\n */\nol_interaction_UndoRedo.prototype.blockStart = function () {\n this._undoStack.push({ type: 'blockstart' });\n this._redoStack = [];\n};\n\n/** @private\n */\nol_interaction_UndoRedo.prototype._onInteraction.beforesplit =\nol_interaction_UndoRedo.prototype._onInteraction.deletestart =\nol_interaction_UndoRedo.prototype.blockStart;\n\n/** End an undo block\n * @api\n */\nol_interaction_UndoRedo.prototype.blockEnd = function () {\n this._undoStack.push({ type: 'blockend' });\n};\n\n/** @private\n */\nol_interaction_UndoRedo.prototype._onInteraction.aftersplit =\nol_interaction_UndoRedo.prototype._onInteraction.deleteend =\nol_interaction_UndoRedo.prototype.blockEnd;\n\n/** handle undo/redo\n * @private\n */\nol_interaction_UndoRedo.prototype._handleDo = function(e, undo) {\n // Not active\n if (!this.getActive()) return;\n\n // Stop recording while undoing\n this._record = false;\n switch (e.type) {\n case 'addfeature': {\n if (undo) e.source.removeFeature(e.feature);\n else e.source.addFeature(e.feature);\n break;\n }\n case 'removefeature': {\n if (undo) e.source.addFeature(e.feature);\n else e.source.removeFeature(e.feature);\n break;\n }\n case 'changefeature': {\n var geom = e.feature.getGeometry();\n e.feature.setGeometry(e.oldFeature.getGeometry());\n e.oldFeature.setGeometry(geom);\n break;\n }\n case 'changeattribute': {\n var newp = e.newProperties;\n var oldp = e.oldProperties;\n for (var p in oldp) {\n if (oldp === undefined) e.feature.unset(p);\n else e.feature.set(p, oldp[p]);\n }\n e.oldProperties = newp;\n e.newProperties = oldp;\n break;\n }\n case 'blockstart': {\n this._block += undo ? -1 : 1;\n break;\n }\n case 'blockend': {\n this._block += undo ? 1 : -1;\n break;\n }\n default: {\n if (this._defs[e.type]) {\n if (undo) this._defs[e.type].undo(e.prop);\n else this._defs[e.type].redo(e.prop);\n } else {\n console.warn('[UndoRedoInteraction]: \"'+e.type.substr(1)+'\" is not defined.');\n }\n }\n }\n\n // Handle block\n if (this._block<0) this._block = 0;\n if (this._block) {\n if (undo) this.undo();\n else this.redo();\n }\n this._record = true;\n\n // Dispatch event\n this.dispatchEvent( { \n type: undo ? 'undo' : 'redo',\n action: e\n });\n};\n\n/** Undo last operation\n * @api\n */\nol_interaction_UndoRedo.prototype.undo = function() {\n var e = this._undoStack.pop();\n if (!e) return;\n this._redoStack.push(e);\n this._handleDo(e, true);\n};\n\n/** Redo last operation\n * @api\n */\nol_interaction_UndoRedo.prototype.redo = function() {\n var e = this._redoStack.pop();\n if (!e) return;\n this._undoStack.push(e);\n this._handleDo(e, false);\n};\n\n/** Clear undo stack\n * @api\n */\nol_interaction_UndoRedo.prototype.clear = function() {\n this._undoStack = [];\n this._redoStack = [];\n};\n\n/** Check if undo is avaliable\n * @return {number} the number of undo \n * @api\n */\nol_interaction_UndoRedo.prototype.hasUndo = function() {\n return this._undoStack.length;\n};\n\n/** Check if redo is avaliable\n * @return {number} the number of redo\n * @api\n */\nol_interaction_UndoRedo.prototype.hasRedo = function() {\n return this._redoStack.length;\n};\n\nexport default ol_interaction_UndoRedo;\n","var validate = require(\"validate.js\");\n\nexport default class Point {\n\n\tconstructor(params) {\n \tthis.name = params.name;\n this.name_ar = params.name_ar;\n this.description = params.description;\n this.description_ar = params.description_ar;\n // this.step = params.step;\n this.category = params.category;\n this.categoryLabel = params.label;\n this.visible = params.visible;\n this.searchable = params.searchable;\n this.clickable = params.clickable;\n \t}\n\n\n \ttoString() {\n return this.name;\n }\n\n getName(){\n \t return this.name;\n }\n\n\n validate(){\n var constraints = {\n category: {\n presence: {\n allowEmpty: false\n }\n },\n name: {\n presence: true,\n length: {\n minimum: 2,\n message: \"must be at least 2 characters\"\n }\n },\n name_ar: {\n presence: true,\n length: {\n minimum: 2,\n message: \"must be at least 2 characters\"\n }\n }\n // description: {\n // presence: true,\n // length: {\n // minimum: 5,\n // maximum:120,\n // message: \"must be at minimum 5 and maximum 120 characters\"\n // }\n // },\n // description_ar: {\n // presence: true,\n // length: {\n // minimum: 5,\n // maximum:120,\n // message: \"must be at minimum 5 and maximum 120 characters\"\n // }\n // }\n };\n return validate({category: this.category,name:this.name,name_ar:this.name_ar}, constraints);\n }\n\n isLift(){\n if(!this.categoryLabel) return false;\n return this.categoryLabel.toLowerCase() == \"lift\" ? true : false;\n }\n\n \n\n\n}","var Handlebars = require(\"../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \" \";\n},\"useData\":true});","import _ from 'underscore';\n\nimport Choices from 'choices.js/public/assets/scripts/choices.min.js';\nimport 'choices.js/public/assets/styles/choices.min.css';\nimport { Rules , NodeType} from './rules.js';\n\n\nvar menuTemplate = require(\"../../../../templates/rules.handlebars\");\n\nconst RULE = \"rules\";\n\nexport default class RuleMenu {\n\n\tconstructor(api, siteData) {\n\t\tthis.name = 'RuleMenu';\n this.siteData = siteData;\n\t\tthis.selectedFeature;\n\t\tthis.configredRule;\n this.floorRule;\n this.rule;\n\t}\n\n\ttoString() {\n return this.name;\n }\n\n\n initMenu(){\n $(\"#rules-body\").html(\"\");\n \t$(\"#rules-body\").append(menuTemplate);\n this.rule = new Rules();\n var _this = this;\n var choices = _.filter(this.siteData.floors, function(floor){ return floor.value != _this.siteData.floor_identifier; });\n\n \tthis.floorRule = new Choices(document.getElementById('FloorRules'),{\n choices : choices,\n paste: false,\n removeItemButton: true\n });\n\n \n\n // rule select\n }\n\n onEditNode(){\n if(this.configredRule.type == 'lift'){\n this.floorRule.setValue(this.configredRule.getFloors());\n }\n this.configRuleSection();\n }\n\n \n configRuleSection(){\n if(this.configredRule && this.configredRule.isLift()){\n this.showLifteRule();\n this.hideEscalatorRule();\n this.hideEmptyView();\n } else {\n this.hideLifteRule();\n this.hideEscalatorRule();\n this.showEmptyView();\n }\n }\n\n showLifteRule(){\n $(\"#lift-rule\").show();\n }\n\n hideLifteRule(){\n $(\"#lift-rule\").hide();\n }\n\n showEscalatorRule(){\n $(\"#escalator-rule\").show();\n }\n\n hideEscalatorRule(){\n $(\"#escalator-rule\").hide();\n }\n\n showEmptyView(){\n $(\"#empty-view\").show();\n }\n\n hideEmptyView(){\n $(\"#empty-view\").hide();\n }\n\n open(feature){\n \tthis.initMenu();\n this.selectedFeature = feature;\n if(feature.getProperties() && feature.getProperties().rule){\n var rule = new Rules();\n rule.setType(feature.getProperties().rule.type);\n rule.setFloors(feature.getProperties().rule.selectedFloors);\n this.configredRule = rule;\n this.onEditNode();\n }\n }\n\n save(selectedPoint){\n \t$(\"#rule-side-menu\").remove();\n let props = {};\n if(this.rule && selectedPoint){\n this.rule.setType(selectedPoint);\n var selectedData = [];\n if(selectedPoint == 'lift'){\n _(this.floorRule.getValue()).each(function(floor){\n selectedData.push({\n label : floor.label,\n value : floor.value\n });\n }); \n }\n \n this.rule.setFloors(selectedData);\n if(this.selectedFeature) props['rule'] = this.rule;\n this.selectedFeature.setProperties(props);\n }\n \n }\n\n static get getRuleVariable() {\n return RULE;\n }\n\n}","var Handlebars = require(\"../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \" \";\n},\"useData\":true});","import _ from 'underscore';\n\nimport Choices from 'choices.js/public/assets/scripts/choices.min.js';\nimport 'choices.js/public/assets/styles/choices.min.css';\n\nimport Beacon from './beacon.js';\n\nvar menuTemplate = require(\"../../../../templates/beacon.handlebars\");\n\nconst BEACON = \"beacon\";\n\n\nexport default class BeaconMenu {\n\n\tconstructor(api, siteData) {\n \tthis.name = 'BeaconMenu';\n this.api = api;\n this.siteData = siteData;\n this.selectedFeature;\n this.selectedBeacon;\n this.menu;\n this.editMode = false;\n this.editNode;\n \t}\n\n \ttoString() {\n return this.name;\n }\n\n\n initMenu(){\n $(\"#beacon-body\").append(menuTemplate);\n\n var _this = this;\n\n this.uuidDD = new Choices('#uuid-dropdown', {\n choices : this.siteData.uuids,\n itemSelectText: 'Click to select'\n });\n \n \n $( \"#remove-beacon\" ).bind( \"click\", function(event) {\n event.preventDefault();\n _this.removeBeacon();\n });\n\n\n $( \"#edit-beacon\" ).bind( \"click\", function(event) {\n event.preventDefault();\n _this.editMode = true;\n _this.editBeacon();\n });\n\n \n $( \"#beacon-cancel\" ).bind( \"click\", function(event) {\n event.preventDefault();\n _this.cancelAddBeacon();\n });\n\n $( \"#beacon-save\" ).bind( \"click\", function(event) {\n event.preventDefault();\n _this.saveBeacon();\n });\n\n $(\"#selected-beacon\").hide(); // Hide the selected beacon section -- need conditon check here \n }\n\n\n onEditNode(){\n $(\"#beacon-cancel\").show(); // Show cancel option on form\n $(\"#selected-beacon\").show(); // Show point selected\n $(\"#selected-beacon-name\").text(this.selectedBeacon.name);\n $(\"#beaconManuallySection\").hide();\n\n // populate form data \n $(\"#InputBeaconName\").val(this.selectedBeacon.name);\n $(\"#InputBeaconMajor\").val(this.selectedBeacon.major);\n $(\"#InputBeaconMinor\").val(this.selectedBeacon.minor);\n this.uuidDD.setChoiceByValue(this.selectedBeacon.uuid);\n $( \"#edit-beacon\" ).show();\n\n var props = {\n name : this.selectedBeacon.name,\n major : this.selectedBeacon.major,\n minor : this.selectedBeacon.minor,\n uuid : this.selectedBeacon.uuid\n };\n \n this.editNode = new Beacon(props);\n\n \n }\n\n async saveBeacon(){\n var props = {\n name : $(\"#InputBeaconName\").val(),\n major : $(\"#InputBeaconMajor\").val(),\n minor : $(\"#InputBeaconMinor\").val(),\n uuid : this.uuidDD.getValue().value\n };\n \n let beacon = new Beacon(props);\n var errors = beacon.validate();\n\n\n this.checkValidation(errors);\n \n if(!errors){\n\n if(!beacon.validateUUID()){\n $( \".validation.beacon-uuid\" ).html(\"UUID invalid
\" );\n $( '.validation.beacon-uuid' ).parent().addClass('validation-beco');\n return;\n }\n\n if(this.editMode && beacon.editIsEqual(this.editNode)){\n }else if(this.editMode && beacon.isEqual(this.editNode)){\n this.menu.removeBeacon(this.editNode);\n if(this.menu.isBeaconExist(beacon)){\n this.menu.addBeacon(this.selectedBeacon);\n $( \".validation.beacon-name\" ).html(\"
Beacon Configuration already exist in this floor
\" );\n $( '.validation.beacon-name' ).parent().addClass('validation-beco');\n return;\n }\n\n }else if(this.menu.isBeaconExist(beacon)){\n $( \".validation.beacon-name\" ).html(\"
Beacon Configuration already exist in this floor
\" );\n $( '.validation.beacon-name' ).parent().addClass('validation-beco');\n return;\n }else if(this.editMode){\n this.menu.removeBeacon(this.editNode);\n }\n\n const data = await this.api.validateBeacon(this.siteData.site_identifier, this.siteData.org_identifier, this.siteData.floor_identifier, props);\n if(data){\n this.selectedBeacon = beacon;\n $(\"#selected-beacon\").show(); // Show beacon selected\n $(\"#beaconManuallySection\").slideToggle(500); // Hide beacon add form\n $(\"#selected-beacon-name\").text(this.selectedBeacon.name);\n $( \"#edit-beacon\" ).show();\n this.menu.addBeacon(this.selectedBeacon);\n } else {\n $( \".validation.beacon-name\" ).html(\"
beacon name already exist in the server
\" );\n $( '.validation.beacon-name' ).parent().addClass('validation-beco');\n }\n \n\n } \n \n }\n\n checkValidation(errors){\n if(errors && errors['name']){\n $( \".validation.beacon-name\" ).html(\"
\"+errors['name'].toString()+\"
\" );\n $( '.validation.beacon-name' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.beacon-name p\" ).remove();\n $( '.validation.beacon-name' ).parent().removeClass('validation-beco');\n }\n if(errors && errors['major']){\n $( \".validation.beacon-major\" ).html(\"
\"+errors['major'].toString()+\"
\");\n $( '.validation.beacon-major' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.beacon-major p\" ).remove();\n $( '.validation.beacon-major' ).parent().removeClass('validation-beco');\n }\n\n if(errors && errors['minor']){\n $( \".validation.beacon-minor\" ).html(\"
\"+errors['minor'].toString()+\"
\");\n $( '.validation.beacon-minor' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.beacon-minor p\" ).remove();\n $( '.validation.beacon-minor' ).parent().removeClass('validation-beco');\n }\n\n if(errors && errors['uuid']){\n $( \".validation.beacon-uuid\" ).html(\"
\"+errors['uuid'].toString()+\"
\");\n $( '.validation.beacon-uuid' ).parent().addClass('validation-beco');\n }else {\n $( \".validation.beacon-uuid p\" ).remove();\n $( '.validation.beacon-uuid' ).parent().removeClass('validation-beco');\n }\n }\n\n\n cancelAddBeacon(){\n $(\"#beaconManuallySection\").slideToggle(500);\n $(\"#selected-beacon\").show();\n }\n\n \n getMenu() {\n return this;\n }\n\n open(feature, menu){\n this.initMenu();\n this.selectedFeature = feature;\n this.menu = menu;\n if(feature.getProperties() && feature.getProperties().beacon){\n this.selectedBeacon = this.getOrCreateBeacon(feature.getProperties().beacon);\n this.onEditNode();\n }\n this.editMode = false;\n }\n\n save(){\n let props = {};\n if(this.selectedFeature) props['beacon'] = this.selectedBeacon;\n this.selectedFeature.setProperties(props);\n\n this.selectedFeature = null;\n this.selectedBeacon = null;\n this.beaconCache = {};\n $(\"#beacon-side-menu\").remove();\n } \n\n removeBeacon(){\n if(this.selectedBeacon){\n this.menu.removeBeacon(this.selectedBeacon);\n this.selectedBeacon = null;\n\n $(\"#beacon-cancel\").hide();\n $(\"#beaconManuallySection\").show();\n $(\"#selected-beacon-name\").text(\"\"); // Reset the beacon name\n $(\"#selected-beacon\").hide(); // Hide beacon selected\n\n }\n }\n\n editBeacon(){\n if(this.selectedBeacon){\n $(\"#selected-beacon\").hide(); // Hide beacon selected\n $(\"#beaconManuallySection\").slideToggle(500);\n $(\"#selected-beacon-name\").text(this.selectedBeacon.name);\n $(\"#InputBeaconName\").val(this.selectedBeacon.name); \n\n var props = {\n name : this.selectedBeacon.name,\n major : this.selectedBeacon.major,\n minor : this.selectedBeacon.minor,\n uuid : this.selectedBeacon.uuid\n };\n \n this.editNode = new Beacon(props);\n\n }\n }\n \n\n static get getBeaconVariable() {\n return BEACON;\n }\n\n getOrCreateBeacon(params){\n var props = {\n major : params.major,\n minor : params.minor,\n uuid : params.uuid,\n name : params.name\n };\n let beacon = new Beacon(props);\n\n return beacon;\n }\n\n\n \n\n\n}","var Handlebars = require(\"../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \"
\";\n},\"useData\":true});","var Handlebars = require(\"../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \" \";\n},\"useData\":true});","import {Icon, Style } from 'ol/style.js';\nimport Feature from 'ol/Feature';\nimport Point from 'ol/geom/Point';\n\nimport Notification from 'ol-ext/control/Notification';\nimport 'ol-ext/control/Notification.css';\n\n//Color Picker\nimport '@simonwep/pickr/dist/themes/classic.min.css';\nimport Pickr from '@simonwep/pickr';\n\n\nvar menuTemplate = require(\"../../../../templates/linemenu.handlebars\");\n\nconst themes = {\n theme: 'classic',\n appClass: 'beco-picker',\n defaultRepresentation: 'HEX',\n position: 'bottom-middle',\n\n components: {\n preview: true,\n opacity: false,\n hue: true,\n\n interaction: {\n hex: false,\n rgba: false,\n hsva: false,\n input: true,\n cancel: true,\n save: true\n }\n }\n};\n\nexport default class LineMenu {\n\n\tconstructor(){\n\t\tthis.name = 'LineMenu';\n\t\tthis.selectIntercation;\n\t\tthis.notification = new Notification({});\n this.labelTextColor = '#FFFFFF';\n this.labelBorderColor = '#5D5755';\n this.labelTextSize = 12;\n\n var _this = this;\n\n $(\"#line-sidebar\").append(menuTemplate);\n\n $( \"#line-menu-close\" ).bind( \"click\", function(event) {\n event.preventDefault();\n _this.close();\n });\n\n $( \"#line-menu-save\" ).bind( \"click\", function(event) {\n event.preventDefault();\n _this.save();\n\t\t});\n\t\t\n\t\t$('.beco-toggle-check .custom-control-input').change(function(){\n var toggle = $('.beco-toggle-check');\n\n\t\t\tif($(this).is(\":checked\")) {\n\t\t\t\ttoggle.addClass(\"show\");\n\t\t\t} else {\n\t\t\t\ttoggle.removeClass(\"show\");\n\t\t\t}\n });\n\n $('input.direction-label').change(function(){\n \n if ($(this).is(':checked')){\n $(this).prop('checked', true).attr('checked', 'checked');\n }\n else {\n $(this).prop('checked', false).removeAttr('checked');\n }\n \n $('input.direction-label').not(this).prop('checked', false).removeAttr('checked');\n });\n\n this.textColor = Pickr.create({\n el: '#textColor',\n default: this.labelTextColor,\n ...themes\n\n }).on('change', (color) => {\n // HEXA Color\n const hexaColor = color.toHEXA().toString();\n this.labelTextColor = hexaColor;\n }).on('save', () => {\n this.textColor.hide();\n });\n\n\n this.borderColor = Pickr.create({\n el: '#borderColor',\n default: this.labelBorderColor,\n ...themes\n\n }).on('change', (color) => {\n // HEXA Color\n const hexaColor = color.toHEXA().toString();\n this.labelBorderColor = hexaColor;\n\n }).on('save', () => {\n this.borderColor.hide();\n });\n\n this.range = document.getElementById(\"labelSize\");\n this.bubble = document.getElementById(\"labelBubble\");\n this.setBubble(this.range, this.bubble);\n this.range.addEventListener(\"input\", () => {\n this.setBubble(this.range, this.bubble);\n });\n\n\t}\n\n\tshowNotification(text){\n var div = $('Length cannot be more than 100
\" );\n $( '.validation.label-name' ).parent().addClass('validation-beco');\n return;\n } else {\n $( \".validation.label-name p\" ).remove();\n $( '.validation.beacon-name' ).parent().removeClass('validation-beco');\n }\n \n\n \tvar direction = 0;\n \tif($(\"#oneway\").is(\":checked\")){ \n \t\tvar atob = $(\"#atob\").is(\":checked\");\n \t\tvar btoa = $(\"#btoa\").is(\":checked\");\n \t\tif(atob) direction = 1;\n \t\tif(btoa) direction = 2;\n \t}\n\n \tvar props = {\n disable : $(\"#disable\").is(\":checked\"),\n direction : direction,\n label : $(\"#InputLabel\").val(),\n labelTextColor : this.labelTextColor,\n labelTextSize : this.labelTextSize,\n labelBorderColor : this.labelBorderColor,\n };\n\n this.feature.setProperties(props);\n \tthis.showNotification(\"Data saved successfully\");\n \tthis.close();\n\n \n }\n\n close(){\n $(\".beco-sidebar-line\").removeClass('show');\n $(\".beco-sidebar\").parent().removeClass('sidebar-active'); \n this.selectIntercation.getFeatures().clear();\n \n }\n}","var Handlebars = require(\"../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \"
\";\n},\"useData\":true});","import ImageLayer from 'ol/layer/Image.js';\nimport Static from 'ol/source/ImageStatic.js';\n\n\nexport default class Grid {\n\n\tconstructor(projection,imageSize,extent) {\n \t this.name = 'Grid';\n \t var gridSource = new ImageLayer({\n title: this.name,\n displayInLayerSwitcher: true,\n class : 'grid',\n \t source: new Static({\n \t url: './public/svg/Grid-map.svg',\n \t imageSize: /*imageSize,*/ [2800, 1280],\n \t projection: projection,\n \t imageExtent: extent,\n \t })\n \t });\n \t this.gridSource = gridSource ;\n\n \t}\n\n \ttoString() {\n return this.name;\n }\n\n\n getGridLayer() {\n \treturn this.gridSource;\n }\n\n\n}","/**\n* Observer pattern\n* https://pawelgrzybek.com/the-observer-pattern-in-javascript-explained/\n**/\nexport default class Observable {\n /**\n * each instance of the Observer class\n * starts with an empty array of things (observers)\n * that react to a state change \n **/\n constructor() {\n this.observers = [];\n }\n\n /**\n * add the ability to subscribe to a new object / DOM element\n * essentially, add something to the observers array\n **/\n\n subscribe(f) {\n this.observers.push(f);\n }\n\n /**\n * add the ability to unsubscribe from a particular object\n * essentially, remove something from the observers array\n **/\n unsubscribe(f) {\n this.observers = this.observers.filter(subscriber => subscriber !== f);\n }\n\n /**\n * update all subscribed objects / DOM elements\n * and pass some data to each of them\n **/\n notify(data) {\n this.observers.forEach(observer => observer(data));\n }\n}","import { axiosInstance } from \"./axiosInstance.js\";\n\nexport default class API {\n\n\tconstructor(){\n this.name = \"API\";\n \n }\n\n toString() {\n return this.name;\n }\n\n getCookie(name) {\n var r = document.cookie.match(\"\\\\b\" + name + \"=([^;]*)\\\\b\");\n return r ? r[1] : null;\n }\n\n getFloorInfo() {\n return axiosInstance.get(\"api/v1/get-site-data/?site_identifier=site-2&floor_identifier=test\");\n }\n\n checkSession() {\n return axiosInstance.get(\"api/v1/editor/check-session/\");\n }\n\n getSiteData(siteIdentifier, floorIdentifier) {\n return axiosInstance.get(\"api/v1/editor/get-site/\",{\n params: {\n site_identifier: siteIdentifier,\n floor_identifier: floorIdentifier\n },\n });\n }\n\n saveMapData(siteIdentifier, floorIdentifier, mapData){\n return axiosInstance.post(\"api/v1/editor/floor-data/\",{\n site_identifier: siteIdentifier,\n floor_identifier: floorIdentifier,\n floor_data: mapData,\n });\n\n // let res = await axiosInstance.post(\"api/v1/editor/floor-data/\", data);\n // if(res.data && (res.status==209 || res.status==200) ){\n // return res;\n // }\n // return res.status;\n\n }\n\n async getPoints(siteIdentifier, orgIdentifier, q) {\n\n let res = await axiosInstance.get(\"api/v1/editor/search-point/\",{\n params: {\n site_identifier: siteIdentifier,\n org_identifier: orgIdentifier,\n q : q\n },\n });\n\n return res.data;\n }\n\n async getBeacons(siteIdentifier, orgIdentifier, q) {\n\n let res = await axiosInstance.get(\"api/v1/editor/search-beacon/\",{\n params: {\n site_identifier: siteIdentifier,\n org_identifier: orgIdentifier,\n q : q\n },\n });\n\n return res.data;\n }\n\n async validatePoint(siteIdentifier, orgIdentifier, floorIdentifier, pointName){\n var data = {\n 'site_identifier': siteIdentifier,\n 'org_identifier': orgIdentifier,\n 'floor_identifier': floorIdentifier,\n 'point_name': pointName\n };\n\n var headers = {\n 'HTTP_X_CSRFTOKEN': this.getCookie('csrftoken')\n };\n\n //let res = await axiosInstance.post(\"api/v1/editor/validate-point/\", data, {headers: headers})\n let res = await axiosInstance.post(\"api/v1/editor/validate-point/\", data);\n \n return res.status == 200 ? true : false;\n }\n\n async validateBeacon(siteIdentifier, orgIdentifier, floorIdentifier, params){\n var data = {\n 'site_identifier': siteIdentifier,\n 'org_identifier': orgIdentifier,\n 'floor_identifier': floorIdentifier,\n 'name': params.name,\n 'major': params.major,\n 'minor': params.minor\n\n };\n\n var headers = {\n 'HTTP_X_CSRFTOKEN': this.getCookie('csrftoken')\n };\n\n //let res = await axiosInstance.post(\"api/v1/editor/validate-point/\", data, {headers: headers})\n let res = await axiosInstance.post(\"api/v1/editor/validate-beacon/\", data);\n \n return res.status == 200 ? true : false;\n }\n\n async saveData(siteIdentifier, floorIdentifier, mapData){\n var data = {\n 'site_identifier': siteIdentifier,\n 'floor_identifier': floorIdentifier,\n 'floor_data': mapData,\n\n };\n\n let res = await axiosInstance.post(\"api/v1/editor/floor-data/\", data);\n if(res.data && (res.status==209 || res.status==200) ){\n return res;\n }\n return res.status;\n\n }\n\n async saveFeedback(siteIdentifier,feedback){\n var data = {\n 'site_identifier' : siteIdentifier,\n 'feedback' : feedback\n };\n let res = await axiosInstance.post(\"api/v1/editor/report-error/\", data).catch(err => {\n console.log(\"error\");\n var res = {\n status : 210\n };\n return res;\n });\n return res.status;\n }\n\n async getData(siteIdentifier, floorIdentifier){\n let res = await axiosInstance.get(\"api/v1/editor/floor-data/\",{\n params: {\n site_identifier: siteIdentifier,\n floor_identifier: floorIdentifier\n },\n });\n return res.data;\n }\n\n}","import axios from \"axios\";\nimport { getSiteIdentifier, getFloorIdentifier } from './util.js';\n\n\nexport const AUTH_FAILED = 'Authentication Failed';\nexport const NOT_FOUND = '404 - Notfound';\nexport const UNKNOWN = 'UNKNOWN';\n\n\nfunction getRedirectUrl(){\n let siteIdentifier;\n let floorIdentifier;\n try {\n siteIdentifier = getSiteIdentifier();\n }\n catch(err) {\n console.log(err);\n } \n try {\n floorIdentifier = getFloorIdentifier();\n }\n catch(err) {\n console.log(err);\n } \n return SERVICE_URL+DASHBOARD_URL + encodeURIComponent(HOST+'/?siteIdentifier='+siteIdentifier+'&floorIdentifier='+floorIdentifier);\n};\n\nconst axiosInstance = axios.create({\n baseURL: SERVICE_URL,\n timeout: 5000,\n withCredentials: true\n});\n\n\naxiosInstance.interceptors.response.use(\n response => {\n return response;\n },\n error => {\n if(error.response && error.response.status){\n if(error.response.status == 401){\n window.location.replace(getRedirectUrl());\n }\n }\n return Promise.reject(error.response);\n }\n);\n\n\n\nexport { axiosInstance };","const i18n = require('./i18n-data.json');\nlet currentLang = 'en';\n\nexport function setLanguage(id) {\n currentLang = id;\n}\nexport function t(text) {\n return (i18n[currentLang] && i18n[currentLang][text]) || text;\n}","\nconst isSame = (date1, date2) => {\n return date1.getDate() == date2.getDate() &&\n date1.getMonth() == date2.getMonth() &&\n date1.getFullYear() == date2.getFullYear();\n};\n\nfunction toLocalTimeZone(dateTime){\n var localDate = new Date(dateTime);\n var monthNames = [\n \"January\", \"February\", \"March\",\n \"April\", \"May\", \"June\", \"July\",\n \"August\", \"September\", \"October\",\n \"November\", \"December\"\n ];\n\n var timeString = '';\n var today = new Date();\n var yesterday = new Date(today);\n yesterday.setDate(today.getDate() - 1);\n\n if ( isSame(localDate, today) ){\n timeString = 'today ';\n }\n else if(isSame(localDate, yesterday)){\n timeString = 'yesterday ';\n }\n else{\n timeString = monthNames[localDate.getMonth()] + ' ' + localDate.getDate() + ' ' + localDate.getFullYear()+' ';\n }\n\n timeString += localDate.toLocaleString('en-US', { hour: 'numeric', minute:'numeric', hour12: true });\n return timeString;\n}\n\n\n\n\nexport { toLocalTimeZone };","var Handlebars = require(\"../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \"\\n\t\t\t\t\t\t![]() | \\n\t\t\t\t\tuni-direction | \\n\t\t\t\t
\\n\t\t\t\t\t\t\\n\t\t\t\t\t | \\n\t\t\t\t\tnode | \\n\t\t\t\t
\\n\t\t\t\t\t\t\\n\t\t\t\t\t | \\n\t\t\t\t\tnode with point | \\n\t\t\t\t
\\n\t\t\t\t\t\t\\n\t\t\t\t\t | \\n\t\t\t\t\tnode with beacon | \\n\t\t\t\t
\\n\t\t\t\t\t\t\\n\t\t\t\t\t | \\n\t\t\t\t\tnode with point and beacon | \\n\t\t\t\t