{"version":3,"sources":["utils/svg2geojson/svg2geojson.js","assets/logo.png","pages/Test/TestMQTT/mqtt.worker.js","components/WebWorker/mqtt.worker.js","NamedAreas/convertFetchNamedAreasToMqtt.js","CacheBuster.js","components/ConfigJs/index.js","../node_modules/react-semantic-ui-datepickers/dist/locales sync /^/.//.*/.json$","components/App/localisation.js","utils/DEFAULTS.js","auth/reducer.js","auth/actions.js","cookies.js","components/Settings/reducer.js","utils/format-date.js","components/BasicTable.js","utils/microTime.js","api/apiAck.js","utils/confirmTokenRxWithRetryAndTimeout.js","utils/messageToken.js","utils/make-random.js","utils/toSlug.js","utils/toFireflyColor.js","utils/colors.js","utils/StatusEnum.js","projection.js","components/Map/util-geoJsonToPixels.js","components/WebWorker/sendNamedAreaButtonUpdateByParent.js","components/WebWorker/reducer.js","apiSaga.js","OperationalChanges/reducer.js","OperationalChanges/actions.js","pages/ControlRoomPage/ActiveOperationalChangesList.js","ApplicationContexts.js","MineLevels/reducer.js","MineLevels/actions.js","FlashMessages/reducer.js","FlashMessages/index.js","components/MineLevelMap.js","colorpalette.js","components/DeviceName.js","admin/firefly/FireflyLink.js","admin/firefly/FireflyLightChangeStatus.js","containers/FireflyName.js","components/FireflyMarker.js","UPSPanelControllers/reducer.js","containers/FireflyMapMarker.js","containers/CurrentMineLevelFirefliesFeatureGroup.js","seismicOverlays/reducer.js","components/SeismicLayerFeatureGroup.js","components/MineLevelSeismicFeatureGroup.js","seismicOverlays/actions.js","containers/CurrentSeismicFeatureGroup.js","components/Settings/actions.js","admin/form-field.js","pages/ControlRoomPage/NamedAreaDisplaySettings/NamedAreaDisplaySettingsModal.js","pages/ControlRoomPage/NamedAreaDisplaySettings/index.js","components/leaflet-search-control/leaflet-search-control.js","components/WebWorker/actions.js","components/Map/reducer.js","components/Map/actions.js","utils/sortAlphaNum.js","utils/number-utils.js","utils/omitDeep.js","UPSPanelControllers/actions.js","utils/toWebColor.js","components/Map/MakeIconSvgIcons.js","components/Map/MakeIcon.js","components/Map/NamedAreaPolygonPopup.js","components/RegionPreview/reducer.js","NamedAreas/actions.js","utils/bit-operations.js","components/RegionPreview/actions.js","admin/named-area-simple/NewNamedAreaTemplate.js","NamedAreas/createNamedAreaAroundFirefly.js","components/Map/ForceSingleLightManageNamedArea.js","components/Map/ForceSingleLight.js","admin/ups/UPSLink.js","components/Map/FireflyMarkerPopupModal.js","components/Map/ControllerMarkerPopupModal.js","components/Map/FireflyMarkerDefinition.js","components/UserAdmin/actions.js","components/Map/MineLevelMapLeafletSimple.js","components/Map/FireflyMarkerPopup.js","components/Map/ControllerMarkerPopup.js","components/Map/MineLevelMapLeaflet.js","NamedAreas/reducer.js","components/Icon/index.js","pages/ControlRoomPage/PrecannedOperations.js","pages/ControlRoomPage/MineLevelPrecannedOperationsList.js","pages/ControlRoomPage/PreCannedOperationsCustomSOP.js","utils/Heartbeat.js","pages/ControlRoomPage/MineLevelCustomSOPList.js","utils/imageCheck.js","pages/ControlRoomPage/MineLevelOpsControl.js","components/Debug/propsMessages.js","components/Legend/index.js","pages/GeneralHomePage.js","pages/ControlRoomPage/MineLevelOpsControlMinimal.js","pages/Test/TestMqttGeoJsonMap.js","assets/leaflet/leaflet-color-markers.js","pages/Test/TestMQTT/DraggableTableRow.js","pages/Test/TestMQTT/mqttMessages.js","pages/Test/TestMQTT/TestMqttNamedAreasSetup.js","pages/Test/TestMQTT/utils-mqttMessages.js","pages/Test/TestMqttGeoJson.js","pages/ControlRoomPage/GatesAndCrane/GatesAndCrane.js","pages/ControlRoomPage/index.js","components/TableTrailingContent.js","admin/DeleteButton.js","components/StatusChecks/reducer.js","utils/format-text.js","components/Download/index.js","admin/firefly/FireflyList.js","containers/CurrentMineLevelFirefliesFeatureGroupGeoJson.js","containers/ChooseMineLevel.js","components/ChooseMineLevelField.js","containers/UPSName.js","utils/propsChildren.js","components/Map/MapWithImage.js","components/Map/MineLevelMap.js","components/ColorableMapMarker.js","admin/firefly/form-value-selector.js","admin/firefly/FireflyMoveableMarker.js","admin/SaveButton.js","components/Map/referencePoints.js","admin/firefly/FireflyRawStatusReport.js","admin/SubmissionModal.js","admin/NavigationPromptModal.js","admin/firefly/FireflyDetailsForm.js","components/DataLoading/dataLoading.js","admin/firefly/FireflyDetail.js","admin/firefly/FireflyAdminPages.js","admin/ups/UPSRawStatusReport.js","admin/bulk-positioning/UPSBulkEditPage/ChooseEditorModeField.js","admin/bulk-positioning/UPSBulkEditPage/port-colors.js","components/LatLngSummary.js","admin/bulk-positioning/UPSBulkEditPage/form-value-selector.js","admin/bulk-positioning/UPSBulkEditPage/FireflyCommissioningStatus.js","admin/bulk-positioning/UPSBulkEditPage/PortSummaryFireflyDetails.js","admin/bulk-positioning/UPSBulkEditPage/PortSummaryField.js","admin/bulk-positioning/UPSBulkEditPage/UPSMoveableMarker.js","admin/bulk-positioning/UPSBulkEditPage/UPSPortStringMapLocationEditor.js","admin/bulk-positioning/UPSBulkEditPage/UPSBulkPositioningForm.js","admin/bulk-positioning/UPSBulkEditPage/index.js","admin/ups/UPSList.js","admin/bulk-positioning/BulkPositioningAdminPages.js","admin/named-area-group/NamedAreaGroupList.js","admin/named-area-group/NamedAreaGroupCreatePage.js","admin/named-area-group/NamedAreaGroupTableSubSubItems.js","admin/named-area-group/NamedAreaGroupTableSubItems.js","utils/normalise.js","components/UserAdmin/reducer.js","admin/named-area-group/NamedAreaGroupCronWizard.js","admin/named-area-group/NamedAreaGroupSettingsModal.js","admin/named-area-group/NamedAreaGroupTableItems.js","admin/named-area-group/NamedAreaGroupEditForm.js","NamedAreaGroups/reducer.js","admin/named-area-group/NamedAreaGroupPostSaveOptionsModal.js","NamedAreaGroups/actions.js","admin/named-area-group/NamedAreaGroupEditPage.js","admin/named-area-group/NamedAreaGroupAdminPages.js","admin/GenericButton.js","admin/named-area/NamedAreaList.js","admin/named-area/NamedAreaListAll.js","admin/named-area/NamedAreaListAllEvents.js","admin/named-area/DraggableTableRow.js","admin/named-area/NamedAreaButtonSettingsModal.js","admin/named-area/NamedAreaTable.js","admin/named-area/utils-mqttMessages.js","admin/named-area/NamedAreaMap.js","admin/named-area/region-colors.js","admin/named-area/NamedAreaCreateForm.js","admin/named-area/NamedAreaCreatePage.js","admin/named-area/NamedAreaEditForm.js","admin/named-area/NamedAreaEditPage.js","components/NoMatch.js","admin/named-area/NamedAreaAdminPages.js","admin/named-area-simple/NamedAreaSimpleList.js","utils/RegionShape.js","admin/named-area-simple/CreateRegionsField.js","admin/named-area-simple/NamedAreaSimpleForm.js","components/Tags/actions.js","admin/named-area-simple/NamedAreaSimpleCreatePage.js","admin/named-area-simple/NamedAreaSimpleEditPage.js","admin/named-area-simple/NamedAreaSimpleAdminPages.js","components/AreaImages/AreaImageImgBlob.js","admin/mine-level/MineLevelList.js","admin/mine-level/ImageUpload.js","admin/mine-level/MineLevelInitialiseArea.js","admin/mine-level/MineLevelCreateForm.js","admin/mine-level/MineLevelCreatePage.js","admin/mine-level/MineLevelEditForm.js","admin/mine-level/MineLevelEditPage.js","admin/mine-level/MineLevelAdminPages.js","admin/tag-tracking/TagTrackingUserDetailsCardPersonnel.js","admin/tag-tracking/TagTrackingUserDetailsCardVehicle.js","components/Tags/reducer.js","admin/tag-tracking/TagTrackingDetailsForm.js","admin/tag-tracking/TagTrackingEditPage.js","components/Logger/actions.js","admin/tag-tracking/TagTrackingList.js","admin/tag-tracking/TagTrackingAdminPages.js","admin/tag-tracking/TagTrackingUserList.js","admin/tag-tracking/TagTrackingUserForm.js","admin/tag-tracking/TagTrackingUserEditPage.js","admin/tag-tracking/TagTrackingUserCreatePage.js","admin/tag-tracking/TagTrackingUserAdminPages.js","admin/event-external-trigger/ExternalTriggerEditForm.js","admin/event-external-trigger/ExternalTriggerEditPage.js","admin/event-scheduled/ScheduledEventList.js","admin/event-scheduled/ScheduleEventFormOptions.js","admin/event-scheduled/ScheduledEventCronUtils.js","admin/event-scheduled/ScheduledEventForm.js","admin/event-scheduled/ScheduledEventCreatePage.js","admin/event-scheduled/ScheduledEventEditPage.js","admin/event-scheduled/ScheduledEventListAllJobs.js","components/EventLog/reducer.js","admin/event-log/EventLogListAllEvents.js","components/EventLog/actions.js","admin/event-scheduled/ScheduledEventListEditForm.js","admin/event-scheduled/ScheduledEventListEditPage.js","admin/event/EventAdminPages.js","admin/logs/Logs.js","admin/logs/FailLog.js","components/AlarmButton/index.js","utils/format-time.js","pages/Faults/FaultPage.js","components/Localisation/reducer.js","components/LoginForm.js","components/Logger/index.js","containers/LoginPage/index.js","components/MineLevelMenuItem/index.js","containers/MineLevelMenus/index.js","components/Menu/AdminMenuItem.js","components/Menu/TagTrackingMenuItem.js","components/Menu/OperatorMenuItem.js","components/Menu/LightingControlMenuItem.js","components/User/UserMenuItem.js","components/Tools/DataCollectButton.js","components/User/UserMenuLogout.js","components/TestMenu/index.js","utils/useWindowDimensions.js","components/Header/index.js","components/Footer/index.js","containers/MineLevelPageHeader.js","firefly_light_colors.js","pages/CreateSeismicOverlayPage/actions.js","pages/MineLevelSeismicLayerSummaryPage/MineLevelSeismicLayerList.js","pages/MineLevelSeismicLayerSummaryPage/index.js","pages/CreateSeismicOverlayPage/reducer.js","pages/CreateSeismicOverlayPage/CreateRegionsMapEditor.js","pages/CreateSeismicOverlayPage/EditSeismicRegionSettings.js","pages/CreateSeismicOverlayPage/index.js","pages/MineLevelStatusPage.js","components/PageNotImplemented.js","pages/LevelSpecificPage.js","components/CheckBrowser/index.js","utils/groupBy.js","admin/tag-tracking/TagTrackingByZoneList.js","components/leaflet-search-control/react-leaflet-search-control/index.js","admin/tag-tracking/TagTrackingMarkerPopupModal.js","admin/tag-tracking/TagTrackingUserDetailsCardUnknown.js","admin/tag-tracking/CurrentTagTrackingFeatureGroupGeoJson.js","admin/tag-tracking/TagTrackingZonesMarkerPopupModal.js","admin/tag-tracking/CurrentTagTrackingZonesFeatureGroupGeoJson.js","admin/tag-tracking/TagTrackingMap.js","components/User/UserEditForm.js","components/User/UserEditPage.js","components/User/UserPages.js","components/UserAdmin/UserAdminList.js","components/UserAdmin/UserCreateForm.js","components/UserAdmin/UserCreatePage.js","components/UserAdmin/UserAdminPages.js","components/Help/HelpFilesList.js","components/Help/HelpFilesListAreas.js","components/Tools/ToolsMqtt.js","components/Tools/ToolsDatabase.js","components/Tools/ToolsTerminal.js","components/Tools/ToolsSystem.js","components/MQTT/actions.js","admin/UploadButton.js","components/Tools/ToolsBackupRestore.js","components/Tools/ToolsMqttList.js","components/Tools/actions.js","pages/Test/TestMQTT/reducer.js","pages/Test/TestMQTT/testMqttWorker.js","pages/Test/TestMQTT/actions.js","components/WebWorker/index.js","components/WebWorker/makeAllDataForWorkerState.js","pages/Test/TestMQTT/TestMqttSimpleTable.js","pages/Test/TestMQTT/TestMqttNamedAreasTable.js","pages/Test/TestMQTT/index.js","pages/Test/TestMarkerIcons.js","components/StatusChecks/index.js","components/StatusChecks/actions.js","components/Localisation/actions.js","components/FetchData/index.js","components/Settings/index.js","components/AreaImages/AreaImageImg.js","admin/localisation/LocalisationList.js","admin/localisation/LocalisationEditForm.js","admin/localisation/LocalisationEditPage.js","admin/localisation/LocalisationAdminPages.js","components/App/index.js","components/CheckBrowser/actions.js","components/AlarmButton/reducer.js","components/CheckBrowser/reducer.js","components/Logger/reducer.js","components/Tools/reducer.js","components/ExternalTrigger/reducer.js","reducers.js","configureStore.js","registerServiceWorker.js","api/apiAxios.js","api/apiArea.js","MineLevels/convertFetchAreasToMqtt.js","MineLevels/sagas.js","api/apiNamedArea.js","NamedAreas/sagas.js","api/apiNamedAreaGroup.js","NamedAreaGroups/sagas.js","seismicOverlays/sagas.js","api/apiAuth.js","auth/saga.js","api/apiController.js","api/apiFirefly.js","UPSPanelControllers/convertFetchControllersToMqtt.js","UPSPanelControllers/convertFetchFireflysToMqtt.js","UPSPanelControllers/sagas.js","pages/CreateSeismicOverlayPage/saga.js","OperationalChanges/sagas.js","LiveUpdates/saga.js","StatusCheck/saga.js","api/apiUsers.js","components/UserAdmin/sagas.js","api/apiSystem.js","components/Localisation/sagas.js","components/EventLog/sagas.js","components/Settings/sagas.js","api/apiTagTracking.js","components/Tags/sagas.js","components/Tools/sagas.js","errorBoundary.js","index.js","components/WebWorker/ackTokenMiddleware.js","NamedAreaGroups/middleware.js","components/UserAdmin/middleware.js","components/Settings/middleware.js","utils/strToObj.js","utils/strToArray.js","FlashMessages/actions.js","NamedAreas/convertFetchNamedAreaEventsToMqtt.js"],"names":["geoFromSVGXML","svgXML","callback","options","require","Parser","explicitChildren","preserveChildrenOrder","xmlns","parseString","err","doc","convertSVGToGeoJSON","svgTolerance","svg","layerByName","layers","units","undefined","unit","test","$","height","value","includes","width","meta","$$","find","e","uri","local","geo","corners","filter","$ns","X","name","prefix","Y","Latitude","Longitude","GeoItem","length","console","error","process","exit","converter","rectangleConverter","midLatRadians","Math","PI","degreeLatLen","cos","verticalRes","deltaLat","tolerance","deltaY","forEach","el","i","id","replace","addGroupToLayer","combineTransform","addElementToLayer","type","creator","features","map","data","convertCoordinates","coordinates","properties","debug","svgID","debugId","area","geometry","push","coords","a","layer","xform","c","attrs","d","addPathData","pathStart","match","addDebugId","addPathToLayer","x","y","addRectToLayer","x1","y1","x2","y2","addLineToLayer","r","s","m","cx","cy","join","addCircleToLayer","points","nums","split","pts","concat","windingIsCorrect","reverse","addPolygonToLayer","addPolylineToLayer","warn","pathData","checkWinding","polys","pathDataToPolys","closed","poly","shouldBeClockwise","sum","p0","o","names","n","isNaN","transform","args","exec","mat","mat23","new","multiply","xLerp","lerp","yLerp","svgXY","deltaX","dx","deltaLon","dy","pt","vec2","create","transformMat23","fallback","minX","maxX","minY","maxY","slope","f","module","exports","Worker","__webpack_public_path__","DEFAULT_EMERGENCY_PRIORITY","lightingEventPriority","emergency","DEFAULT_LEVEL_WIDE_PRIORITY","levelWide","DEFAULT_START_FORCED_LIGHT_PRIORITY","forced","strToObj","str","obj","objStr","eval","convertFetchNamedAreasToMqtt","namedAreaFeatures","namedAreaStatuses","allAreasButtons","isConfigJs","TemplateAllAreasButtons","list","namedArea","cloneNamedAreaFeatures","cloneNamedAreaStatuses","addInfosStatuses","makeNamedAreaInfosStatuses","namedAreaInfos","Object","values","newMessage","oldNamedAreaInfos","oldNamedAreaStatuses","rxName","rxShape","shape","origin","Firefly_List","sub_type","priority","rxParent","parent","rxParentName","parent_name","active_color","active_state","rxButton","button","rxStyle","style","toUpperCase","parentName","geomType","color","fillColor","fillOpacity","opacity","weight","_isEmpty","templateButton","JSON","parse","stringify","named_area","priorityOffset","pop","substring","toLowerCase","status","coordinatesUtm","global","appVersion","packageJson","version","CacheBuster","props","state","loading","isLatestVersion","refreshCacheAndReload","log","caches","keys","then","Promise","all","delete","window","location","reload","fetch","response","json","msg","latestVersion","currentVersion","semver","gt","setState","this","children","React","Component","is","config","isDevelopmentVersion","hasOwnProperty","isDemoMode","isDebugScreensize","isMqttDebugToConsole","isShowLightControlSim","appResponsive","mobile","tablet","laptop","desktop","isActiveArea","getMapDisplayOptions","controllerLocations","controllerCables","mapDisplayOptions","getMapMarkerDisplayOptions","firefly","showMac","showStatus","showUtm","showEventInfo","showForced","controller","tagTracking","mapMarkerDisplayOptions","isDebugPagePropsMessages","isMqttNotApiPost","checkForBrowserType","NetworkTimeout","networkTimeout","isBoomgateCrane","BoomgateControllerIp","boomgateControllerIp","BoomgateColors","boomgateColors","gate","up","down","crane","on","off","alarm","mqttBroker","network","address","mqttBrokerAddress","addressSecondary","mqttBrokerAddressTWO","mqttBrokerPort","mqttBrokerProtocol","port","protocol","https","http","faultFlash","battery","statusChecks","faultMessageBannerDisplay","fireflySamePosition","fireflySamePositionCorrected","controllerLikelyReplacement","controllerLikelyReplacementCorrected","areaImageNotFound","faultMessageBannerText","templateAllAreasButtons_railway","templateAllAreasButtons","namedAreaIconOptions","legend","boomgateCraneIcons","commonIcons","freeportIcons","TemplateDefaultArea","defaultArea","isAreaMapSimple","isShowBackupRestore","isShowExternalTriggerEvent","isShowScheduledEvent","isShowEventLog","isAreaImageToState","isDeleteFireflyNotCommissioned","isDataCollectionDuringMarkerPopupOpen","mqttTopicOptions","eventTriggerOptions","userSettings","strings","key","text","icon","feature","option","isCustomSOP","isShowEventButtons","isUserRelay","isPolygonShowHide","colorOptions","image","src","allowedLightColors","newColorOptions","call","opt","allowedAlternateLightColors","stateOptions","allowedLightStates","newStateOptions","markerOptions","allowedMapMarkers","newMarkerOptions","languageOptions","regioncodelanguage","allowedLanguages","newLanguageOptions","roleOptions","allowedRoles","newRoleOptions","applicationOptions","allowedApplications","newApplicationOptions","featureOptions","allowedFeatures","newAllowedFeatures","markerSize","marker","tag","markerAcceptableEventLabels","controlScreenEmergencyEventButtons","show","label","controlScreenSOPdata","deviceCheckTimeout","checkPeriod","period","pollRates","disable","workerEssentials","worker","server","checkServiceOptions","application","service","checkService","configHomepage","configAppTitle","isLightingControl","isTagTracking","isTagTrackingMap","tagTrackingPort","CheckConfigJs","errorType","extraMessage","header","message","addErrorFlashMessage","displayErrors","connect","dispatch","ownProps","clearFlashMessages","extra","webpackContext","req","webpackContextResolve","__webpack_require__","Error","code","resolve","defaultStrings","Login","Email","Password","Unauthorized","Status","Faults","Admin","Areas","Controllers","FireFly","FireFlys","Logs","System","Tools","Users","Profile","Sorry","Logout","USER_PROFILE_SETTING_MESSAGE","Next","LOADING_MESSAGE","Map","Northing","Easting","Letter","Number","Order","ID","Device","Fault","Clear","Copy","copy","Save","Submitting","Reset","Cancel","Add","Edit","Close","Enable","Disable","Delete","Yes","No","ON","OFF","unknown","Update","Restore","Upload","File","Files","Backup","BACKUP_LIST_UPDATE_POP_MSG","Tag","Tags","Personnel","Vehicle","Vehicles","Type","Types","Zones","Zone","RSSI","Unassign","TAG_ZONE_LIST_UPDATE_POP_MSG","Documents","Help","Header_Controller_BulkPosition","Controller","Area","Location","Master","Version","Ports","Position","MAC","Note","FireFly_Note_Placeholder","LocalizedStrings","DEFAULT_SETTINGS","display","columnWidth","hint","view","sopInterface","componentState","namedAreaGroup","parseUserDataSettings","user","newUser","settings","newSettings","initialState","Immutable","errors","isLoading","isCheckingAuth","hasCheckedOnce","isLoggingOut","isAuthenticated","isEmpty","auth","getRoles","getIn","isUserSuper","indexOf","isUserAdmin","isUserUser","isUserGuest","getUsername","username","getEmail","email","getUserData","getUserSettings","logout","checkAuth","reset","NAMED_AREA_DISPLAY_SETTINGS","getCookie","setCookie","toString","getNamedAreaDisplaySettings","document","cookie","parts","shift","clearCookie","cookieName","cookieValue","hourToExpire","date","Date","setTime","getTime","toGMTString","namedAreaDisplaySettings","folderFilesList","serverInfo","serverStatus","turnOnPokeWorker","settingsDataLoading","mapImages","mapSettings","isSystemRestore","getFolderFileNamesListById","file","filename","getServerInfo","getServerInfoVersion","getServerStatus","isOnOffPokeTheWorker","isDisabledPokeTheWorker","getPollRates","getMqttBroker","getSettingsDataLoading","getMapImages","getMapImageById","img","isServiceBackupMonitor","some","item","check","isServiceTagTracker","formatDate","fmtDefault","format","formatDateRelativeNow","now","formatRelative","parseDate","parseISO","minutesAgo","differenceInMinutes","BasicTable","HeaderComponent","RowComponent","items","getItemKey","idx","trailingContent","wholeRowMessage","Table","sortable","celled","fixed","Header","Body","microTime","performanceNow","currentAckToken","setAckToken","ack","acks","compareTime","timeStamp","filterOldAckToken","removeAckToken","removeToken","token","isAckReceivedByToken","reject","indexInAcks","confirmTokenRxWithRetryAndTimeout","retry","catch","setTimeout","userSessionIp","getUserSessionIp","setUserSessionIp","ip","sessionStorage","getItem","messageToken","time","randString","result","characters","charactersLength","charAt","floor","random","makeRandomString","toFireflyColor","toFireflyAlternateColor","distinctColors","StatusEnum","OK","OLD_STATUS_REPORT","NO_STATUS_REPORT","DIFFERENT_TOPOLOGY","NOT_COMMISSIONED","SAME_POSITION","NEW","INACTIVE","TIMEOUT","API_FETCH","SHIFTED_POSITION","CONTROLLER_ON_BATTERY","CONTROLLER_NETWORK_FAULT","0","ok","1","warning","2","3","4","5","6","7","8","9","10","11","12","StatusEnumToReadable","arrayFromLatLng","latLng","lng","lat","latlntFromArray","array","LeastSquaresApproximationFourPointsSixParametersTransformation","Sa","Sb","Tx","Sc","Sd","Ty","T","bind","Array","isArray","flatten","results","numeric","dot","asPoints","chunk","res","standardPoints","localPoints","s1","s2","s3","s4","l1","l2","l3","l4","L","x3","y3","x4","y4","A","Atrans","transpose","AtransA","invAtransA","inv","AtransL","invAtransAAtransL","transformGeoJsonUtmToPixels","geoJson","areaStatuses","scale","geoJsonTransform","newFeature","arrayLatLng","slice","isAreaUndefined","isAllZero","every","randomHoldingPenCoordinate","arrayPoints","transformX","transformUtmToPixels","arr","j","arrayPoint","i_value","j_value","k_value","k","transformGeoJsonUtmToPixelsByChangeList","prevFeature","changeList","updateList","transformGeoJsonPixelsToUtm","transformPixelsToUtm","standardPtsUtmX","mineLevel","ref_coord","coord","index","utm","sort","v","localPtsX","image_xy","easting","northing","zoneNum","utm_zone_number","zoneLetter","utm_zone_letter","localPts","standardPts","fromPoints","sendNamedAreaButtonUpdateByParent","parentId","buttons","namedAreasByParentId","b","messagePayloads","namedAreaClone","newButtons","updatedNamedArea","precanned","namedAreaPayload","topic","qos","retained","initialStateMqtt","dataFetched","recalcState","dataLoading","dataloadingResponseRequestMessageQueue","mqttMsg","latestFaultTs","externalTrigger","buttonTrigger","machineStatus","mapMessages","fireflyCoordinates","fireflyStatuses","fireflyIdsUpdateList","controllerCoordinates","controllerStatuses","activeArea","areaInfos","isAreaImagesChanged","namedAreaEvents","namedAreaEventsButtonGroupState","emergencyEventSettings","triggerEventSettings","namedAreaExtTriggerEventInfo","namedAreaScheduledEventInfo","scheduledEventJobInfo","serverTimestamp","deviceTimestamps","systemProcessMsg","timedOutDevices","timedOutLatestCheck","timeoutPeriod","timeoutCheckPeriod","waitEventTimeout","publish","processAreaStatuses","payload","newAreaStatus","std","mapStateInitialState","deleteSelected","hideSelected","isDirty","ackInitialState","stableOrder","order","getMqttMsg","webWorker","general","getFaults","getMachineStatus","getMapState","getControllerCoordinatesByAreaId","filteredgeojson","getAllControllerStatuses","byId","getControllerById","getFireflyCoordinatesById","getFeaturesByProperty","getFireflyCoordinatesByAreaId","getAllFireflyStatuses","getFireflyById","getFireflyIdsForMineLevelId","ff","getFireflyIdsUpdateListByArea","idArray","getFireflyIdsDeleteListByArea","fireflyIdsDeleteList","getActiveArea","getAllAreaStatuses","sortAreas","getAreaById","getAreaStatusesById","getIsAreaImagesChanged","getNamedAreaInfos","getNamedAreaInfosByParentId","getButtonPrioritysInNamedAreaGroups","areas","buttonPrioritysInNamedAreaGroups","namedAreaButtonList","group","subItems","level","active","event","getButtonPrioritysInNamedAreaGroupByAreaId","assignDistinctColorToNamedAreasInGroupByAreaId","namedAreasInNamedAreaGroupByAreaId","namedAreaParentList","Set","getNamedAreasInNamedAreaGroupByAreaId","distinctColorsNamedAreas","getAllNamedAreaStatuses","getNamedAreaStatusesByAreaId","getNamedAreaParentStatusesByAreaId","namedAreasByAreaId","uniqueParents","self","sortedUniqueParents","localeCompare","parents","uniqueParent","namedAreaParentInfo","nameArray","groups","get","set","groupsArray","operationsValue","getNamedAreaStatusesById","getAllAreasButtonState","allAreasObject","getAllNamedAreaEvents","getNamedAreaEventsByAreaId","getNamedAreaEventButtonGroupState","getScheduledEventJobInfo","jobs","eventJobInfo","job","cron","cronActiveDuration","cron_active_duration","eventJobId","event_job_id","cronId","note","password","polygonId","polygon_id","timestamp","userRelay","user_relay","info","activeJob","active_job","sendNamedAreaEventParent","operation","relay_active","namedAreas","buttonGroupState","eventPayloads","active_button","eventMsg","button_groups","active_alternate_color","on_time","off_time","train","relay_event_active","operator","eventPayload","sendNamedAreaEventSingle","activeButton","namedAreaId","sendNamedAreaEventAllAreas","namedAreaEventAllAreasMsg","getTimedOutDevices","getServerTimestamp","getAcks","getMqttDataLoading","getMqttDataLoadingResponseRequestMessageQueue","getNamedAreaDeleteSelections","mapState","getNamedAreaHideSelections","getIsDirty","GetMapNamedAreasReducedProperties","reducedProperties","reducedProperty","combineReducers","action","newState","publishEvents","publishChanges","newControllerCoordinates","newControllerStatus","newSystemProcessMsg","newClearSystemProcessMsg","newRecalcState","newFireflyCoordinates","prevFireflyCoordinates","newFireflyProperty","newProperties","prevFireflyProperty","prevFireflyFeature","prevFireflyFeatureWithTimestamp","newFFStatusIds","isFireflyPropertyChanged","updatedFireflyCoordinates","updatedFireflyCoordinatesFeatures","updateFireflyIdsUpdateList","newRecalcStateForFireflyCoord","fireflyIdsUpdateListIds","oldIds","newIds","deletedId","currentAreaStatuses","changesAreaStatuses","naEventsArray","newNamedAreaEventsButtonGroupState","namedAreaEventParentInfo","asMutable","scheduledEventJobs","tempArray","setIn","watchDownloadFileChannel","apiSaga","downloadFileChannel","channel","channelBufferPublishMsg","put","take","fork","activeOpsInitialState","remoteButtonClick","activeOpsChanges","newRemoteButtonClick","getRemoteButtonClick","operationalChanges","isActiveEvent","spec","areaId","namedAreaPriority","namedAreaEventsParents","namedAreasEventsByAreaId","getNamedAreaEventsParentsByAreaId","getActiveForcedOverride","fireflyId","activeChanges","change","createdFrom","cancelNamedAreaEvent","activateNamedAreaEvent","activateNamedAreaEventSingle","updateButtonGroupState","waitEventTimeOut","updateRemoteButtonClick","ItemRow","cancelOperationalChange","Row","Cell","colSpan","opsChange","description","createdAt","createdBy","Button","onClick","ActiveOperationalChangesList","Container","MineLevelContext","createContext","withMineLevel","Consumer","displaySettings","getAllMineLevels","createSelector","mineLevels","getMineLevelById","levelId","getMineLevelBounds","bounds","yx","xy","Util","getMineLevelBounds_new","image_info","latLngBounds","makeTemporaryCoordsFactory","ZeroProvider","ups","passUpsPosition","upsLatLng","reduce","acc","latAbs","abs","getNorth","getSouth","lngAbs","getEast","getWest","latDelta","lngDelta","latRef","lngRef","latStart","lngStart","portNumber","position","asNumber","getMineLevelTemporaryCoordsProvider","ForMineLevelId","parseFloat","fetchMineLevels","saveNewMineLevel","deleteMineLevel","getAllMessages","flashMessages","FlashMessagesList","messages","addLongToMessages","contentLong","content","miniMessages","miniMsg","maxWidth","rest","Popup","trigger","Message","removeFlashMessage","minWidth","flexGrow","paddingRight","DEFAULT_MAP_STYLE","zIndex","SimpleCRSImageMap","imageInfo","center","minZoom","tilepath","maxBounds","pad","ref","leafletElement","getMinZoom","setMinZoom","minZoomCalced","getBoundsZoom","fitBounds","setMaxZoom","attributionControl","ScaleControl","imperial","TileLayer","url","maxZoom","tms","MineLevelMapWithContext","mineLevelId","Provider","SEMANTIC_DEFAULTS","red","orange","yellow","amber","olive","green","teal","blue","violet","purple","pink","brown","grey","black","white","getSemanticColor","semantic","getEquivalentSemanticColorName","DeviceName","notFound","to","Link","brightness","light","offset","isNotResponding","lastCommand","lastCommandColor","transitionIndicatorIcon","lastCommandRow","timeRxd","Icon","cmdColor","plan","Grid","Column","singleLine","formatDateShort","statusTimeReceived","lastStatusReport","timeReceived","statusColor","cmdTimeSent","updated","includeLink","float","clear","paddingTop","JustId","FireflyName","RoundMarker","Circle","SquareMarker","radius","toBounds","Rectangle","BowtieMarker","positions","getNorthWest","getCenter","getNorthEast","getSouthEast","getSouthWest","Polygon","TriangleMarker","StarMarker","boundsOuter","boundsInner","HourGlassMarker","TravelwayMarker","DiamondMarker","FireflyMarker","statusSettings","deviceSettings","topologySettings","commandSettings","PopupContent","dashArray","lineColor","Marker","isInCommission","mode","isInTransition","isStrobing","led_state","status_check","travelway","pane","PureComponent","upsById","travelwayByLocation","fireflysById","isCommissioning","commissioningError","discoveryRequests","upsCommandRequests","advancedConfigRequests","makeHasChanged","fields","hasTopologyChanged","hasPositionChanged","calcTimeAndStatus","lastStatusReceived","handleFFUpdate","existing","topology","topo","isEqual","updateAllFFStatus","getAllUPSs","upsPanelControllers","getAllFireflys","ConnectedFirefly","statusError","CurrentMineLevelFirefliesFeatureGroup","nextProps","nextState","current","fireflies","next","lookup","len","FeatureGroup","fetchingAll","fetchingCurrent","merge","layersById","getMineLevelHistory","includeCurrent","seismicOverlays","forMineLevel","getCurrentSeismicLayer","history","getIsLoadingSeismicLayersForMineLevel","getSeismicLayerById","SeismicMapRegion","lightSettings","semColor","pointsFromBounds","pt1","pt2","lng1","lat1","lng2","lat2","SeismicLayerFeatureGroup","defaultRegion","regionSettings","levelDefault","mineLevelBounds","displayDefault","region","defaultProps","seismicLayerId","fetchCurrentSeismicLayerForMineLevel","CurrentSeismicFeatureGroup","prevProps","currentSeismicLayer","MineLevelSeismicFeatureGroup","UpdateNamedAreaDisplaySettings","fetchFolderFilesListByFolder","folder","TurnOnOffPokeTheWorker","SetMapImage","renderField","input","placeholder","disabled","touched","className","min","step","max","Form","Field","Boolean","Label","pointing","renderCheckbox","field","Checkbox","checked","onChange","renderRadio","Radio","radioValue","renderSelect","inline","multiple","backgroundColor","Select","onBlur","renderTextArea","TextArea","renderInput","Input","NamedAreaDisplaySettingsModal","handleOpen","modalOpen","handleCancel","resetModal","myHandleSubmit","handleSettingsSave","initialValues","open","prevState","handleSubmit","pristine","submitting","allowOperator","role","start","Modal","onClose","closeIcon","Content","onSubmit","stopPropagation","GridRow","GridColumn","component","columns","paddingBottom","Group","discrete","inverted","Segment","floated","Or","textAlign","reduxForm","form","enableReinitialize","keepDirtyOnReinitialize","touchOnChange","userSuper","userAdmin","userUser","allowGuest","allowAdmin","allowSuper","NamedAreaDisplaySettings","isOpenSettingsModal","showOptions","prevDisplaySettings","buttonSize","size","sortId","_a","_b","SearchControl","Control","extend","initialize","setOptions","onAdd","container","DomUtil","DomEvent","addListener","_","debounce","keyup","submit","disableClickPropagation","onRemove","removeListener","keyCode","innerHTML","href","setAttribute","appendChild","itemSelected","preventDefault","elem","target","getAttribute","getLatLng","_map","setView","getMaxZoom","UpdateMqttReset","bool","SetActiveArea","removeAcks","mqttPublish","namedAreaSetDeleteSelections","deleteSelections","namedAreaClearDeleteSelections","namedAreaSetShowHideSelections","hideSelections","namedAreaClearShowHideSelections","namedAreasSetIsDirty","namedAreasClearIsDirty","fireflyIdsUpdateListDeleteId","localMapState","movingMap","draggingMarker","GetLocalMap","isMapMoving","isDraggingMarker","UpdateLocalMap","SetMapMoving","SetMapMarkerDragging","sortAlphaNum","round","val","places","rnd","pow","omitDeep","newObject","assign","saveUPS","saveFirefly","fetchUPSs","fetchFireflys","deleteUPS","deleteFirefly","toWebColor","lowerCaseColor","iconName","iconUrl","btoa","iconColor","stroke","fill","iconSize","hackedAmbulancePng","hackedLightVehiclePng","hackedLoaderPng","hackedTruckPng","hackedJumboPng","IconMarkerSize","tagSize","makeIcon","zoom","strokeColor","alternateStrokeColor","alternate_stroke","alternateFillColor","alternate_fill","stdText_1","iconClass","posnText","svgURL","scaleIcon","trunc","svgIcon","typicalNumberedMapMarker","divIcon","html","iconAnchor","tagMarkerIcon","markerType","relaySirenMarker","markerClass","viewBox","strokeWidth","RenderSvgIcon","stroke-width","CrossMarker","Cross45Marker","paintOrder","BowTieMarker","ForwardMarker","BackwardMarker","WorkerMarker","NamedAreaPolygonPopup","strNamedArea","dataid","getRegionPreviewListByAreaId","regionPreview","preview","fetchNamedAreas","fetchNamedAreaEvents","fetchNamedAreaTriggers","fetchNamedAreaExtTriggerEventInfo","fetchNamedAreaScheduledEventInfo","saveNewNamedArea","saveNewNamedAreaEvent","deleteNamedArea","saveNewScheduledEvent","fetchScheduledEventJobs","deleteScheduledEventJob","isKthBitSet","showAreaPreview","stopAreaPreview","addAreaPreview","removeAreaPreview","newNamedAreaTemplate","lightState","namedAreaSubType","makeButton","clickable","title","alt","default","column","siren_state","createFireflyNamedAreaId","createNamedAreaAroundFirefly","point","areaName","uuid","ForceSingleLightManageNamedArea","setFireflyColor","setFireflyState","activate","fireflyNamedAreaId","namedAreaEventForFirefly","promiseArray","operationButton","isActivate","newSetFireflyState","currentNamedAreaEventForFireflyColor","currentNamedAreaEventForFireflyState","isStateChanged","isColorChanged","allForcedNamedAreas","highestForcedNamedAreaPriority","newNamedArea","SingleColorOperation","lightSetting","isEnabled","semanticColorName","popMsgForceButton","basic","ForceSingleLight","onChangeCheckboxStrobe","isNewForcedStrobe","checkedStrobe","buttonColor","onChangeCheckboxOff","isNewForcedOff","checkedOff","onToggleColor","evt","isCurrentForcedActive","isCurrentForcedStrobe","isForcedActive","currentForcedColor","isStrobe","isOff","_allowedLightColors","newAllowedLightColors","popupMsgStrobe","background","htmlFor","marginLeft","marginRight","cancel","FireflyMarkerPopupModal","handleForceSingleLightChange","isChanging","isPokeTheWorker","event_id","colorStatus","colorPlan","lightStatus","lightPlan","ups_id","z","fireflyNote","ffMac","deviceStatus","forcedClickList","currentForcedId","currentForcedState","controllerLink","controllerNoLink","fireflyLink","fireflyNoLink","replaceAll","isProcessingRequest","fontWeight","paddingLeft","Actions","fireflyCoords","device","mac","includeSeconds","ControllerMarkerPopupModal","network_name","controllerLabel","loc","locString","system","markerDefinition","controllerMode","alternate_color","ColorPlan","ColorStatus","AlternateColorPlan","AlternateColorStatus","StatePlan","StateStatus","textLabel","eventIdLabel","svgStyle","fetchAllUsers","saveUser","deleteUser","changeSettings","saveUserSettingsComponentState","DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER","tagTrackingFFsMarkers","faultMessageBannerId","faultType","messageBanners","clearFaultMessageBanner","bannerId","tmpObj","SetMessageBanner","areaImageNotFoundMessage","imageFilename","bannerDisplayed","bannerInfo","isBannerDisplayedForThisImageFilename","setFaultMessageBanner","cuid","getFaultMessageBannerText","messageBannerText","geojsonPolygonStyle","showCoordinates","alert","latlng","centerMap","panTo","fitMap","zoomIn","zoomOut","drawTheMap","mapId","geoJSONMarkersData","geoJSONNamedAreas","geoJSONControllers","image_filename","mapViewState","setCenter","setZoom","isMapLoading","mapSrc","overlayUrl","base","tileLayer","noWrap","tile","crs","CRS","Simple","zoomSnap","zoomControl","doubleClickZoom","contextmenu","contextmenuWidth","contextmenuItems","scrollWheelZoom","smoothWheelZoom","smoothSensitivity","canvas","createElement","toDataURL","myCustomControl","_div","_click","dataset","layerlistFireflies","setContent","getContainer","addTo","fireflySelection","isMapImageFromState","mapImageFromState","imageData","imageOverlay","_url","previousZoom","getZoom","previousCenter","testExternalStr","myRenderer","padding","uniqueProperties","entries","add","locationGroupLayers","featureGroup","filterArea","geoJSONGroupLayer","geoJSON","pointToLayer","currentZoom","renderer","draggable","onEachFeature","popupInfo","bindPopup","isPopupOpen","isMarkerDragging","isMapView","enableDataCollect","disableDataCollect","getPopup","getElement","querySelector","addEventListener","newModal","isOpenFireflyMarkerPopupModal","newFireFlySelection","ctrlKey","markerProperties","newMarkerPositionChanges","markerPositionChanges","setFillColor","layerlistControllers","geoJSONControllerGroupLayer","isOpenControllerMarkerPopupModal","layerlistNamedAreas","geoJSONNamedAreaGroupLayer","namedAreaPolygonPopup","renderToString","goto","coordsToLatLng","LatLng","eachLayer","_leaflet_id","geoJsonPixels","toGeoJSON","mineLevelObj","geoJsonUtm","convertGeoJsonPixelsToUtm","thislocalMapState","bringToBack","groupedOverlays","Markers","Polygons","control","groupedLayers","collapsed","groupsCollapsable","groupCheckboxes","disableMapMovement","dragging","touchZoom","boxZoom","keyboard","tap","moveMapViewButtonClick","moveMapViewButton","zoomOutButton","enable","zoomInButton","cancelMapViewButton","moveMarkerPositionsButton","saveMapViewStateButton","restoreMapViewStateButton","searchButton","enableMapMovement","mapStartMoving","toggleMapLayers","changeMarkerStyle","mapMoveLockButton","easyButton","states","stateName","disableActiveLayer","layerName","activeLayersList","newActiveLayersList","hasLayer","removeLayer","enableActiveLayer","enableAllActiveLayers","newActiveLayerList","moveMap","forceMapRefreshFireflys","forceMapRefreshControllers","activeLayerList","closePopup","setRestoreMapViewStateButton","mapStopMoving","easyBar","enableFeatureGroupDraggable","layerlist","markerName","newColor","setIcon","saveMarkerPositionsButton","cancelMarkerPositionsButton","disableAllActiveLayers","isPokeTheWorkerLocal","changedPosition","objLatLng","newPosition","fireflyPosition","fireflyLocation","fireflyMac","upsId","closeMarkerPositionButtons","editBar","savedMapViewState","animation","newMapViewState","section","componentstate","refreshMarkerPositionsButton","searchButtonClick","isNewShowSearchBox","isShowSearchBox","searchControl","remove","isMoving","iconOptions","getIcon","fire","ctrlKeyDown","ctrlKeyUp","mapMount","render","geoJSONMarkersDataUtm","geoJSONNamedAreasUtm","geoJSONControllersUtm","resetModalFirefly","resetModalController","refPts","heartBeat","isMapLoaded","layerControlState","isMapComponentDidMount","showTags","isMoveMarkerPositions","isEnableSearchBox","searchBoxContent","addWarningFlashMessageIdColor","removeEventListener","showMap","invalidateSize","newFireflyIdsUpdateList","newLayerListFireflies","updatedFireflyIds","currentLayerlistFireflies","newFireflyIdsUpdateListInCurrentLayers","newFireflyIdsUpdateListNotInCurrentLayers","updateFireflyMarkersGeoJSON","prevGeoJSONControllers","updateControllerMarkersGeoJSON","updateNamedAreasGeoJSON","prevGeoJSONMarkersData","forceUpdate","newLatLng","setLatLng","addData","prevJSONControllers","prevMarkerData","master","isChanged","_isEqual","isUpsBatteryOnFault","isUpsNetworkFault","isSirenActive","geoJSONPolygonData","layersIds","namedAreaIds","visibility","showLegend","minHeight","bgColor","g","contextTypes","router","PropTypes","object","isRequired","withComponentStateCache","markersData","regions","getNamedAreaInfosByParentInArray","getNamedAreaInfosByRegionPreviewByAreaId","faults","alarmButton","path","messageState","ALLOWED_LIGHT_COLORS","FireflyMarkerPopup","deviceStatusString","showForcedStyleDisplayHidden","hidden","clearing","buttonBackgroundStyle","borderColor","borderStyle","class","ControllerMarkerPopup","buttonLink","noLink","DEFAULT_SHOW_FIREFLY_POLYLINE_GROUP_LAYER","markerPts","localPtsGeoJson","geojsonFeature","markerToGeoJSON","geoJSONMarkersDataForced","geoJSONNamedAreaParents","setForceLight","rxSetFireflyState","forcedLightState","newForcedLightState","fireflyMarkerPopup","newForcedClickList","popup","_source","popUp","IdArray","forceMapRefresh","checkingCheck","toggleFireflyLed","querySelectorAll","isActiveForcedButton","currentFireflyLight","addLayer","geoJSONGroupLayerFireflyTooltips","circleMarker","TooltipClass","bindTooltip","direction","permanent","geoJSONGroupLayerFireflySimple","simpleSvgStyle","layerlistFirefliesForced","geoJSONGroupLayerFireflyForcedTooltips","geoJSONGroupLayerTags","onEachFeatureMarker","update","geoJsonPt","imagePt","coordPt","markerGroupLayer","refPtGroupLayer","controllerMarkerPopup","parentsUnionGroupLayers","uniqueNamedAreaParentProperties","regionGroupLayers","layerlistNamedAreaParents","geoJSONNamedAreaParentGroupLayer","orderedParentsUnionGroupLayers","Forced","Locations","polylineGroupLayers","posObject","ordered","polyline","addOverlay","_handlingClick","updateLayerControlState","currentCenter","editableLayers","randomPointInPoly","polygon","getBounds","x_min","x_max","y_min","y_max","turf","geoJSONMarkersDataUtmForced","geoJSONNamedAreaParentsUtm","regionGroupLayersCount","parentsUnionGroupLayersCount","Cables","regionPreviewList","isShow","isParentDirty","namedAreaDeleteSelections","namedAreaDeleted","selection","prevGeoJSONMarkersDataForced","updateFireflyForcedMarkersGeoJSON","prevGeoJSONNamedAreasUtm","newGeoJSONNamedAreasUtm","mqtt","localIds","mqttIds","geoIds","namedAreasHidden","namedAreaHideSelections","na","updateNamedAreaParentsGeoJSON","openPopup","newLayerlist","prevLayerlistFirefliesForcedIds","geoJSONMarkersDataForcedIds","LayerGroup","polyList","highQuality","unionTemp","unify","getLayers","getFireflyCoordinatesForcedByAreaId","geoJsonNamedAreaByParent","namedAreaInfosByParentId","combinedCoords","subType","naInfo","sameArea","sameType","sameSubType","sameParent","getNamedAreaParentInfos","createSelectorCreator","defaultMemoize","createDeepEqualSelector","endsWith","svgstyle","wrapper","SingleOperation","_onClick","buttonInfo","processClick","namedAreaParent","selectedNamedAreaButtonGroups","isActiveButton","isActive","isToggleButton","getNextPriorityEventOperation","selectedButtonGroups","nextPriorityEventOperation","groupButtonSet","seconds","updatebuttons","buttonStyle","buttonActive","buttonEnabled","iconOpacity","isShowHint","allAreas","createGroup","compact","createGroupMinimal","displayAllOnMineLevel","isTabletOrMobileDevice","useMediaQuery","query","sizes","MineLevelPrecannedOperationsList","_prepViewables","namedAreasParents","levelWideNamedArea","viewables","rowHeight","fontSize","rowGetter","_getDatum","disableHeader","rowCount","onRowMouseOver","rowData","onRowMouseOut","dataKey","cellRenderer","ICON_DEFINITIONS","isSirenIcon","isExtTriggerIcon","isScheduledIcon","rxOperation","prevRelayActive","isRemoteButtonClick","isResendEvent","contextRef","createRef","buttonRef","prevRemoteButtonClick","handleClick","removeRemoteButtonClick","maxLabelLength","_isUserRelay","handleItemClick","clearAreaPreview","addAllAreaPreview","currentArea","allNamedAreaPolygons","row","previewState","isPreview","isAnyPreview","isDesktopOrLaptop","displayIcons","isButtonIcons","buttonWidth","marginBottom","displayIcon","Ref","innerRef","onContextMenu","left","clientX","top","clientY","right","bottom","getBoundingClientRect","createContextFromEvent","context","Menu","vertical","Item","as","stringnamedareaparentpriority","getRegionPreviewList","allPolygonsArray","clickList","Heartbeat","_Component","instance","Constructor","TypeError","_classCallCheck","_this","ReferenceError","_possibleConstructorReturn","beat","nextBeat","heartbeatInterval","heartbeatFunction","diff_time","nextTimeout","timeout","subClass","superClass","prototype","constructor","enumerable","writable","configurable","setPrototypeOf","__proto__","_inherits","componentDidMount","componentWillUnmount","clearTimeout","Fragment","MineLevelCustomSOPList","getSimData","simData","handleTimeoutSirenIconClick","newSirenIconClickTimeout","sirenIconClickTimeout","timerSirenIconClick","ids","handleSirenIconClick","namedAreaParentsPriorityByLevel","uniqueParentsNamedAreaEventsSirenActive","isSirenIconActive","toggleIdState","stringAllOnLevel","stringActiveSiren","sirenState","handleTimeoutLightControlSim","timerProps","sampleRandomButton","sample","lightControlSimData","onChangeLightControlSimCheckbox","isLightControlSim","lightControlSimRate","styleInfo","settingsLightControlSim","getStringUniqueParentsNamedAreaEvents_Source_EventActive","namedAreasEvents_Source_Active","uniqueParentnamedAreasEvents_Source_ActiveArray","uniqueParentsNamedAreaEvents_Source_Active","has","stringUniqueParentsNamedAreaEvents_Source_Active","boomgateCrane","headerFontSize","showEventButtons","sopRows","sopRowStyle","userAccessThisGroup","nag","access","hide","subItem","namedAreasEventsSirenActive","stringUniqueParentsNamedAreaEventsSirenActive","it","newSirenState","siren","isShowSiren","toggleIdStateON","toggleIdStateOFF","namedAreasEventsExternalTriggerEventActive","stringUniqueParentsNamedAreaEventsExternalTriggerEventActive","namedAreasEventsScheduledEventActive","stringUniqueParentsNamedAreaEventsScheduledEventActive","flexWrap","newGroupsArray","buttonLabel","toggle","imageCheck","MineLevelOpsControl","areaMapSimple","areaImageToState","_isBoomgateCrane","_isLightingControl","areaIds","areaImageFileNames","Image","imageSrc","onload","mapsLoaded","isDragging","mapImagesFromState","mapImageIds","controlsWidth","imageWidth","hideLeftColumn","hideRightColumn","divided","tertiary","loadingMessage","Dimmer","Loader","parentState","DebugPagePropsMessages","that","LegendIcon","imageUrl","tooltip","Legend","icons","GeneralHomePage","levels","isDataLoading","isShowLegend","configJs","startupProblem","templateDefaultArea","FlashMessages","Tab","menu","attached","tabular","justifyContent","panes","menuItem","Pane","thisUser","shadowUrl","popupAnchor","shadowSize","standardPtsUtm","Transform","subGroupData","tempGroupData","MySimple","transformation","Transformation","holdingPen","baseLayers","MineMap","overLayers","RefPt","layerControl","_round","num","strLatLng","drawPluginOptions","draw","allowIntersection","drawError","shapeOptions","circle","rectangle","circlemarker","edit","selectedPathOptions","drawControl","Draw","addControl","Event","CREATED","namedAreaTimestamp","stamp","default_state","default_color","EDITED","CircleMarker","getRadius","latlngs","_defaultShape","getLatLngs","Polyline","distance","distanceTo","getPopupContent","setPopupContent","EDITSTOP","DRAWSTOP","DELETED","editedlayers","_container","addNewFeatureToGeoJsonLayerGroup","myGeoJsonLayerGroup","newGeoJsonData","updateFeature","updatedGeoJsonData","deleteFeature","myFeaturesMap","deletedGeoJsonData","deletedFeature","objectID","isCheckboxMarker","isCheckboxRefMarker","iconSelection","prevGeoJSONMarkersDataUtm","newGeoJSONMarkersDataUtm","hasHoldingPen","newValue","newPointUTtm","isCheckboxFireflies","isCheckboxPolyline","isAddPolygonClicked","blueMarker","redMarker","yellowMarker","greenMarker","newStyle","setStyle","getFireflyCoordinates","DraggableTableRow","onDragStart","ev","dataTransfer","setData","onDragOver","onDrop","getData","parseInt","rowStyle","rowStyles","testController","Z","testFF","testLedFF","testArea","slug","ceiling","testNamedAreaEvent","testNamedArea","testNamedAreas","officeControllers","officeFireflies","TableMade","swap","splice","onColorClick","newData","colors","currentColor","findIndex","onEventClick","col","eventsSelected","onSendMqtt","onDeleteClick","deleteRowId","onShowHideClick","hideRowId","getRowsData","itemsLength","dataLength","sendNamedAreaSetupMqtt","changedNamedAreas","newMsg","GeoJsonToMqttNamedAreaChange","resetIsDirty","isEventSelected","isEventSet","events","notMineLevels","element","isDeleteAllSelected","onDeleteAllClicked","eventColumns","parentIsDirty","mergedData","currentNamedRowIds","indexOfButtonObject","iconButtons","headerCellsRowTop","HeaderCell","indeterminate","Footer","RenderRow","useState","setOpen","eyeIcon","gripIcon","handleShowHideClick","handleDeleteClick","RenderRowColorBox","colorBoxStyle","borderRadius","border","margin","TestNamedAreaTable","tableData","deleteSelection","hideSelection","ts","namedAreasReduced","getNamedAreaEvents","localNamedAreasReduced","GetLocalMapNamedAreasReducedProperties","Default","_getIconUrl","mergeOptions","iconRetinaUrl","TestMqttGeoJson","onClickCheckbox","getNested","overflowWrap","GatesAndCrane","machines","gateColor","craneColor","alarmColor","boomgate","machineIndex","notHint","controllerIp","getAllExternalTriggerById","getAllButtonTriggerById","ControlRoomPage","updateWindowDimensions","innerWidth","innerHeight","handleTabChange","activeIndex","tabIndex","currentMapTab","isInteger","prevLevelIds","levelIds","mapTab","allAreasNamedArea","isSopInterface","allAreasButtonGroup","_controlScreenEmergencyEventButtons","onTabChange","MineLevelOpsControlMinimal","TrailingContent","columnSpan","DeleteButton","clicked","close","onOpen","getAllConflicts","conflicts","capitalize","ExcelFile","ReactExport","ExcelSheet","ExcelColumn","exportFieldsTemplate","Download","dataType","exportFields","exportExcelColumns","displayOptions","_derivedState","incomingState","areAnySelected","selections","selectedCount","_size","FireflyList","handleSort","clickedColumn","handleFilterStatusChange","statusGroup","search","setFilterState","handleFilterChange","include","filterInput","string","handleDropdownItemsPerPage","itemsPerPage","page","setPageNum","activePage","handleClearAll","handleSelect","_has","$unset","$set","handleSelectAll","newSelections","statusValue","areAllIndeterminate","areAllSelected","_every","isItemSelected","requestDelete","checkMatch","checkItemString","checkMatchString","checkIncludes","pagination","itemsCount","viewablesPage","totalPages","alignItems","Pagination","ceil","siblingRange","onPageChange","Dropdown","defaultValue","deleteButton","fireflyDeleteList","allData","fireflyFromDataById","fireflyNames","fireflyName","headerCellStyle","borderBottom","striped","fluid","sorted","disableDelete","swVersion","_prepData","elements","roles","filteredElements","ups_name","sw_ver","elementStatus","shiftedInLocation","shiftedPosition","sortedShiftedInLocation","nextItem","newMac","oldMac","prevPosition","isShiftedPosition","getStatus","fireflyIds","jsonObj","tryParseJSON","GeoJSON","hash","popupContent","ml","currentValue","ChooseMineLevelField","getUPSById","simplify","flat","Children","toArray","reactChildrenToFlatArray","child","node","memo","padBounds","setMap","mapRef","useRef","useEffect","log2","getSize","touchExtend","ImageOverlay","rxMapViewState","mapViewType","isPanZoomButton","isShowRestoreMapViewStateButton","isShowSearchControl","setIsMapView","isMapViewCurent","newOptions","setting","newCenter","newZoom","handleMoveZoomEnd","mapKey","onZoomEnd","onMoveEnd","MineLevelMapById","image_Info","DivIcon","SVGIcon","circleText","circleAnchor","circleColor","circleOpacity","circleFillColor","circleFillOpacity","circleRatio","circleWeight","fontColor","fontOpacity","_createPath","_createCircle","_createSVG","strokeOpacity","_createPathDescription","pathDescription","Opacity","_createText","lineHeight","SVGMarker","iconFactory","_latlng","_icon","iconBody","iconCircle","setOpacity","MapMarker","onDragend","selector","formValueSelector","SEMANTIC_BLACK","FireflyMoveableMarker","onDragEnded","ll","markerColor","outline","SaveButton","positive","statusReport","updatedStatusReport","timestampRx","deviceStatusRx","SubmissionModal","handleClose","onResetError","modalMessage","errorMessage","NavigationPromptModal","shouldPromptSaveShow","submitted","isFormDirty","isSubmitting","submitSucceeded","formValues","_action","promptSaveCatchAndSave","onConfirm","onCancel","formName","remoteSubmit","isValid","when","getFormValues","hasSubmitSucceeded","MapPositioningDisplay","FireflyDetailsForm","expandCollapse","collapse","handleAddition","handleChange","submitMyForm","newValues","errorMsg","cancelForm","clickControllerIdIcon","controllerId","isDeleteButton","isCollapse","openModal","LayersControl","Overlay","FireflyRawStatusReport","stretched","Divider","widths","borderless","withRouter","fireflyCoord","controllerName","commissionedTopology","isBLETagDetect","idBLETag","previousValues","mdt","dataLoadingMessageQueue","List","FireflyDetail","params","FireflyAdminPages","Switch","Route","ChooseEditorMode","ChooseEditorModeField","PORT_COLORS","getPortColor","CommissioningStatus","ERROR","NO_CHANGES","TOPO_AND_POS","TOPO_ONLY","POS_ONLY","formname","originalCommissioning","diffTopo","fireflyFormRecord","diffPos","hasLatLngChanged","FireflyRow","PortSummaryFireflyDetails","normalise","PortSummaryField","expanded","resetForm","locationHint","showSection","_allowedLightStates","isEmergencyEventSettings","isTriggerEventSettings","form_emergencyPortEnable","form_triggerPortEnable","flexFlow","normalize","Accordion","Title","form_ups","portIndex","isPristine","UPSMoveableMarker","UPSPortStringMapLocationEditor","newLocation","asIndividuals","onRepositioned","first","last","numIntevals","startPos","endPos","offsetLat","offsetLng","dLat","dLng","newPositions","baseColor","upsPosition","lastIdx","lineLocations","isMoveable","onDragEnd","makeOnDragEnd","from","Cable","UPSBulkPositioningForm","formdata","saveEmergencyEventSettings","saveTriggerEventSettings","ports","changePositions","ffInitialValue","positionInitialValue","upsIdInitial","positionInitial","upsPositionsInitialValue","makeEventSettings","portSettings","initialValuesEmergencyEventSettings","initialValuesTriggerEventSettings","changeSetting","changePosition","isIgnoreEmergencyTriggerEvents","areaError","PortComponent","UPSPortString","UPSRawStatusReport","isPorts","PortSummary","ListPorts","ForAllPorts","FieldArray","unboundChange","ffId","positionMode","isAsIndividuals","stateUPS","firefly_count","ignore_server","controllerCoord","getControllerCoordinatesById","tempCoordsProvider","created","stateFireflies","getFireflyByControllerId","byPortByOrdinal","port_number","portByOrdinal","lastStatus","ffCoord","isSomeZero","ffPosition","getControllerEmergencyEventSettingsById","getControllerTriggerEventSettingsById","defaultPortSettings","sortBy","ordinal","savePositions","UPSDetail","UPSList","requestAction","dataRx","prevDataRx","controllerBulkPosLink","controllerIpLink","theRest","prevData","controllerDeleteList","controllerFromDataById","controllerNames","masterIcon","batteryVoltage","dcVoltage","diskUsed","memUsed","allFireflyStatuses","locations","rel","controllerSoftVersion","electrical","voltage","dc_supply","disk","mem","newLocations","controllerUpsId","controllers","controllerFireflies","isControllerCommissioned","isControllerAllFireflysCommissioned","BulkPositioningAdminPages","UPSBulkEditPage","exact","ListNamedAreaGroups","language","strNamedAreaGroups","strArea","CreateNamedAreaGroups","onSetError","SubmissionError","validationErrors","getItemStyle","highlightColor","draggableStyle","userSelect","getListStyle","isDraggingOver","NamedAreaGroupTableSubSubItems","onClickHandler","groupId","NAMEDAREAS","_eventTriggerOptions","droppableId","provided","snapshot","droppableProps","buttonProps","namedAreaButtons","draggableId","draggableProps","dragHandleProps","permission","NamedAreaGroupTableSubItems","newCollapse","collapseAll","groupIds","minValueEqual","maxValueEqual","users","getAllUsers","getUserById","monthOptions","dayOptions","_CronWizard","handleMonthChange","handleEveryCheck","handleTrashClick","rowContent","checkProp","NamedAreaGroupSettingsModal","handleReset","handleDelete","handleSettingsDelete","saveAccessSettings","allUserUsers","isSaveUserChanges","u","newUserUser","newSettingNamedAreaGroup","userNagSetting","newCron","cron_duration","cron_user_relay","changedAccessSettings","handleActiveColorChange","handleActiveAlternateStateChange","handleActiveStateChange","onChangePermission","bit","stateValuePermission","optionKey","newPermissions","bit_test","bit_clear","bit_set","permissionRadiosContent","onClickHandlerAccessIcon","propData","accessIcon","popupMsg","permissions","isPriorityLevel","isStateOn","isStateStrobe","isStateForwardBackward","buttonOptions","namedAreaParentButton","sectionTitle","_allowedAlternateLightColors","_allowedMapMarkers","defaultAccessRow","structured","rowSpan","stateValueActiveState","eventTriggerOptionsTemplate","isBitSet","getAllUsersByRole","sortAccessSettings","allUsersRoleUser","nagSettings","getAllUsersRoleUserSettingsNamedAreaGroup","defaultSettings","reorder","startIndex","endIndex","removed","findParent","MergeSettings","obj1","obj2","obj3","attrname","NamedAreaGroupTable","collapseLevel","source","destination","cloneItems","itemId","itemSubItemMap","destParentId","destParentObject","destClone","newItems","newSubItem","setStateNewItems","sourceIndex","destIndex","sourceParentId","sourceSubItems","destSubItems","reorderedSubItems","newSourceSubItems","draggedItem","newDestSubItems","sourceParentObject","updatedNewDestSubItems","newItem","newButton","findItem","updateItem","newSubSubItem","prevSettings","deleteItem","newCollapseAll","openSettingsModal","modalSettings","newId","newId2","newGroup","active_brightness_level","newLevel","listOfNamedAreas","onItemsChange","strNamedAreas","flex","isDropDisabled","EditNamedAreaGroupForm","contentLoading","strNamedAreaGroup","validate","reduxFormValues","prevNamedAreaGroup","prevNamedAreaGroupButtonStates","getPrevNamedAreaGroups","namedAreaGroups","getPrevNamedAreaGroupButtonStates","NamedAreaGroupPostSaveOptionsModal","restoreButton","handleRestore","namedAreaGroupButtons","buttonGroupStates","prevNamedAreaGroups","activeAllNamedAreaEvents","namedAreaGroupButtonStates","buttonId","buttonPriority","buttonEvent","newButtonGroupState","newActiveEventList","prevNamedAreaGroupButtonState","restoreToButton","_restorePrevActiveEvents","namedAreaEventButtonGroupState","updateNamedAreaGroup","EditNamedAreaGroup","getInitialValues","namedAreaParents","setItemsPriority","namedAreaParentsChanges","priorityBase","indexGroup","indexLevel","indexNamedArea","temp","buttonChanges","setButtonsByPriority","maxPriority","firstPoint","named_area_group","updateNamedAreaButtonsByParentIdMqtt","clear_events","saveSuccess","onSubmitFail","NamedAreaGroupAdminPages","EnableDisableButton","ListNamedAreas","deleteItemByNamedAreaParentId","newNamedAreaGroup","allNamedAreas","namedAreaSelectedList","namedAreaFromDataById","namedAreaNames","namedAreaName","namedAreaLink","filteredParents","ListAllNamedAreas","relayEventActive","filtered","relay_event_inactive","ListAllNamedAreaEvents","sendEventClearMsg","activeColor","activeState","activeStateInfo","range","allNamedAreaEvents","end","NamedAreaButtonSettingsModal","buttonIdx","marginTop","stateValue","homogoniseButtonsForAllNamedAreas","incomingData","currentState","prevNamedAreas","homoNamedAreas","currentNumberOfButtons","updateButtonsId","getRowIcons","leftPaddingHeaderCells","rightPaddingHeaderCells","handleCogClick","editSettingsButton","handleLinkClick","leftButtonGroup","thisButtonGroup","newButtonGroupArray","but","getRowDefaults","rowPropertieStyle","getRowButtonActives","setButtonActive","buttonIndex","buttonState","onButtonActiveToggle","onButtonAdd","lastButton","getRowButtonDeletes","namedAreaIdValue","namedAreaParentName","newParent","newParentName","namedAreaMsg","buttonSettings","updatedButton","buttonsDeleted","prevDataNamedArea","thisDataNamedArea","RenderCogLinkIcon","buttonsLen","iconBg","iconHint","cursor","RenderRowDefaults","RenderRowButtonActives","isCheckSelected","verticalAlign","handleCheckClick","RenderRowAddButton","handleAddButtonClick","RenderRowButtonDeletes","colorBoxIcon","NamedAreaTable","polygonStyle","numberofEditableLayers","numberofGeoJsonLayers","number","selectColor","holdingPenPolygon_bottomLeft","drawLocal","toolbar","actions","finish","undo","handlers","cont","simpleshape","save","clearAll","editDisabled","removeDisabled","subtext","showArea","namedAreaRegionId","parentNamedArea","newPolygonStyle","setDrawingOptions","southWest","northEast","namedAreaByParent","getNamedAreaInfosByParentId_local","newPointUtm","orangeMarker","whiteMarker","fireflyMarkers","required","isNamedAreaNameOK","allValues","uniqueNamedAreaParentIds","valueNoSpace","notIncludingThisId","CreateNamedAreaForm","ClearLocalMap","refLocationsComponent","t","CreateNamedArea","onSubmitSuccess","EditNamedAreaForm","EditNamedArea","updateNamedArea","NoMatch","pathname","NamedAreaPage","ListNamedAreasSimple","namedAreaParentId","newNamedAreaParent","newNamedAreaName","copyString","lengthCoord","butt","copyNamedArea","rxColumn","addButton","copyButton","newElements","sanitizeRegionShape","smallest","indexOfSmallest","buildNewRegion","regionListWithoutId","CreateRegionsField","addRegion","newRegionList","addRegion_New","deleteRegion","deleteRegion_New","changeRegion","changeRegion_New","handleActivityStarted","editing","handleActivityStopped","mineLevelIdValue","onCreated","onDeleted","onEdited","onActivityStarted","onActivityStopped","controlProps","showLength","metric","feet","maintainColor","NamedAreaSimpleForm","onDelete","importSvgCheck","importSvg","importSvgSubmit","diagonalRefCoords","ref2","ref1","ref4","ref3","newGeo","currentRegions","newRegions","newRegion","handleColorClick","displayColorPicker","handleColorClose","handleColorChange","rgb","isActivity","activeEvent","stylesColorPicker","reactCSS","swatch","boxShadow","popover","cover","isNewNamedArea","formatString","polygon_type","getAreaStatuses","fetchTags","unassignUser","unassignVehicle","addUpdateUser","addUpdateVehicle","deleteTagUserById","deleteTagVehicleById","updateTagZone","fetchAllTagUsers","fetchAllTagVehicles","CreateNamedAreaSimple","_preProcessValues","thisArea","newNamedAreas","isNamedAreaActive","EditNamedAreaSimple","updateItemByNamedAreaParentId","tempItem","makeNewNamedAreaGroup","old_newNamedAreaGroup","parentIds","namedAreasByParent","activateEvent","activeNamedAreaEventButton","originalNamedAreaIds","updatedNamedAreaIds","deletedNamedAreaIds","templateObj","updateButtons","allSettled","topicArray","topicType","topicId","topicAction","checkToken","Api","reason","namedAreaParentStyle","backgroundObjTemplate","rgbString","alpha","colorArr","getNamedAreaEventsByParentId","templateNamedAreaParent","startSubmit","NamedAreaSimpleAdminPages","xhr","XMLHttpRequest","responseType","reader","FileReader","readAsDataURL","onloadend","base64data","send","ListMineLevels","deleteArea","isAreaImage","strAreas","pageTitle","areaSelectedList","areaFromDataById","areaNames","areaLink","ImageUpload","files","onFileChanged","labelPosition","click","_handleImageChange","accept","loadImgToFile","newFilename","clone","blob","blobFile","loadImage","imageLoadPromise","isAreaNameOK","allAreaIds","calculateAreaRegion","imageRef1","imageRef2","imageRef3","imageRef4","utmRef","pixelRef","_northEast","boundsArray","bound","initialiseValues","defaultColor","defaultState","defaultRefCoords","imageFile","imageHeight","newFile","newImageInfo","areaRegion","mapFile","mapUrl","CreateMineLevelForm","svgMarkerIcon","textAnchor","onFieldChanged","createRefTable","colObjRef","colLabel","colType","colFieldType","table","transparent","onMapChanged","handleOrderChange","templateDefaultAreaRefCoords","contains","MapWithImage","orderOptions","CreateMineLevel","stopSubmit","prepValues","refObject","filenameArray","EditMineLevelForm","currentBounds","handleDefaultColorChange","handleDefaultStateChange","testImageUrl","theInitialValues","EditMineLevel","updateMineLevel","submitError","MineLevelAdminPages","tagTrackingUserDetailsCardPersonnel","urlImage","tagUserId","showDetails","cardTitle","minValueEqual0","maxValueEqual25","tagTrackingUserDetailsCardVehicle","tagsObject","tagCoordinates","tagPersonnel","tagVehicles","makeGeoJson","updateTagObjectStatus","newTagObjects","newTagObject","last_updated","reported_ts","updateTagCoordStatus","tagsCoords","newTagCoords","newTagCoord","updateTagsObject","newTagsObject","coord_to","locations_to","calculated_rssi","tag_id","user_info","vehicle_info","makeTagCoordFeature","newTag","tagId","tagUserType","userInfo","vehicleInfo","zones","tempCoords","zone","getTagsAssignedByTagType","tagObjects","tagType","getAllTags","tags","getTagById","getTagPersonnel","getTagVehicles","getAllTagTrackingGeoJson","getTagTrackingCoordinatesByAreaId","tagTypeOptions","TagTrackingDetailsForm","requestUnassign","onUnassign","isAssigned","onChangeSelectUserType","onChangeSelectUser","assigned","allowToShowDetails","tagPersonnelSelectOptions","tagVehicleSelectOptions","tagUserOptions","loadUserOptions","searchText","tagUserImage","getOptionLabel","getOptionValue","loadOptions","firstname","lastname","TagTrackingEditPage","assignVehicle","assignPersonnel","assignUser","unassignPersonnel","user_id","vehicle_id","unassignId","tagData","tagUserData","LogIt","thingsLogged","ClearLog","TagTrackingList","disableUnassign","fetchStuff","tagSelection","rssi","vehicle","tagZone","tagEntry","includeTitles","strTags","unassignButton","tagSelectedList","tagUserFromDataById","tagNames","tagName","list_items","segmentStyle","list_count_item","list_length","tagLink","getAllTagCoordinates","tagUsers","personnel","vehicles","lastUpdated","tagZones","tagInfoPersonnel","DateTime","fromISO","toFormat","TagTrackingAdminPages","TagTrackingUserList","tagUser","strTagUser","strTagUsers","tagUserSelectedList","tagUserNames","tagUserName","tagUserLink","userData","tagsAssigned","TagTrackingUserForm","formType","assignedTags","uniqueTagIds","uniqueAssignedTags","TagTrackingUserEditPage","saveAddUpdateUser","saveAddUpdateVehicle","deleteId","nick","TagTrackingUserCreatePage","TagTrackingUserAdminPages","ExternalTriggerEditForm","rxData","selectedArea","strExternalTriggers","updateButton","enableButton","disableButton","externalTriggerSelectedList","externalTriggerFromDataById","externalTriggerNames","externalTriggerName","ExternalTriggerEditPage","changeLocalisation","localisation","fieldData","buttonCustomLabel","groupLabel","levelLabel","eventInfo","button_custom_label","button_label","group_label","level_label","secure_key","secureKey","getNamedAreaExtTriggerEventInfo","ScheduledEventList","strScheduledEventJob","optionsMonths","optionsDayOfWeek","optionsHours","hours","optionsMinutes","minutes","options60mins","options24hours","options12months","optionsDuration","dateToCron","second","getSeconds","minute","getMinutes","hour","getHours","dayOfMonth","getDate","month","getMonth","dayOfWeek","getDay","DEFAULT_CRON","year","isScheduledEventNameOK","DEBUG_HIDDEN","ScheduledEventForm","setSelectedTimezone","selectedTimezone","cronValue","handleSelectMonth","handleCheckEveryMonth","handleSelectDay","handleCheckEveryDay","handleSelectDayOfWeek","disableDay","handleCheckEveryHour","handleCheckEveryMinute","valueDuration","handleSelectGroup","isAddEvent","handleSelectLevel","handleSelectPolygon","onClickAddEvent","namedAreaGroupOption","namedAreaGroupInfo","newEvents","nagInfo","handleUserRelayChange","currentEvent","handleChangeStepperBitRegister","valueBitRegister","handleChangeDuration","handleSelectDurationUnit","currentTimezone","dateTime","datesRange","dateStart","dateStop","Intl","DateTimeFormat","resolvedOptions","timeZone","cronStartExpression","cronStopExpression","userLanguage","everyDay","everyHour","everyMinute","strScheduledEvent","isNewScheduledEvent","cronstrueLocale","userLocale","optionsFilteredDuration","optionsFilteredDayOfMonth","days","optionsDays","eventsTableNoneContent","everyMonth","handleSelectHour","handleSelectMinute","minValue","maxValue","duration","valueMin","everyMin","durationInputMax","stepAmount","cronstrue","locale","use24HourTimeFormat","startExp","stopExp","parseExpression","stop","dateFormat","weekday","day","hour12","startDate","toLocaleString","stopDate","nextCronTableContent","groupOptions","levelOptions","polygonOptions","eventsTableContent","getNamedAreasInfoInNamedAreaGroupByAreaId","newNamedAreaGroupInfo","getGroupOptions","groupOption","getLevelOptions","levelOption","isAlreadySelected","getPolygonOptions","durationUnit","cronObj","everyString","cronString","cronStringNoYear","isCronOK","isValidCron","cronResult","override","useSeconds","useYears","validValue","getValue","years","daysOfWeek","months","daysOfMonth","cronStartStringNoYear","startParse","nextStartParse","cronNextStart","durationSecs","setSeconds","cronDuration","arrayStart","arrayDuration","diff","startString","arrayCron","stopString","errorValue","getError","convertFieldsToCronExpression","ScheduledEventCreatePage","area_id","ScheduledEventEdtPage","eventJob","ScheduledEventListAllJobs","onlyActiveJobs","jobTemplate","newName","cronExpression","periodSelection","newFilterInput","strEventJob","eventJobSelectedList","eventJobFromDataById","eventJobNames","eventJobName","nameLink","jobCreated","jobState","jobStateClass","uniqueKeys","firstJobInOnlyActiveJobs","eventLog","allEventLog","downloadHeaders","periodOptions","EventLogListAllEvents","handleFilterPeriodSelectorChange","fetchEventLogPeriod","strEventLog","headers","strShape","fireflyList","rxElements","ts_string","firefly_list","ts_sec","ts_msec","strTimestamp","getEventLog","ScheduledEventListEditForm","strScheduledEvents","scheduledEventSelectedList","scheduledEventFromDataById","scheduledEventNames","scheduledEventName","sourceId","ScheduledEventListEditPage","sourceName","operatorArray","getNamedAreaScheduledEventInfo","EventAdminPages","ScheduledEventEditPage","LogPage","frameBorder","FailPage","AlarmButton","clickAction","faultAction","mqttFaultTs","faultMaxFaultTs","SetLatestFaultTs","getHighestFaultLevel","prev","fault_level","pageFaultTs","isMessageBannerForFaultType","getButtonStyle","getButtonClass","getButtonIcon","getButtonIconRotate","getButtonLink","getButtonTooltip","fault_type","getLatestFaultTs","timeConverter","UNIX_timestamp","getFullYear","FaultList","downloadData","mqttMsgDefault","fault_ts","allFaultData","prevPropsData","idLink","descriptionLink","fault_tsReadable","subtype","faultLevel","ipLink","matches","ipArray","controllerMac","getLocalisation","getLocalisationByComponentId","allTerms","getLocalisationByApplicationId","uniqueLanguages","sortUniqueLanguages","byLanguage","term","terms","reference","LoginForm","fieldErrors","login","validateInput","toggleShow","onKeyDown","keyEvent","getModifierState","capsLockOn","link","primary","Logger","logger","logOfThingsLogged","HomePage","Card","MineLevelMenuItem","toSlug","simple","Wrapped","Wrapper","actionObject","actionOnMount","AdminMenu","_isShowBackupRestore","areaTitle","_isTagTracking","TagTrackingMenu","_isTagTrackingMap","OperatorMenu","LightingControlMenu","_isShowExternalTriggerEvent","_isShowScheduledEvent","_isShowEventLog","DataCollectButton","isFetching","TestMenu","getWindowDimensions","userLinks","userLinksMinimal","subHeader","showMinimal","_configAppTitle","_isDevelopmentVersion","_isDemoMode","windowDimensions","setWindowDimensions","handleResize","useWindowDimensions","isMobile","isTablet","isLaptop","isDesktop","alarmButtonSize","hideAlarmButtons","strTitle","navButtons","serverVersion","atob","getConfigItem","sanitizeLightSettings","buildPlainAction","lowerRegionPriority","raiseRegionPriority","forceWholeSettings","HeaderRow","BuildItemRow","activeLayer","previewingId","onPreview","onReinstate","onStartEditorWithSeismic","toISOString","SeismicLayerList","ConnectedSeismicLayerList","fetchSeismicLayers","startEditingWithSeismicAsStart","MineLevelSeismicLayerSummaryPage","selectForPreview","previewId","showPreview","MineLevelSeismicLayerList","blankSeismic","regionsReducer","isSaving","savingError","without","swapIndexes","index1","index2","newList","getEditingDefaultSettings","editorSeismicLayer","getEditingRegionsInOrder","makeId","CreateRegionsMapEditor","regionId","renderId","orderedRegions","newShape","ChooseLightSettings","closeOnChange","UpDown","onUp","onDown","iconStyle","EditRegionSettingsList","regionActions","changeLightSettings","raisePriority","lowerPriority","lastIndex","relaxed","Description","changeDefaultColor","onCopyExistingSettings","dividing","SaveSettingsButton","isEditing","saveAndApply","SaveError","UISettings","onOpacityChange","showDefault","onToggleShowDefault","formatLabel","CreateSeismicOverlayPage","onStartedEditingShapes","onStoppedEditingShapes","triggerReset","currentSeismicControlName","defaultLevel","defaultLayerColor","Pattern","spreadMethod","stopColor","stopOpacity","useActiveSeismicAsStartingPoint","PageNotImplemented","getMineLevelByNameSlug","nameSlug","MineLevelStatusPage","CheckBrowser","checkBrowser","isBrowerOfLimitedFunctionality","TagTrackingByZoneList","zoneContent","NbTags","placeContent","borderLeft","levelData","stackable","tagZoneNamedAreas","tagsByAreaByZone","tagZoneNamedAreasByArea","sortedByDatetagZoneNamedAreasByArea","groupedTagZonesByAreaByParent","tagsByArea","leaflet","containerDiv","MapControl","withLeaflet","TagTrackingMarkerPopupModal","tagTrackingUserDetailsCardUnknown","newInitialVales","createClusterCustomIcon","cluster","getChildCount","filterTags","activeTagType","CurrentTagTrackingFeatureGroup","isOpenTagTrackingMarkerPopupModal","isOpenTagTrackingMarkerPopup","newTags","valid","showCoverageOnHover","spiderfyDistanceMultiplier","iconCreateFunction","tagIcon","tagColor","tagIds","getTagIdsByAreaId","TagTrackingZonesMarkerPopupModal","CurrentTagTrackingZonesFeatureGroup","isOpenTagTrackingZonesMarkerPopupModal","isOpenTagTrackingZonesMarkerPopup","getNamedAreaInfosBySubTypeId","tagTypeDisplaySettings","TagTrackingMap","handleOnClick","newActiveTagType","fetchTagTrackingAreaStatuses","displayTagTypes","savedMapViewStates","newCurrentArea","savedMapViewStateForArea","newDisplayOptions","checkState","nextsavedMapViewStateCurrentArea","checkSavedMapViewState","newSavedMapViewStateCurrentArea","tagsAreas","isSearchControl","mapKeyObject","tagSetting","allTagTrackingGeoJson","tagsArea","UserEditForm","changeRole","changePassword","changeName","changeLanguage","isSuper","changes","onChangeApplication","stateValueApplication","optionkey","newApplication","app","applicationRadiosContent","isAdmin","onChangeFeature","stateValueFeature","featureRadiosContent","allUserEmails","isThisUser","dataError","emailId","_allowedLanguages","_allowedRoles","_allowedApplications","_allowedFeatures","thisUserId","thisUserLang","UserEditPage","UserPages","ListUsers","allUsers","allUsersExceptThisUser","userName","userEmail","userApplication","usersSelectedList","usersFromDataById","userEmailNames","userEmailName","userEmailLink","userRole","userLang","thisUserRole","getUserRole","uniqueEmail","UserCreateForm","UserCreatePage","UserAdminPages","UserAdminList","iconForFileType","fileArray","HelpFilesList","noFilesMessage","filesMessage","HelpFilesListAreas","ToolsMqtt","ToolsDatabase","Terminal","xtermRef","terminal","writeln","ToolsTerminal","buttonData","ToolsSystem","sendFaultDeleteMsg","fault","faultTopic","faultMsg","ClearFaults","sendFaultClearMsg","clear_faults","handleDeleteEventLog","deleteEventLog","handleDeleteEventJob","deleteScheduledEventJobs","onChangeCheckbox","DisablePokeTheWorker","workerDisable","handleTimeout","reportDebugLightingEvents","namedAreaEventsByAreaId","sortActiveAllNamedAreaEvents","workerPollRate","fetchServerInfo","getElementById","isDisable","fetchedMqttBroker","settingsWebworker","SetPokeTheWorkerPollRate","humanReadable","DATETIME_MED","milliseconds","_Upload","fileInputRef","saveFolderFile","fileChange","uploadButton","isFileUploaded","fileName","fileType","ToolsBackupRestore","backup","callRunScript","backupButton","restore","filenames","deleteFolderFile","fileDateStr","fileSize","strFiles","filenameSelectedList","filenameFromDataById","isRestoreMessage","fileDate","toolsMqttListClient","getFolderFilesListById","dateStr","filedate","filesize","_mqttTopicOptions","messageTxt","ToolsMqttList","onMessageArrived","unshift","payloadString","unSubscribe","unsubscribe","onSubscribe","isClientConnected","onConnectionLost","responseObject","errorCode","onConnect","subscribe","onSuccess","_setupMQTT","onClickStart","newTopic","topicSelect","onClickClear","onClickStop","handleDropdownMqttTopic","upsFFCount","clientId","substr","Paho","Client","WebSocket","onopen","onerror","connectWS","disconnect","promiseWorker","setupWorker","PromiseWorker","myWorker","postMessage","prepErrors","workerResponse","errorCase","mqttErrors","askWebWorker","pokeTheWorker","mqttConnected","mqttMessages","displayOnPageHeader","mqttMessage","clearMqttMessages","getAllMqttMessages","removeMqttMessage","terminateWorker","terminate","workerSetup","deviceCheckTimeoutSetup","initialiseWorker","boomgateControllerIP","defaultAreaStatuses","demoMode","processGetConnectStatus","jobId","workerJobId","pokeTheWorkerStart","newRequest","request","w","responseRequestMessageQueue","dataLoadingResponseRequestMessageQueue","getMqttMessages","getConnectedStatus","getExternalTrigger","getButtonTrigger","getMapMsg","getControllerCoordinates","getControllerStatuses","getFireflyStatuses","getAreaInfos","getNamedAreaStatuses","getEmergencyEventSettings","getTriggerEventSettings","getDeviceTimestamps","getSystemProcessMsg","isAreaImageChanged","setAreaImageChanged","UpdateMqttMsg","UpdateLatestFaultTs","UpdateExternalTrigger","UpdateButtonTrigger","UpdateMachineStatus","UpdateMapMsg","UpdateControllerCoordinates","UpdateControllerStatuses","UpdateFireflyCoordinates","UpdateFireflyStatuses","UpdateAreaInfos","UpdateAreaStatuses","UpdateNamedAreaInfos","UpdateNamedAreaStatuses","UpdateNamedAreaEvents","UpdateEmergencyEventSettings","UpdateTriggerEventSettings","UpdateDeviceTimestamps","UpdateServerTimestamp","UpdateSystemProcessMsg","tokenArray","sessionIp","isSameSession","UpdateAcks","UpdateRecalcState","pokeTheWorkerEnd","pokeTheWorkerEssentials","isDisabled","pokeTheServer","fetchServerOk","pokeTheDemoModeFetchData","isSettingsDataLoading","mqttReset","removeMqttMessageByToken","dataFetchedList","saveNewEmergencyEvent","allDataForWorkerState","rawAreaInfos","rawAreaStatuses","rawFireflyCoordinates","rawControllerCoordinates","makeAllDataForWorkerState","clearDataFetched","pollingRateWorker","pollingRateWorkerEssentials","pollingRateServer","getMqttReset","getAllData","getDataFetched","ClearSystemProcessMsg","UpdateDataLoadingResponseRequestQueue","fetchFireflyAreaLightingplan","TestMqttSimpleTable","cloneDeep","changeNamedArea","changeMsg","deleteMsg","eventNamedArea","newArea","changeArea","newController","changeController","deleteController","newOfficeControllers","newFF","changeFF","deleteFF","ledFF","newOfficeFFs","toggleActive","handleGroupClick","handleClickDataKeyQue1","que1","attributes","getNamedItem","isButtonActiveQue1","handleClickDataKeyQue2","que2","isButtonActiveQue2","handleClickDataKeyQue3","que3","isButtonActiveQue3","groupActive","data-key","isAcksReceived","getKeys","getHeader","onClickColor","testNamedAreaId","rows","greenBox","TestMqttControl","TestMqttNamedAreasTable","mqttTest","TAG_MARKER_ICONS","TestMarkerIcons","onClickRadioButton","isCheckboxTagPersonnel","StatusChecks","checkAllControllers","controllersNeedingDiscovering","firefliesForController","String","pi","atEachOrdinal","topoPos","likelyReplacements","uniq","fireflyIps","checkAllFireflies","samePosition","changedTopology","fixedPosition","toFixed","fixedFFPosition","displaySamePositionMessage","displayControllerRunDiscoverMessage","displayChangedTopologyMessage","headerDefault","messageDefault","colorDefault","UpdateConflicts","fetchLocalisation","FetchAllData","SetNamedAreaDisplaySettings","SetPollRates","rates","fetchMqttBroker","fetchCheckService","serv","isApplication","isFeature","AreaImages","onError","onLoad","imgData","getContext","drawImage","getBase64Image","images","LocalisationList","onClickExport","onClickImport","regionCode","localisationLink","_props","LocalisationEditForm","english","LocalisationEditPage","localisations","existingTerm","languageKeys","LocalisationAdminPages","AuthorizedApp","componentKey","_configHomepage","isNotGuest","lightingControlPage","LevelSpecificPage","FaultPage","NamedAreaAdminPages","UnauthorizedApp","columWidth","plain","centered","LoginPage","Redirect","CheckingAuth","App","clientLocale","clientLanguage","NumberFormat","getClientLocale","navigator","languages","localisedTerms","newLocalisedTerms","lang","dbTerms","setLanguage","WebWorker","Helmet","titleTemplate","defaultTitle","logList","ignore","deep","upsPositions","fireflyPositions","cmdPayload","closedConnectionDisplayed","LOCATION_CHANGE","tempStr","newPrevNamedAreaGroup","newPrevNamedAreaGroupButtonStates","formReducer","tempResult","tempObj","isInLogList","threeDaysInSeconds","threeDaysAgo","newFolderFilesList","newCheckService","newMapImages","mapSettingsId","newMapSettings","newAreaStatuses","derivedAreas","newTagId","newZones","newTagFeatures","newTagCoordinatesToTransform","tempTransformedCoords","newTagCoordinates","tempTransformedCoordsFeatures","INITIAL_locations_to","INITIAL_derivedAreas","newInitialPayload","newInitialTagsObject","newInitialTagCoordinates","newInitialTagCoordinatesToTransform","initialChangedTagCoordinates","LOST_locations_to","LOST_derivedAreas","newLostPayload","CHANGE_locations_to","CHANGE_derivedAreas","newChangePayload","newChangeTagsObject","newTagCoordinate","tagCoordinatesToTransform","changedTagCoordinates","ZONE_UPDATE_locations_to","ZONE_UPDATE_derivedAreas","newZoneUpdatePayload","newTagsObjectZones","newTagsObjectZone","newTagCoordZones","newTagCoordZone","tagPersonnelAssignedTags","tagVehicleAssignedTags","tools","timestring","timestamp_sec","timestamp_msec","composeFunction","compose","isLocalhost","hostname","protectedAPI","axios","baseURL","withCredentials","Accept","tagServicePort","tagApi","getBaseURL","interceptors","use","myApi","dummyResponse","deleteMineLevelPost","pf","areaSlug","newAreaMessage","imageForm","FormData","errs","append","newAreaImage","post","newFilenameArray","strError","errorString","_isString","areaMessage","URIError","payloadDeleteMsg","convertFetchAreasToMqtt","areaFeatures","areaFeature","strToArray","handleSaveNewMineLevel","handleUpdateMineLevel","handleDeleteMineLevel","mineLevelSaga","formError","_error","takeLatest","takeEvery","saveNewNamedAreaPost","saveNewNamedAreaEventPost","saveNewEmergencyEventPost","saveNewScheduledEventPost","getScheduledEventJobs","deleteAllScheduledEventJobs","deleteNamedAreaPost","payloadNewSaveMsg","saveMessage","payloadSaveMsg","handleSaveNewNamedArea","handleSaveNewNamedAreaEvent","handleSaveNewScheduledEvent","handleSaveNewEmergencyEvent","handleDeleteNamedArea","handleDeleteScheduledEventJobs","handleDeleteScheduledEventJob","saga","convertFetchNamedAreaEventsToMqtt","namedAreaTriggers","updateNamedAreaGroupPost","saveNamedAreaGroup","handleUpdateNamedAreaGroup","fetchSeismicLayersForMineLevel","seismicSettingsSaga","cur","getUser","loginFlow","authorize","unauthorize","manageErrors","authSagas","task","cancelled","fetchControllers","saveUpsPost","deleteUpsPost","controllerNoteNote","saveFireflyPost","deleteFireflyPost","saveFireflyLed","getAreaLightingPlan","convertFetchControllersToMqtt","controllerFeatures","utm_zone","rxLocation","sw_version","emergency_config","trigger_config","controllerFeature","fromCharCode","controllerStatus","convertFetchFireflysToMqtt","Fireflys","ff_list","fireflyFeatures","defaultMarker","defaultStatusNum","timeNow","Altered","Resend","Timestamp_State_Change","Timestamp_Status","reported_state","reported_color","reported_alternate_color","controller_name","tag_detect","ignoreServer","stringUtmZoneLetter","lowerCaseAlternateColor","colorPlanStatus","alternateColorPlanStatus","lightStatePlanStatus","fireflyFeature","fetchAreaLightingplan","upsSaga","makeSaveFunction","apiCall","ApiC","ApiFF","delay","isMqtt","ApiNA","interceptSaveAndApply","useCurrentSettings","startEditingFrom","select","plainRegions","newLayer","mineLevelCurrentSeismic","seismicLayer","fetchPrecannedOperations","activatePrecannedOperationalChange","deactivatePrecannedOperationalChange","handleToggleForcedColor","operations","currentForce","publishMessage","websocketFlow","websocketSubscriptionFlow","liveUpdateSaga","chan","statusMessage","flush","dumped","handleWsMessage","wsMessage","newStatusMessage","ws","buffers","expanding","processChannel","spawn","publishMessages","processMessages","getBackoffReconnect","reconnectInMs","urlSocket","generateTicks","statusCheckSaga","changeUserSettingsComponentState","userAdminSagas","getServerOk","postCheckService","getEventLogPeriod","postRunScript","localisationSagas","fetchEventLog","handleDeleteLog","eventLogSagas","fetchCheckServer","settingsSagas","networkInfo","getTags","getAllTagUsers","getAllTagVehicles","handleFetchAllTagUsers","handleFetchAllTagVehicles","handleAssignUser","handleAssignVehicle","handleUnassignUser","handleUnassignVehicle","handleAddUpdateUser","handleAddUpdateVehicle","handleDeleteTagUserById","handleDeleteTagVehicleById","handleUpdateTagZone","tagsSagas","checkTagData","toolsSagas","ErrorBoundary","errorInfo","whiteSpace","componentStack","svg4everybody","createHistory","sagaMiddleware","createSagaMiddleware","middlewares","routerMiddleware","websocket","store","setItem","removeItem","newAction","getState","userId","newComponentState","compState","storeState","processId","flashing","newMessageArray","countdown","countDownMsg","rootReducer","reducer","preloadedState","enhancers","reduxBatch","applyMiddleware","enhancer","createStore","configureStore","reducers","routerReducer","swUrl","serviceWorker","register","registration","run","mineLevelsSaga","namedAreasSaga","namedAreaGroupsSaga","seismicOverlaySaga","authSaga","createSeismicSaga","operationalChangesSaga","liveUpdates","statusCheck","ReactDOM","objArr","other","addFlashMessageIdColor","addFlashMessage","cloneNamedAreaEvents","addEvents","makeNamedAreaEvent","oldNamedAreaEvents"],"mappings":"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AA0B7lB,GAK/B,IAJA,IAAI8lB,EAAS,GACTC,EACF,iEACEC,EAAmBD,EAAW/lB,OACzBkB,EAAI,EAAGA,EAAIlB,EAAQkB,IAC1B4kB,GAAUC,EAAWE,OAAOzlB,KAAK0lB,MAAM1lB,KAAK2lB,SAAWH,IAEzD,OAAOF,EDmBYM,CAAiB,GACpC,MAAM,SAAN,OAAgBP,EAAhB,YAA8BD,EAA9B,YAAsCN,OE5BzB,YAAU1mB,GACvB,OAAOA,EACJ0M,cACAlK,QAAQ,KAAM,KACdA,QAAQ,WAAY,KCHlB,SAASilB,GAAe7b,GAC7B,OAAQA,GACN,IAAK,QACH,MAAO,QACT,IAAK,OACH,MAAO,OACT,IAAK,QACL,IAAK,SACH,MAAO,QAIT,IAAK,OACL,IAAK,QACH,MAAO,QACT,IAAK,MACH,MAAO,MACT,QACE,MAAO,SAKN,SAAS8b,GAAwB9b,GACpC,OAAQA,GACN,IAAK,QACH,MAAO,QACT,IAAK,OACH,MAAO,OACT,IAAK,QACL,IAAK,SACH,MAAO,QAIT,IAAK,OACL,IAAK,QACH,MAAO,QACT,IAAK,MACH,MAAO,MACT,QACE,MAAO,OC/BR,IAAM+b,GAAiB,CAM5B,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UAGA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,W,yCChQWC,GAAa,CACxBC,GAAI,EACJC,kBAAmB,EACnBC,iBAAkB,EAClBC,mBAAoB,EACpBC,iBAAkB,EAClBC,cAAe,EACfC,IAAK,EACLC,SAAU,EACVC,QAAS,EACTC,UAAW,EACXC,iBAAkB,GAClBC,sBAAuB,GACvBC,yBAA0B,GAC1BtlB,WAAY,CACVulB,EAAG,CAAEC,IAAI,GACTC,EAAG,CAAEC,SAAS,GACdC,EAAG,CAAExnB,OAAO,GACZynB,EAAG,CAAEznB,OAAO,GACZ0nB,EAAG,CAAE1nB,OAAO,GACZ2nB,EAAG,CAAE3nB,OAAO,GACZ4nB,EAAG,CAAE5nB,OAAO,GACZ6nB,EAAG,CAAE7nB,OAAO,GACZ8nB,EAAG,CAAE9nB,OAAO,GACZ+nB,EAAG,CAAE/nB,OAAO,GACZgoB,GAAI,CAAEhoB,OAAO,GACbioB,GAAI,CAAEjoB,OAAO,GACbkoB,GAAI,CAAEloB,OAAO,KAIJmoB,GAAuB,CAClCf,EAAG,KACHE,EAAG,oBACHE,EAAG,mBACHC,EAA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BE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,wBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,wBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,wBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,wBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,wBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,EACH3kD,IAAK,CAAC,iBAAkB,kBACxBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,SACH3kD,IAAK,CAAC,WAAY,aAClBzI,MAAOc,MAET,CACExkB,GAAI,yBACJqhD,IAAK,oBACL10B,gBAAiB,GACjBE,gBAAiB,IACjBikD,EAAG,QACH3kD,IAAK,CAAC,UAAW,aACjBzI,MAAOc,MAET,CACExkB,GAAI,yBAC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","file":"static/js/main.a7786042.chunk.js","sourcesContent":["// A hack job based on https://github.com/Phrogz/svg2geojson\n\n// geoFromSVGXML: loadFromString,\n\nimport { pathDataToPolys } from \"svg-path-to-polygons\";\nimport { vec2, mat23 } from \"vmath\";\n\nexport function geoFromSVGXML(svgXML, callback, options = {}) {\n require(\"xml2js\")\n .Parser({ explicitChildren: 1, preserveChildrenOrder: 1, xmlns: 1 })\n .parseString(svgXML, (err, doc) => {\n if (err) throw err;\n callback(convertSVGToGeoJSON(doc, options));\n });\n}\n\nlet svgTolerance = 1;\n\nfunction convertSVGToGeoJSON(doc, options = {}) {\n const { svg } = doc,\n layerByName = {},\n layers = [];\n\n // Find Units\n let units = undefined;\n\n for (let unit of [\"mm\", \"cm\", \"m\", \"in\"]) {\n const test =\n svg.$?.height?.value?.includes(unit) ||\n svg.$?.width?.value?.includes(unit);\n if (test) {\n units = unit;\n break;\n }\n }\n\n // Find Geolocation\n const meta = svg.$$.find(\n (e) =>\n e[\"$ns\"] &&\n e[\"$ns\"].uri == \"http://www.prognoz.ru\" &&\n e[\"$ns\"].local == \"MetaInfo\"\n );\n\n let geo = meta && meta.$$.find((e) => e[\"$ns\"].local == \"Geo\");\n let corners = geo && geo.$$.filter((e) => e[\"$ns\"].local == \"GeoItem\");\n\n // #NOTE #HACK\n // setup default content although element, containing 2 GeoItems. See:\\nhttp://help.prognoz.com/8.0/en/mergedProjects/Specifications/svgmapspecification/structure/svgmap_structure.htm\"\n );\n\n process.exit(1);\n }\n\n const converter = rectangleConverter(corners);\n\n // Convert tolerance from real-world meters to SVG units\n const midLatRadians =\n (((corners[0].$.Latitude.value * 1 + corners[1].$.Latitude.value * 1) / 2) *\n Math.PI) /\n 180;\n\n // https://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters\n // convert lat to meters\n //\n // https://en.wikipedia.org/wiki/Geographic_coordinate_system\n //\n // const m_per_deg_lat =\n // 111132.954 - 559.822 * Math.cos(2 * latMid) + 1.175 * Math.cos(4 * latMid);\n // const m_per_deg_lon = 111132.954 * Math.cos(latMid);\n\n // meters per degree latitude\n let degreeLatLen =\n 111132.954 -\n 559.822 * Math.cos(2 * midLatRadians) +\n 1.175 * Math.cos(4 * midLatRadians);\n\n const verticalRes = (converter.deltaLat * degreeLatLen) / options.tolerance;\n svgTolerance = converter.deltaY / verticalRes;\n\n svg.$$.forEach((el, i) => {\n if (options.layers && el[\"#name\"] === \"g\") {\n const name = el.$.id\n ? el.$.id.value.replace(/_1_$/, \"\").replace(/_/g, \" \")\n : \"Layer \" + i;\n if (!layerByName[name]) layerByName[name] = [];\n addGroupToLayer(el, layerByName[name], combineTransform(el));\n } else {\n if (!layerByName[\"\"]) layerByName[\"\"] = [];\n addElementToLayer(el, layerByName[\"\"]);\n }\n });\n\n for (var name in layerByName) {\n if (!layerByName[name].length) continue;\n const geo = {\n type: \"FeatureCollection\",\n creator: `svg2geojson`,\n units: units,\n features: layerByName[name].map((data) => {\n convertCoordinates(data.coordinates, converter);\n return {\n type: \"Feature\",\n properties: options.debug\n ? {\n svgID: data.coordinates.debugId,\n area: options.area,\n }\n : { area: options.area },\n geometry: data,\n };\n }),\n };\n layers.push({ name: name, geo: geo });\n }\n\n return options.layers ? layers : layers[0].geo;\n\n function convertCoordinates(coords) {\n if (typeof coords[0] === \"number\") converter(coords);\n else\n coords.forEach((a) => {\n // #NOTE - this is the main hack.\n // This does not convert, it only parses to geoJson\n return a; //convertCoordinates(a);\n });\n return coords;\n }\n}\n\nfunction addElementToLayer(el, layer, xform) {\n xform = combineTransform(el, xform);\n switch (el[\"#name\"]) {\n case \"g\":\n return addGroupToLayer(el, layer, xform);\n case \"path\":\n return addPathToLayer(el, layer, xform);\n case \"rect\":\n return addRectToLayer(el, layer, xform);\n case \"line\":\n return addLineToLayer(el, layer, xform);\n case \"circle\":\n return addCircleToLayer(el, layer, xform);\n case \"ellipse\":\n return addEllipseToLayer(el, layer, xform);\n case \"polygon\":\n return addPolygonToLayer(el, layer, xform);\n case \"polyline\":\n return addPolylineToLayer(el, layer, xform);\n case \"style\":\n case \"MetaInfo\":\n case \"defs\":\n case \"use\":\n // Elements we expect, that have no impact on the output\n break;\n default:\n console.warn(\"Ignoring unhandled element \" + el[\"#name\"]);\n }\n}\n\nfunction addGroupToLayer(el, layer, xform) {\n el.$$ &&\n el.$$.forEach((e) => {\n addElementToLayer(e, layer, xform);\n });\n}\n\nfunction addPathToLayer(el, layer, xform) {\n const c = attrs(el, \"d\");\n if (c.d) {\n const geo = addPathData(layer, xform, c.d, true);\n const pathStart = c.d.match(/^.+?\\d.*?[\\s,-].*?\\d.*?(?=[\\s,a-z-]|$)/i);\n addDebugId(geo, el, `path @ ${pathStart && pathStart[0]}`);\n }\n}\n\nfunction addRectToLayer(el, layer, xform) {\n const c = attrs(el, \"x\", \"y\", \"width\", \"height\");\n const geo = {\n type: \"Polygon\",\n coordinates: [\n coords(\n [\n [c.x, c.y],\n [c.x, c.y + c.height],\n [c.x + c.width, c.y + c.height],\n [c.x + c.width, c.y],\n [c.x, c.y],\n ],\n xform\n ),\n ],\n };\n addDebugId(geo, el, `rect @ ${c.x},${c.y}`);\n layer.push(geo);\n}\n\nfunction addLineToLayer(el, layer, xform) {\n const c = attrs(el, \"x1\", \"y1\", \"x2\", \"y2\");\n const geo = {\n type: \"LineString\",\n coordinates: coords(\n [\n [c.x1, c.y1],\n [c.x2, c.y2],\n ],\n xform\n ),\n };\n addDebugId(geo, el, `line @ ${c.x1},${c.y1}`);\n layer.push(geo);\n}\n\nfunction addCircleToLayer(el, layer, xform) {\n const c = attrs(el, \"cx\", \"cy\", \"r\");\n if (!c.r) return;\n const s = 0.55191502449 * c.r,\n m = c.r - s;\n const geo = addPathData(\n layer,\n xform,\n [\n \"M\",\n c.cx,\n c.cy + c.r,\n \"c\",\n s,\n 0,\n c.r,\n -m,\n c.r,\n -c.r,\n \"s\",\n -m,\n -c.r,\n -c.r,\n -c.r,\n \"s\",\n -c.r,\n m,\n -c.r,\n c.r,\n \"s\",\n m,\n c.r,\n c.r,\n c.r,\n \"z\",\n ].join(\" \")\n );\n addDebugId(geo, el, `circle @ ${c.cx},${c.cy}`);\n}\n\nfunction addEllipseToLayer(el, layer, xform) {\n console.error(\"FIXME: ADD SUPPORT FOR ELLIPSES\");\n process.exit(2);\n}\n\nfunction addPolygonToLayer(el, layer, xform) {\n const c = attrs(el, \"points\");\n if (!c.points) return;\n const nums = c.points.split(/[\\s,]+/);\n const pts = [];\n for (var i = 0; i < nums.length; i += 2)\n if (nums[i] && nums[i + 1]) pts.push([nums[i] * 1, nums[i + 1] * 1]);\n pts.push(pts[0].concat()); // Duplicate the array since it will be mutated during transformation\n const geo = {\n type: \"Polygon\",\n coordinates: [coords(pts, xform)],\n };\n if (!windingIsCorrect(geo.coordinates[0], 0))\n geo.coordinates[0] = geo.coordinates[0].reverse();\n addDebugId(geo, el, `polygon @ ${pts[0]},${pts[1]}`);\n layer.push(geo);\n}\n\nfunction addPolylineToLayer(el, layer, xform) {\n const c = attrs(el, \"points\");\n if (!c.points) return;\n const nums = c.points.split(/[\\s,]+/);\n const pts = [];\n for (var i = 0; i < nums.length; i += 2)\n if (nums[i] && nums[i + 1]) pts.push([nums[i] * 1, nums[i + 1] * 1]);\n pts.push(pts[0].concat()); // Duplicate the array since it will be mutated during transformation\n const geo = {\n type: \"LineString\",\n coordinates: coords(pts, xform),\n };\n addDebugId(geo, el, `polyline @ ${pts[0]},${pts[1]}`);\n layer.push(geo);\n}\n\nfunction addPathData(layer, xform, pathData, checkWinding) {\n const polys = pathDataToPolys(pathData, { tolerance: svgTolerance });\n const geo = {\n type: polys.length > 1 || polys[0].closed ? \"Polygon\" : \"LineString\",\n coordinates: polys.map((poly) => {\n return coords(poly, xform);\n }),\n };\n\n if (geo.type === \"LineString\") {\n geo.coordinates = geo.coordinates[0];\n if (geo.coordinates.length === 1) {\n geo.type = \"Point\";\n geo.coordinates = geo.coordinates[0];\n }\n } else if (checkWinding)\n for (var i = geo.coordinates.length; i--; )\n if (!windingIsCorrect(geo.coordinates[i], i))\n geo.coordinates[i] = geo.coordinates[i].reverse();\n\n layer.push(geo);\n return geo;\n}\n\n// https://stackoverflow.com/a/1165943/405017\nfunction windingIsCorrect(pts, shouldBeClockwise) {\n var sum = 0;\n for (var i = 0; i < pts.length; ++i) {\n var p0 = pts[(i || pts.length) - 1];\n sum += (pts[i][0] - p0[0]) * (pts[i][1] + p0[1]);\n }\n return shouldBeClockwise ? sum < 0 : sum > 0;\n}\n\nfunction attrs(el, ...names) {\n const o = {};\n names.forEach((n) => {\n o[n] = el.$[n]\n ? isNaN(el.$[n].value * 1)\n ? el.$[n].value\n : el.$[n].value * 1\n : 0;\n });\n return o;\n}\n\nfunction combineTransform(el, xform) {\n if (el.$ && el.$.transform) {\n // FIXME: handle arbitrary SVG transform stack here\n const args = /matrix\\((.+?)\\)/.exec(el.$.transform.value);\n if (args) {\n const n = args[1].split(/[\\s,]+/);\n const mat = mat23.new(\n n[0] * 1,\n n[1] * 1,\n n[2] * 1,\n n[3] * 1,\n n[4] * 1,\n n[5] * 1\n );\n // FIXME: is this the correct multiplication order?\n\n return xform ? mat23.multiply(xform, xform, mat) : mat;\n }\n }\n return xform;\n}\n\nfunction rectangleConverter(corners) {\n const xLerp = lerp(\n corners[0].$.X.value * 1,\n corners[1].$.X.value * 1,\n corners[0].$.Longitude.value * 1,\n corners[1].$.Longitude.value * 1\n );\n const yLerp = lerp(\n corners[0].$.Y.value * 1,\n corners[1].$.Y.value * 1,\n corners[0].$.Latitude.value * 1,\n corners[1].$.Latitude.value * 1\n );\n const converter = (svgXY) => {\n svgXY[0] = xLerp(svgXY[0]);\n svgXY[1] = yLerp(svgXY[1]);\n };\n converter.deltaX = xLerp.dx;\n converter.deltaY = yLerp.dx;\n converter.deltaLon = xLerp.dy;\n converter.deltaLat = yLerp.dy;\n\n return converter;\n}\n\nfunction coords(coords, xform) {\n if (xform) {\n const pt = vec2.create();\n coords.forEach((a) => {\n pt.x = a[0];\n pt.y = a[1];\n vec2.transformMat23(pt, pt, xform);\n a[0] = pt.x;\n a[1] = pt.y;\n });\n }\n return coords;\n}\n\nfunction addDebugId(geo, el, fallback) {\n geo.coordinates.debugId = el.$ && el.$.id ? `#${el.$.id}` : fallback;\n}\n\nfunction lerp(minX, maxX, minY, maxY) {\n const dx = maxX - minX,\n dy = maxY - minY,\n slope = dy / dx;\n const f = (x) => (x - minX) * slope + minY;\n f.dx = dx;\n f.dy = dy;\n return f;\n}\n","module.exports = __webpack_public_path__ + \"static/media/logo.1194f0da.png\";","module.exports = function() {\n return new Worker(__webpack_public_path__ + \"0417815cc82d3f736d2c.worker.js\");\n};","module.exports = function() {\n return new Worker(__webpack_public_path__ + \"a6a1d56fd64e2dc1ae42.worker.js\");\n};","import _isEmpty from \"lodash/isEmpty\";\nimport {\n isConfigJs,\n TemplateAllAreasButtons,\n lightingEventPriority,\n} from \"components/ConfigJs\";\n\n// #NOTE - DEFAULT PRIORITY SETTINGS\n//\n// MAX_PRIORITY = 10000 // <<--- see 'manager/manager.go'\nconst DEFAULT_EMERGENCY_PRIORITY = lightingEventPriority()?.emergency || 9900;\nconst DEFAULT_LEVEL_WIDE_PRIORITY = lightingEventPriority()?.levelWide || 9800;\nconst DEFAULT_START_FORCED_LIGHT_PRIORITY =\n lightingEventPriority()?.forced || 5000;\n\nfunction strToObj(str) {\n var obj = {};\n if (str && typeof str === \"string\") {\n var objStr = str.match(/\\{(.)+\\}/g);\n eval(\"obj =\" + objStr);\n }\n return obj;\n}\n\nexport const convertFetchNamedAreasToMqtt = (data) => {\n let namedAreaInfos = {};\n let namedAreaFeatures = {};\n\n let namedAreaStatuses = {};\n let allAreasButtons = [];\n\n if (isConfigJs() && TemplateAllAreasButtons()) {\n // get template for ALL_AREAS and level wide AREA button groups\n allAreasButtons = TemplateAllAreasButtons();\n }\n\n data.list.forEach((namedArea) => {\n const cloneNamedAreaFeatures = { ...namedAreaFeatures };\n const cloneNamedAreaStatuses = { ...namedAreaStatuses };\n const addInfosStatuses = makeNamedAreaInfosStatuses(\n namedArea,\n cloneNamedAreaFeatures,\n cloneNamedAreaStatuses,\n allAreasButtons\n );\n\n namedAreaFeatures = addInfosStatuses.namedAreaInfos;\n namedAreaStatuses = addInfosStatuses.namedAreaStatuses;\n });\n\n namedAreaInfos = {\n type: \"FeatureCollection\",\n features: Object.values(namedAreaFeatures),\n };\n\n return {\n namedAreaInfos,\n namedAreaStatuses,\n };\n};\n\nconst makeNamedAreaInfosStatuses = (\n newMessage,\n oldNamedAreaInfos,\n oldNamedAreaStatuses,\n allAreasButtons\n) => {\n let namedAreaInfos = { ...oldNamedAreaInfos };\n let namedAreaStatuses = { ...oldNamedAreaStatuses };\n\n const {\n id,\n area,\n name: rxName,\n shape: rxShape,\n origin,\n Firefly_List,\n type, //= \"NAMED_AREA\", //#REVIEW - at time of testing is in confluence definition but not passed in message yet\n sub_type,\n priority,\n parent: rxParent,\n parent_name: rxParentName,\n active_color,\n active_state,\n button: rxButton,\n style: rxStyle,\n } = newMessage;\n\n if (\n [\"LEVEL_WIDE\", \"ALL_AREAS\", \"POLYGON\"].includes(type.toUpperCase())\n // excludes \"TRIGGER\", \"EMERGENCY_EVENT\", \"ALL_AREAS_EMERGENCY_EVENT\"\n ) {\n // assign these variables so can update later\n // #REVIEW - all these should be set by the server\n let shape = rxShape;\n let button = rxButton;\n let name = rxName;\n let parent = rxParent;\n let parentName = rxParentName;\n\n // check parent is \"AREA:NAMED_AREA\"\n if (parent === \"\") {\n parent = id;\n }\n\n // #polygonStyleDefault\n // #TODO - move this default style to config.js (pass through setup)\n const style =\n rxStyle !== undefined || rxStyle !== \"\"\n ? strToObj(rxStyle)\n : {\n color: \"grey\",\n fillColor: \"grey\",\n fillOpacity: 0.3,\n opacity: 1,\n weight: 1,\n };\n\n // id - string. Contains > 2 :\n // area - string\n // shape - array\n\n // Firefly_String - string - - if null make \"\"\n // Firefly_List - string - if null make \"\"\n // type: \"Polygon\",\n\n // Note: named_area ids are of the form\n // e.g. \"DMLZ_Undercut:Area_A:1234567890\"\n // where if you parse by ':' you get:\n // 1 - area\n // 2 - named_area parent group\n // 3 - named_area region\n // In the case of level wide named areas this will be\n // e.g. \"DMLZ_Undercut\"\n\n // LEVEL_WIDE named_area messages may not have shape defined, don't include LEVEL_WIDE in drawn named areas.\n // Don't include named areas which do not have a shape defined i.e. ATM\n\n // #REVIEW/TODO - need to accommodate LEVEL_WIDE and other named areas which may not have a shape defined.\n //\n\n // Setup LEVEL_WIDE named areas when new area created\n //\n // 1- copy shape from region defined in area\n // 2 - setup default button group\n //\n\n // #REVIEW - force the area to single point\n // until do otherwise\n //\n\n if (type === \"LEVEL_WIDE\" || type === \"ALL_AREAS\") {\n name = type;\n parent = area;\n\n // console.log(\"eee type\", type);\n // console.log(\"eee name\", name);\n // console.log(\"eee parent\", parent);\n // console.log(\"eee shape\", shape);\n\n // #NOTE - requiring this differs from MQTT processing ?! areaInfos[topicId] is not available.\n\n // #REVIEW - update shape irrespective of the content from the server\n if (shape === null) {\n // if (areaInfos[topicId] !== undefined) {\n // if (areaInfos[topicId].bounds !== undefined) {\n // shape = areaInfos[topicId].bounds;\n // } else {\n // shape = [\n // [0, 0],\n // [1, 0],\n // [0, 1],\n // [1, 1],\n // [0, 0],\n // ]; // #REVIEW/TODO/FIX - default defined b/c at the time this was not part of the object sent by server.\n // }\n // } else {\n shape = [\n [0, 0],\n [1, 0],\n [0, 1],\n [1, 1],\n [0, 0],\n ]; // #REVIEW/TODO/FIX - default defined b/c at the time this was not part of the object sent by server.\n //}\n }\n // console.log(\"eee shape\", shape);\n // console.log(\"eee button\", button);\n\n if (button === null || _isEmpty(button)) {\n let templateButton = JSON.parse(JSON.stringify(allAreasButtons[0])); // #REVIEW - why array in array???\n\n for (let i = 0; i < templateButton.length; i++) {\n templateButton[i].id = type;\n templateButton[i].named_area = area;\n\n // add offset to AREA and ALL_AREAS buttons, except for the 1st button which is always priority 0\n if (i !== 0) {\n let priorityOffset = 0;\n switch (type) {\n case \"LEVEL_WIDE\":\n priorityOffset = DEFAULT_LEVEL_WIDE_PRIORITY; //80; // LEVEL_WIDE priority starts from 80+\n break;\n case \"ALL_AREAS\":\n priorityOffset = DEFAULT_EMERGENCY_PRIORITY; //90;\n break;\n default:\n priorityOffset = 0;\n break;\n }\n templateButton[i].priority =\n templateButton[i].priority + priorityOffset;\n }\n }\n button = templateButton;\n }\n\n // console.log(\"eee type, button\", type, button);\n }\n\n if (shape !== null && shape !== undefined) {\n // pop off the last element of the array which is the close point added for psql\n shape.pop();\n\n // geometry type has to be \"Point\" or \"Polygon\" i.e. this upper first char syntax\n // use 'type' to support passing polygons, rect, polyline etc.\n let geomType;\n\n if ([\"LEVEL_WIDE\", \"ALL_AREAS\"].includes(type)) {\n geomType = \"Polygon\";\n } else {\n geomType = type[0].toUpperCase() + type.substring(1).toLowerCase();\n }\n\n // set key value by topicId, if the shape is defined\n namedAreaInfos[id] = {\n id,\n type: \"Feature\",\n properties: {\n status: \"mqtt\", // for info, file search for \"used to track the status of the object on maps and in lists\"\n id: id,\n type: type,\n sub_type: sub_type,\n name: name,\n parent: parent,\n parent_name: parentName,\n origin: origin,\n area: area,\n priority: priority,\n Firefly_List: Firefly_List,\n active_color: active_color,\n active_state: active_state,\n button: button !== null ? button : [],\n\n // // following below are not yet defined in mqtt object\n // easting: easting,\n // northing: northing,\n // utm_zone_number: utm_zone_number,\n // utm_zone_letter: utm_zone_letter,\n // z: z,\n coordinatesUtm: [shape],\n style,\n },\n geometry: {\n type: geomType,\n coordinates: [shape],\n },\n };\n\n namedAreaStatuses[id] = namedAreaInfos[id].properties;\n\n // console.log(\n // \"eee namedArea Infos[topicId]\",\n // namedAreaInfos[topicId]\n // );\n // console.log(\n // \"eee namedArea Statuses[topicId]\",\n // namedAreaStatuses[topicId]\n // );\n }\n }\n\n return {\n namedAreaInfos: { ...namedAreaInfos },\n namedAreaStatuses: { ...namedAreaStatuses },\n };\n};\n","// This component has been inspired by:\n//\n// https://dev.to/flexdinesh/cache-busting-a-react-app-22lk\n//\n\nimport React from \"react\";\nimport semver from \"semver\";\nimport packageJson from \"../package.json\";\n\nglobal.appVersion = packageJson.version;\n\nclass CacheBuster extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n loading: true,\n isLatestVersion: false,\n refreshCacheAndReload: () => {\n const msg = \"Clearing cache and hard reloading...\";\n console.log(msg);\n if (caches) {\n //\n // Service worker cache should be cleared with caches.delete()\n //\n // ----------------------------------------------------------------------------------------------\n // caches.keys().then(function(names) {\n // for (let name of names) caches.delete(name);\n // });\n // ----------------------------------------------------------------------------------------------\n //\n // - Issues with infinite looping when our app updated and it seems due to window.location.reload\n // firing before our caches had time to clear, in the code you shared for CacheBuster.\n // - Simply adding aPromise.all() on the caches.delete() promises solved the issue in our case.\n // \n // ----------------------------------------------------------------------------------------------\n caches.keys().then(async function(names) {\n await Promise.all(names.map(name => caches.delete(name)));\n });\n }\n // Delete browser cache and hard reload.\n window.location.reload(true);\n }\n };\n }\n\n componentDidMount() { \n fetch(\"/meta.json\")\n .then(response => response.json())\n .then(meta => {\n const latestVersion = meta.version;\n const currentVersion = global.appVersion;\n const shouldForceRefresh = semver.gt(latestVersion, currentVersion);\n let msg;\n if (shouldForceRefresh) {\n msg = `We have a new version - ${latestVersion}. Should force refresh`;\n console.log(msg);\n this.setState({ loading: false, isLatestVersion: false });\n } else {\n msg = `You already have the latest version - ${latestVersion}. No cache refresh needed.`;\n console.log(msg);\n this.setState({ loading: false, isLatestVersion: true });\n }\n });\n }\n\n render() {\n const { loading, isLatestVersion, refreshCacheAndReload } = this.state;\n return this.props.children({\n loading,\n isLatestVersion,\n refreshCacheAndReload\n });\n }\n}\n\n// NOTE: Connecting to Redux kills all application routing.\nexport default CacheBuster;\n","// @10Aug22 - I apologise for this unbelievably crap code.\n// It all started as a couple of config functions,\n// then years of \"I'll get around to refactoring this\".\n// The config was always supposed to come from the db there was always\n// something more important to do.\n//\n// So now there is this awefulness _AND_ settings which comes from the db via the\n// user config.\n//\n// NOTE that in most cases if settings are defined by the /iot-firefly-server-web-app.js config\n// they will set the setting globally for all users so these functions often apply.\n//\n//\n\nimport { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n addErrorFlashMessage,\n clearFlashMessages,\n} from \"FlashMessages/actions\";\n\nimport * as is from \"is_js\";\nimport { strings } from \"components/App/localisation\";\n\n// test if config.js is in public/ and loaded onto page\nexport const isConfigJs = () => {\n return is.object(window.config);\n};\n\n// test if network.js is in public/ and loaded onto page\nexport const isConfigNetworkJs = () => {\n return is.object(window.network);\n};\n\nexport const isDevelopmentVersion = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isDevelopmentVersion\")) {\n const { isDevelopmentVersion } = window.config;\n return isDevelopmentVersion;\n }\n } else {\n return true; // default to true - if can't find config file....problem!\n }\n};\n\nexport const isDemoMode = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isDemoMode\")) {\n const { isDemoMode } = window.config;\n return isDemoMode === true;\n }\n } else {\n return false;\n }\n};\n\nexport const isDebugScreensize = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isDebugScreensize\")) {\n const { isDebugScreensize } = window.config;\n return isDebugScreensize === true;\n }\n } else {\n return false;\n }\n};\n\nexport const isMqttDebugToConsole = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isMqttDebugToConsole\")) {\n const { isMqttDebugToConsole } = window.config;\n return isMqttDebugToConsole;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isShowLightControlSim = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isShowLightControlSim\")) {\n const { isShowLightControlSim } = window.config;\n return isShowLightControlSim;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\n//\n\n// app responsive sizing\nexport const appResponsive = () => {\n let response = {\n mobile: 1350,\n tablet: 1350,\n laptop: 1351,\n desktop: 1351,\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"appResponsive\")) {\n const { appResponsive } = window.config;\n return appResponsive;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isActiveArea = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isActiveArea\")) {\n const { isActiveArea } = window.config;\n return isActiveArea;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const getMapDisplayOptions = () => {\n let response = {\n controllerLocations: false,\n controllerCables: false,\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"mapDisplayOptions\")) {\n const { mapDisplayOptions } = window.config;\n return mapDisplayOptions;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const getMapMarkerDisplayOptions = () => {\n let response = {\n firefly: {\n showMac: false,\n showStatus: true,\n showUtm: false,\n showEventInfo: false,\n showForced: true,\n },\n controller: {},\n tagTracking: {},\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"mapMarkerDisplayOptions\")) {\n const { mapMarkerDisplayOptions } = window.config;\n return mapMarkerDisplayOptions;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isDebugPagePropsMessages = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isDebugPagePropsMessages\")) {\n const { isDebugPagePropsMessages } = window.config;\n return isDebugPagePropsMessages;\n }\n } else {\n return true; // default to true - if can't find config file....problem!\n }\n};\n\nexport const isMqttNotApiPost = () => {\n let response = {\n isMqttNotApiPost: false,\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isMqttNotApiPost\")) {\n const { isMqttNotApiPost } = window.config;\n return isMqttNotApiPost;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isExtendedNavMenu = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isExtendedNavMenu\")) {\n const { isExtendedNavMenu } = window.config;\n\n return isExtendedNavMenu;\n }\n } else {\n return false; // default to false - if can't find config file....problem!\n }\n};\n\nexport const checkForBrowserType = () => {\n if (isConfigJs()) {\n const { checkForBrowserType } = window.config;\n return checkForBrowserType;\n } else {\n return false; // default to false\n }\n};\n\nexport const NetworkTimeout = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"networkTimeout\")) {\n const { networkTimeout } = window.config;\n return networkTimeout * 1000;\n }\n } else {\n return 60 * 1000; // default to 60 seconds\n }\n};\n\n// railway_application\nexport const isBoomgateCrane = () => {\n if (isConfigJs()) {\n if (\n window.config.hasOwnProperty(\"isBoomgateCrane\") &&\n window.config.hasOwnProperty(\"boomgateControllerIp\") &&\n window.config.hasOwnProperty(\"boomgateColors\") &&\n window.config.hasOwnProperty(\"templateAllAreasButtons_railway\")\n ) {\n const { isBoomgateCrane } = window.config;\n return isBoomgateCrane;\n }\n } else {\n return false;\n }\n};\n\nexport const BoomgateControllerIp = () => {\n let response = \"+\";\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"boomgateControllerIp\")) {\n const { boomgateControllerIp } = window.config;\n return boomgateControllerIp;\n }\n }\n return response;\n};\n\nexport const BoomgateColors = () => {\n let response = {\n gate: { up: \"grey\", down: \"grey\" },\n crane: { on: \"grey\", off: \"grey\" },\n alarm: { on: \"grey\", off: \"grey\" },\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"boomgateColors\")) {\n const { boomgateColors } = window.config;\n return boomgateColors;\n }\n }\n return response;\n};\n\nexport const mqttBroker = () => {\n if (isConfigNetworkJs()) {\n if (\n window.network.hasOwnProperty(\"mqttBrokerAddress\") &&\n // #NOTE - do no insist on secondary address\n // window.network.hasOwnProperty(\"mqttBrokerAddressTWO\") &&\n window.network.hasOwnProperty(\"mqttBrokerPort\") &&\n window.network.hasOwnProperty(\"mqttBrokerProtocol\")\n ) {\n const {\n mqttBrokerAddress: address,\n mqttBrokerAddressTWO: addressSecondary,\n mqttBrokerPort,\n mqttBrokerProtocol,\n } = window.network;\n\n const port =\n window.location.protocol === \"https:\"\n ? mqttBrokerPort.https\n : mqttBrokerPort.http;\n\n const protocol =\n window.location.protocol === \"https:\"\n ? mqttBrokerProtocol.https\n : mqttBrokerProtocol.http;\n\n return { address, addressSecondary, port, protocol };\n } else {\n return {\n address: undefined,\n addressSecondary: undefined,\n port: undefined,\n protocol: undefined,\n };\n }\n } else {\n return {\n address: undefined,\n addressSecondary: undefined,\n port: undefined,\n protocol: undefined,\n };\n }\n};\n\n// faultFlash: { battery: true, network: true, firefly: true },\nexport const faultFlash = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"faultFlash\")) {\n const { faultFlash } = window.config;\n const { battery, network, firefly, controller, statusChecks } =\n faultFlash;\n return {\n battery,\n network,\n firefly,\n controller,\n statusChecks,\n };\n }\n } else {\n return false; // default to false\n }\n};\n\n// faultMessageBannerDisplay: { battery: true, network: true, firefly: true },\nexport const faultMessageBannerDisplay = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"faultMessageBannerDisplay\")) {\n const { faultMessageBannerDisplay } = window.config;\n\n const {\n battery,\n network,\n firefly,\n controller,\n statusChecks,\n fireflySamePosition,\n fireflySamePositionCorrected,\n controllerLikelyReplacement,\n controllerLikelyReplacementCorrected,\n areaImageNotFound,\n } = faultMessageBannerDisplay;\n return {\n battery,\n network,\n firefly,\n controller,\n statusChecks,\n fireflySamePosition,\n fireflySamePositionCorrected,\n controllerLikelyReplacement,\n controllerLikelyReplacementCorrected,\n areaImageNotFound,\n };\n }\n } else {\n return false; // default to false\n }\n};\n\n// faultMessageBannerDisplay: { battery: true, network: true, firefly: true },\nexport const faultMessageBannerText = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"faultMessageBannerText\")) {\n const { faultMessageBannerText } = window.config;\n const {\n battery,\n network,\n firefly,\n controller,\n statusChecks,\n fireflySamePosition,\n fireflySamePositionCorrected,\n controllerLikelyReplacement,\n controllerLikelyReplacementCorrected,\n areaImageNotFound,\n } = faultMessageBannerText;\n return {\n battery,\n network,\n firefly,\n controller,\n statusChecks,\n fireflySamePosition,\n fireflySamePositionCorrected,\n controllerLikelyReplacement,\n controllerLikelyReplacementCorrected,\n areaImageNotFound,\n };\n }\n } else {\n return \"no message assigned\"; // default to false\n }\n};\n\n// railway_application\nexport const TemplateAllAreasButtons = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"templateAllAreasButtons\")) {\n if (isBoomgateCrane()) {\n const { templateAllAreasButtons_railway } = window.config;\n return templateAllAreasButtons_railway;\n }\n const { templateAllAreasButtons } = window.config;\n return templateAllAreasButtons;\n }\n } else {\n return [];\n }\n};\n\nexport const namedAreaIconOptions = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"namedAreaIconOptions\")) {\n const { namedAreaIconOptions } = window.config;\n return namedAreaIconOptions;\n }\n } else {\n return [];\n }\n};\n\n// railway_application\nexport const legend = () => {\n if (isConfigJs()) {\n if (isBoomgateCrane()) {\n if (\n window.config.hasOwnProperty(\"boomgateCraneIcons\") &&\n window.config.hasOwnProperty(\"commonIcons\")\n ) {\n const { boomgateCraneIcons, commonIcons } = window.config;\n return [...boomgateCraneIcons, ...commonIcons];\n }\n } else {\n if (\n window.config.hasOwnProperty(\"freeportIcons\") &&\n window.config.hasOwnProperty(\"commonIcons\")\n ) {\n const { freeportIcons, commonIcons } = window.config;\n return [...freeportIcons, ...commonIcons];\n }\n }\n } else {\n return [];\n }\n};\n\nexport const legend_old = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"legend\")) {\n const { legend } = window.config;\n return legend;\n }\n } else {\n return [];\n }\n};\n\nexport const TemplateDefaultArea = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"defaultArea\")) {\n const { defaultArea } = window.config;\n return defaultArea;\n }\n } else {\n return [];\n }\n};\n\nexport const isAreaMapSimple = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isAreaMapSimple\")) {\n const { isAreaMapSimple } = window.config;\n return isAreaMapSimple;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isShowBackupRestore = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isShowBackupRestore\")) {\n const { isShowBackupRestore } = window.config;\n return isShowBackupRestore;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isShowExternalTriggerEvent = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isShowExternalTriggerEvent\")) {\n const { isShowExternalTriggerEvent } = window.config;\n return isShowExternalTriggerEvent;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isShowScheduledEvent = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isShowScheduledEvent\")) {\n const { isShowScheduledEvent } = window.config;\n return isShowScheduledEvent;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isShowEventLog = () => {\n let response = true;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isShowEventLog\")) {\n const { isShowEventLog } = window.config;\n return isShowEventLog;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isAreaImageToState = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isAreaImageToState\")) {\n const { isAreaImageToState } = window.config;\n return isAreaImageToState;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isDeleteFireflyNotCommissioned = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isDeleteFireflyNotCommissioned\")) {\n const { isDeleteFireflyNotCommissioned } = window.config;\n return isDeleteFireflyNotCommissioned;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isDataCollectionDuringMarkerPopupOpen = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isDataCollectionDuringMarkerPopupOpen\")) {\n const { isDataCollectionDuringMarkerPopupOpen } = window.config;\n return isDataCollectionDuringMarkerPopupOpen;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const mqttTopicOptions = () => {\n let response = [];\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"mqttTopicOptions\")) {\n const { mqttTopicOptions } = window.config;\n return mqttTopicOptions;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nconst triggerOptions = (strings) => [\n {\n key: 1, // i.e. bit 1 of the `settings.permission` flag bit register\n value: \"isShowExternalTriggerEvent\",\n text: strings?.[\"External Trigger\"],\n icon: \"chain\",\n },\n {\n key: 2, // // i.e. bit 2 of the `settings.permission` flag bit register\n value: \"isShowScheduledEvent\",\n text: strings?.[\"Scheduled Event\"],\n icon: \"clock outline\",\n },\n // ....next one?\n // {\n // key: 3,\n // value: \"isShow...?????\", //\n // text: \"?????? Event\",\n // icon: \"clock outline\",\n // },\n];\n\nexport const eventTriggerOptions = (userSettings) => {\n let response = triggerOptions(strings);\n\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"eventTriggerOptions\")) {\n const { eventTriggerOptions } = window.config;\n\n response = eventTriggerOptions;\n\n // filter options based on value ...\n // - isShowExternalTriggerEvent\n // - isShowScheduledEvent\n\n if (\n !userSettings?.feature?.includes(\"showExternalTriggerEvent\") &&\n !isShowExternalTriggerEvent()\n ) {\n response = response.filter(\n (option) => option.value !== \"isShowExternalTriggerEvent\"\n );\n }\n\n // console.log(\n // \"xxx isShowExternalTriggerEvent\",\n // isShowExternalTriggerEvent(),\n // response\n // );\n\n if (\n !userSettings?.feature?.includes(\"showScheduledEvent\") &&\n !isShowScheduledEvent()\n ) {\n response = response.filter(\n (option) => option.value !== \"isShowScheduledEvent\"\n );\n }\n\n return response;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\n// SOP UI button layout\n\nexport const isCustomSOP = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isCustomSOP\")) {\n const { isCustomSOP } = window.config;\n return isCustomSOP;\n }\n } else {\n return false;\n }\n};\n\nexport const isShowEventButtons = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isShowEventButtons\")) {\n const { isShowEventButtons } = window.config;\n return isShowEventButtons;\n }\n } else {\n return false;\n }\n};\n\nexport const isUserRelay = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isUserRelay\")) {\n const { isUserRelay } = window.config;\n return isUserRelay;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const isPolygonShowHide = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isPolygonShowHide\")) {\n const { isPolygonShowHide } = window.config;\n return isPolygonShowHide;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nconst colorOptions = (strings) => {\n return [\n {\n key: \"green\",\n text: strings?.[\"green\"],\n value: \"green\",\n image: { src: \"/images/picker-green.png\" },\n },\n {\n key: \"red\",\n text: strings?.[\"red\"],\n value: \"red\",\n image: { src: \"/images/picker-red.png\" },\n },\n {\n key: \"blue\",\n text: strings?.[\"blue\"],\n value: \"blue\",\n image: { src: \"/images/picker-blue.png\" },\n },\n {\n key: \"amber\",\n text: strings?.[\"amber\"],\n value: \"amber\",\n image: { src: \"/images/picker-orange.png\" },\n },\n {\n key: \"white\",\n text: strings?.[\"white\"],\n value: \"white\",\n image: { src: \"/images/picker-white.png\" },\n },\n {\n key: \"off\",\n text: strings?.[\"off\"],\n value: \"off\",\n image: { src: \"/images/picker-black.png\" },\n },\n ];\n};\n\nexport const allowedLightColors = () => {\n let response = colorOptions(strings);\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedLightColors\")) {\n const { allowedLightColors } = window.config;\n\n let newColorOptions = [];\n for (const key in allowedLightColors) {\n if (Object.hasOwnProperty.call(allowedLightColors, key)) {\n const isAllowedColor = allowedLightColors[key];\n if (isAllowedColor) {\n newColorOptions.push(\n colorOptions(strings).find((opt) => opt.key === key)\n );\n }\n }\n }\n\n return newColorOptions;\n }\n }\n return response;\n};\n\nexport const allowedAlternateLightColors = () => {\n let response = colorOptions(strings);\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedAlternateLightColors\")) {\n const { allowedAlternateLightColors } = window.config;\n \n let newColorOptions = [];\n for (const key in allowedAlternateLightColors) {\n if (Object.hasOwnProperty.call(allowedAlternateLightColors, key)) {\n const isAllowedColor = allowedAlternateLightColors[key];\n if (isAllowedColor) {\n newColorOptions.push(\n colorOptions(strings).find((opt) => opt.key === key)\n );\n }\n }\n }\n \n return newColorOptions;\n }\n }\n return response;\n };\n\nconst stateOptions = (strings) => {\n return [\n {\n key: \"on\",\n text: strings?.[\"on\"],\n value: \"on\",\n },\n {\n key: \"off\",\n text: strings?.[\"off\"],\n value: \"off\",\n },\n {\n key: \"strobe\",\n text: strings?.[\"strobe\"],\n value: \"strobe\",\n },\n {\n key: \"forward\",\n text: strings?.[\"forward\"],\n value: \"forward\",\n },\n {\n key: \"backward\",\n text: strings?.[\"backward\"],\n value: \"backward\",\n },\n\n // #REVIEW\n // future option for precanned effects. i.e. setup of on and off time to simulate slow and fast effects\n // {\n // key: \"slow\",\n // text: strings?.[\"slow\"],\n // value: \"slow\",\n // },\n // {\n // key: \"fast\",\n // text: strings?.[\"fast\"],\n // value: \"fast\",\n // },\n ];\n};\n\nexport const allowedLightStates = () => {\n let response = stateOptions(strings);\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedLightStates\")) {\n const { allowedLightStates } = window.config;\n\n let newStateOptions = [];\n for (const key in allowedLightStates) {\n if (Object.hasOwnProperty.call(allowedLightStates, key)) {\n const isAllowedState = allowedLightStates[key];\n if (isAllowedState) {\n newStateOptions.push(\n stateOptions(strings).find((opt) => opt.key === key)\n );\n }\n }\n }\n\n return newStateOptions;\n }\n }\n return response;\n};\n\nconst markerOptions = (strings) => {\n return [\n {\n key: \"CrossMarker\",\n text: strings?.[\"plus\"],\n value: \"CrossMarker\",\n image: { src: \"/images/cross-plus-green.png\" },\n },\n {\n key: \"Cross45Marker\",\n text: strings?.[\"cross\"],\n value: \"Cross45Marker\",\n image: { src: \"/images/cross-blue.png\" },\n },\n {\n key: \"RoundMarker\",\n text: strings?.[\"circle\"],\n value: \"RoundMarker\",\n image: { src: \"/images/circle-green.png\" },\n },\n {\n key: \"MultiStrobeMarker\",\n text: strings?.[\"multistrobe\"],\n value: \"MultiStrobeMarker\",\n image: { src: \"/images/multi-strobe.png\" },\n },\n {\n key: \"SquareMarker\",\n text: strings?.[\"square\"],\n value: \"SquareMarker\",\n image: { src: \"/images/square-blue.png\" },\n },\n {\n key: \"DiamondMarker\",\n text: strings?.[\"diamond\"],\n value: \"DiamondMarker\",\n image: { src: \"/images/diamond-blue-orange.png\" },\n },\n {\n key: \"TravelwayMarker\",\n text: strings?.[\"travelway\"],\n value: \"TravelwayMarker\",\n image: { src: \"/images/polygon-amber-purple.png\" },\n },\n {\n key: \"StarMarker\",\n text: strings?.[\"star\"],\n value: \"StarMarker\",\n image: { src: \"/images/star-red-green.png\" },\n },\n {\n key: \"HourGlassMarker\",\n text: strings?.[\"hourglass\"],\n value: \"HourGlassMarker\",\n image: { src: \"/images/hourglass-sienna-fuchsia.png\" },\n },\n {\n key: \"BowTieMarker\",\n text: strings?.[\"bowtie\"],\n value: \"BowTieMarker\",\n image: { src: \"/images/bowtie-black-fuchsia.png\" },\n },\n {\n key: \"TriangleMarker\",\n text: strings?.[\"triangle\"],\n value: \"TriangleMarker\",\n image: { src: \"/images/triangle-red-green.png\" },\n },\n {\n key: \"OffMarker\",\n text: strings?.[\"off\"],\n value: \"OffMarker\",\n image: { src: \"/images/off.png\" },\n },\n {\n key: \"ForwardMarker\",\n text: strings?.[\"forward\"],\n value: \"ForwardMarker\",\n image: { src: \"/images/forward-blue.png\" },\n },\n {\n key: \"BackwardMarker\",\n text: strings?.[\"backward\"],\n value: \"BackwardMarker\",\n image: { src: \"/images/backward-blue.png\" },\n },\n ];\n};\n\nexport const allowedMapMarkers = () => {\n let response = markerOptions(strings);\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedMapMarkers\")) {\n const { allowedMapMarkers } = window.config;\n\n let newMarkerOptions = [];\n for (const key in allowedMapMarkers) {\n if (Object.hasOwnProperty.call(allowedMapMarkers, key)) {\n const isAllowedMapMarkers = allowedMapMarkers[key];\n if (isAllowedMapMarkers) {\n newMarkerOptions.push(\n markerOptions(strings).find((opt) => opt.key === key)\n );\n }\n }\n }\n\n return newMarkerOptions;\n }\n }\n return response;\n};\n\n//# NOTE #TODO - get available languages from setup/sql query\n\n// #NOTE - at the moment this is the list of languages which will be offered at the\n// LOCALISATION list page.\n//\n// see - https://iotautomation.atlassian.net/wiki/spaces/FSSV/pages/1630240769/References\n\nexport const languageOptions = [\n {\n key: \"en-US\",\n text: \"American English\",\n regioncodelanguage: \"English - United States\",\n value: \"en-US\",\n },\n {\n key: \"es-419\",\n text: \"Español latinoamericano\",\n regioncodelanguage: \"Spanish - Latin America/Caribbean \",\n value: \"es-419\",\n },\n {\n key: \"hi-IN\",\n text: \"हिन्दी भाषा\",\n regioncodelanguage: \"Hindi - India\",\n value: \"hi-IN\",\n },\n {\n key: \"it-IT\",\n text: \"Italiano\",\n regioncodelanguage: \"Italian - Italy\",\n value: \"it-IT\",\n },\n {\n key: \"id-ID\",\n text: \"Bahasa Indonesia\",\n regioncodelanguage: \"Indonesian - Indonesia\",\n value: \"id-ID\",\n },\n];\n\nexport const allowedLanguages = () => {\n let response = languageOptions;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedLanguages\")) {\n const { allowedLanguages } = window.config;\n\n let newLanguageOptions = [];\n for (const key in allowedLanguages) {\n if (Object.hasOwnProperty.call(allowedLanguages, key)) {\n const isAllowedLanguages = allowedLanguages[key];\n if (isAllowedLanguages) {\n newLanguageOptions.push(\n languageOptions.find((opt) => opt.key === key)\n );\n }\n }\n }\n return newLanguageOptions;\n }\n }\n return response;\n};\n\n// https://iotautomation.atlassian.net/wiki/spaces/FSSV/pages/386367491/Roles+and+Permissions\n// SUPER - administer other users (Admin)\n// ADMIN - configure system (LIghtPlanner)\n// USER - operate events (ControlRoomOperator, Network Admin)\n// GUEST - view area maps and light status\n\nconst roleOptions = (strings) => {\n return [\n {\n key: \"super\",\n text: strings?.[\"Super User - Administrator + administer users\"],\n value: \"super\",\n },\n {\n key: \"admin\",\n text: strings?.[\n \"Administrator - Operator + administer areas and devices\"\n ],\n value: \"admin\",\n },\n {\n key: \"user\",\n text: strings?.[\"Operator - All general operations. Trigger events etc.\"],\n value: \"user\",\n },\n {\n key: \"guest\",\n text: strings?.[\"Guest - View area maps and light status\"],\n value: \"guest\",\n },\n ];\n};\n\nexport const allowedRoles = () => {\n let response = roleOptions(strings);\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedRoles\")) {\n const { allowedRoles } = window.config;\n\n let newRoleOptions = [];\n for (const key in allowedRoles) {\n if (Object.hasOwnProperty.call(allowedRoles, key)) {\n const isAllowedRoles = allowedRoles[key];\n if (isAllowedRoles) {\n newRoleOptions.push(\n roleOptions(strings).find((opt) => opt.key === key)\n );\n }\n }\n }\n\n return newRoleOptions;\n }\n }\n return response;\n};\n\nconst applicationOptions = (strings) => {\n return [\n {\n key: \"smartLighting\",\n text: strings?.[\"smartLighting\"],\n value: \"smartLighting\",\n },\n {\n key: \"tagTracking\",\n text: strings?.[\"tagTracking\"],\n value: \"tagTracking\",\n },\n ];\n};\n\nexport const allowedApplications = () => {\n let response = applicationOptions(strings);\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedApplications\")) {\n const { allowedApplications } = window.config;\n\n let newApplicationOptions = [];\n for (const key in allowedApplications) {\n if (Object.hasOwnProperty.call(allowedApplications, key)) {\n const isAllowedApplications = allowedApplications[key];\n if (isAllowedApplications) {\n newApplicationOptions.push(\n applicationOptions(strings).find((opt) => opt.key === key)\n );\n }\n }\n }\n\n return newApplicationOptions;\n }\n }\n return response;\n};\n\n// allowedFeatures: {\n// showDemoMode: true,\n// showDevelopmentVersion: true,\n// showExternalTriggerEvent: true,\n// showScheduledEvent: true,\n// },\n\nconst featureOptions = (strings) => {\n return [\n {\n key: \"showUserRelay\",\n text: strings?.[\"showUserRelay\"],\n value: \"showUserRelay\",\n },\n {\n key: \"showExternalTriggerEvent\",\n text: strings?.[\"showExternalTriggerEvent\"],\n value: \"showExternalTriggerEvent\",\n },\n {\n key: \"showScheduledEvent\",\n text: strings?.[\"showScheduledEvent\"],\n value: \"showScheduledEvent\",\n },\n {\n key: \"showDemoMode\",\n text: strings?.[\"showDemoMode\"],\n value: \"showDemoMode\",\n },\n {\n key: \"showDevelopmentVersion\",\n text: strings?.[\"showDevelopmentVersion\"],\n value: \"showDevelopmentVersion\",\n },\n {\n key: \"showBackupRestore\",\n text: strings?.[\"showBackupRestore\"],\n value: \"showBackupRestore\",\n },\n ];\n};\n\nexport const allowedFeatures = () => {\n let response = featureOptions(strings);\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"allowedFeatures\")) {\n const { allowedFeatures } = window.config;\n\n let newAllowedFeatures = [];\n for (const key in allowedFeatures) {\n if (Object.hasOwnProperty.call(allowedFeatures, key)) {\n const isAllowedFeatures = allowedFeatures[key];\n if (isAllowedFeatures) {\n newAllowedFeatures.push(\n featureOptions(strings).find((opt) => opt.key === key)\n );\n }\n }\n }\n\n return newAllowedFeatures;\n }\n }\n return response;\n};\n\nexport const lightingEventPriority = () => {\n let response = { emergency: 9900, levelWide: 9800, forced: 5000 };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"lightingEventPriority\")) {\n const { lightingEventPriority } = window.config;\n return lightingEventPriority;\n }\n }\n return response;\n};\n\nexport const markerSize = () => {\n let response = {\n marker: 2,\n tag: 2,\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"markerSize\")) {\n const { markerSize } = window.config;\n return markerSize;\n } else {\n return response;\n }\n } else {\n return response;\n }\n};\n\nexport const markerAcceptableEventLabels = () => {\n let response = [\"M\", \"P\", \"F\", \"S\", \"T\", \"E\", \"C\"];\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"markerAcceptableEventLabels\")) {\n const { markerAcceptableEventLabels } = window.config;\n return markerAcceptableEventLabels;\n }\n }\n return response;\n};\n\nexport const controlScreenEmergencyEventButtons = () => {\n let response = { show: false, label: \"MINE WIDE\" };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"controlScreenEmergencyEventButtons\")) {\n const { controlScreenEmergencyEventButtons } = window.config;\n return controlScreenEmergencyEventButtons;\n }\n return response;\n }\n return response;\n};\n\nexport const controlScreenSOPdata = () => {\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"controlScreenSOPdata\")) {\n const { controlScreenSOPdata } = window.config;\n return controlScreenSOPdata;\n }\n } else {\n return [];\n }\n};\n\nexport const deviceCheckTimeout = () => {\n let response = {\n checkPeriod: 2 * 60 * 1000, // 2 minutes\n period: 5 * 60 * 1000, //5 * 60 * 1000; // 5 minutes\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"deviceCheckTimeout\")) {\n const { deviceCheckTimeout } = window.config;\n return deviceCheckTimeout;\n }\n }\n return response;\n};\n\nexport const pollRates = () => {\n let response = {\n disable: false, // disables data collection via web worker\n workerEssentials: 1 * 1000, // 1 second\n worker: 10 * 1000, // 10 seconds\n server: 30 * 1000, // 30 seconds\n tagTracking: 30 * 1000, // 30 seconds\n };\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"pollRates\")) {\n const { pollRates } = window.config;\n return pollRates;\n }\n }\n return response;\n};\n\n// Some application features are reliant on specific services running.\n// Check if these are active services on the server\n// #NOTE - the 'feature' property must match the features, application defined in featureOptions() and applicationOptions().\n// See - src/components/ConfigJs/index.js > allowedFeatures() / allowedApplications()\n//\nconst checkServiceOptions = [\n {\n application: \"\",\n feature: \"showBackupRestore\",\n service: \"iot-firefly-server-backup-monitor\",\n },\n { application: \"tagTracking\", feature: \"\", service: \"iot-tag-tracker\" },\n];\n\nexport const checkService = () => {\n let response = checkServiceOptions;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"checkService\")) {\n const { checkService } = window.config;\n return checkService;\n }\n }\n return response;\n};\n\nexport const configHomepage = () => {\n let response = \"lightingControl\"; // default is to have the application display lighting control\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"configHomepage\")) {\n const { configHomepage } = window.config;\n return configHomepage;\n }\n }\n return response;\n};\n\nexport const configAppTitle = () => {\n let response = \"FireFly Lighting System\"; // default is to have the application display lighting control\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"configAppTitle\")) {\n const { configAppTitle } = window.config;\n return configAppTitle;\n }\n }\n return response;\n};\n\nexport const isLightingControl = () => {\n let response = true; // default is to have the application display lighting control\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isLightingControl\")) {\n const { isLightingControl } = window.config;\n return isLightingControl;\n }\n }\n return response;\n};\n\nexport const isTagTracking = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isTagTracking\")) {\n const { isTagTracking } = window.config;\n return isTagTracking;\n }\n }\n return response;\n};\n\nexport const isTagTrackingMap = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isTagTrackingMap\")) {\n const { isTagTrackingMap } = window.config;\n return isTagTrackingMap;\n }\n }\n return response;\n};\n\nexport const isTagTrackingOneUserPerTag = () => {\n let response = false;\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"isTagTrackingOneUserPerTag\")) {\n const { isTagTrackingOneUserPerTag } = window.config;\n return isTagTrackingOneUserPerTag;\n }\n }\n return response;\n};\n\nexport const tagTrackingPort = () => {\n let response = \"8010\";\n if (isConfigJs()) {\n if (window.config.hasOwnProperty(\"tagTrackingPort\")) {\n const { tagTrackingPort } = window.config;\n return tagTrackingPort;\n }\n }\n return response;\n};\n\nexport class CheckConfigJs extends Component {\n constructor(props) {\n super(props);\n this.state = {};\n }\n\n // loads header and message to display on control screen page\n displayErrors(errorType, extraMessage) {\n let header;\n let message;\n\n switch (errorType) {\n case \"CONFIG_JS_PROBLEM\":\n header = \"Problem Loading Config File\";\n message = \"Check config.js file exists and is properly setup.\";\n break;\n default:\n break;\n }\n //this.props.clearFlashMessages(); // clear off previous messages\n this.props.addErrorFlashMessage(header, message || \"Unknown problem\");\n console.log(header + \" - \" + message);\n }\n\n // not in use - yet?\n componentDidMount() {}\n componentDidUpdate() {}\n\n render() {\n // #REVIEW - // can't use this.isConfigJsOK because it has not loaded at this stage\n //\n // if (!this.isConfigJsOK)) {\n if (!is.object(window.config)) {\n this.displayErrors(\"CONFIG_JS_PROBLEM\", \"\");\n }\n\n return null;\n }\n}\n\n// placeholder for connect()\nfunction mapStateToProps(state) {\n return {};\n}\n\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n clearFlashMessages: () => {\n dispatch(clearFlashMessages());\n },\n addErrorFlashMessage: (error, extra) => {\n dispatch(addErrorFlashMessage(error, extra));\n },\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(CheckConfigJs);\n","var map = {\n\t\"./bg-BG.json\": 1761,\n\t\"./ca-ES.json\": 1762,\n\t\"./cs-CZ.json\": 1763,\n\t\"./de-DE.json\": 1764,\n\t\"./el-GR.json\": 1765,\n\t\"./en-US.json\": 1013,\n\t\"./es-ES.json\": 1766,\n\t\"./et-EE.json\": 1767,\n\t\"./fi-FI.json\": 1768,\n\t\"./fr-FR.json\": 1769,\n\t\"./he-IL.json\": 1770,\n\t\"./it-IT.json\": 1771,\n\t\"./ja-JP.json\": 1772,\n\t\"./ko-KR.json\": 1773,\n\t\"./nb-NO.json\": 1774,\n\t\"./nl-NL.json\": 1775,\n\t\"./nn-NO.json\": 1776,\n\t\"./pl-PL.json\": 1777,\n\t\"./pt-BR.json\": 1778,\n\t\"./ro-RO.json\": 1779,\n\t\"./ru-RU.json\": 1780,\n\t\"./sk-SK.json\": 1781,\n\t\"./sv-SE.json\": 1782,\n\t\"./tr-TR.json\": 1783,\n\t\"./zh-CN.json\": 1784\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn map[req];\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 1760;","// #LOCALISATION\n//\n// see - https://www.npmjs.com/package/react-localization\n// uses - https://www.npmjs.com/package/localized-strings\n\nimport LocalizedStrings from \"react-localization\";\n\nexport const defaultStrings = {\n // Main nav & menus\n \"FireFly Lighting System\": \"FireFly Lighting System\",\n Login: \"Login\",\n Email: \"Email\",\n Password: \"Password\",\n \"Authentication Error\": \"Authentication Error\",\n Unauthorized: \"Unauthorized\",\n Status: \"Status\",\n \"Controller Status\": \"Controller Status\",\n \"FireFly Status\": \"FireFly Status\",\n Faults: \"Faults\",\n \"FireFly Faults\": \"FireFly Faults\",\n \"Battery Faults\": \"Battery Faults\",\n \"Network Faults\": \"Network Faults\",\n \"Controller Reports\": \"Controller Reports\",\n \"Smart Lighting\": \"Smart Lighting\",\n Admin: \"Admin\",\n Areas: \"Areas\",\n Controllers: \"Controllers\",\n FireFly: \"FireFly\",\n FireFlys: \"FireFlys\",\n \"Bulk Positioning\": \"Bulk Positioning\",\n \"Lighting Events\": \"Lighting Events\",\n \"Scheduled Events\": \"Scheduled Events\",\n \"Scheduled Event\": \"Scheduled Event\",\n \"Scheduled Lighting Events\": \"Scheduled Lighting Events\",\n Logs: \"Logs\",\n \"System Logs\": \"System Logs\",\n \"Browser Logs\": \"Browser Logs\",\n System: \"System\",\n Tools: \"Tools\",\n \"System Tools\": \"System Tools\",\n \"Backup and Restore\": \"Backup and Restore\",\n Users: \"Users\",\n Profile: \"Profile\",\n \"User Profile\": \"User Profile\",\n \"Select items in the table below to enable or disable.\":\n \"Select items in the table below to enable or disable.\",\n Sorry: \"Sorry\",\n Logout: \"Logout\",\n USER_PROFILE_SETTING_MESSAGE: \"Log out/log in to apply Settings changes.\",\n Next: \"Next\",\n \"Next Activate\": \"Next Activate\",\n \"Next Deactivate\": \"Next Deactivate\",\n\n // Controlroompage\n \"Loading ...\": \"Loading ...\",\n \"Loading data ...\": \"Loading data ...\",\n LOADING_MESSAGE:\n \"There are currently no areas to display. Select 'Admin > Areas' to create a new area. If areas have already been defined there could be a problem loading data. If the problem persists, check the console and mqtt.\",\n \"There are no levels defined for this group.\":\n \"There are no levels defined for this group.\",\n\n // Area pages\n Map: \"Map\",\n \"Map Image\": \"Map Image\",\n \"Edit Area\": \"Edit Area\",\n \"Light Settings\": \"Light Settings\",\n \"Default Color of Lights\": \"Default Color of Lights\",\n \"Default State of Lights\": \"Default State of Lights\",\n \"Map Settings\": \"Map Settings\",\n \"Background Color\": \"Background Color\",\n \"Choose Map Image\": \"Choose Map Image\",\n \"Add another file\": \"Add another file\",\n \"Map Background Color\": \"Map Background Color\",\n \"Map Reference Markers\": \"Map Reference Markers\",\n Northing: \"Northing\",\n Easting: \"Easting\",\n Letter: \"Letter\",\n Number: \"Number\",\n \"Area Message Header\": \"Set the default state of the FireFlys in the Area\",\n \"Area Message Content\":\n \"e.g. ON and AMBER, or OFF, but GREEN when turned ON.\",\n \"Enter Area Name\": \"Enter Area Name\",\n Order: \"Order\",\n\n // Faults pages\n ID: \"ID\",\n Device: \"Device\",\n Fault: \"Fault\",\n \"Fault Level\": \"Fault Level\",\n \"Fault Time\": \"Fault Time\",\n \"Total current faults\": \"Total current faults\",\n\n // Generic form page terms\n Clear: \"Clear\",\n Copy: \"Copy\",\n copy: \"copy\",\n \"Filter...\": \"Filter...\",\n \"Nothing changed\": \"Nothing changed\",\n Save: \"Save\",\n Submitting: \"Submitting\",\n Reset: \"Reset\",\n Cancel: \"Cancel\",\n Add: \"Add\",\n Edit: \"Edit\",\n Close: \"Close\",\n Enable: \"Enable\",\n Disable: \"Disable\",\n Delete: \"Delete\",\n \"Delete Button Message Header\": \"Delete\",\n \"Delete Button Message Content\": \"Are you sure you want to delete?\",\n Yes: \"Yes\",\n No: \"No\",\n \"Collapse Left Side\": \"Collapse Left Side\",\n \"Expand Left Side\": \"Expand Left Side\",\n ON: \"ON\",\n OFF: \"OFF\",\n \"This name has already been used\": \"This name has already been used\",\n unknown: \"unknown\",\n \"No Area data available. Waiting...\": \"No Area data available. Waiting...\",\n Update: \"Update\",\n\n // Generic list page terms\n \"Select items in the table below to apply an action\":\n \"Select items in the table below to apply an action.\",\n \"Empty list. Waiting for data...\": \"Empty list. Waiting for data...\",\n \"{list_length} items displayed\": \"{list_length} items displayed\",\n \"{list_items} selected...\": \"{list_items} selected...\",\n \"{list_count_item} count. Click to refresh data.\":\n \"{list_count_item} count. Click to refresh data.\",\n \"{list_count_item} count. Click to clear.\":\n \"{list_count_item} count. Click to clear.\",\n\n // Alarm Buttons\n \"View {fault_type} faults\": \"View {fault_type} faults\",\n \"View FireFly controller {fault_type} faults\":\n \"View FireFly controller {fault_type} faults\",\n \"View Controller Reports\": \"View Controller Reports\",\n \"View FireFly Status\": \"View FireFly Status\",\n \"View External Source Events\": \"View External Source Events\",\n\n // Backup and Restore\n \"Click to restore the selected backup archive\":\n \"Click to restore the selected backup archive.\",\n Restore: \"Restore\",\n \"Click to create a backup\": \"Click to create a backup\",\n \"Click to upload a file\": \"Click to upload a file\",\n Upload: \"Upload\",\n \"Restore Warning Message Header\":\n \"Administrator Use Only - Restore will perform a system restart\",\n \"Restore Warning Message Content\":\n \"Select the Restore button to restore the system database and area images from the archive. Users will be logged out until after the system has been restarted.\",\n \"File Name\": \"File Name\",\n \"File Date\": \"File Date\",\n \"File Size\": \"File Size\",\n File: \"File\",\n Files: \"Files\",\n Backup: \"Backup\",\n BACKUP_LIST_UPDATE_POP_MSG: \"Update page data\",\n\n // error messages\n \"Data Loading Message Header\": \"Loading\",\n \"Data Loading Message Content\":\n \"Loading data. Please wait. If there is a very long delay data may not exist for this Area.\",\n \"Data Loading Receiving\": \"Receiving data...\",\n // 404\n \"Page not found\": \"Page not found\",\n \"No match for\": \"No match for\",\n\n // Tag Tracking\n Tag: \"Tag\",\n Tags: \"Tags\",\n \"Tag Tracking\": \"Tag Tracking\",\n \"Tag Map\": \"Tag Map\",\n \"Tags In Zones\": \"Tags In Zones\",\n \"Tag Zone\": \"Tag Zone\",\n \"Tag Zones\": \"Tag Zones\",\n \"Tags for\": \"Tags for\",\n \"Assigned Tags\": \"Assigned Tags\",\n Personnel: \"Personnel\",\n Vehicle: \"Vehicle\",\n Vehicles: \"Vehicles\",\n \"No Tag Information\": \"No Tag Information\",\n \"Tag information is not available. Please reload the page or check the server settings.\":\n \"Tag information is not available. Please reload the page or check the server settings.\",\n\n \"Tag User\": \"Tag User\",\n Type: \"Type\",\n Types: \"Types\",\n Zones: \"Zones\",\n Zone: \"Zone\",\n RSSI: \"RSSI\",\n Unassign: \"Unassign\",\n \"Tag Zone List Message Header\": \"No Tag Zones\",\n \"Tag Zone List Message Content\":\n \"Tag Zones are not found for this Area. Check zones or wait for data to load.\",\n TAG_ZONE_LIST_UPDATE_POP_MSG: \"Fetch new Tag info\",\n \"Click Update to fetch data.\": \"Click Update to fetch data.\",\n\n // Help and Doc pages\n Documents: \"Documents\",\n\n Help: \"Help\",\n \"Help Files\": \"Help Files\",\n \"Help Files Header\": \"\",\n \"Help Files Message\":\n \"This area contains an assortment of help files and tips which have been prepared to assist you with Lighting Control, Controllers and the FireFly lighting control system in general. Click to open the files in a separate window.\",\n \"No Files\": \"Sorry, there are no files available at the moment.\",\n\n // Controller pages\n Header_Controller_BulkPosition: \"Controller Status\",\n Controller: \"Controller\",\n \"Controller URL\": \"Controller URL\",\n Area: \"Area\",\n Location: \"Location\",\n Master: \"Master\",\n Version: \"Version\",\n \"DC Supply Voltage\": \"DC Supply Voltage\",\n \"Battery Voltage\": \"Battery Voltage\",\n \"Disk Used\": \"Disk Used\",\n \"Memory Used\": \"Memory Used\",\n \"User Relay\": \"User Relay\",\n \"Latest Report\": \"Latest Report\",\n \"Controller Config\": \"Controller Config\",\n \"Controller ID\": \"Controller ID\",\n \"Controller Address\": \"Controller Address\",\n \"Controller Mode\": \"Controller Mode\",\n \"Controller Location\": \"Controller Location\",\n Ports: \"Ports\",\n \"Enable Emergency Events\": \"Enable Emergency Events\",\n \"Enable Trigger Events\": \"Enable Trigger Events\",\n \"Controller Port Message Header\": \"No Port Information\",\n \"Controller Port Message Content\":\n \"Port information is not available. Please reload the page or check the controller settings. Check FireFlys are connected to the controller.\",\n \"Controller Area Message Header\": \"Unknown Area\",\n \"Controller Area Message Content\":\n 'Area \"areaError_id\" is undefined. Please check the controller settings to configure the Area.',\n\n // FireFly pages\n Position: \"Position\",\n MAC: \"MAC\",\n \"MAC Address\": \"MAC Address\",\n \"SW Version\": \"SW Version\",\n Note: \"Note\",\n FireFly_Note_Placeholder:\n \"...enter notes. This text displays on the FireFly marker popup and in the FireFly list.\",\n \"FireFly ID\": \"FireFly ID\",\n \"FireFly Location\": \"FireFly Location\",\n \"FireFly Position\": \"FireFly Position\",\n \"FireFly MAC Address\": \"FireFly MAC Address\",\n Controller: \"Controller\",\n \"Controller Name\": \"Controller Name\",\n \"Controller MAC\": \"Controller MAC\",\n \"Controller Config Address\": \"Controller Config Address\",\n // Forced\n \"Forced FireFly\": \"Forced FireFly\",\n \"Forced FireFlys\": \"Forced FireFlys\",\n\n // Polygon pages / namedarea pages\n Polygon: \"Polygon\",\n Polygons: \"Polygons\",\n \"Add Polygon\": \"Add Polygon\",\n \"Delete Polygon\": \"Delete Polygon\",\n \"Polygon Active Event Message Header\": \"Active Lights\",\n \"Polygon Active Event Message Content\":\n \"This polygon has an active event. Changes to this polygon will change the state of lights.\",\n \"Polygon Info Message Header\": \"Use the map controls to add a new polygon\",\n \"Polygon Info Message Content\":\n \"Click on the map's Polygon or Rectangle icon to draw a new polygon shape. A shape must be drawn to be able to save the polygon settings.\",\n \"Set the color of the {polygon_type} region\":\n \"Set the color of the {polygon_type} region\",\n Styling: \"Styling\",\n \"{polygon_type} Name\": \"{polygon_type} Name\",\n \"Enter the name of the {polygon_type}\":\n \"Enter the name of the {polygon_type}\",\n NAMED_AREA_SIMPLE_LIST_UPDATE_POP_MSG: \"Update page data\",\n\n // NamedAreaGroup pages\n\n \"No Lighting Control Layout\": \"No Lighting Control Layout\",\n NO_LIGHTING_CONTROL_LAYOUT_MESSAGE:\n \"There is no Lighting Control layout defined for this Area. Check Smart Lighting > Lighting Control Layouts\",\n\n \"Lighting Control\": \"Lighting Control\",\n \"Lighting Control Layouts\": \"Lighting Control Layouts\",\n \"Control Layout for Area\": \"Control Layout for Area\",\n\n Groups: \"Groups\",\n Group: \"Group\",\n \"Add Group\": \"Add Group\",\n \"No Groups. Add a group.\": \"No Groups. Add a group.\",\n \"No Levels. Add a level.\": \"No Levels. Add a level.\",\n \"No Polygons. Add a polygon.\": \"No Polygons. Add a polygon.\",\n Levels: \"Levels\",\n Level: \"Level\",\n \"Add Level\": \"Add Level\",\n \"Control Layout\": \"Control Layout\",\n \"Edit Settings\": \"Edit Settings\",\n Label: \"Label\",\n \"Custom Button Label\": \"Custom Button Label\",\n \"Custom label for buttons\": \"Custom label for buttons\",\n \"Polygon ID\": \"Polygon ID\",\n \"Polygon Unique ID\": \"Polygon Unique ID\",\n \"Edit Group settings\": \"Edit Group settings\",\n \"Edit Level settings\": \"Edit Level settings\",\n \"Edit Polygon settings\": \"Edit Polygon settings\",\n \"Delete Group\": \"Delete Group\",\n \"Delete Level\": \"Delete Level\",\n \"Drag and drop Polygons here. Configure light states after adding Polygons.\":\n \"Drag and drop Polygons here. Configure light states after adding Polygons.\",\n\n \"Drag Group to reorder\": \"Drag Group to reorder\",\n \"Drag Level to reorder\": \"Drag Level to reorder\",\n \"Drag Polygon to reorder\": \"Drag Polygon to reorder\",\n \"Drag Polygon to Level\": \"Drag Polygon to Level\",\n \"Click to expand/collapse the Group\": \"Click to expand/collapse the Group\",\n \"Click to expand/collapse the Level\": \"Click to expand/collapse the Level\",\n \"Click to expand/collapse all Groups\": \"Click to expand/collapse all Groups\",\n\n Hint: \"Hint\",\n \"Active Color of Lights\": \"Active Color of Lights\",\n \"Active Alternate Color of Lights\": \"Active Alternate Color of Lights\",\n \"Active Brightness Level\": \"Active Brightness Level\",\n \"Display Marker Icon\": \"Display Marker Icon\",\n \"Active State of Lights\": \"Active State of Lights\",\n \"Off Time\": \"Off Time\",\n \"On Time\": \"On Time\",\n \"Train Time\": \"Train Time\",\n \"About Active State Forward and Backward\":\n \"About Active State Forward and Backward\",\n Warning_FORWARD_BACKWARD:\n \"Forward and Backward creates a light 'chaser' effect over the FireFly lights per location (i.e. Controller port). The effect does not work across FireFlys on different ports.\",\n \"Relay Settings\": \"Relay Settings\",\n Siren: \"Siren\",\n \"Button Permissions\": \"Button Permissions\",\n \"Bit register of button permissions e.g. 1\":\n \"Bit register of button permissions e.g. 1\",\n \"Button Permissions Register\": \"Button Permissions Register\",\n \"Access Settings\": \"Access Settings\",\n User: \"User\",\n Permission: \"Permission\",\n Show: \"Show\",\n Control: \"Control\",\n ACCESS_MESSAGE:\n \"Restrict access to Operators. Default settings show all groups to all Operators.\",\n \"Click to delete row\": \"Click to delete row\",\n \"Click to toggle Show/Hide\": \"Click to toggle Show/Hide\",\n \"Click to toggle Control enable/disable\":\n \"Click to toggle Control enable/disable\",\n\n // External trigger pages\n \"External Trigger\": \"External Trigger\",\n \"External Triggers\": \"External Triggers\",\n \"External Trigger Status\": \"External Trigger Status\",\n \"External Trigger Event\": \"External Trigger Event\",\n \"External Trigger Events\": \"External Trigger Events\",\n \"Event Log\": \"Event Log\",\n \"External Trigger ID\": \"External Trigger ID\",\n\n Active: \"Active\",\n ACTIVE: \"ACTIVE\",\n Inactive: \"Inactive\",\n INACTIVE: \"INACTIVE\",\n Source: \"Source\",\n \"Event Source\": \"Event Source\",\n \"Scheduled Job\": \"Scheduled Job\",\n Job: \"Job\",\n Reason: \"Reason\",\n Disabled: \"Disabled\",\n \"Not Applicable\": \"Not Applicable\",\n \"Not applicable\": \"Not Applicable\",\n \"Polygon Coords\": \"Polygon Coords\",\n \"No event sources enabled\": \"No event sources enabled\",\n \"Allowed Event Source\": \"Allowed Event Source\",\n EXT_TRIGGER_EVENT_LIST_UPDATE_POP_MSG: \"Update page data\",\n\n // event Log pages\n\n Operator: \"Operator\",\n Origin: \"Origin\",\n Time: \"Time\",\n Event: \"Event\",\n \"Event/Shape ID\": \"Event/Shape ID\",\n Priority: \"Priority\",\n \"Active Color\": \"Active Color\",\n \"Active State\": \"Active State\",\n \"State Info ( On | Off | Train)\": \"State Info ( On | Off | Train)\",\n \"Range (Start -> End)\": \"Range (Start -> End)\",\n \"Relay Event Active\": \"Relay Event Active\",\n Shape: \"Shape\",\n ACTIVE: \"ACTIVE\",\n INACTIVE: \"INACTIVE\",\n EVENT_LOG_LIST_UPDATE_POP_MSG: \"Update page data\",\n\n // Misc selector options\n green: \"Green\",\n red: \"Red\",\n blue: \"Blue\",\n amber: \"Amber\",\n white: \"White\",\n off: \"Off\",\n on: \"On\",\n\n strobe: \"Strobe\",\n forward: \"Forward\",\n backward: \"Backward\",\n slow: \"slow\",\n fast: \"fast\",\n\n plus: \"Plus\",\n cross: \"Cross\",\n circle: \"Circle\",\n square: \"Square\",\n diamond: \"Diamond\",\n multistrobe: \"Multistrobe\",\n travelway: \"Travelway\",\n star: \"Star\",\n hourglass: \"Hour Glass\",\n bowtie: \"Bow Tie\",\n triangle: \"Triangle\",\n\n // Scheduled event pages\n\n \"Scheduled Jobs\": \"Scheduled Jobs\",\n \"Scheduled Job\": \"Scheduled Job\",\n \"Add Scheduled Job\": \"Add Scheduled Job\",\n \"Edit Scheduled Job\": \"Edit Scheduled Job\",\n \"Scheduled Events\": \"Scheduled Events\",\n \"Scheduled Event\": \"Scheduled Event\",\n \"Scheduled Lighting Event\": \"Scheduled Lighting Event\",\n \"Schedule Event Job Name\": \"Schedule Event Job Name\",\n \"Enter the name of the Scheduled Event Job\":\n \"Enter the name of the Scheduled Event Job\",\n \"Disable Job\": \"Disable Job\",\n \"Add a Polygon\": \"Add a Polygon\",\n \"Choose Polygons\": \"Choose Polygons\",\n ENABLED: \"ENABLED\",\n DISABLED: \"DISABLED\",\n QUEUED: \"QUEUED\",\n RUNNING: \"RUNNING\",\n Start: \"Start\",\n Date: \"Date\",\n Now: \"Now\",\n Never: \"Never\",\n Duration: \"Duration\",\n all: \"all\",\n every: \"every\",\n Month: \"Month\",\n Months: \"Months\",\n month: \"month\",\n months: \"months\",\n \"any day\": \"any day\",\n Day: \"Day\",\n Days: \"Days\",\n day: \"day\",\n days: \"days\",\n DAY_WEEK: \"Day of the Week\",\n hour: \"hour\",\n hours: \"hours\",\n Hour: \"Hour\",\n Hours: \"Hours\",\n minute: \"minute\",\n minutes: \"minutes\",\n Minute: \"Minute\",\n Minutes: \"Minutes\",\n second: \"second\",\n seconds: \"seconds\",\n Stop: \"Stop\",\n\n timezone: \"Timezone\",\n \"Select Date\": \"Select Date\",\n january: \"January\",\n february: \"February\",\n march: \"March\",\n april: \"April\",\n may: \"May\",\n june: \"June\",\n july: \"July\",\n august: \"August\",\n september: \"September\",\n october: \"October\",\n november: \"November\",\n december: \"December\",\n week: \"Week\",\n year: \"Year\",\n date: \"Date\",\n \"any weekday\": \"any weekday\",\n monday: \"Monday\",\n tuesday: \"Tuesday\",\n wednesday: \"Wednesday\",\n thursday: \"Thursday\",\n friday: \"Friday\",\n saturday: \"Saturday\",\n sunday: \"Sunday\",\n\n \"Show All\": \"Show All\",\n Today: \"Today\",\n Yesterday: \"Yesterday\",\n \"24 Hours\": \"24 Hours\",\n \"7 Days\": \"7 Days\",\n \"30 Days\": \"30 Days\",\n All: \"All\",\n CRON: \"CRON\",\n \"CRON Schedule Expression\": \"CRON Schedule Expression\",\n \"Start CRON Expression\": \"Start CRON Expression\",\n \"Stop CRON Expression\": \"Stop CRON Expression\",\n \"CRON Expression\": \"CRON Expression\",\n \"Scheduled Event Settings\": \"Scheduled Event Settings\",\n \"CRON Wizard\": \"CRON Wizard\",\n Wizard: \"Wizard\",\n Duration: \"Duration\",\n \"Duration Units\": \"Duration Units\",\n \"Bit register of CRON Speci e.g. 1\": \"Bit register of CRON Speci e.g. 1\",\n Sched_Event_Note_Placeholder: \"...enter notes. Recorded in the Event Log.\",\n \"Lighting Event\": \"Lighting Event\",\n Activate: \"Activate\",\n Deactivate: \"Deactivate\",\n Schedule: \"Schedule\",\n \"System Message\": \"System Message\",\n FUTURE_FEATURE: \"Future feature\",\n JOB_DAY_SELECTOR_POP_MSG: \"Day of the month - one day or periodic\",\n JOB_MONTH_SELECTOR_POP_MSG: \"Month - one month or periodic\",\n JOB_DAYOFWEEK_SELECTOR_POP_MSG: \"Day of the week\",\n Created: \"Created\",\n \"Click to add selected Polygon\": \"Click to add selected Polygon\",\n \"Select Group\": \"Select Group\",\n \"Select Level\": \"Select Level\",\n \"Select Polygon\": \"Select Polygon\",\n \"Choose an Area\": \"Choose an Area\",\n \"Choose a Group\": \"Choose a Group\",\n \"Choose a Level\": \"Choose a Level\",\n \"No Groups defined\": \"No Groups defined\",\n \"No Levels defined\": \"No Levels defined\",\n \"No Polygons defined\": \"No Polygons defined\",\n SCHEDULED_JOBS_LIST_UPDATE_POP_MSG: \"Update page data\",\n SCHEDULED_EVENTS_LIST_UPDATE_POP_MSG: \"Update page data\",\n\n // User pages\n Name: \"Name\",\n Role: \"Role\",\n \"User Group\": \"User Group\",\n Language: \"Language\",\n Application: \"Application\",\n \"Users Details\": \"Users Details\",\n \"User Name\": \"User Name\",\n \"Email Address\": \"Email Address\",\n \"User's Role\": \"User's Role\",\n \"Change Password\": \"Change Password\",\n \"New Password\": \"New Password\",\n \"Enter a new user password\": \"Enter a new user password\",\n \"Confirm Password\": \"Confirm Password\",\n \"Reenter your new password to confirm\":\n \"Reenter your new password to confirm\",\n\n \"Create New User\": \"Create New User\",\n\n \"Super User - Administrator + administer users\":\n \"Super User - Administrator + administer users\",\n \"Administrator - Operator + administer areas and devices\":\n \"Administrator - Operator + administer areas and devices\",\n \"Operator - All general operations. Trigger events etc.\":\n \"Operator - All general operations. Trigger events etc.\",\n \"Guest - View area maps and light status\":\n \"Guest - View area maps and light status\",\n\n // Settings\n Settings: \"Settings\",\n Display: \"Display\",\n Features: \"Features\",\n Options: \"Options\",\n \"Show Lighting Control Layout\": \"Show Lighting Control Layout\",\n \"Show hints on Polygon buttons\": \"Show hints on Polygon buttons\",\n Compressed: \"Compressed\",\n Normal: \"Normal\",\n Expanded: \"Expanded\",\n \"Control Size\": \"Control Size\",\n \"Column Width\": \"Column Width\",\n smartLighting: \"Smart Lighting\",\n tagTracking: \"Tag Tracking\",\n \"No applications enabled\": \"No applications enabled\",\n Applications: \"Applications\",\n \"No features enabled\": \"No features enabled\",\n showDemoMode: \"Demo Mode\",\n showDevelopmentVersion: \"Development Mode\",\n showExternalTriggerEvent:\n \"Show External Trigger Event options (requires Smart Lighting)\",\n showScheduledEvent: \"Show Scheduled Job options (requires Smart Lighting)\",\n showUserRelay:\n \"Show User Relay options (e.g. Siren) (requires Smart Lighting)\",\n showBackupRestore: \"Show Backup and Restore options\",\n\n // Log page\n \"System Log\": \"System Log\",\n \"Browser Log\": \"Browser Log\",\n Logged: \"Logged\",\n\n // Fault log\n \"Fault Log\": \"Fault Log\",\n\n // Message banner messages\n \"Requested by\": \"Initiated by\",\n \"ERROR: Service Fault\": \"ERROR: Service Fault\",\n \"Service reports\": \"Service reports\",\n NOW: \"NOW!\",\n \"Click to dismiss message\": \"(Click to dismiss this message)\",\n PROCESS_RESTORE_REQUESTED_MSG: \"System Restore Requested\",\n PROCESS_RESTORE_REQUESTED_MSG_CONTENT:\n \"A system restore has been requested. Within 1 minute all users will be logged off and the system reset and restored.\",\n PROCESS_RESTORE_SUCCEEDED_MSG: \"System Restore Succeeded\",\n PROCESS_RESTORE_SUCCEEDED_MSG_CONTENT: \"The system restore was successful\",\n PROCESS_RESTORE_FAILED_MSG: \"System Restore Failed\",\n PROCESS_RESTORE_FAILED_MSG_CONTENT: \"System restore failed\",\n //\n PROCESS_RESTORE_LOGOUT_MSG: \"System Restore Logout\",\n PROCESS_RESTORE_LOGOUT_MSG_CONTENT: \"Logged out all users.\",\n PROCESS_RESTORE_LOGOUT_WARNING_MSG: \"System Restore Underway\",\n PROCESS_RESTORE_LOGOUT_WARNING_MSG_CONTENT:\n \"All users will be logged out and the system will restart in \",\n\n PROCESS_RESTORE_FAILED_MSG_FILE_CHECKS:\n \"System restore process failed file checks.\",\n\n PROCESS_RESTORE_FAILED_MSG_SQL_SCHEMA_TMP: \"tmp_db SQL schema dump failed\",\n PROCESS_RESTORE_FAILED_MSG_SQL_SCHEMA_IOT:\n \"iot_server SQL schema dump failed\",\n PROCESS_RESTORE_FAILED_MSG_SQL_SCHEMA_COMPARE: \"Schema comparison failed.\",\n PROCESS_RESTORE_FAILED_MSG_SQL_SCHEMA_COMPARE_FILES:\n \"Schema comparison files missing.\",\n\n //\n PROCESS_BACKUP_REQUESTED_MSG: \"System Backup Requested\",\n PROCESS_BACKUP_REQUESTED_MSG_CONTENT: \"A system backup has been requested\",\n PROCESS_BACKUP_SUCCEEDED_MSG: \"System Backup Succeeded\",\n PROCESS_BACKUP_SUCCEEDED_MSG_CONTENT: \"The system backup is complete\",\n\n PROCESS_BACKUP_FAILED_MSG: \"System Backup Failed\",\n PROCESS_BACKUP_FAILED_MSG_CONTENT:\n \"System Backup process failed. Check logs for errors.\",\n PROCESS_BACKUP_FAILED_MSG_NO_FILE: \"PROCESS_BACKUP_FAILED_MSG_NO_FILE\",\n PROCESS_BACKUP_FAILED_MSG_SQL_DUMP_ERROR:\n \"PROCESS_BACKUP_FAILED_MSG_SQL_DUMP_ERROR\",\n PROCESS_BACKUP_FAILED_MSG_ZIP_COMPRESS_FAIL:\n \"PROCESS_BACKUP_FAILED_MSG_ZIP_COMPRESS_FAIL\",\n\n //\n // System Tools\n \"Administrator Use Only\": \"Administrator Use Only\",\n ADMIN_ONLY_MESSAGE:\n \" The following tools can cause significant changes to your system state. Please be familiar with the operation before using any of these tools.\",\n \"Server Operations\": \"Server Operations\",\n \"MQTT Information\": \"MQTT Information\",\n \"Session Information\": \"Session Information\",\n};\n\n// Default english terms.\n// Key is the reference key, value is the displayed text.\nexport let strings = new LocalizedStrings({\n \"en-US\": { ...defaultStrings },\n});\n","// #TODO - consolidate hardcoded default settings here\n// search for \"DEFAULT_\" or similar\n//\n\nexport const DEFAULT_SETTINGS = {\n display: {\n columnWidth: 6,\n legend: false,\n hint: true,\n view: \"normal\",\n sopInterface: true,\n },\n componentState: [],\n application: [],\n namedAreaGroup: [],\n options: [],\n};\n\nexport const DEFAULT_CRON_EXPRESSION = \"0 0 12 * * *\";\nexport const DEFAULT_CRON_EXPRESSION_STOP = \"0 1 12 * * *\";\n","import Immutable from \"seamless-immutable\";\nimport isEmpty from \"lodash/isEmpty\";\nimport { DEFAULT_SETTINGS } from \"utils/DEFAULTS\";\n\nconst parseUserDataSettings = (user) => {\n let newUser = { ...user };\n let settings = newUser?.data?.settings;\n\n let newSettings = DEFAULT_SETTINGS;\n // check settings exist or set DEFAULT\n if (settings !== \"\") {\n if (settings?.includes(\"display\")) {\n newSettings = JSON.parse(settings);\n }\n }\n\n newUser.data.settings = newSettings;\n\n return newUser;\n};\n\nconst initialState = Immutable({\n errors: {},\n isLoading: false,\n user: {},\n isCheckingAuth: false,\n hasCheckedOnce: false,\n isLoggingOut: false,\n});\n\nexport default function reduce(state = initialState, action = {}) {\n switch (action.type) {\n case \"LOGIN_REQUEST\":\n return state.merge([\n { isLoading: true },\n { errors: {} },\n { hasCheckedOnce: true },\n ]);\n case \"LOGIN_ERROR\":\n return state.merge([{ isLoading: false }, { errors: action.errors }]);\n case \"LOGIN_SUCCESS\":\n console.log(\"LOGIN_SUCCESS action.payload\", action.payload);\n\n return state.merge([\n { isLoading: false },\n { errors: [] },\n { user: parseUserDataSettings(action.payload.user) },\n ]);\n case \"CHECK_AUTH\":\n return state.merge([{ isCheckingAuth: true, hasCheckedOnce: true }]);\n case \"AUTH_FAILURE\":\n return state.merge([{ isCheckingAuth: false, user: {} }]);\n case \"AUTH_UNKNOWN\":\n return state.merge([{ isCheckingAuth: false }]);\n case \"FOUND_VALID_AUTH\":\n return state.merge([\n { isCheckingAuth: false },\n { errors: [] },\n { user: parseUserDataSettings(action.payload.user) },\n ]);\n\n case \"LOGOUT_REQUEST\":\n return state.merge([{ isLoggingOut: true }]);\n case \"LOGOUT_SUCCESS\":\n return initialState.merge([{ hasCheckedOnce: true }]);\n case \"LOGOUT_ERROR\":\n return state.merge([{ isLoggingOut: false }, { errors: action.errors }]);\n case \"RESET\":\n console.log(\"RESET! - Auth\");\n return state;\n default:\n return state;\n }\n}\n\nexport const isAuthenticated = (state) => {\n return !isEmpty(state.auth.user);\n};\n\nexport const isLoading = (state) => {\n return state.auth.isLoading;\n};\n\nexport const getRoles = (state) => {\n //console.log(\"getRoles - state.auth\", state.auth);\n return state.auth.getIn([\"user\", \"data\", \"roles\"], []);\n};\n\nexport const isUserSuper = (state) => {\n // console.log(\n // 'getRoles(state).indexOf(\"super\")',\n // getRoles(state).indexOf(\"super\")\n // );\n return getRoles(state).indexOf(\"super\") >= 0;\n};\n\nexport const isUserAdmin = (state) => {\n return getRoles(state).indexOf(\"admin\") >= 0;\n};\n\nexport const isUserUser = (state) => {\n return getRoles(state).indexOf(\"user\") >= 0;\n};\n// i.e. operator\n\n// isLightPlanner\n// isControlRoomOperator\n// isNetworkAdmin\n\nexport const isUserGuest = (state) => {\n return getRoles(state).indexOf(\"guest\") >= 0;\n};\n\nexport const getUsername = (state) => {\n return state.auth.user.data?.username;\n};\n\nexport const getEmail = (state) => {\n return state.auth.user.data?.email;\n};\n\nexport const getUserRole = (state) => {\n return state.auth.user.data?.roles;\n};\n\nexport const getUserData = (state) => {\n return state.auth.user.data;\n};\n\nexport const getUserSettings = (state) => {\n return state.auth.user.data?.settings;\n};\n","export function login({ email, password }) {\n return { type: \"LOGIN_REQUEST\", payload: { email, password } };\n}\n\nexport function logout() {\n return { type: \"LOGOUT_REQUEST\" };\n}\n\nexport function checkAuth() {\n return { type: \"CHECK_AUTH\" };\n}\n\nexport function reset() {\n return { type: \"RESET\" };\n}\n","import { isCustomSOP } from \"components/ConfigJs\";\n\nexport const NAMED_AREA_DISPLAY_SETTINGS = getNamedAreaDisplaySettings();\n\nfunction getNamedAreaDisplaySettings() {\n let hint = getCookie(\"hint\");\n if (hint === undefined) {\n // default\n hint = false;\n setCookie(\"hint\", hint, 500);\n } else {\n hint = hint?.toString() === \"true\";\n }\n\n let legend = getCookie(\"legend\");\n if (legend === undefined) {\n // default\n legend = false;\n setCookie(\"legend\", legend, 500);\n } else {\n legend = legend?.toString() === \"true\";\n }\n\n let view = getCookie(\"view\");\n if (view === undefined) {\n // default\n view = \"normal\";\n setCookie(\"view\", view, 500);\n }\n\n let columnWidth = getCookie(\"columnWidth\");\n if (columnWidth === undefined) {\n columnWidth = 6;\n setCookie(\"columnWidth\", columnWidth, 500);\n }\n\n let sopInterface = getCookie(\"sopInterface\");\n if (sopInterface === undefined) {\n sopInterface = isCustomSOP()?.toString() === \"true\";\n //console.log(\"isCustomSOP(), sopInterface\", isCustomSOP(), sopInterface);\n setCookie(\"sopInterface\", sopInterface, 500);\n } else {\n // make absolutely sure!!!!!!!!!!!!!\n sopInterface = true;\n }\n\n return { hint, legend, view, columnWidth, sopInterface };\n}\n\nexport function getCookie(name) {\n var value = \"; \" + document.cookie;\n var parts = value?.split(\"; \" + name + \"=\");\n if (parts.length === 2) {\n return parts.pop()?.split(\";\")?.shift();\n }\n return undefined;\n}\n\nexport function clearCookie(cookieName) {\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\n}\n\nexport function setCookie(cookieName, cookieValue, hourToExpire) {\n // console.log(\"setCookie\", cookieName, \"value \", cookieValue);\n let date = new Date();\n date.setTime(date.getTime() + hourToExpire * 60 * 60 * 1000);\n document.cookie =\n cookieName + \" = \" + cookieValue + \"; expires = \" + date.toGMTString();\n}\n","import Immutable from \"seamless-immutable\";\nimport { setCookie } from \"cookies\";\nimport { isConfigJs, pollRates } from \"components/ConfigJs\";\n\nconst initialState = Immutable({\n namedAreaDisplaySettings: {},\n folderFilesList: {},\n serverInfo: {},\n serverStatus: \"OK\", // assume everything is OK ;)\n turnOnPokeWorker: true,\n //\n pollRates: {\n disable: false, // disables data collection via web worker\n worker: 10 * 1000, // 10 seconds // #DEFAULT_POLL_RATE on startup\n workerEssentials: 1 * 1000, // 1 second // #DEFAULT_POLL_RATE on startup\n server: 30 * 1000, // 30 seconds // #DEFAULT_POLL_RATE on startup\n },\n //\n mqttBroker: {},\n //\n // monitors loading of essential settings data to manage startup/reload\n settingsDataLoading: true,\n //\n // keep copies of loaded map images\n mapImages: [],\n mapSettings: [],\n //\n checkService: [], // status of services when logged in\n //\n isSystemRestore: false, // flag indicating restore has been triggered\n});\n\nexport default function reduce(state = initialState, action = {}) {\n const newState = { ...state };\n const { type, payload } = action;\n\n switch (type) {\n case \"SET_NAMED_AREA_DISPLAY_SETTINGS\":\n newState.namedAreaDisplaySettings = payload;\n return newState;\n\n case \"UPDATE_NAMED_AREA_DISPLAY_SETTINGS\":\n const { hint, legend, view, columnWidth, sopInterface } = payload;\n\n // update cookie setting\n setCookie(\"hint\", hint, 500);\n setCookie(\"legend\", legend, 500);\n setCookie(\"view\", view, 500);\n setCookie(\"columnWidth\", columnWidth, 500);\n setCookie(\"sopInterface\", sopInterface, 500);\n\n newState.namedAreaDisplaySettings = payload;\n return newState;\n\n case \"FOLDER_FILES_LIST_FETCH_SUCCEEDED\":\n //console.log(`FOLDER_FILES_LIST_FETCH_SUCCEEDED payload`, payload);\n\n const {\n data: { list, folder },\n } = payload;\n\n // list may return null if no files\n let newList = [];\n if (list !== null) {\n newList = list;\n }\n\n // clone it\n let newFolderFilesList = JSON.parse(\n JSON.stringify(newState.folderFilesList)\n );\n\n newFolderFilesList[folder] = newList;\n newState.folderFilesList = newFolderFilesList;\n return newState;\n\n case \"SERVER_INFO_FETCH_SUCCEEDED\":\n const { info } = payload;\n\n //console.log(`SERVER_INFO_FETCH_SUCCEEDED`, info);\n newState.serverInfo = info;\n\n // set server status\n newState.serverStatus = \"OK\";\n return newState;\n\n // #NOTE - should generalise these fetch failures as common error banner\n // #WIP\n case \"SERVER_INFO_FETCH_FAILED\":\n //console.log(`SERVER_INFO_FETCH_FAILED status:`, payload);\n\n // pop a message banner for SERVER_CONNECTION_CLOSED\n // see - `src/components/Settings/sagas.js`\n // When fetch fails msg SERVER_CONNECTION_CLOSED is sent to pop server failed dlg\n\n // set server status\n newState.serverStatus = payload;\n\n return newState;\n\n case \"SYSTEM_TURN_ON_OFF_POKE_THE_WORKER\":\n //console.log(`SYSTEM_TURN_ON_OFF_POKE_THE_WORKER payload:`, payload);\n\n newState.turnOnPokeWorker = payload;\n\n return newState;\n\n case \"SYSTEM_DISABLE_POKE_THE_WORKER\":\n //console.log(`SYSTEM_DISABLE_POKE_THE_WORKER payload:`, payload);\n\n newState.pollRates = { ...newState.pollRates, disable: payload };\n\n return newState;\n\n case \"SYSTEM_SET_POLL_RATES\":\n console.log(`SYSTEM_SET_POLL_RATES payload:`, payload);\n\n newState.pollRates = payload;\n return newState;\n\n case \"SYSTEM_POLL_RATE_POKE_THE_WORKER\":\n //console.log(`SYSTEM_POLL_RATE_POKE_THE_WORKER payload:`, payload);\n\n newState.pollRates = { ...newState.pollRates, worker: payload };\n return newState;\n\n case \"MQTT_BROKER_FETCH_SUCCEEDED\":\n //console.log(`MQTT_BROKER_FETCH_SUCCEEDED`, payload);\n\n const {\n mqttBrokerAddress: address,\n mqttBrokerAddressTWO: addressSecondary, // if it exists\n mqttBrokerPort,\n mqttBrokerProtocol,\n } = payload;\n\n const port =\n window.location.protocol === \"https:\"\n ? mqttBrokerPort.https\n : mqttBrokerPort.http;\n\n const protocol =\n window.location.protocol === \"https:\"\n ? mqttBrokerProtocol.https\n : mqttBrokerProtocol.http;\n\n newState.mqttBroker = { address, addressSecondary, port, protocol };\n\n // set dataLoading flag, ATM this is the only essential data required before started.\n // This should be expanded later to accommodate more server based settings.\n newState.settingsDataLoading = false;\n return newState;\n\n // #WIP - not implemented\n case \"MQTT_BROKER_FETCH_FAILED\":\n console.log(`MQTT_BROKER_FETCH_FAILED payload`, payload);\n //\n // ...if fails pull in mqtt details from secondary sources like network.js\n //newState.mqttBroker = payload;\n return newState;\n\n case \"SERVER_CHECK_SERVICE_FETCH_SUCCEEDED\":\n console.log(`SERVER_CHECK_SERVICE_FETCH_SUCCEEDED`, payload);\n\n const { service } = payload;\n let newCheckService = [...newState.checkService];\n // remove existing service (if exists)\n newCheckService = newCheckService.filter(\n (item) => item.service !== service\n );\n // push new result\n newCheckService.push(payload);\n\n // console.log(\n // \"xxx postCheckService SERVER_CHECK_SERVICE_FETCH_SUCCEEDED newCheckService\",\n // newCheckService\n // );\n\n newState.checkService = newCheckService;\n\n return newState;\n\n // #WIP - not implemented\n case \"SYSTEM_SET_MAP_IMAGE\":\n console.log(`SYSTEM_SET_MAP_IMAGE payload`, payload);\n const { id, imageData } = payload;\n\n let newMapImages = [...newState.mapImages];\n // remove existing image with the same id\n newMapImages = newMapImages.filter((img) => img.id !== id);\n // push new image\n newMapImages.push(payload);\n\n console.log(`SYSTEM_SET_MAP_IMAGE newMapImages`, newMapImages);\n newState.mapImages = newMapImages;\n return newState;\n\n case \"SYSTEM_SET_MAP_SETTING\":\n // console.log(\n // `MapViewState >>>>>>>>>>> SYSTEM_SET_MAP_SETTING payload`,\n // payload\n // );\n const { mapSettingsId } = payload;\n\n let newMapSettings = [...newState.mapSettings];\n // remove existing settings\n newMapSettings = newMapSettings.filter(\n (img) => img.mapSettingsId !== mapSettingsId\n );\n // push new image\n newMapSettings.push(payload);\n newState.mapSettings = newMapSettings;\n return newState;\n\n case \"SET_SYSTEM_RESTORE\":\n const { restore } = payload;\n newState.isSystemRestore = restore;\n return newState;\n\n case \"RESET\":\n console.log(\"RESET! - Settings\");\n return initialState;\n\n default:\n return state;\n }\n}\n\nexport function getNamedAreaDisplaySettings(state) {\n return state.settings.namedAreaDisplaySettings;\n}\n\nexport const getFolderFilesListById = (state, id) =>\n state.settings.folderFilesList[id];\n\nexport const getFolderFileNamesListById = (state, id) =>\n state.settings.folderFilesList?.[id]?.map((file) => file.filename) || [];\n\nexport const getServerInfo = (state) => state.settings.serverInfo;\n\nexport const getServerInfoVersion = (state) =>\n state.settings.serverInfo?.version;\n\nexport const getServerInfoMemStat = (state) =>\n state.settings.serverInfo?.mem_stat;\n\nexport const getServerStatus = (state) => state.settings.serverStatus;\n\nexport const isOnOffPokeTheWorker = (state) => state.settings.turnOnPokeWorker;\n\nexport const isDisabledPokeTheWorker = (state) =>\n state.settings.pollRates.disable;\n\nexport const getPollRates = (state) => state.settings.pollRates;\n\nexport const getMqttBroker = (state) => state.settings.mqttBroker;\n\nexport const getSettingsDataLoading = (state) =>\n state.settings.settingsDataLoading;\n\nexport const getMapImages = (state) => state.settings.mapImages;\nexport const getMapImageById = (state, id) =>\n state.settings.mapImages.find((img) => img.id === id);\n\nexport const getMapSettings = (state) => state.settings.mapSettings;\nexport const getMapSettingsById = (state, id) =>\n state.settings.mapSettings.find((img) => img.id === id);\n\nexport const getCheckService = (state) => state.settings.checkService;\n\nexport const isServiceBackupMonitor = (state) =>\n state.settings.checkService.some(\n (item) =>\n item.service === \"iot-firefly-server-backup-monitor\" &&\n item.check === \"active\"\n );\n\nexport const isServiceTagTracker = (state) =>\n state.settings.checkService.some(\n (item) => item.service === \"iot-tag-tracker\" && item.check === \"active\"\n );\n\nexport const isSystemRestore = (state) => state.settings.isSystemRestore;\n","import {\n parseISO,\n format,\n formatRelative,\n differenceInMinutes,\n} from \"date-fns\";\n\nexport function formatDate(d, fmtDefault = \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\") {\n return format(d, fmtDefault);\n}\n\nexport function formatDateShort(d, fmtDefault = \"yyyy-MM-dd HH:mm\") {\n return format(d, fmtDefault);\n}\n\nexport function formatDateRelativeNow(d, now = new Date()) {\n return formatRelative(d, now);\n}\n\nexport function parseDate(d) {\n return parseISO(d);\n}\n\nexport function minutesAgo(d) {\n return differenceInMinutes(new Date(), d);\n}\n\nconst SECS_PER_MIN = 60;\nconst SECS_PER_HR = 60 * SECS_PER_MIN;\nconst SECS_PER_DAY = 24 * SECS_PER_HR;\n\nfunction fmt(singular, value) {\n return value > 1 ? `${value} ${singular}s` : `${value} ${singular}`;\n}\n\nexport function formatDuration(up) {\n const days = Math.floor(up / SECS_PER_DAY);\n up -= days * SECS_PER_DAY;\n const hours = Math.floor(up / SECS_PER_HR);\n up -= hours * SECS_PER_HR;\n const mins = Math.floor(up / SECS_PER_MIN);\n up -= mins * SECS_PER_MIN;\n const secs = up;\n\n let uptime = \"n/a\";\n if (days > 0) {\n uptime = [fmt(\"day\", days), fmt(\"hr\", hours), fmt(\"min\", mins)].join(\" \");\n } else if (hours > 0) {\n uptime = [fmt(\"hr\", hours), fmt(\"min\", hours), fmt(\"sec\", secs)].join(\" \");\n } else if (mins > 0) {\n uptime = [fmt(\"min\", hours), fmt(\"sec\", secs)].join(\" \");\n } else {\n uptime = fmt(\"sec\", secs);\n }\n\n return uptime;\n}\n","import React, { Component } from \"react\";\n\nimport { Table } from \"semantic-ui-react\";\n\nexport default class BasicTable extends Component {\n render() {\n const {\n HeaderComponent,\n RowComponent,\n items,\n isLoading,\n error,\n getItemKey = (item, idx) => idx,\n dispatch,\n } = this.props;\n\n var trailingContent = null;\n if (isLoading) {\n trailingContent = ;\n } else if (error) {\n trailingContent = ;\n } else if (items.length === 0) {\n trailingContent = ;\n }\n return (\n \n \n \n \n\n \n {items.map((item, idx) => {\n return (\n \n );\n })}\n {trailingContent}\n \n
\n );\n }\n}\n","// see - https://stackoverflow.com/questions/11725691/how-to-get-a-microtime-in-node-js\nexport const microTime = () => {\n var loadTimeInMS = Date.now();\n var performanceNow = require(\"performance-now\");\n return (loadTimeInMS + performanceNow()) * 1000;\n};\n","let currentAckToken = [];\n\nexport function setAckToken(ack) {\n currentAckToken = [...currentAckToken, ack];\n\n // housekeeping, cleanup old acks as these are no longer relevant\n currentAckToken = filterOldAckToken(currentAckToken);\n\n console.log(`CURRENT ACKS`, currentAckToken);\n}\n\nfunction filterOldAckToken(acks) {\n // parse the token to get timestamp string\n // get most recent ack timestamp and delete all acks older than 1min\n //\n\n // get timestamps same order of magn\n const compareTime = new Date().getTime();\n\n //console.log(`compareTime`, compareTime);\n const newAckToken = currentAckToken.filter(\n (ack) => ack.timeStamp > compareTime - 30 * 1000 // 30 seconds\n );\n\n //#TODO - #NOTE - set ACK delete in config db\n\n return newAckToken;\n}\n\nexport function getAckToken() {\n //console.log(\"isAckReceived getAckToken currentAckToken\", currentAckToken);\n\n return currentAckToken;\n}\n\nexport function clearAckToken() {\n currentAckToken = [];\n return currentAckToken;\n}\n\nexport function removeAckToken(removeToken) {\n currentAckToken = currentAckToken.filter(\n ({ token }) => token !== removeToken\n );\n return currentAckToken;\n}\n","// import { connect } from \"react-redux\";\n// import { getAcks } from \"components/WebWorker/reducer\";\n\nimport * as Api from \"api/apiAck\"; // getAckToken\n\nconst isAckReceivedByToken = (token) => {\n return new Promise((resolve, reject) => {\n let acks = Api.getAckToken(); // get latest acks\n\n console.log(\"isAckReceived ... looking for token \", token);\n console.log(\n \"isAckReceived ... in \",\n acks.length,\n \" acks \",\n JSON.stringify(acks)\n );\n\n const indexInAcks = acks\n .map(function (a) {\n return a.token;\n })\n .indexOf(token);\n\n if (indexInAcks > -1) {\n // found ack\n console.log(\"isAckReceived ... found it!\");\n resolve(indexInAcks);\n } else {\n console.log(\"isAckReceived ... nope, not here. Try again?\");\n reject(indexInAcks); //new Error(\"ack not found\")\n }\n });\n};\n\nfunction wait(n) {\n return new Promise((resolve) => setTimeout(resolve, n));\n}\n\nexport const confirmTokenRxWithRetryAndTimeout = (token, retry) => {\n console.log(\"retry\", retry);\n if (retry < 0) return Promise.reject(new Error(\"timeout\"));\n\n return isAckReceivedByToken(token).catch(() =>\n wait(2000).then(() => confirmTokenRxWithRetryAndTimeout(token, retry - 1))\n );\n};\n\n// const mapStateToProps = (state, ownProps) => {\n// // ack mqtt messages\n// const acks = getAcks(state);\n// return {\n// acks,\n// };\n// };\n\n// connect(mapStateToProps, null)(confirmTokenRxWithRetryAndTimeout);\n","import { makeRandomString } from \"utils/make-random\";\nimport { microTime } from \"utils/microTime\";\nimport { confirmTokenRxWithRetryAndTimeout } from \"utils/confirmTokenRxWithRetryAndTimeout\";\n\nexport var userSessionIp = getUserSessionIp() || \"admin,0.0.0.0\";\n\nexport function setUserSessionIp(ip) {\n if (ip !== undefined) {\n userSessionIp = ip;\n }\n}\n\nexport function getUserSessionIp() {\n // Get saved data from sessionStorage\n return sessionStorage.getItem(\"userSessionIp\");\n}\n\nexport const checkToken = async (token) => {\n // after message sent get confirmation of action (ACK) by comparing with token returned\n // wait for ack message with promise message timer\n // waits time is 2000 mS between retries\n const retries = 5;\n return await confirmTokenRxWithRetryAndTimeout(token, retries);\n};\n\nexport const messageToken = () => {\n const time = microTime().toString();\n const randString = makeRandomString(8);\n return `token-${randString}-${time},${getUserSessionIp()}`;\n};\n","export function makeRandomString(length) {\n var result = \"\";\n var characters =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n var charactersLength = characters.length;\n for (var i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength));\n }\n return result;\n}\n","export default function (value) {\n return value\n .toLowerCase()\n .replace(/ /g, '-')\n .replace(/[^\\w-]+/g, '')\n}\n","// change colors to web colors\nexport function toFireflyColor(color) {\n switch (color) {\n case \"green\":\n return \"green\";\n case \"blue\":\n return \"blue\";\n case \"amber\":\n case \"orange\":\n return \"amber\";\n // e.g. forced light modal displays the 'white' color as grey b/c can't do white on white bg.\n // Also white on white for the Lighting Control buttons.\n // So convert back to white for change command\n case \"grey\":\n case \"white\":\n return \"white\";\n case \"red\":\n return \"red\";\n default:\n return \"green\";\n }\n}\n\n// change colors to web colors\nexport function toFireflyAlternateColor(color) {\n switch (color) {\n case \"green\":\n return \"green\";\n case \"blue\":\n return \"blue\";\n case \"amber\":\n case \"orange\":\n return \"amber\";\n // e.g. forced light modal displays the 'white' color as grey b/c can't do white on white bg.\n // Also white on white for the Lighting Control buttons.\n // So convert back to white for change command\n case \"grey\":\n case \"white\":\n return \"white\";\n case \"red\":\n return \"red\";\n default:\n return \"off\";\n }\n }\n","// #NOTE - I needed to differentiate polygons by color.\n// I did not know how many polygons are displayed.\n// Rather than creating a sophisticated algorithm to choose contrasting colors in a color wheel\n// I chose instead to copy a huge lookup table from someone who has done this.\n// There are a lot of colors here. I doubt there will ever be that many polygon 'parents', and if there is\n// we just start from the beginning again.\n//\n// #NOTE _ manually excluded all colors starting with #FF...as these are two light for most use situations (i.e. in poor lighting)\n//\n// see - https://stackoverflow.com/questions/309149/generate-distinctly-different-rgb-colors-in-graphs\n\nexport const distinctColors = [\n //\"#000000\", // don't use black\n //\"#FFFF00\",\n //\"#1CE6FF\",\n //\"#FF34FF\",\n //\"#FF4A46\",\n \"#008941\",\n \"#006FA6\",\n \"#A30059\",\n //\"#FFDBE5\",\n \"#7A4900\",\n \"#0000A6\",\n \"#63FFAC\",\n \"#B79762\",\n \"#004D43\",\n \"#8FB0FF\",\n \"#997D87\",\n \"#5A0007\",\n \"#809693\",\n //\"#FEFFE6\",\n \"#1B4400\",\n \"#4FC601\",\n \"#3B5DFF\",\n \"#4A3B53\",\n //\"#FF2F80\",\n \"#61615A\",\n \"#BA0900\",\n \"#6B7900\",\n \"#00C2A0\",\n //\"#FFAA92\",\n //\"#FF90C9\",\n \"#B903AA\",\n \"#D16100\",\n \"#DDEFFF\",\n \"#000035\",\n \"#7B4F4B\",\n \"#A1C299\",\n \"#300018\",\n \"#0AA6D8\",\n \"#013349\",\n \"#00846F\",\n \"#372101\",\n //\"#FFB500\",\n \"#C2FFED\",\n \"#A079BF\",\n \"#CC0744\",\n \"#C0B9B2\",\n \"#C2FF99\",\n \"#001E09\",\n \"#00489C\",\n \"#6F0062\",\n \"#0CBD66\",\n \"#EEC3FF\",\n \"#456D75\",\n \"#B77B68\",\n \"#7A87A1\",\n \"#788D66\",\n \"#885578\",\n \"#FAD09F\",\n \"#FF8A9A\",\n \"#D157A0\",\n \"#BEC459\",\n \"#456648\",\n \"#0086ED\",\n \"#886F4C\",\n \"#34362D\",\n \"#B4A8BD\",\n \"#00A6AA\",\n \"#452C2C\",\n \"#636375\",\n \"#A3C8C9\",\n //\"#FF913F\",\n \"#938A81\",\n \"#575329\",\n \"#00FECF\",\n \"#B05B6F\",\n \"#8CD0FF\",\n \"#3B9700\",\n \"#04F757\",\n \"#C8A1A1\",\n \"#1E6E00\",\n \"#7900D7\",\n \"#A77500\",\n \"#6367A9\",\n \"#A05837\",\n \"#6B002C\",\n \"#772600\",\n \"#D790FF\",\n \"#9B9700\",\n \"#549E79\",\n \"#FFF69F\",\n \"#201625\",\n \"#72418F\",\n \"#BC23FF\",\n \"#99ADC0\",\n \"#3A2465\",\n \"#922329\",\n \"#5B4534\",\n \"#FDE8DC\",\n \"#404E55\",\n \"#0089A3\",\n \"#CB7E98\",\n \"#A4E804\",\n \"#324E72\",\n \"#6A3A4C\",\n \"#83AB58\",\n \"#001C1E\",\n \"#D1F7CE\",\n \"#004B28\",\n \"#C8D0F6\",\n \"#A3A489\",\n \"#806C66\",\n \"#222800\",\n \"#BF5650\",\n \"#E83000\",\n \"#66796D\",\n \"#DA007C\",\n \"#FF1A59\",\n \"#8ADBB4\",\n \"#1E0200\",\n \"#5B4E51\",\n \"#C895C5\",\n \"#320033\",\n \"#FF6832\",\n \"#66E1D3\",\n \"#CFCDAC\",\n \"#D0AC94\",\n \"#7ED379\",\n \"#012C58\",\n \"#7A7BFF\",\n \"#D68E01\",\n \"#353339\",\n \"#78AFA1\",\n \"#FEB2C6\",\n \"#75797C\",\n \"#837393\",\n \"#943A4D\",\n \"#B5F4FF\",\n \"#D2DCD5\",\n \"#9556BD\",\n \"#6A714A\",\n \"#001325\",\n \"#02525F\",\n \"#0AA3F7\",\n \"#E98176\",\n \"#DBD5DD\",\n \"#5EBCD1\",\n \"#3D4F44\",\n \"#7E6405\",\n \"#02684E\",\n \"#962B75\",\n \"#8D8546\",\n \"#9695C5\",\n \"#E773CE\",\n \"#D86A78\",\n \"#3E89BE\",\n \"#CA834E\",\n \"#518A87\",\n \"#5B113C\",\n \"#55813B\",\n \"#E704C4\",\n \"#00005F\",\n \"#A97399\",\n \"#4B8160\",\n \"#59738A\",\n \"#FF5DA7\",\n \"#F7C9BF\",\n \"#643127\",\n \"#513A01\",\n \"#6B94AA\",\n \"#51A058\",\n \"#A45B02\",\n \"#1D1702\",\n \"#E20027\",\n \"#E7AB63\",\n \"#4C6001\",\n \"#9C6966\",\n \"#64547B\",\n \"#97979E\",\n \"#006A66\",\n \"#391406\",\n \"#F4D749\",\n \"#0045D2\",\n \"#006C31\",\n \"#DDB6D0\",\n \"#7C6571\",\n \"#9FB2A4\",\n \"#00D891\",\n \"#15A08A\",\n \"#BC65E9\",\n \"#FFFFFE\",\n \"#C6DC99\",\n \"#203B3C\",\n \"#671190\",\n \"#6B3A64\",\n \"#F5E1FF\",\n \"#FFA0F2\",\n \"#CCAA35\",\n \"#374527\",\n \"#8BB400\",\n \"#797868\",\n \"#C6005A\",\n \"#3B000A\",\n \"#C86240\",\n \"#29607C\",\n \"#402334\",\n \"#7D5A44\",\n \"#CCB87C\",\n \"#B88183\",\n \"#AA5199\",\n \"#B5D6C3\",\n \"#A38469\",\n \"#9F94F0\",\n \"#A74571\",\n \"#B894A6\",\n \"#71BB8C\",\n \"#00B433\",\n \"#789EC9\",\n \"#6D80BA\",\n \"#953F00\",\n \"#5EFF03\",\n \"#E4FFFC\",\n \"#1BE177\",\n \"#BCB1E5\",\n \"#76912F\",\n \"#003109\",\n \"#0060CD\",\n \"#D20096\",\n \"#895563\",\n \"#29201D\",\n \"#5B3213\",\n \"#A76F42\",\n \"#89412E\",\n \"#1A3A2A\",\n \"#494B5A\",\n \"#A88C85\",\n \"#F4ABAA\",\n \"#A3F3AB\",\n \"#00C6C8\",\n \"#EA8B66\",\n \"#958A9F\",\n \"#BDC9D2\",\n \"#9FA064\",\n \"#BE4700\",\n \"#658188\",\n \"#83A485\",\n // \"#453C23\",\n // \"#47675D\",\n // \"#3A3F00\",\n // \"#061203\",\n // \"#DFFB71\",\n // \"#868E7E\",\n // \"#98D058\",\n // \"#6C8F7D\",\n // \"#D7BFC2\",\n // \"#3C3E6E\",\n // \"#D83D66\",\n // \"#2F5D9B\",\n // \"#6C5E46\",\n // \"#D25B88\",\n // \"#5B656C\",\n // \"#00B57F\",\n // \"#545C46\",\n // \"#866097\",\n // \"#365D25\",\n // \"#252F99\",\n // \"#00CCFF\",\n // \"#674E60\",\n // \"#FC009C\",\n // \"#92896B\",\n // \"#1E2324\",\n // \"#DEC9B2\",\n // \"#9D4948\",\n // \"#85ABB4\",\n // \"#342142\",\n // \"#D09685\",\n // \"#A4ACAC\",\n // \"#00FFFF\",\n // \"#AE9C86\",\n // \"#742A33\",\n // \"#0E72C5\",\n // \"#AFD8EC\",\n // \"#C064B9\",\n // \"#91028C\",\n // \"#FEEDBF\",\n // \"#FFB789\",\n // \"#9CB8E4\",\n // \"#AFFFD1\",\n // \"#2A364C\",\n // \"#4F4A43\",\n // \"#647095\",\n // \"#34BBFF\",\n // \"#807781\",\n // \"#920003\",\n // \"#B3A5A7\",\n // \"#018615\",\n // \"#F1FFC8\",\n // \"#976F5C\",\n // \"#FF3BC1\",\n // \"#FF5F6B\",\n // \"#077D84\",\n // \"#F56D93\",\n // \"#5771DA\",\n // \"#4E1E2A\",\n // \"#830055\",\n // \"#02D346\",\n // \"#BE452D\",\n // \"#00905E\",\n // \"#BE0028\",\n // \"#6E96E3\",\n // \"#007699\",\n // \"#FEC96D\",\n // \"#9C6A7D\",\n // \"#3FA1B8\",\n // \"#893DE3\",\n // \"#79B4D6\",\n // \"#7FD4D9\",\n // \"#6751BB\",\n // \"#B28D2D\",\n // \"#E27A05\",\n // \"#DD9CB8\",\n // \"#AABC7A\",\n // \"#980034\",\n // \"#561A02\",\n // \"#8F7F00\",\n // \"#635000\",\n // \"#CD7DAE\",\n // \"#8A5E2D\",\n // \"#FFB3E1\",\n // \"#6B6466\",\n // \"#C6D300\",\n // \"#0100E2\",\n // \"#88EC69\",\n // \"#8FCCBE\",\n // \"#21001C\",\n // \"#511F4D\",\n // \"#E3F6E3\",\n // \"#FF8EB1\",\n // \"#6B4F29\",\n // \"#A37F46\",\n // \"#6A5950\",\n // \"#1F2A1A\",\n // \"#04784D\",\n // \"#101835\",\n // \"#E6E0D0\",\n // \"#FF74FE\",\n // \"#00A45F\",\n // \"#8F5DF8\",\n // \"#4B0059\",\n // \"#412F23\",\n // \"#D8939E\",\n // \"#DB9D72\",\n // \"#604143\",\n // \"#B5BACE\",\n // \"#989EB7\",\n // \"#D2C4DB\",\n // \"#A587AF\",\n // \"#77D796\",\n // \"#7F8C94\",\n // \"#FF9B03\",\n // \"#555196\",\n // \"#31DDAE\",\n // \"#74B671\",\n // \"#802647\",\n // \"#2A373F\",\n // \"#014A68\",\n // \"#696628\",\n // \"#4C7B6D\",\n // \"#002C27\",\n // \"#7A4522\",\n // \"#3B5859\",\n // \"#E5D381\",\n // \"#FFF3FF\",\n // \"#679FA0\",\n // \"#261300\",\n // \"#2C5742\",\n // \"#9131AF\",\n // \"#AF5D88\",\n // \"#C7706A\",\n // \"#61AB1F\",\n // \"#8CF2D4\",\n // \"#C5D9B8\",\n // \"#9FFFFB\",\n // \"#BF45CC\",\n // \"#493941\",\n // \"#863B60\",\n // \"#B90076\",\n // \"#003177\",\n // \"#C582D2\",\n // \"#C1B394\",\n // \"#602B70\",\n // \"#887868\",\n // \"#BABFB0\",\n // \"#030012\",\n // \"#D1ACFE\",\n // \"#7FDEFE\",\n // \"#4B5C71\",\n // \"#A3A097\",\n // \"#E66D53\",\n // \"#637B5D\",\n // \"#92BEA5\",\n // \"#00F8B3\",\n // \"#BEDDFF\",\n // \"#3DB5A7\",\n // \"#DD3248\",\n // \"#B6E4DE\",\n // \"#427745\",\n // \"#598C5A\",\n // \"#B94C59\",\n // \"#8181D5\",\n // \"#94888B\",\n // \"#FED6BD\",\n // \"#536D31\",\n // \"#6EFF92\",\n // \"#E4E8FF\",\n // \"#20E200\",\n // \"#FFD0F2\",\n // \"#4C83A1\",\n // \"#BD7322\",\n // \"#915C4E\",\n // \"#8C4787\",\n // \"#025117\",\n // \"#A2AA45\",\n // \"#2D1B21\",\n // \"#A9DDB0\",\n // \"#FF4F78\",\n // \"#528500\",\n // \"#009A2E\",\n // \"#17FCE4\",\n // \"#71555A\",\n // \"#525D82\",\n // \"#00195A\",\n // \"#967874\",\n // \"#555558\",\n // \"#0B212C\",\n // \"#1E202B\",\n // \"#EFBFC4\",\n // \"#6F9755\",\n // \"#6F7586\",\n // \"#501D1D\",\n // \"#372D00\",\n // \"#741D16\",\n // \"#5EB393\",\n // \"#B5B400\",\n // \"#DD4A38\",\n // \"#363DFF\",\n // \"#AD6552\",\n // \"#6635AF\",\n // \"#836BBA\",\n // \"#98AA7F\",\n // \"#464836\",\n // \"#322C3E\",\n // \"#7CB9BA\",\n // \"#5B6965\",\n // \"#707D3D\",\n // \"#7A001D\",\n // \"#6E4636\",\n // \"#443A38\",\n // \"#AE81FF\",\n // \"#489079\",\n // \"#897334\",\n // \"#009087\",\n // \"#DA713C\",\n // \"#361618\",\n // \"#FF6F01\",\n // \"#006679\",\n // \"#370E77\",\n // \"#4B3A83\",\n // \"#C9E2E6\",\n // \"#C44170\",\n // \"#FF4526\",\n // \"#73BE54\",\n // \"#C4DF72\",\n // \"#ADFF60\",\n // \"#00447D\",\n // \"#DCCEC9\",\n // \"#BD9479\",\n // \"#656E5B\",\n // \"#EC5200\",\n // \"#FF6EC2\",\n // \"#7A617E\",\n // \"#DDAEA2\",\n // \"#77837F\",\n // \"#A53327\",\n // \"#608EFF\",\n // \"#B599D7\",\n // \"#A50149\",\n // \"#4E0025\",\n // \"#C9B1A9\",\n // \"#03919A\",\n // \"#1B2A25\",\n // \"#E500F1\",\n // \"#982E0B\",\n // \"#B67180\",\n // \"#E05859\",\n // \"#006039\",\n // \"#578F9B\",\n // \"#305230\",\n // \"#CE934C\",\n // \"#B3C2BE\",\n // \"#C0BAC0\",\n // \"#B506D3\",\n // \"#170C10\",\n // \"#4C534F\",\n // \"#224451\",\n // \"#3E4141\",\n // \"#78726D\",\n // \"#B6602B\",\n // \"#200441\",\n // \"#DDB588\",\n // \"#497200\",\n // \"#C5AAB6\",\n // \"#033C61\",\n // \"#71B2F5\",\n // \"#A9E088\",\n // \"#4979B0\",\n // \"#A2C3DF\",\n // \"#784149\",\n // \"#2D2B17\",\n // \"#3E0E2F\",\n // \"#57344C\",\n // \"#0091BE\",\n // \"#E451D1\",\n // \"#4B4B6A\",\n // \"#5C011A\",\n // \"#7C8060\",\n // \"#FF9491\",\n // \"#4C325D\",\n // \"#005C8B\",\n // \"#E5FDA4\",\n // \"#68D1B6\",\n // \"#032641\",\n // \"#140023\",\n // \"#8683A9\",\n // \"#CFFF00\",\n // \"#A72C3E\",\n // \"#34475A\",\n // \"#B1BB9A\",\n // \"#B4A04F\",\n // \"#8D918E\",\n // \"#A168A6\",\n // \"#813D3A\",\n // \"#425218\",\n // \"#DA8386\",\n // \"#776133\",\n // \"#563930\",\n // \"#8498AE\",\n // \"#90C1D3\",\n // \"#B5666B\",\n // \"#9B585E\",\n // \"#856465\",\n // \"#AD7C90\",\n // \"#E2BC00\",\n // \"#E3AAE0\",\n // \"#B2C2FE\",\n // \"#FD0039\",\n // \"#009B75\",\n // \"#FFF46D\",\n // \"#E87EAC\",\n // \"#DFE3E6\",\n // \"#848590\",\n // \"#AA9297\",\n // \"#83A193\",\n // \"#577977\",\n // \"#3E7158\",\n // \"#C64289\",\n // \"#EA0072\",\n // \"#C4A8CB\",\n // \"#55C899\",\n // \"#E78FCF\",\n // \"#004547\",\n // \"#F6E2E3\",\n // \"#966716\",\n // \"#378FDB\",\n // \"#435E6A\",\n // \"#DA0004\",\n // \"#1B000F\",\n // \"#5B9C8F\",\n // \"#6E2B52\",\n // \"#011115\",\n // \"#E3E8C4\",\n // \"#AE3B85\",\n // \"#EA1CA9\",\n // \"#FF9E6B\",\n // \"#457D8B\",\n // \"#92678B\",\n // \"#00CDBB\",\n // \"#9CCC04\",\n // \"#002E38\",\n // \"#96C57F\",\n // \"#CFF6B4\",\n // \"#492818\",\n // \"#766E52\",\n // \"#20370E\",\n // \"#E3D19F\",\n // \"#2E3C30\",\n // \"#B2EACE\",\n // \"#F3BDA4\",\n // \"#A24E3D\",\n // \"#976FD9\",\n // \"#8C9FA8\",\n // \"#7C2B73\",\n // \"#4E5F37\",\n // \"#5D5462\",\n // \"#90956F\",\n // \"#6AA776\",\n // \"#DBCBF6\",\n // \"#DA71FF\",\n // \"#987C95\",\n // \"#52323C\",\n // \"#BB3C42\",\n // \"#584D39\",\n // \"#4FC15F\",\n // \"#A2B9C1\",\n // \"#79DB21\",\n // \"#1D5958\",\n // \"#BD744E\",\n // \"#160B00\",\n // \"#20221A\",\n // \"#6B8295\",\n // \"#00E0E4\",\n // \"#102401\",\n // \"#1B782A\",\n // \"#DAA9B5\",\n // \"#B0415D\",\n // \"#859253\",\n // \"#97A094\",\n // \"#06E3C4\",\n // \"#47688C\",\n // \"#7C6755\",\n // \"#075C00\",\n // \"#7560D5\",\n // \"#7D9F00\",\n // \"#C36D96\",\n // \"#4D913E\",\n // \"#5F4276\",\n // \"#FCE4C8\",\n // \"#303052\",\n // \"#4F381B\",\n // \"#E5A532\",\n // \"#706690\",\n // \"#AA9A92\",\n // \"#237363\",\n // \"#73013E\",\n // \"#FF9079\",\n // \"#A79A74\",\n // \"#029BDB\",\n // \"#FF0169\",\n // \"#C7D2E7\",\n // \"#CA8869\",\n // \"#80FFCD\",\n // \"#BB1F69\",\n // \"#90B0AB\",\n // \"#7D74A9\",\n // \"#FCC7DB\",\n // \"#99375B\",\n // \"#00AB4D\",\n // \"#ABAED1\",\n // \"#BE9D91\",\n // \"#E6E5A7\",\n // \"#332C22\",\n // \"#DD587B\",\n // \"#F5FFF7\",\n // \"#5D3033\",\n // \"#6D3800\",\n // \"#FF0020\",\n // \"#B57BB3\",\n // \"#D7FFE6\",\n // \"#C535A9\",\n // \"#260009\",\n // \"#6A8781\",\n // \"#A8ABB4\",\n // \"#D45262\",\n // \"#794B61\",\n // \"#4621B2\",\n // \"#8DA4DB\",\n // \"#C7C890\",\n // \"#6FE9AD\",\n // \"#A243A7\",\n // \"#B2B081\",\n // \"#181B00\",\n // \"#286154\",\n // \"#4CA43B\",\n // \"#6A9573\",\n // \"#A8441D\",\n // \"#5C727B\",\n // \"#738671\",\n // \"#D0CFCB\",\n // \"#897B77\",\n // \"#1F3F22\",\n // \"#4145A7\",\n // \"#DA9894\",\n // \"#A1757A\",\n // \"#63243C\",\n // \"#ADAAFF\",\n // \"#00CDE2\",\n // \"#DDBC62\",\n // \"#698EB1\",\n // \"#208462\",\n // \"#00B7E0\",\n // \"#614A44\",\n // \"#9BBB57\",\n // \"#7A5C54\",\n // \"#857A50\",\n // \"#766B7E\",\n // \"#014833\",\n // \"#FF8347\",\n // \"#7A8EBA\",\n // \"#274740\",\n // \"#946444\",\n // \"#EBD8E6\",\n // \"#646241\",\n // \"#373917\",\n // \"#6AD450\",\n // \"#81817B\",\n // \"#D499E3\",\n // \"#979440\",\n // \"#011A12\",\n // \"#526554\",\n // \"#B5885C\",\n // \"#A499A5\",\n // \"#03AD89\",\n // \"#B3008B\",\n // \"#E3C4B5\",\n // \"#96531F\",\n // \"#867175\",\n // \"#74569E\",\n // \"#617D9F\",\n // \"#E70452\",\n // \"#067EAF\",\n // \"#A697B6\",\n // \"#B787A8\",\n // \"#9CFF93\",\n // \"#311D19\",\n // \"#3A9459\",\n // \"#6E746E\",\n // \"#B0C5AE\",\n // \"#84EDF7\",\n // \"#ED3488\",\n // \"#754C78\",\n // \"#384644\",\n // \"#C7847B\",\n // \"#00B6C5\",\n // \"#7FA670\",\n // \"#C1AF9E\",\n // \"#2A7FFF\",\n // \"#72A58C\",\n // \"#FFC07F\",\n // \"#9DEBDD\",\n // \"#D97C8E\",\n // \"#7E7C93\",\n // \"#62E674\",\n // \"#B5639E\",\n // \"#FFA861\",\n // \"#C2A580\",\n // \"#8D9C83\",\n // \"#B70546\",\n // \"#372B2E\",\n // \"#0098FF\",\n // \"#985975\",\n // \"#20204C\",\n // \"#FF6C60\",\n // \"#445083\",\n // \"#8502AA\",\n // \"#72361F\",\n // \"#9676A3\",\n // \"#484449\",\n // \"#CED6C2\",\n // \"#3B164A\",\n // \"#CCA763\",\n // \"#2C7F77\",\n // \"#02227B\",\n // \"#A37E6F\",\n // \"#CDE6DC\",\n // \"#CDFFFB\",\n // \"#BE811A\",\n // \"#F77183\",\n // \"#EDE6E2\",\n // \"#CDC6B4\",\n // \"#FFE09E\",\n // \"#3A7271\",\n // \"#FF7B59\",\n // \"#4E4E01\",\n // \"#4AC684\",\n // \"#8BC891\",\n // \"#BC8A96\",\n // \"#CF6353\",\n // \"#DCDE5C\",\n // \"#5EAADD\",\n // \"#F6A0AD\",\n // \"#E269AA\",\n // \"#A3DAE4\",\n // \"#436E83\",\n // \"#002E17\",\n // \"#ECFBFF\",\n // \"#A1C2B6\",\n // \"#50003F\",\n // \"#71695B\",\n // \"#67C4BB\",\n // \"#536EFF\",\n // \"#5D5A48\",\n // \"#890039\",\n // \"#969381\",\n // \"#371521\",\n // \"#5E4665\",\n // \"#AA62C3\",\n // \"#8D6F81\",\n // \"#2C6135\",\n // \"#410601\",\n // \"#564620\",\n // \"#E69034\",\n // \"#6DA6BD\",\n // \"#E58E56\",\n // \"#E3A68B\",\n // \"#48B176\",\n // \"#D27D67\",\n // \"#B5B268\",\n // \"#7F8427\",\n // \"#FF84E6\",\n // \"#435740\",\n // \"#EAE408\",\n // \"#F4F5FF\",\n // \"#325800\",\n // \"#4B6BA5\",\n // \"#ADCEFF\",\n // \"#9B8ACC\",\n // \"#885138\",\n // \"#5875C1\",\n // \"#7E7311\",\n // \"#FEA5CA\",\n // \"#9F8B5B\",\n // \"#A55B54\",\n // \"#89006A\",\n // \"#AF756F\",\n // \"#2A2000\",\n // \"#576E4A\",\n // \"#7F9EFF\",\n // \"#7499A1\",\n // \"#FFB550\",\n // \"#00011E\",\n // \"#D1511C\",\n // \"#688151\",\n // \"#BC908A\",\n // \"#78C8EB\",\n // \"#8502FF\",\n // \"#483D30\",\n // \"#C42221\",\n // \"#5EA7FF\",\n // \"#785715\",\n // \"#0CEA91\",\n // \"#FFFAED\",\n // \"#B3AF9D\",\n // \"#3E3D52\",\n // \"#5A9BC2\",\n // \"#9C2F90\",\n // \"#8D5700\",\n // \"#ADD79C\",\n // \"#00768B\",\n // \"#337D00\",\n // \"#C59700\",\n // \"#3156DC\",\n // \"#944575\",\n // \"#ECFFDC\",\n // \"#D24CB2\",\n // \"#97703C\",\n // \"#4C257F\",\n // \"#9E0366\",\n // \"#88FFEC\",\n // \"#B56481\",\n // \"#396D2B\",\n // \"#56735F\",\n // \"#988376\",\n // \"#9BB195\",\n // \"#A9795C\",\n // \"#E4C5D3\",\n // \"#9F4F67\",\n // \"#1E2B39\",\n // \"#664327\",\n // \"#AFCE78\",\n // \"#322EDF\",\n // \"#86B487\",\n // \"#C23000\",\n // \"#ABE86B\",\n // \"#96656D\",\n // \"#250E35\",\n // \"#A60019\",\n // \"#0080CF\",\n // \"#CAEFFF\",\n // \"#323F61\",\n // \"#A449DC\",\n // \"#6A9D3B\",\n // \"#FF5AE4\",\n // \"#636A01\",\n // \"#D16CDA\",\n // \"#736060\",\n // \"#FFBAAD\",\n // \"#D369B4\",\n // \"#FFDED6\",\n // \"#6C6D74\",\n // \"#927D5E\",\n // \"#845D70\",\n // \"#5B62C1\",\n // \"#2F4A36\",\n // \"#E45F35\",\n // \"#FF3B53\",\n // \"#AC84DD\",\n // \"#762988\",\n // \"#70EC98\",\n // \"#408543\",\n // \"#2C3533\",\n // \"#2E182D\",\n // \"#323925\",\n // \"#19181B\",\n // \"#2F2E2C\",\n // \"#023C32\",\n // \"#9B9EE2\",\n // \"#58AFAD\",\n // \"#5C424D\",\n // \"#7AC5A6\",\n // \"#685D75\",\n // \"#B9BCBD\",\n // \"#834357\",\n // \"#1A7B42\",\n // \"#2E57AA\",\n // \"#E55199\",\n // \"#316E47\",\n // \"#CD00C5\",\n // \"#6A004D\",\n // \"#7FBBEC\",\n // \"#F35691\",\n // \"#D7C54A\",\n // \"#62ACB7\",\n // \"#CBA1BC\",\n // \"#A28A9A\",\n // \"#6C3F3B\",\n // \"#FFE47D\",\n // \"#DCBAE3\",\n // \"#5F816D\",\n // \"#3A404A\",\n // \"#7DBF32\",\n // \"#E6ECDC\",\n // \"#852C19\",\n // \"#285366\",\n // \"#B8CB9C\",\n // \"#0E0D00\",\n // \"#4B5D56\",\n // \"#6B543F\",\n // \"#E27172\",\n // \"#0568EC\",\n // \"#2EB500\",\n // \"#D21656\",\n // \"#EFAFFF\",\n // \"#682021\",\n // \"#2D2011\",\n // \"#DA4CFF\",\n // \"#70968E\",\n // \"#FF7B7D\",\n // \"#4A1930\",\n // \"#E8C282\",\n // \"#E7DBBC\",\n // \"#A68486\",\n // \"#1F263C\",\n // \"#36574E\",\n // \"#52CE79\",\n // \"#ADAAA9\",\n // \"#8A9F45\",\n // \"#6542D2\",\n // \"#00FB8C\",\n // \"#5D697B\",\n // \"#CCD27F\",\n // \"#94A5A1\",\n // \"#790229\",\n // \"#E383E6\",\n // \"#7EA4C1\",\n // \"#4E4452\",\n // \"#4B2C00\",\n // \"#620B70\",\n // \"#314C1E\",\n // \"#874AA6\",\n // \"#E30091\",\n // \"#66460A\",\n // \"#EB9A8B\",\n // \"#EAC3A3\",\n // \"#98EAB3\",\n // \"#AB9180\",\n // \"#B8552F\",\n // \"#1A2B2F\",\n // \"#94DDC5\",\n // \"#9D8C76\",\n // \"#9C8333\",\n // \"#94A9C9\",\n // \"#392935\",\n // \"#8C675E\",\n // \"#CCE93A\",\n // \"#917100\",\n // \"#01400B\",\n // \"#449896\",\n // \"#1CA370\",\n // \"#E08DA7\",\n // \"#8B4A4E\",\n // \"#667776\",\n // \"#4692AD\",\n // \"#67BDA8\",\n // \"#69255C\",\n // \"#D3BFFF\",\n // \"#4A5132\",\n // \"#7E9285\",\n // \"#77733C\",\n // \"#E7A0CC\",\n // \"#51A288\",\n // \"#2C656A\",\n // \"#4D5C5E\",\n // \"#C9403A\",\n // \"#DDD7F3\",\n // \"#005844\",\n // \"#B4A200\",\n // \"#488F69\",\n // \"#858182\",\n // \"#D4E9B9\",\n // \"#3D7397\",\n // \"#CAE8CE\",\n // \"#D60034\",\n // \"#AA6746\",\n // \"#9E5585\",\n // \"#BA6200\",\n];\n","export const StatusEnum = {\n OK: 0,\n OLD_STATUS_REPORT: 1,\n NO_STATUS_REPORT: 2,\n DIFFERENT_TOPOLOGY: 3,\n NOT_COMMISSIONED: 4,\n SAME_POSITION: 5,\n NEW: 6,\n INACTIVE: 7,\n TIMEOUT: 8,\n API_FETCH: 9, // data fetched by api call\n SHIFTED_POSITION: 10,\n CONTROLLER_ON_BATTERY: 11,\n CONTROLLER_NETWORK_FAULT: 12, // NOT USED ATM\n properties: {\n 0: { ok: true },\n 1: { warning: true },\n 2: { error: true },\n 3: { error: true },\n 4: { error: true },\n 5: { error: true },\n 6: { error: true },\n 7: { error: true },\n 8: { error: true },\n 9: { error: true },\n 10: { error: true },\n 11: { error: true },\n 12: { error: true },\n },\n};\n\nexport const StatusEnumToReadable = {\n 0: \"OK\",\n 1: \"OLD_STATUS_REPORT\",\n 2: \"NO_STATUS_REPORT\",\n 3: \"DIFFERENT_TOPOLOGY\",\n 4: \"NOT_COMMISSIONED\",\n 5: \"SAME_POSITION\",\n 6: \"NEW\",\n 7: \"INACTIVE\",\n 8: \"TIMEOUT\",\n 9: \"API_FETCH\",\n 10: \"SHIFTED_POSITION\",\n 11: \"CONTROLLER_ON_BATTERY\",\n 12: \"CONTROLLER_NETWORK_FAULT\",\n};\n","import numeric from \"numeric\";\nimport flatten from \"lodash/flatten\";\nimport chunk from \"lodash/chunk\";\n\n// 2D Conformal Transformation\n//\n// All of this stuff is just an implementation of the processes described in the\n// Bentley 2D Conformal Transformation pdf\n\nexport class ConformalTransformation {\n constructor(k, theta, Tx, Ty) {\n this.k = k;\n this.theta = theta;\n this.Tx = Tx;\n this.Ty = Ty;\n const a = k * Math.cos(theta);\n const b = k * Math.sin(theta);\n this.T = [[a], [b], [Tx], [Ty]];\n this.transform = this.transform.bind(this);\n }\n\n static fromPoints(standardPoints, localPoints) {\n const [s1, s2] = standardPoints;\n const [l1, l2] = localPoints;\n\n const e1 = s1.lng;\n const n1 = s1.lat;\n const e2 = s2.lng;\n const n2 = s2.lat;\n const E = [[e1], [n1], [e2], [n2]];\n\n const x1 = l1.lng;\n const y1 = l1.lat;\n const x2 = l2.lng;\n const y2 = l2.lat;\n\n const X = [\n [x1, -y1, 1, 0],\n [y1, x1, 0, 1],\n [x2, -y2, 1, 0],\n [y2, x2, 0, 1]\n ];\n\n const invX = numeric.inv(X);\n let T = numeric.dot(invX, E);\n T = flatten(T);\n const [a, b, Tx, Ty] = T;\n const theta = Math.atan(b / a);\n const k = a / Math.cos(theta);\n\n return new ConformalTransformation(k, theta, Tx, Ty);\n }\n\n transform(pts) {\n const list = Array.isArray(pts) ? pts : [pts];\n const X = flatten(\n list.map(pt => {\n const [x, y] = arrayFromLatLng(pt);\n return [\n [x, -y, 1, 0],\n [y, x, 0, 1]\n ];\n })\n );\n\n let results = numeric.dot(X, this.T);\n results = chunk(flatten(results), 2);\n const asPoints = results.map(res => latlntFromArray(res));\n\n if (Array.isArray(pts)) {\n return asPoints;\n }\n return asPoints[0];\n }\n}\n\nconst arrayFromLatLng = latLng => [latLng.lng, latLng.lat];\nconst latlntFromArray = array => ({ lng: array[0], lat: array[1] });\n\nexport class MineLevelMapImageProjection {\n constructor(mineFromImageTranform, imageFromMineTranform) {\n this.mineFromImageTranform = mineFromImageTranform;\n this.imageFromMineTranform = imageFromMineTranform;\n }\n\n mineFromImage(pts) {\n return this.mineFromImageTranform.transform(pts);\n }\n\n imageFromMine(pts) {\n return this.imageFromMineTranform.transform(pts);\n }\n\n static fromPoints(mineCoords, imageCoords) {\n return new MineLevelMapImageProjection(\n AffineWithoutRotationTransformation.fromPoints(mineCoords, imageCoords),\n AffineWithoutRotationTransformation.fromPoints(imageCoords, mineCoords)\n );\n }\n}\n\nexport class AffineWithoutRotationTransformation {\n constructor(Sx, Sy, Tx, Ty) {\n this.Sx = Sx;\n this.Sy = Sy;\n this.Tx = Tx;\n this.Ty = Ty;\n this.T = [[Sx], [Sy], [Tx], [Ty]];\n this.transform = this.transform.bind(this);\n }\n\n static fromPoints(standardPoints, localPoints) {\n const [s1, s2] = standardPoints;\n const [l1, l2] = localPoints;\n\n const e1 = s1.lng;\n const n1 = s1.lat;\n const e2 = s2.lng;\n const n2 = s2.lat;\n const E = [[e1], [n1], [e2], [n2]];\n\n const x1 = l1.lng;\n const y1 = l1.lat;\n const x2 = l2.lng;\n const y2 = l2.lat;\n\n const X = [\n [x1, 0, 1, 0],\n [0, y1, 0, 1],\n [x2, 0, 1, 0],\n [0, y2, 0, 1]\n ];\n\n const invX = numeric.inv(X);\n let T = numeric.dot(invX, E);\n T = flatten(T);\n const [Sx, Sy, Tx, Ty] = T;\n\n return new AffineWithoutRotationTransformation(Sx, Sy, Tx, Ty);\n }\n\n transform(pts) {\n const list = Array.isArray(pts) ? pts : [pts];\n const X = flatten(\n list.map(pt => {\n const [x, y] = arrayFromLatLng(pt);\n return [\n [x, 0, 1, 0],\n [0, y, 0, 1]\n ];\n })\n );\n\n let results = numeric.dot(X, this.T);\n results = chunk(flatten(results), 2);\n const asPoints = results.map(res => latlntFromArray(res));\n\n if (Array.isArray(pts)) {\n return asPoints;\n }\n return asPoints[0];\n }\n}\n\nexport class LeastSquaresApproximationFourPointsSixParametersTransformation {\n constructor(Sa, Sb, Tx, Sc, Sd, Ty) {\n this.Sa = Sa;\n this.Sb = Sb;\n this.Tx = Tx;\n this.Sc = Sc;\n this.Sd = Sd;\n this.Ty = Ty;\n this.T = [[Sa], [Sb], [Tx], [Sc], [Sd], [Ty]];\n this.transform = this.transform.bind(this);\n }\n\n static fromPoints(standardPoints, localPoints) {\n const [s1, s2, s3, s4] = standardPoints;\n const [l1, l2, l3, l4] = localPoints;\n\n const e1 = s1.lng;\n const n1 = s1.lat;\n const e2 = s2.lng;\n const n2 = s2.lat;\n const e3 = s3.lng;\n const n3 = s3.lat;\n const e4 = s4.lng;\n const n4 = s4.lat;\n const L = [[e1], [n1], [e2], [n2], [e3], [n3], [e4], [n4]];\n\n const x1 = l1.lng;\n const y1 = l1.lat;\n const x2 = l2.lng;\n const y2 = l2.lat;\n const x3 = l3.lng;\n const y3 = l3.lat;\n const x4 = l4.lng;\n const y4 = l4.lat;\n const A = [\n [x1, y1, 1, 0, 0, 0],\n [0, 0, 0, x1, y1, 1],\n [x2, y2, 1, 0, 0, 0],\n [0, 0, 0, x2, y2, 1],\n [x3, y3, 1, 0, 0, 0],\n [0, 0, 0, x3, y3, 1],\n [x4, y4, 1, 0, 0, 0],\n [0, 0, 0, x4, y4, 1]\n ];\n\n // A trans\n const Atrans = numeric.transpose(A);\n\n // A trans.A\n const AtransA = numeric.dot(Atrans, A);\n\n // inverse A trans . A\n const invAtransA = numeric.inv(AtransA);\n\n // Atrans.L\n const AtransL = numeric.dot(Atrans, L);\n\n // (inverse A trans . A).Atrans.L\n\n const invAtransAAtransL = numeric.dot(invAtransA, AtransL);\n\n let T = flatten(invAtransAAtransL);\n const [Sa, Sb, Tx, Sc, Sd, Ty] = T;\n\n return new LeastSquaresApproximationFourPointsSixParametersTransformation(\n Sa,\n Sb,\n Tx,\n Sc,\n Sd,\n Ty\n );\n }\n\n transform(pts) {\n const list = Array.isArray(pts) ? pts : [pts];\n const X = flatten(\n list.map(pt => {\n const [x, y] = arrayFromLatLng(pt);\n return [\n [x, y, 1, 0, 0, 0],\n [0, 0, 0, x, y, 1]\n ];\n })\n );\n\n let results = numeric.dot(X, this.T);\n results = chunk(flatten(results), 2);\n const asPoints = results.map(res => latlntFromArray(res));\n\n if (Array.isArray(pts)) {\n return asPoints;\n }\n return asPoints[0];\n }\n}\n","import { LeastSquaresApproximationFourPointsSixParametersTransformation } from \"projection\";\n\nexport const transformGeoJsonUtmToPixels = (\n geoJson,\n areaStatuses,\n scale = 1,\n transpose = false\n) => {\n let geoJsonTransform = [];\n geoJson.features.map((value, idx) => {\n let newFeature = value;\n\n // transform the point from latlng to pixels\n const arrayLatLng = newFeature.geometry.coordinates.slice();\n\n // check if there is an area record\n const area = newFeature.properties.area;\n const isAreaUndefined = areaStatuses[area] === undefined;\n\n // check if rx an un positioned marker i.e. [0,0]\n const isAllZero = arrayLatLng.every((item) => item === 0);\n\n // if (isAllZero) {\n // console.log(\n // \"isAllZero feature\",\n // newFeature.properties.id,\n // JSON.stringify(newFeature)\n // );\n // }\n // check if map has the holding pen setup\n\n // #REVIEW/TODO #WIP\n // make sure there is a default pen point\n let randomHoldingPenCoordinate = [0, 0];\n // why is this undefined on startup? img is defined ok?!\n // if (this.holdingPen !== undefined) {\n // const hasHoldingPen = this.map.hasLayer(this.holdingPen);\n // if (isAllZero && hasHoldingPen) {\n // randomHoldingPenCoordinate = this.randomPointInPoly(this.holdingPen)\n // .geometry.coordinates;\n // console.log(\n // \"randomholdingPenCoordinate\",\n // newFeature.properties.id,\n // randomHoldingPenCoordinate\n // );\n // }\n // }\n\n // 1D array\n let arrayPoints = [];\n const shapeType = newFeature.geometry.type;\n switch (shapeType.toLowerCase()) {\n case \"point\":\n // convert to LatLng, transform, then convert back to array\n\n if (!isAllZero && !isAreaUndefined) {\n const transformX = areaStatuses[area].transformUtmToPixels;\n arrayPoints = Object.values(\n transformX.transform({\n lat: arrayLatLng[0] / scale, // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: arrayLatLng[1] / scale,\n })\n );\n\n arrayPoints = transpose ? arrayPoints.reverse() : arrayPoints;\n } else {\n arrayPoints = randomHoldingPenCoordinate;\n }\n\n break;\n case \"polygon\":\n // iterate the geojons coord array\n\n // 2D array\n //arrayPoints = [[]];\n arrayLatLng.forEach((value, i, arr) => {\n arrayPoints.push([]);\n value.forEach((value, j) => {\n // convert to LatLng, transform, then convert back to array\n\n let arrayPoint;\n if (!isAllZero && !isAreaUndefined) {\n const transformX = areaStatuses[area].transformUtmToPixels;\n arrayPoint = Object.values(\n transformX.transform({\n lat: value[0] / scale, // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: value[1] / scale,\n })\n );\n\n arrayPoint = transpose ? arrayPoint.reverse() : arrayPoint;\n } else {\n arrayPoint = randomHoldingPenCoordinate;\n }\n\n // accumulate results\n arrayPoints[i][j] = arrayPoint;\n });\n });\n break;\n case \"multipolygon\":\n // iterate the geojons coord array\n // Bracketing for MultiPolylines and MultiPolygons can get confusing.\n // You need brackets to hold the MultiPolyline or MultiPolygon, brackets for each polyline or polygon,\n // and brackets for each latitude and longitude.\n\n // https://leafletjs.com/examples/geojson/\n //\n // example working coordinates broken down to two separated polygons\n // from http://jsfiddle.net/erictheise/VaGy5/\n\n // 3D array\n // console.log(\"arrayLatLng\", JSON.stringify(arrayLatLng));\n arrayLatLng.forEach((i_value, i, arr) => {\n arrayPoints.push([]);\n // console.log(\"----------------------------------\");\n // console.log(\"i_value\", i, i_value, JSON.stringify(arrayPoints));\n\n i_value.forEach((j_value, j) => {\n arrayPoints[i].push([]);\n // console.log(\"----------------------------------\");\n // console.log(\n // \" j_value\",\n // j,\n // j_value,\n // JSON.stringify(arrayPoints)\n // );\n j_value.forEach((k_value, k) => {\n // console.log(\"----------------------------------\");\n // console.log(\n // \" k_value\",\n // k,\n // k_value,\n // JSON.stringify(arrayPoints)\n // );\n\n // convert to LatLng, transform, then convert back to array\n let arrayPoint;\n if (!isAllZero && !isAreaUndefined && true) {\n const transformX = areaStatuses[area].transformUtmToPixels;\n arrayPoint = Object.values(\n transformX.transform({\n lat: k_value[0] / scale, // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: k_value[1] / scale,\n })\n );\n\n arrayPoint = transpose ? arrayPoint.reverse() : arrayPoint;\n } else {\n arrayPoint = randomHoldingPenCoordinate;\n }\n // accumulate results\n // console.log(\n // \" arrayPoints\",\n // i,\n // j,\n // k,\n // \" -> \",\n // JSON.stringify(arrayPoint)\n // );\n arrayPoints[i][j].push(arrayPoint);\n // console.log(\n // \" arrayPoints\",\n // i,\n // j,\n // k,\n // \" -> ########\",\n // JSON.stringify(arrayPoints),\n // \"#########\"\n // );\n });\n });\n });\n break;\n default:\n break;\n }\n\n // update geometry\n\n newFeature.geometry.coordinates = arrayPoints;\n geoJsonTransform.push(newFeature);\n });\n\n return {\n type: \"FeatureCollection\",\n features: geoJsonTransform,\n };\n};\n\nexport const transformGeoJsonUtmToPixelsByChangeList = (\n prevFeature,\n geoJson,\n changeList,\n areaStatuses\n) => {\n let geoJsonTransform = [];\n geoJson.features.map((value, idx) => {\n const {\n properties: { id },\n } = value;\n\n let updateList = changeList;\n\n //\n if (updateList.includes(id)) {\n // delete array item after processing to speed search time next round\n //\n updateList = updateList.filter((item) => item !== id);\n //\n //\n let newFeature = value;\n // transform the point from latlng to pixels\n const arrayLatLng = newFeature.geometry.coordinates.slice();\n\n // check if there is an area record\n const area = newFeature.properties.area;\n const isAreaUndefined = areaStatuses[area] === undefined;\n\n // check if rx an un positioned marker i.e. [0,0]\n const isAllZero = arrayLatLng.every((item) => item === 0);\n\n // holding pen stuff.........\n\n let randomHoldingPenCoordinate = [0, 0];\n\n // 1D array\n let arrayPoints = [];\n const shapeType = newFeature.geometry.type;\n switch (shapeType.toLowerCase()) {\n case \"point\":\n // convert to LatLng, transform, then convert back to array\n\n if (!isAllZero && !isAreaUndefined) {\n const transformX = areaStatuses[area].transformUtmToPixels;\n arrayPoints = Object.values(\n transformX.transform({\n lat: arrayLatLng[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: arrayLatLng[1],\n })\n );\n } else {\n arrayPoints = randomHoldingPenCoordinate;\n }\n\n break;\n case \"polygon\":\n // iterate the geojons coord array\n\n // 2D array\n //arrayPoints = [[]];\n arrayLatLng.forEach((value, i, arr) => {\n arrayPoints.push([]);\n value.forEach((value, j) => {\n // convert to LatLng, transform, then convert back to array\n let arrayPoint;\n if (!isAllZero && !isAreaUndefined) {\n const transformX = areaStatuses[area].transformUtmToPixels;\n arrayPoint = Object.values(\n transformX.transform({\n lat: value[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: value[1],\n })\n );\n } else {\n arrayPoint = randomHoldingPenCoordinate;\n }\n\n // accumulate results\n arrayPoints[i][j] = arrayPoint;\n });\n });\n break;\n case \"multipolygon\":\n // iterate the geojons coord array\n // ........................\n\n // 3D array\n // console.log(\"arrayLatLng\", JSON.stringify(arrayLatLng));\n arrayLatLng.forEach((i_value, i, arr) => {\n arrayPoints.push([]);\n i_value.forEach((j_value, j) => {\n arrayPoints[i].push([]);\n j_value.forEach((k_value, k) => {\n // convert to LatLng, transform, then convert back to array\n let arrayPoint;\n if (!isAllZero && !isAreaUndefined && true) {\n const transformX = areaStatuses[area].transformUtmToPixels;\n arrayPoint = Object.values(\n transformX.transform({\n lat: k_value[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: k_value[1],\n })\n );\n } else {\n arrayPoint = randomHoldingPenCoordinate;\n }\n arrayPoints[i][j].push(arrayPoint);\n });\n });\n });\n break;\n default:\n break;\n }\n\n // update geometry\n newFeature.geometry.coordinates = arrayPoints;\n geoJsonTransform.push(newFeature);\n //\n } else {\n geoJsonTransform.push(prevFeature[id]);\n }\n //\n });\n\n return {\n type: \"FeatureCollection\",\n features: geoJsonTransform,\n };\n};\n\nexport const transformGeoJsonPixelsToUtm = (geoJson, areaStatuses) => {\n let geoJsonTransform = [];\n let error = false;\n geoJson.features.map((value, idx) => {\n let newFeature = value;\n // transform the point from pixels to pixels\n const arrayLatLng = newFeature.geometry.coordinates.slice();\n\n // check if there is an area record\n const area = newFeature.properties.area;\n const isAreaUndefined = areaStatuses[area] === undefined;\n\n let arrayPoints = [];\n const shapeType = newFeature.geometry.type;\n switch (shapeType.toLowerCase()) {\n case \"point\":\n // convert to LatLng, transform, then convert back to array\n\n if (!isAreaUndefined) {\n const transformX = areaStatuses[area].transformPixelsToUtm;\n arrayPoints = Object.values(\n transformX.transform({\n // lat: arrayLatLng[1], // <-- **NOTE: lat & lng are swapped! **\n // lng: arrayLatLng[0],\n lat: arrayLatLng[1], // <-- **NOTE: lat & lng are swapped! **\n lng: arrayLatLng[0],\n })\n ).reverse();\n } else {\n error = true;\n }\n break;\n case \"polygon\":\n // iterate the geojons coord array\n arrayLatLng.forEach((value, i, arr) => {\n arrayPoints.push([]);\n value.forEach((value, j) => {\n // convert to LatLng, transform, then convert back to array\n let arrayPoint;\n if (!isAreaUndefined) {\n const transformX = areaStatuses[area].transformPixelsToUtm;\n arrayPoint = Object.values(\n transformX.transform({\n // lat: value[1], // <-- **NOTE: lat & lng are swapped! **\n // lng: value[0],\n lat: value[1], // <-- **NOTE: lat & lng are swapped! **\n lng: value[0],\n })\n ).reverse();\n } else {\n error = true;\n }\n\n // accumulate results\n arrayPoints[i][j] = arrayPoint;\n });\n });\n break;\n default:\n break;\n }\n // update geometry\n newFeature.geometry.coordinates = arrayPoints;\n geoJsonTransform.push(newFeature);\n });\n if (error) {\n return geoJson; // do nothing\n } else {\n return {\n type: \"FeatureCollection\",\n features: geoJsonTransform,\n };\n }\n};\n\nconst standardPtsUtm = () => {\n // #TODO - this is duplicated in localPts()\n const ref1utm = {\n northing: 9549076.153,\n easting: 736959.54,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref2utm = {\n northing: 9549315.041,\n easting: 737526.058,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref3utm = {\n northing: 9548885.911,\n easting: 737883.021,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref4utm = {\n northing: 9548630.213,\n easting: 737564.472,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n\n // rest UTM values\n const standardRef1 = { lat: ref1utm.easting, lng: ref1utm.northing };\n const standardRef2 = { lat: ref2utm.easting, lng: ref2utm.northing };\n const standardRef3 = { lat: ref3utm.easting, lng: ref3utm.northing };\n const standardRef4 = { lat: ref4utm.easting, lng: ref4utm.northing };\n\n const standardAll = [standardRef1, standardRef2, standardRef3, standardRef4];\n\n return standardAll;\n};\n\nexport const localPts = () => {\n // measured from pixel positions\n const localRef1 = {\n lat: 4764,\n lng: 4202,\n easting: 736959.54,\n northing: 9549076.153,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef2 = {\n lat: 3236,\n lng: 7815,\n easting: 737526.058,\n northing: 9549315.041,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef3 = {\n lat: 5978,\n lng: 10090,\n easting: 737883.021,\n northing: 9548885.911,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef4 = {\n lat: 7611,\n lng: 8061,\n easting: 737564.472,\n northing: 9548630.213,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n return [localRef1, localRef2, localRef3, localRef4];\n};\n\nexport const standardPtsUtmX = (mineLevel) => {\n if (mineLevel?.ref_coord === undefined || mineLevel?.ref_coord === null) {\n return {};\n }\n const { ref_coord } = mineLevel;\n\n let result = {};\n ref_coord.forEach((coord) => {\n const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n const index = indexArray[1];\n\n result[index] = { lat: coord.utm[0], lng: coord.utm[1] };\n });\n\n // sort object by key\n Object.keys(result)\n .sort()\n .forEach(function (v, i) {\n //console.log(v, result[v]);\n });\n\n // return the values\n return Object.values(result);\n};\n\nexport const localPtsX = (mineLevel) => {\n if (mineLevel?.ref_coord === undefined || mineLevel?.ref_coord === null) {\n return {};\n }\n\n const { ref_coord } = mineLevel;\n\n let result = {};\n ref_coord.forEach((coord) => {\n const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n const index = indexArray[1];\n\n result[index] = {\n id: coord.id,\n lat: coord.image_xy[0],\n lng: coord.image_xy[1],\n easting: coord.utm[0],\n northing: coord.utm[1],\n zoneNum: coord.utm_zone_number,\n zoneLetter: coord.utm_zone_letter,\n };\n });\n\n // sort object by key\n Object.keys(result)\n .sort()\n .forEach(function (v, i) {\n //console.log(v, result[v]);\n });\n\n // return the values\n return Object.values(result);\n};\n\n// the geometric coordinate to map pixel transformation\nconst TransformUtmToPixels = (localPts, standardPts) => {\n const LeastSq4Pt =\n LeastSquaresApproximationFourPointsSixParametersTransformation.fromPoints(\n localPts,\n standardPts\n );\n return LeastSq4Pt;\n};\n\n// the map pixel to geometric coordinate transformation\nconst TransformPixelsToUtm = (localPts, standardPts) => {\n const LeastSq4Pt =\n LeastSquaresApproximationFourPointsSixParametersTransformation.fromPoints(\n standardPts,\n localPts\n );\n return LeastSq4Pt;\n};\n\nexport const transformUtmToPixels = (area) =>\n TransformUtmToPixels(localPtsX(area), standardPtsUtmX(area));\n\nexport const transformPixelsToUtm = (area) =>\n TransformPixelsToUtm(localPtsX(area), standardPtsUtmX(area));\n","import { getUserSessionIp, messageToken } from \"utils/messageToken\";\n\n// This has a history...this is/was used to prepare mqtt messages to sent out 'name_area/id/change' message,\n// but with performance issues and delays the /change messages were moved to\n// POST api requests.\n// However this same function is used for the POST by using the 'message' property in the POST request.\n//\n\nexport const sendNamedAreaButtonUpdateByParent = (\n namedAreaStatuses,\n parentId,\n buttons\n) => {\n const namedAreas = Object.values(namedAreaStatuses);\n const namedAreasByParentId = namedAreas\n .filter((namedArea) => namedArea.parent === parentId)\n .sort((a, b) => (a.priority > b.priority ? 1 : -1));\n\n if (false) {\n console.log(\"sendNamedAreaButtonUpdateByParent namedAreas\", namedAreas);\n console.log(\"sendNamedAreaButtonUpdateByParent parentId\", parentId);\n console.log(\n \"sendNamedAreaButtonUpdateByParent namedAreasByParentId\",\n namedAreasByParentId\n );\n console.log(\"sendNamedAreaButtonUpdateByParent buttons\", buttons);\n }\n\n // send out backwards because controllers overlay based on order received\n\n let messagePayloads = [];\n\n namedAreasByParentId.reverse().forEach((namedArea, index) => {\n let namedAreaClone = JSON.parse(JSON.stringify(namedArea));\n let newButtons = [];\n\n //console.log(\"namedAreaClone\", namedAreaClone);\n\n // massage named area to prep data for sending\n //\n // remove from msg\n delete namedAreaClone.status;\n delete namedAreaClone.Firefly_List;\n // change `coordinateUtm` to `shape`\n let shape;\n // NOTE - only supports a single polygon shape, not multi-, so get the first shape in coordinates array\n shape = namedAreaClone.coordinatesUtm[0];\n // check first point and last should be the same\n if (shape[0] !== shape[shape.length - 1]) {\n // or append first to end point to close the polygon ring\n shape = [...shape, shape[0]];\n }\n namedAreaClone.shape = shape;\n delete namedAreaClone.coordinatesUtm; // remove from msg\n // change `style` to a string\n namedAreaClone.style = JSON.stringify(namedAreaClone.style);\n // update the new buttons with the original area id\n buttons.forEach((button, idx) => {\n newButtons[idx] = buttons[idx];\n newButtons[idx].id = namedArea.id;\n });\n namedAreaClone.button = newButtons;\n\n //console.log(\"namedAreaClone\", namedAreaClone);\n\n // prepare message token\n const userSessionIp = getUserSessionIp();\n const token = messageToken(userSessionIp);\n\n let updatedNamedArea = {\n ...namedAreaClone,\n precanned: 0, // not used ATM\n token: token,\n };\n\n //console.log(\"updatedNamedArea\", updatedNamedArea);\n\n const namedAreaPayload = {\n topic: `named_area/${updatedNamedArea.id}/change`,\n qos: 0,\n message: updatedNamedArea,\n retained: false,\n };\n\n //console.log(\"namedAreaPayload\", namedAreaPayload);\n\n messagePayloads.push(namedAreaPayload); // channelBufferPublishMsg(eventPayload, \"MQTT_PUBLISH\");\n });\n\n return messagePayloads;\n};\n","// #WEBWORKER REDUCER\n//\n// see main reducer at src/reducers.js\n//\n// Reducers for messages from web worker mqtt interface\n//\n\nimport Immutable from \"seamless-immutable\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport { combineReducers } from \"redux\";\nimport { getUserSessionIp, messageToken } from \"utils/messageToken\";\nimport { microTime } from \"utils/microTime\";\nimport toSlug from \"utils/toSlug\";\nimport { toFireflyColor, toFireflyAlternateColor } from \"utils/toFireflyColor\";\nimport { distinctColors } from \"utils/colors\";\n\nimport {\n isConfigJs, \n TemplateDefaultArea,\n deviceCheckTimeout,\n isDemoMode,\n isActiveArea,\n} from \"components/ConfigJs\";\n\nimport { processAreaInfoMessage } from \"components/WebWorker/processAreaInfoMessage\";\nimport { processControllerCoordinateMessage } from \"components/WebWorker/processControllerCoordinateMessage\";\nimport { processControllerStatusMessage } from \"components/WebWorker/processControllerStatusMessage\";\n\nimport {\n transformGeoJsonUtmToPixels,\n transformUtmToPixels,\n transformGeoJsonUtmToPixelsByChangeList,\n transformPixelsToUtm,\n standardPtsUtmX,\n localPtsX,\n} from \"components/Map/util-geoJsonToPixels\";\n\nimport { StatusEnum } from \"utils/StatusEnum\";\nimport { sendNamedAreaButtonUpdateByParent } from \"components/WebWorker/sendNamedAreaButtonUpdateByParent\";\n\nlet initialStateMqtt = Immutable({\n // flag indicating recent fetched data to update web worker\n dataFetched: [],\n\n // triggers reset/terminate of webWorker after RESET\n reset: true,\n\n // triggers recalculation of the objects which have transform data. i.e. FFs and Controller\n recalcState: { firefly: false, controller: false },\n\n // monitors loading of essential mqtt message data to manage startup/reload\n dataLoading: true,\n dataloadingResponseRequestMessageQueue: [],\n\n // displayed message list\n mqttMsg: [], // fault/+/+ messages\n // record of most recent fault_ts for each fault type determined by incoming MQTT\n latestFaultTs: {\n firefly: 0,\n battery: 0,\n network: 0,\n },\n\n // railway_application\n externalTrigger: {},\n buttonTrigger: {},\n machineStatus: {},\n\n // state of map position markers\n mapMessages: [],\n\n //\n fireflyCoordinates: {},\n fireflyStatuses: {},\n\n fireflyIdsUpdateList: [],\n\n //\n controllerCoordinates: {},\n controllerStatuses: {},\n\n //\n activeArea: \"\",\n areaInfos: {}, // geoJson object with coordinate info\n areaStatuses: {}, // key/value reference of the same properties as in areaInfos\n\n // flag to reload area image changed\n isAreaImagesChanged: false,\n\n //\n namedAreaInfos: {},\n namedAreaStatuses: {},\n namedAreaEvents: {},\n //\n namedAreaEventsButtonGroupState: {},\n\n //\n emergencyEventSettings: {},\n triggerEventSettings: {},\n\n //\n namedAreaExtTriggerEventInfo: [],\n\n //\n namedAreaScheduledEventInfo: [],\n //\n scheduledEventJobInfo: [],\n\n //\n serverTimestamp: 0,\n deviceTimestamps: {},\n systemProcessMsg: [],\n\n //\n timedOutDevices: [],\n timedOutLatestCheck: 0,\n timeoutPeriod: 15 * 60 * 1000, //5 * 60 * 1000; // 15 minutes\n timeoutCheckPeriod: 5 * 60 * 1000, // 5 minutes\n //\n waitEventTimeout: true, // timeout has expired on startup\n //\n publish: [],\n});\n\nfunction reduceGeneral(state = initialStateMqtt, action = {}) {\n // copy existing state\n const newState = { ...state };\n\n const { type, payload } = action;\n\n let areaStatuses = {};\n let publishEvents = {};\n let publishChanges = {};\n\n switch (type) {\n // reset to clear state after logout\n case \"MQTT_RESET\":\n newState.reset = payload;\n return newState;\n\n // data loading\n case \"MQTT_DATA_LOADING_RESPONSE_REQUEST_MESSAGE_QUEUE\":\n newState.dataloadingResponseRequestMessageQueue = payload;\n return newState;\n\n // fault messages\n // #NOTE - historically these were the first ever messages rx via MQTT\n // so they have the `honour` of being called \"mqttMsg\".\n //\n case \"MQTT_MSG_UPDATE\":\n //console.log(\"xxx MQTT_MSG_UPDATE\", payload);\n\n newState.mqttMsg = payload;\n return newState;\n case \"MQTT_LATEST_FAULT_TS_UPDATE\":\n newState.latestFaultTs = payload;\n return newState;\n case \"MQTT_MSG_CLEAR\":\n //console.log(\"xxx MQTT_MSG_CLEAR\");\n newState.mqttMsg = [];\n return newState;\n\n // railway_application\n case \"MQTT_LATEST_EXTERNAL_TRIGGER\":\n newState.externalTrigger = payload;\n return newState;\n case \"MQTT_LATEST_BUTTON_TRIGGER\":\n newState.buttonTrigger = payload;\n return newState;\n case \"MQTT_LATEST_MACHINE_STATUS_UPDATE\":\n newState.machineStatus = payload;\n return newState;\n\n // API fetch flag\n // reset to clear state after logout\n case \"CLEAR_DATA_FETCHED\":\n newState.dataFetched = [...newState.dataFetched].filter(\n (item) => item !== payload\n );\n return newState;\n\n // firefly messages\n case \"MQTT_MAP_MSG_UPDATE\":\n newState.mapMessages = payload;\n return newState;\n\n case \"UPS_FETCH_SUCCEEDED\":\n //console.log(`UPS_FETCH_SUCCEEDED`);\n\n if (false) {\n let cloneControllerCoordinates = {};\n\n if (newState?.controllerCoordinates?.features !== undefined) {\n // convert existing controller coordinates to keyed object\n newState.controllerCoordinates.features.map((value, idx) => {\n const {\n properties: { id },\n } = value;\n\n cloneControllerCoordinates[id] = value;\n });\n }\n\n // console.log(\n // `mmmm cloneControllerCoordinates`,\n // cloneControllerCoordinates\n // );\n let cloneControllerStatuses = JSON.parse(\n JSON.stringify(newState?.controllerStatuses)\n );\n\n const fetchedControllers = payload?.Controllers || [];\n let newFetchControllerCoordinates = {};\n let newFetchControllerStatuses = {};\n\n fetchedControllers.forEach((controller, idx) => {\n const { id } = controller;\n\n const step1 = processControllerCoordinateMessage(\n id,\n controller,\n cloneControllerCoordinates,\n cloneControllerStatuses\n );\n\n const {\n controllerCoordinates: step1Coordinates,\n controllerStatuses: step1Statuses,\n } = step1;\n\n // DISABLE STEP 2 FOR NOW - NOT ALL INFORMATION SUPLIED BY THE API\n if (false) {\n const step2 = processControllerStatusMessage(\n id,\n controller,\n step1Coordinates,\n step1Statuses\n );\n\n const {\n controllerCoordinates: step2Coordinates,\n controllerStatuses: step2Statuses,\n } = step2;\n }\n if (!_isEmpty(step1Coordinates)) {\n newFetchControllerCoordinates = step1Coordinates;\n }\n\n if (!_isEmpty(step1Statuses)) {\n newFetchControllerStatuses = step1Statuses;\n }\n });\n\n const newFetchGeoJsonControllerCoordinates = {\n type: \"FeatureCollection\",\n features: Object.values(newFetchControllerCoordinates),\n };\n\n // DISABLE API PROCESSING OF CONTROLLER DATA\n if (false) {\n newState.controllerCoordinates = transformGeoJsonUtmToPixels(\n newFetchGeoJsonControllerCoordinates,\n newState.areaStatuses,\n 1,\n false\n );\n\n newState.controllerStatuses = newFetchControllerStatuses;\n }\n\n // console.log(\n // `444 newFetchGeoJsonControllerCoordinates`,\n // newState.controllerCoordinates\n // );\n // console.log(\n // `444 newFetchControllerStatuses`,\n // newState.controllerStatuses\n // );\n }\n\n newState.dataFetched = [...newState.dataFetched, \"UPS_FETCH_SUCCEEDED\"];\n\n return newState;\n\n case \"MQTT_CONTROLLER_COORDINATES_UPDATE\":\n // convert geoJson coordinate date to relative pixel value based on area and ref coordinates\n\n // don't process coordinates if areaStatuses is empty\n // This is a very crude method to determined if it is empty\n // ...WTF????\n areaStatuses = JSON.parse(JSON.stringify(newState.areaStatuses));\n if (_isEmpty(areaStatuses)) {\n return newState;\n }\n\n //\n const newControllerCoordinates = JSON.parse(JSON.stringify(payload));\n\n // console.log(\n // `MQTT_CONTROLLER_COORDINATES_UPDATE newControllerCoordinates - #REVIEW - need change check as this does a transform!`,\n // newControllerCoordinates\n // );\n\n newState.controllerCoordinates = transformGeoJsonUtmToPixels(\n newControllerCoordinates,\n newState.areaStatuses,\n 1,\n false\n );\n\n return newState;\n case \"MQTT_CONTROLLER_STATUSES_UPDATE\":\n let newControllerStatus = payload;\n\n // DISABLE API PROCESSING OF CONTROLLER DATA - DIFFERENCE CHECKS\n\n if (false) {\n // check if newControllerStatus is different to current controllerStatus\n let changesControllerStatuses = [];\n const currentControllerStatuses = newState?.controllerStatuses;\n for (const controller of Object.keys(newControllerStatus)) {\n // if not in current set is a `new` controller\n if (currentControllerStatuses[controller] !== undefined) {\n for (const key of Object.keys(\n currentControllerStatuses[controller]\n )) {\n // ignore new properties added to current objects e.g transformations\n if (newControllerStatus[controller][key] !== undefined) {\n if (\n JSON.stringify(currentControllerStatuses[controller][key]) !==\n JSON.stringify(newControllerStatus[controller][key])\n ) {\n changesControllerStatuses.push(`${controller}:${key}`);\n }\n }\n }\n } else {\n changesControllerStatuses.push(`${controller}:new`);\n }\n }\n\n console.log(`changesControllerStatuses`, changesControllerStatuses);\n\n // run update process is there are any changes\n if (!_isEmpty(changesControllerStatuses)) {\n newState.controllerStatuses = newControllerStatus;\n }\n }\n\n newState.controllerStatuses = newControllerStatus;\n\n return newState;\n //\n case \"MQTT_EMERGENCY_EVENT_SETTINGS_UPDATE\":\n newState.emergencyEventSettings = payload;\n return newState;\n //\n case \"MQTT_TRIGGER_EVENT_SETTINGS_UPDATE\":\n newState.triggerEventSettings = payload;\n return newState;\n //\n\n case \"MQTT_SERVER_TIMESTAMP\":\n newState.serverTimestamp = payload;\n return newState;\n //\n\n case \"MQTT_SYSTEM_PROCESS_MSG_UPDATE\":\n // there is also middleware servicing this message but it gets here first.\n // see - src/components/Settings/middleware.js\n\n //console.log(\"xxx MQTT_SYSTEM_PROCESS_MSG_UPDATE\", payload);\n\n let newSystemProcessMsg = [...newState.systemProcessMsg];\n\n newSystemProcessMsg.push(...payload);\n\n // console.log(\n // \"xxx MQTT_SYSTEM_PROCESS_MSG_UPDATE newSystemProcessMsg\",\n // newSystemProcessMsg\n // );\n\n newState.systemProcessMsg = newSystemProcessMsg;\n return newState;\n //\n\n case \"MQTT_SYSTEM_PROCESS_MSG_CLEAR\":\n // console.log(\"xxx MQTT_SYSTEM_PROCESS_MSG_CLEAR payload\", payload);\n\n let newClearSystemProcessMsg = [...newState.systemProcessMsg];\n newClearSystemProcessMsg = newClearSystemProcessMsg.filter(\n (msg) => msg.id !== payload.id\n );\n\n newState.systemProcessMsg = newClearSystemProcessMsg;\n return newState;\n //\n\n case \"MQTT_DEVICE_TIMESTAMPS\":\n newState.deviceTimestamps = payload;\n\n // #NOTE\n // #WIP - disable pending removal\n // Replaced with simple process in Worker\n //\n\n if (false) {\n console.log(`xxx deviceTimestamps`, payload);\n\n // #NOTE\n // heartbeat pollrate = 1000\n // Run checks on timeout every 5 seconds = 5 * pollrate\n\n let timedOutDevices = [];\n\n // check how many timestamps are > timeout period\n\n const timeOutNow = new Date().getTime();\n\n // initialise time count & settings\n\n if (\n newState.timedOutLatestCheck === 0 ||\n newState?.timedOutLatestCheck === undefined\n ) {\n if (isConfigJs() && deviceCheckTimeout()) {\n const { period, checkPeriod } = deviceCheckTimeout();\n\n newState.timeoutPeriod = period || 15 * 60 * 1000; //5 * 60 * 1000; // 15 minutes;\n newState.timeoutCheckPeriod = checkPeriod || 5 * 60 * 1000; // 5 minutes\n }\n\n newState.timedOutLatestCheck = timeOutNow;\n\n console.log(\n `CHECK DEVICE TIMEOUT - CONFIGURED FOR TIMEOUT PERIOD: `,\n newState.timeoutPeriod,\n \"CHECK PERIOD: \",\n newState.timeoutCheckPeriod,\n \" (mSec)\"\n );\n\n //console.log(`>>>>>> set timedOutLatestCheck`, timeOutNow);\n\n return newState;\n }\n\n // console.log(\n // `timeOutNow - newState.timedOutLatestCheck > timeoutCheckPeriod`,\n // timeOutNow - newState.timedOutLatestCheck > newState.timeoutCheckPeriod\n // );\n\n // check for timeout after timoutPeriod\n if (\n timeOutNow - newState.timedOutLatestCheck >\n newState.timeoutCheckPeriod\n ) {\n console.log(\n `CHECK DEVICE TIMEOUT - NOW: `,\n timeOutNow,\n \" LAST CHECK: \",\n newState.timedOutLatestCheck\n );\n\n for (const key in newState.deviceTimestamps) {\n const item = newState.deviceTimestamps[key];\n const deviceTimestamp = Date.parse(item.ts);\n\n if (timeOutNow - deviceTimestamp > newState.timeoutPeriod) {\n console.log(`CHECK DEVICE TIMEOUT - ITEM:`, item);\n timedOutDevices.push(item);\n }\n }\n newState.timedOutLatestCheck = timeOutNow;\n }\n\n //console.log(`CHECK DEVICE TIMEOUT - TIMED OUT DEVICES `, timedOutDevices);\n\n newState.timedOutDevices = timedOutDevices;\n\n // update controller coordinates for timed out devices\n const timedOutControllers = timedOutDevices.filter(\n (device) => device.device === \"controller\"\n );\n\n //console.log(`>>>>>> timedOutControllers`, timedOutControllers);\n\n if (!_isEmpty(timedOutControllers)) {\n let updateControllerCoordinatesForDeviceTimestamps = [];\n newState.controllerCoordinates.features.map((feature, idx) => {\n const { properties } = feature;\n const { id } = properties;\n\n let newFeature = feature;\n let cloneProperties = JSON.parse(JSON.stringify(properties));\n if (\n timedOutControllers.some((controller) => controller.id === id)\n ) {\n cloneProperties.deviceStatus.push(StatusEnum.TIMEOUT);\n newFeature.properties = cloneProperties;\n }\n updateControllerCoordinatesForDeviceTimestamps.push(newFeature);\n });\n\n // newState.controllerCoordinates = {\n // type: \"FeatureCollection\",\n // features: updateControllerCoordinatesForDeviceTimestamps,\n // };\n }\n\n // console.log(`newState.controllerCoordinates`, newState.controllerCoordinates)\n\n // update firefly coordinates for timed out devices\n const timedOutFireflies = timedOutDevices.filter(\n (device) => device.device === \"firefly\"\n );\n\n if (!_isEmpty(timedOutFireflies)) {\n //console.log(`sss timedOutFireflies`, timedOutFireflies);\n\n // add FFs to update list if it's changed\n let fireflyIdsUpdateList = JSON.parse(\n JSON.stringify(newState.fireflyIdsUpdateList)\n );\n\n let updateFireflyCoordinatesForDeviceTimestamps = [];\n newState.fireflyCoordinates.features.map((feature, idx) => {\n const { properties } = feature;\n const { id } = properties;\n\n let newFeature = feature;\n let cloneProperties = JSON.parse(JSON.stringify(properties));\n if (timedOutFireflies.some((firefly) => firefly.id === id)) {\n cloneProperties.deviceStatus.push(StatusEnum.TIMEOUT);\n newFeature.properties = cloneProperties;\n }\n updateFireflyCoordinatesForDeviceTimestamps.push(newFeature);\n\n // force update of FF draw\n fireflyIdsUpdateList.push(id);\n\n if (id === \"DMLZ_Extraction:P43:1\") {\n console.log(\n `DMLZ_Extraction:P43:1 processed newFeature`,\n newFeature\n );\n }\n });\n\n // newState.FireflyCoordinates = {\n // type: \"FeatureCollection\",\n // features: updateFireflyCoordinatesForDeviceTimestamps,\n // };\n console.log(`sss fireflyIdsUpdateList`, fireflyIdsUpdateList);\n\n //newState.fireflyIdsUpdateList = fireflyIdsUpdateList;\n }\n }\n // console.log(`newState.FireflyCoordinates`, newState.FireflyCoordinates)\n return newState;\n //\n\n // #NOTE\n // Recalc state is used to trigger the recalculation of the state of area, controllers, fireflies etc.\n // This particular applies to the recalculation of the transforms after area reference coordinates\n // have been shifted.\n //\n case \"MQTT_RECALC_STATE\":\n //console.log(`MQTT_RECALC_STATE payload`, payload);\n\n // only update for TRUE recalc state. Allow reducer state.recalcState to be cleared\n // in the reducer itself.\n\n // clone a copy of the recalcState\n // #WIP #TODO - fix this cloning process\n let newRecalcState = JSON.parse(JSON.stringify(newState.recalcState));\n\n if (payload.firefly === true) {\n newRecalcState.firefly = true;\n }\n if (payload.controller === true) {\n newRecalcState.controller = true;\n }\n newState.recalcState = newRecalcState;\n\n return newState;\n\n case \"FIREFLY_FETCH_SUCCEEDED\":\n //console.log(`FIREFLY_FETCH_SUCCEEDED payload`, payload);\n\n newState.dataFetched = [\n ...newState.dataFetched,\n \"FIREFLY_FETCH_SUCCEEDED\",\n ];\n return newState;\n\n case \"MQTT_FIREFLY_COORDINATES_UPDATE\":\n const { fireflyCoordinates, userSettings } = payload;\n\n // process new firefly coordinate messages\n // convert geoJson coordinate date to relative pixel value based on area and ref coordinates\n\n // ... get an updated copy of area statuses\n areaStatuses = JSON.parse(JSON.stringify(newState.areaStatuses));\n if (_isEmpty(areaStatuses)) {\n return newState;\n }\n\n // Check if the coordinates have changed and only update those that have changed,\n // by adding them to a change list 'fireflyIdsUpdateList'.\n\n // make a copy\n const newFireflyCoordinates = JSON.parse(\n JSON.stringify(fireflyCoordinates)\n );\n\n // console.log(\n // `fireflyIdsUpdateList rx newFireflyCoordinates`,\n // newFireflyCoordinates\n // );\n\n const prevFireflyCoordinates = JSON.parse(\n JSON.stringify(newState.fireflyCoordinates)\n );\n\n // console.log(\n // `fireflyIdsUpdateList rx prevFireflyCoordinates`,\n // prevFireflyCoordinates\n // );\n\n // #WIP - considering changing the process\n // omitDeep\n // let isChanged = !isEqual(\n // omitDeep(newFireflyCoordinates?.feature, [\"timestamp\"]),\n // omitDeep(prevFireflyCoordinates?.features, [\"timestamp\"])\n // );\n\n // add FFs to update list if it's changed\n let fireflyIdsUpdateList = JSON.parse(\n JSON.stringify(newState.fireflyIdsUpdateList)\n );\n // console.log(\n // `fireflyIdsUpdateList rx fireflyIdsUpdateList`,\n // fireflyIdsUpdateList\n // );\n\n // Create indexed versions of current and previous fireflyCoordinates.\n // Use these to compare for differences. Only update the FFs which have changed.\n //\n // FFs could be identical except for the timestamp so remove the timestamp before comparison.\n //\n // convert new FFs from geojson array to indexed object\n\n let newFireflyProperty = {};\n if (newFireflyCoordinates?.features !== undefined) {\n newFireflyCoordinates.features.forEach((feature) => {\n const { properties } = feature;\n const { id } = properties;\n\n // make a copy before deleting timestamp\n const { timestamp, ...newProperties } = properties;\n newFireflyProperty[id] = newProperties; //JSON.parse(JSON.stringify(properties)) || {};\n\n //delete newFireflyProperty[id].timestamp;\n });\n }\n\n // convert prev FFs from geojson array to indexed object\n let prevFireflyProperty = {};\n let prevFireflyFeature = {};\n // a separate copy which does not have the timestamp deleted\n let prevFireflyFeatureWithTimestamp = {};\n if (prevFireflyCoordinates?.features !== undefined) {\n prevFireflyCoordinates.features.forEach((feature) => {\n const { properties } = feature;\n const { id } = properties;\n\n // make a copy before deleting timestamp\n const { timestamp, ...newProperties } = properties;\n prevFireflyProperty[id] = newProperties; // JSON.parse(JSON.stringify(properties)) || {};\n //delete prevFireflyProperty[id].timestamp;\n //\n prevFireflyFeatureWithTimestamp[id] = properties || {};\n //\n prevFireflyFeature[id] = feature;\n });\n }\n\n // compare new and prev objects, add changed FFs to change list array 'fireflyIdsUpdateList'\n //\n const newFFStatusIds = Object.keys(newFireflyProperty);\n\n // to track deleted IDs, start with all prev IDs and progressively remove those which are in the new/current set\n let fireflyIdsDeleteList = Object.keys(prevFireflyProperty);\n\n // console.log(\n // `fireflyIdsUpdateList 1 fireflyIdsDeleteList`,\n // fireflyIdsDeleteList\n // );\n\n newFFStatusIds.forEach((id) => {\n let isFireflyPropertyChanged =\n // this will check for FFs which are NEW and for FFs which are UPDATED\n JSON.stringify(newFireflyProperty[id]) !==\n JSON.stringify(prevFireflyProperty[id]) ||\n // add every FF to recalculate the state (e.g. area ref coordinates have changed)\n newState.recalcState?.firefly === true;\n\n // To account for DELETED FFs, remove the current ID from the list of prev FFs.\n // The FFs left over at the end are those that have been deleted.\n fireflyIdsDeleteList = fireflyIdsDeleteList.filter((ff) => ff !== id);\n\n // console.log(\n // `fireflyIdsUpdateList 2 fireflyIdsDeleteList`,\n // fireflyIdsDeleteList\n // );\n\n // _#DEMO_MODE\n if (userSettings?.feature?.includes(\"showDemoMode\") || isDemoMode()) {\n // console.log(\n // \"DEMO_MODE - PROCESS UPDATE <=================================== #REVIEW - CAN FF CHANGES BE CHECKED???\"\n // );\n\n //\n // If demo mode update every firefly, every update. Don't check for changes.\n // This is to ensure firefly states are updated even though only /lightingplan is tx/rx.\n // e.g. the events from namedArea, emergency and triggers are not sent through /lightingplan\n // but are updated later.\n //\n // see - src/components/WebWorker/index.js\n // search `heartbeatFunction={this.pokeTheDemoModeFetchData}`\n //\n //\n // #NOTE @8Aug22 - this method has been reviewed/changed so that instead of waiting for\n // the /lightingplan in demo mode, so instead 'pokeTheDemoModeFetchData' is used to periodically fetch data via the API.\n // This was done b/c the demoMode was often used for public demonstration sites which are\n // accessed by users notably 'distant' from the server. The mqtt messages from the server to the client\n // are delayed which caused problems.\n // This method gets data straight from the server.\n //\n // *HOWEVER* this means the demo mode can not also use live connections.\n\n isFireflyPropertyChanged = true;\n }\n\n // if (isFireflyPropertyChanged) {\n // console.log(\n // \"isDemoMode - PROCESS UPDATE isFireflyPropertyChanged <===================================\"\n // );\n // }\n\n if (isFireflyPropertyChanged) {\n //#WIP #NOTE #TODO\n // #fireflyIdsUpdateList\n // Consider passing a list of changes to the `fireflyIdsUpdateList` so can update only changes\n // e.g. { id: \"DMLZ_Extraction:P23:10\", changes: [\"color\", \"light\", \"controllerMode\", \"deviceStatus\", \"ups_id\"]}\n //\n // This means I'll have to filter `fireflyIdsUpdateList` instead.\n //\n // could change fireflyIdsUpdateList from array to object\n // i.e. fireflyIdsUpdateList[id]= getObjectDiff(newFireflyProperty[id], prevFireflyProperty[id] || [])\n\n const alreadyInTheList = fireflyIdsUpdateList.includes(id);\n\n if (!alreadyInTheList) {\n fireflyIdsUpdateList.push(id);\n }\n\n // console.log(\n // `fireflyIdsUpdateList newFFStatusIds ADDED id`,\n // id,\n // `--`,\n // fireflyIdsUpdateList,\n // \"new\",\n // newFireflyProperty[id],\n // \"prev\",\n // prevFireflyProperty[id]\n // );\n }\n });\n\n // transform FFs which are in the change list 'fireflyIdsUpdateList'\n let updatedFireflyCoordinates = transformGeoJsonUtmToPixelsByChangeList(\n prevFireflyFeature,\n // #NOTE - 'newFireflyCoordinates' does not contain the 'timestamp'\n // pass payload for update to retain the timestamp information\n JSON.parse(JSON.stringify(fireflyCoordinates)), // was 'newFireflyCoordinates',\n fireflyIdsUpdateList,\n newState.areaStatuses\n );\n\n // filter out the deleted fireflies\n let updatedFireflyCoordinatesFeatures =\n updatedFireflyCoordinates?.features?.filter(\n (ff) => !fireflyIdsDeleteList.includes(ff.id)\n );\n\n // ... and update the coordinate information\n updatedFireflyCoordinates = {\n type: \"FeatureCollection\",\n features: updatedFireflyCoordinatesFeatures,\n };\n\n newState.fireflyCoordinates = updatedFireflyCoordinates;\n\n // #Note - the MinelevelMapLeaflet > geoJSONMarkersData @\"Update firefly marker\" code should now have the latest coordinate\n // data with the deleted FFs. However geoJSONMarkersData will only re-render if there are updates.\n // IF FFs have *only* been deleted (and not added or updated) then there is no reason to update.\n // Force an update by adding one of the delete list to the update list.\n // i.e. if there *are* deleted items.\n // The deleted Id will have no impact on the update (as the IDs are not in the fireflyCoordinates data) but will\n // have the effect of triggering the update process.\n\n // console.log(`update fireflyIdsUpdateList`, fireflyIdsUpdateList);\n // console.log(\n // `update fireflyIdsUpdateList fireflyIdsUpdateList.length`,\n // fireflyIdsUpdateList.length\n // );\n // console.log(\n // `update fireflyIdsUpdateList fireflyIdsDeleteList`,\n // fireflyIdsDeleteList\n // );\n // console.log(\n // `update fireflyIdsUpdateList fireflyIdsDeleteList.length > 0`,\n // fireflyIdsDeleteList.length > 0\n // );\n // console.log(`update fireflyIdsUpdateList [fireflyIdsDeleteList[0]]`, [\n // fireflyIdsDeleteList[0],\n // ]);\n\n const updateFireflyIdsUpdateList =\n fireflyIdsUpdateList.length > 0\n ? fireflyIdsUpdateList\n : fireflyIdsDeleteList.length > 0 // force update to clear the screen (see comment above)\n ? [fireflyIdsDeleteList[0]] // add arbitrary item\n : [];\n\n newState.fireflyIdsUpdateList = updateFireflyIdsUpdateList;\n\n // Although the coordinate data has been updated, the map layers still exist.\n // Need to pass a delete list to remove from the leaflet map layers\n newState.fireflyIdsDeleteList = fireflyIdsDeleteList;\n\n // _#DEBUG - useful for debugging the update and delete list\n if (false) {\n console.log(\n `UPDATE -> fireflyIdsUpdateList fireflyIdsDeleteList`,\n fireflyIdsDeleteList\n );\n console.log(\n `UPDATE -> fireflyIdsUpdateList updateFireflyIdsUpdateList`,\n updateFireflyIdsUpdateList\n );\n }\n\n // firefly recalculation has been done\n // #WIP #TODO - this is shitty code because state is immutable\n // Fix this.\n let newRecalcStateForFireflyCoord = JSON.parse(\n JSON.stringify(newState.recalcState)\n );\n newRecalcStateForFireflyCoord.firefly = false;\n newState.recalcState = newRecalcStateForFireflyCoord;\n\n return newState;\n case \"MQTT_FIREFLY_STATUSES_UPDATE\":\n // const newFireflyStatuses = payload;\n // const fireflyStatuses = newState.fireflyStatuses;\n\n // // add FFs to update list if it's changed\n // let fireflyIdsUpdateList = JSON.parse(\n // JSON.stringify(newState.fireflyIdsUpdateList)\n // );\n\n // const newFireflyStatusesIds = Object.keys(newFireflyStatuses);\n // newFireflyStatusesIds.forEach((id) => {\n // let newStatus = JSON.parse(\n // JSON.stringify(newFireflyStatuses[id] || {})\n // );\n // if (newStatus?.timestamp !== undefined) {\n // delete newStatus.timestamp;\n // }\n // let status = JSON.parse(JSON.stringify(fireflyStatuses[id] || {}));\n // if (status?.timestamp !== undefined) {\n // delete status.timestamp;\n // }\n\n // console.log(\"JSON.stringify(newStatus) \", JSON.stringify(newStatus));\n // console.log(\"JSON.stringify(status)\", JSON.stringify(status));\n\n // if (JSON.stringify(newStatus) !== JSON.stringify(status)) {\n // fireflyIdsUpdateList.push(id);\n // }\n // });\n\n // // console.log(\"fireflyIdsUpdateList\", fireflyIdsUpdateList);\n\n // newState.fireflyIdsUpdateList = fireflyIdsUpdateList;\n\n // break fireflies down by STATUS Status.Enum\n\n //console.log(`fireflyStatuses`, payload);\n\n newState.fireflyStatuses = payload;\n return newState;\n //\n\n case \"MQTT_FIREFLY_STATUSES_UPDATE_LIST_DELETE_ID\":\n const fireflyIdsUpdateListIds = payload;\n //console.log(\"deleteId\", payload);\n const oldIds = newState.fireflyIdsUpdateList;\n //console.log(\"QQQ fireflyIdsUpdateList fireflyIdsUpdateListIds\", payload);\n\n //console.log(\"QQQ fireflyIdsUpdateList updatedFireflyIds oldIds\", oldIds);\n let newIds = [...oldIds];\n\n fireflyIdsUpdateListIds.forEach((deletedId) => {\n newIds = newIds.filter((id) => id !== deletedId);\n });\n //console.log(\"QQQ fireflyIdsUpdateList updatedFireflyIds newIds\", newIds);\n newState.fireflyIdsUpdateList = newIds;\n\n return newState;\n\n //\n case \"SET_AREA_IMAGES_CHANGED\":\n newState.isAreaImagesChanged = payload;\n return newState;\n\n case \"MINE_LEVELS_FETCH_SUCCEEDED\":\n console.log(`MINE_LEVELS_FETCH_SUCCEEDED`);\n\n if (false) {\n let newFetchAreaInfos = JSON.parse(JSON.stringify(newState?.areaInfos));\n let newFetchAreaStatuses = JSON.parse(\n JSON.stringify(newState?.areaStatuses)\n );\n\n const fetchedAreas = payload?.areas || [];\n fetchedAreas.forEach((area, idx) => {\n const { id } = area;\n if (id !== \"ALL_AREAS\") {\n const newAreaInfosStatuses = processAreaInfoMessage(\n id,\n area,\n newFetchAreaInfos,\n newFetchAreaStatuses,\n TemplateDefaultArea()\n );\n\n const { areaInfos: newAreaInfos, areaStatuses: newAreaStatuses } =\n newAreaInfosStatuses;\n\n //console.log(`newFetchAreaInfos`, newAreaInfos);\n //console.log(`newFetchAreaStatuses`, newAreaStatuses);\n\n if (!_isEmpty(newAreaInfos)) {\n newFetchAreaInfos = newAreaInfos;\n }\n\n if (!_isEmpty(newAreaStatuses)) {\n newFetchAreaStatuses = newAreaStatuses;\n }\n }\n });\n\n const newFetchFeatureCollectionAreaInfos = {\n type: \"FeatureCollection\",\n features: Object.values(newFetchAreaInfos),\n };\n\n newState.areaInfos = newFetchFeatureCollectionAreaInfos;\n newState.areaStatuses = processAreaStatuses(newFetchAreaStatuses);\n\n // manage data loading state\n // if > 1 areas, consider data has loaded\n if (Object.keys(newFetchAreaStatuses).length > 1) {\n newState.dataLoading = false;\n }\n }\n\n newState.dataFetched = [\n ...newState.dataFetched,\n \"MINE_LEVELS_FETCH_SUCCEEDED\",\n ];\n return newState;\n\n case \"SET_ACTIVE_AREA\":\n if (isActiveArea()) {\n newState.activeArea = payload;\n }\n return newState;\n\n case \"MQTT_AREA_INFOS_UPDATE\":\n newState.areaInfos = payload;\n\n //console.log(`KKKKK MQTT_AREA_INFOS_UPDATE`, payload);\n\n return newState;\n\n case \"MQTT_AREA_STATUSES_UPDATE\":\n // update area with transform data\n let newAreaStatus = payload;\n\n //console.log(`KKKKK MQTT_AREA_STATUSES_UPDATE`, payload);\n\n if (false) {\n const areas = Object.keys(newAreaStatus);\n\n // add transforms to the areaStatus object\n for (const area of areas) {\n if (!_isEmpty(newAreaStatus[area].ref_coord)) {\n newAreaStatus[area].transform = transformUtmToPixels(\n newAreaStatus[area]\n );\n newAreaStatus[area].transformUtmToPixels = transformUtmToPixels(\n newAreaStatus[area]\n );\n newAreaStatus[area].transformPixelsToUtm = transformPixelsToUtm(\n newAreaStatus[area]\n );\n\n // add reference points\n const std = standardPtsUtmX(newAreaStatus[area]);\n const local = localPtsX(newAreaStatus[area]);\n newAreaStatus[area].standardPtsUtmX = std;\n newAreaStatus[area].localPtsX = local;\n\n //\n } else {\n console.log(\n `LOADING ERROR: Area '${newAreaStatus[area].id}' Ref_coord is empty. Check mqtt message 'mosquitto_sub -v -t area/${newAreaStatus[area].id}/info'`\n );\n // ref_coord empty - can't process so delete object\n delete newAreaStatus[area];\n }\n }\n\n newState.areaStatuses = newAreaStatus;\n }\n\n // check if an area has been deleted\n const currentAreaStatuses = newState?.areaStatuses;\n\n Object.keys(currentAreaStatuses).forEach((key) => {\n if (currentAreaStatuses[key].id !== newAreaStatus[key]?.id) {\n delete currentAreaStatuses[key];\n }\n });\n\n // check if newAreaStatus is different to current areaStatus\n let changesAreaStatuses = [];\n for (const area of Object.keys(newAreaStatus)) {\n // ignore defaultArea\n if (area !== \"defaultArea\") {\n // if not in current set is a `new` area\n if (currentAreaStatuses[area] !== undefined) {\n for (const key of Object.keys(currentAreaStatuses[area])) {\n // ignore new properties added to current named areas e.g transformations\n if (newAreaStatus[area][key] !== undefined) {\n if (\n JSON.stringify(currentAreaStatuses[area][key]) !==\n JSON.stringify(newAreaStatus[area][key])\n ) {\n changesAreaStatuses.push(`${area}:${key}`);\n }\n }\n }\n } else {\n changesAreaStatuses.push(`${area}:new`);\n }\n }\n }\n\n // run update process is there are any changes\n if (!_isEmpty(changesAreaStatuses)) {\n newState.areaStatuses = processAreaStatuses(newAreaStatus);\n // manage data loading state\n // if > 1 areas, consider data has loaded\n if (Object.keys(newAreaStatus).length > 1) {\n newState.dataLoading = false;\n }\n }\n\n return newState;\n\n //\n // fetch named area data from server\n case \"NAMED_AREA_FETCH_SUCCEEDED\":\n console.log(`NAMED_AREA_FETCH_SUCCEEDED payload`, payload);\n\n newState.dataFetched = [\n ...newState.dataFetched,\n \"NAMED_AREA_FETCH_SUCCEEDED\",\n ];\n return newState;\n\n case \"MQTT_NAMED_AREA_INFOS_UPDATE\":\n newState.namedAreaInfos = payload;\n return newState;\n case \"MQTT_NAMED_AREA_STATUSES_UPDATE\":\n newState.namedAreaStatuses = payload;\n return newState;\n //\n // Event messages\n //\n case \"MQTT_NAMED_AREA_EVENTS_UPDATE\":\n // update events payload\n newState.namedAreaEvents = payload;\n\n // #DEBUG\n if (false) {\n console.log(\n \"buttonActive Single MQTT_NAMED_AREA_EVENTS_UPDATE\",\n payload\n );\n }\n\n // get the named area events\n const namedAreaEvents = newState.namedAreaEvents;\n\n // update event group states if the timeout has expired &\n // named area events have been logged\n //\n if (newState.waitEventTimeout && !_isEmpty(namedAreaEvents)) {\n // **************************************************************\n // #REVIEW - this is similar process to finding a parent for the namedArea\n // generalise this!!!!\n //\n\n // convert from a keyed object to an array\n const keys = Object.keys(namedAreaEvents).sort();\n const naEventsArray = stableOrder(keys, namedAreaEvents);\n // get the unique parents of this array\n const uniqueParents = naEventsArray\n .map((item) => item.parent)\n .filter((value, index, self) => self.indexOf(value) === index);\n // setup to get the new named area event button groups for each event parent\n // as an object keyed on the parent with the groups status....\n //\n let newNamedAreaEventsButtonGroupState = {};\n uniqueParents.forEach(function (uniqueParent, idx) {\n const namedAreaEventParentInfo = naEventsArray.find(\n (item) => item.parent === uniqueParent\n );\n const id = uniqueParent;\n const { button_groups } = namedAreaEventParentInfo;\n //...the keyed object...\n newNamedAreaEventsButtonGroupState[id] =\n button_groups !== undefined ? button_groups : {};\n });\n\n // #NOTE - this code applied before ALL_AREAS events were introducte\n // and level wide events were not consider normal named areas\n\n if (false) {\n // add group state for whole mine status\n\n // find all named areas for the mine,\n // there is a level wide named area named after\n // each area name. i.e. area id = named area id\n\n //\n // the button state for the level wide named areas and\n // set whole mine state is same\n\n newNamedAreaEventsButtonGroupState[\"ALL_AREAS\"] = { 0: 0 };\n\n const allAreas = newState.areaStatuses;\n // convert from a keyed object to an array\n const allAreasKeys = Object.keys(allAreas).sort();\n const allAreasKeysArray = stableOrder(allAreasKeys, allAreas);\n\n if (allAreasKeysArray !== undefined && allAreasKeysArray.length > 0) {\n const allNamedAreas = allAreasKeysArray.map((area) => area.id);\n // use 1st named area as a template\n const template =\n newNamedAreaEventsButtonGroupState[allNamedAreas[0]];\n\n //console.log(\"xxx template\", template);\n let isWholeMine = true;\n for (let index = 0; index < allNamedAreas.length; index++) {\n if (\n JSON.stringify(template) !==\n JSON.stringify(\n newNamedAreaEventsButtonGroupState[allNamedAreas[index]]\n )\n ) {\n isWholeMine = false;\n }\n }\n if (isWholeMine) {\n newNamedAreaEventsButtonGroupState[\"ALL_AREAS\"] = template;\n }\n }\n }\n\n // **************************************************************\n\n // assign the latest state of the buttons to the local store\n newState.namedAreaEventsButtonGroupState =\n newNamedAreaEventsButtonGroupState;\n\n // console.log(\n // `MQTT_NAMED_AREA_EVENTS_UPDATE newNamedAreaEventsButtonGroupState`,\n // newNamedAreaEventsButtonGroupState\n // );\n\n // reset timeout flag\n newState.waitEventTimeout = true;\n }\n\n return newState;\n\n // DEACTIVATE AN EVENT -------->\n case \"DEACTIVATE_NAMED_AREA_EVENT\":\n console.log(\"DEACTIVATE_NAMED_AREA_EVENT payload\", payload);\n\n if (\n payload.operation.id === \"ALL_AREAS\" ||\n payload.operation.id === \"LEVEL_WIDE\"\n ) {\n console.log(\"Processing ALL_AREAS DEACTIVATE ... event!!\");\n\n publishEvents = sendNamedAreaEventAllAreas(\n newState.namedAreaStatuses,\n payload.operation,\n newState.namedAreaEventsButtonGroupState,\n false\n );\n } else {\n publishEvents = sendNamedAreaEventParent({\n namedAreaStatuses: newState.namedAreaStatuses,\n operation: payload.operation,\n namedAreaEventsButtonGroupState:\n newState.namedAreaEventsButtonGroupState,\n namedAreaEvents: newState.namedAreaEvents,\n active: false,\n });\n }\n console.log(\"MQTT_PUBLISH publishEvents\", publishEvents);\n newState.publish = Immutable(\n newState.publish.asMutable().concat(publishEvents)\n );\n return newState;\n\n // ACTIVATE AN EVENT -------->\n // #NOTE - this sends a group of events based on the parent\n //\n\n case \"ACTIVATE_NAMED_AREA_EVENT\":\n console.log(\"ACTIVATE_NAMED_AREA_EVENT payload\", payload);\n\n if (\n payload.operation.id === \"ALL_AREAS\" ||\n payload.operation.id === \"LEVEL_WIDE\"\n ) {\n console.log(\"PROCESSING 'ALL_AREAS' ACTIVATE... EVENT!!\");\n\n publishEvents = sendNamedAreaEventAllAreas(\n newState.namedAreaStatuses,\n payload.operation,\n newState.namedAreaEventsButtonGroupState,\n true\n );\n } else {\n publishEvents = sendNamedAreaEventParent({\n namedAreaStatuses: newState.namedAreaStatuses,\n operation: payload.operation,\n namedAreaEventsButtonGroupState:\n newState.namedAreaEventsButtonGroupState,\n namedAreaEvents: newState.namedAreaEvents,\n active: true,\n });\n }\n\n console.log(\"MQTT_PUBLISH publishEvents\", publishEvents);\n newState.publish = Immutable(\n newState.publish.asMutable().concat(publishEvents)\n );\n return newState;\n\n // ACTIVATE A SINGLE EVENT -------->\n // #NOTE - this sends a single event\n //\n\n case \"ACTIVATE_NAMED_AREA_EVENT_SINGLE\":\n //console.log(\"ACTIVATE_NAMED_AREA_EVENT_SINGLE payload\", payload);\n\n if (\n payload.operation.id === \"ALL_AREAS\" ||\n payload.operation.id === \"LEVEL_WIDE\"\n ) {\n console.log(\"PROCESSING ALL_AREAS ACTIVATE...SINGLE...EVENT!!\");\n\n // Don't do anything...shouldn't be here\n } else {\n publishEvents = sendNamedAreaEventSingle(\n newState.namedAreaStatuses,\n payload.operation,\n newState.namedAreaEventsButtonGroupState,\n newState.namedAreaEvents,\n true\n );\n }\n\n console.log(\"MQTT_PUBLISH publishEvents\", publishEvents);\n newState.publish = Immutable(\n newState.publish.asMutable().concat(publishEvents)\n );\n return newState;\n\n case \"UPDATE_BUTTONS_GROUP_STATE\":\n newState.namedAreaEventsButtonGroupState = payload.buttons;\n // console.log(\n // \"kkk xxx newState.namedAreaEventsButtonGroupState\",\n // newState.namedAreaEventsButtonGroupState\n // );\n return newState;\n\n case \"UPDATE_BUTTONS_IN_NAMED_AREAS_BY_PARENT_MQTT\":\n // console.log(\n // \"UPDATE_BUTTONS_IN_NAMED_AREAS_BY_PARENT_MQTT payload\",\n // payload\n // );\n\n const { parentId, buttons } = payload;\n\n publishChanges = sendNamedAreaButtonUpdateByParent(\n newState.namedAreaStatuses,\n parentId,\n buttons\n );\n\n console.log(\"MQTT_PUBLISH publishButtonUpdates\", publishChanges);\n newState.publish = Immutable(\n newState.publish.asMutable().concat(publishChanges)\n );\n\n return newState;\n\n case \"WAIT_EVENT_TIMEOUT\":\n //console.log(\"WAIT_EVENT_TIMEOUT payload.action\", payload.action);\n switch (payload.action) {\n case \"start\": // start the timeout (wait) period\n newState.waitEventTimeout = false;\n break;\n case \"stop\": // don't wait\n newState.waitEventTimeout = true;\n break;\n default:\n newState.waitEventTimeout = true;\n break;\n }\n return newState;\n\n // Publish Messages\n case \"MQTT_PUBLISH\":\n newState.publish = Immutable(\n newState.publish.asMutable().concat([payload])\n );\n return newState;\n case \"REMOVE_MQTT_MESSAGE_BY_TOKEN\":\n newState.publish = Immutable(\n newState.publish\n .asMutable()\n .filter((item) => item.message.token !== payload)\n );\n return newState;\n\n // #REVIEW - review need. Either re-write or delete\n //\n // // case \"CLEAR_MQTT_MESSAGES\":\n // // console.log(\"CLEAR_MQTT_MESSAGES MQTT_PUBLISH\");\n // // return publishInitialState;\n // case \"REMOVE_MQTT_MESSAGE\":\n // return Immutable(\n // newState.publish\n // .asMutable()\n // .filter(({ id }) => id !== action.payload.id)\n // );\n\n case \"NAMED_AREA_EXT_TRIGGER_EVENT_INFO_FETCH_SUCCEEDED\":\n newState.namedAreaExtTriggerEventInfo = payload;\n // console.log(\n // \"kkk xxx newState.namedAreaExtTriggerEventInfo\",\n // newState.namedAreaExtTriggerEventInfo\n // );\n\n return newState;\n\n case \"NAMED_AREA_SCHEDULED_EVENT_INFO_FETCH_SUCCEEDED\":\n newState.namedAreaScheduledEventInfo = payload;\n // console.log(\n // \"kkk xxx newState.namedAreaScheduledEventInfo\",\n // newState.namedAreaScheduledEventInfo\n // );\n\n return newState;\n\n case \"SCHEDULED_EVENT_JOBS_FETCH_SUCCEEDED\":\n const {\n scheduledEventJobs: { list },\n } = payload;\n\n newState.scheduledEventJobInfo = list;\n\n // console.log(\n // \"kkk xxx newState.scheduledEventJobInfo\",\n // newState.scheduledEventJobInfo\n // );\n\n return newState;\n\n case \"RESET\":\n console.log(`RESET! - reduceGeneral`);\n return initialStateMqtt; //Always return the initial state\n default:\n return newState;\n }\n}\n\n// processAreaStatuses\nconst processAreaStatuses = (payload) => {\n // update area with transform data\n let newAreaStatus = payload;\n\n const areas = Object.keys(newAreaStatus);\n\n // add transforms to the areaStatus object\n for (const area of areas) {\n if (!_isEmpty(newAreaStatus[area].ref_coord)) {\n newAreaStatus[area].transform = transformUtmToPixels(newAreaStatus[area]);\n newAreaStatus[area].transformUtmToPixels = transformUtmToPixels(\n newAreaStatus[area]\n );\n newAreaStatus[area].transformPixelsToUtm = transformPixelsToUtm(\n newAreaStatus[area]\n );\n\n // add reference points\n const std = standardPtsUtmX(newAreaStatus[area]);\n const local = localPtsX(newAreaStatus[area]);\n newAreaStatus[area].standardPtsUtmX = std;\n newAreaStatus[area].localPtsX = local;\n\n //\n } else {\n console.log(\n `LOADING ERROR: Area '${newAreaStatus[area].id}' Ref_coord is empty. Check mqtt message 'mosquitto_sub -v -t area/${newAreaStatus[area].id}/info'`\n );\n console.log(`LOADING ERROR: newAreaStatus[area]`, newAreaStatus[area]);\n // ref_coord empty - can't process so delete object\n delete newAreaStatus[area];\n }\n }\n\n return newAreaStatus;\n};\n\n// ********************************************************************************\n\n//getAllAreaStatuses\n\n// ********************************************************************************\n\n// reducer used to pass map information and settings\nconst mapStateInitialState = Immutable({\n deleteSelected: [],\n hideSelected: [],\n isDirty: {\n firefly: [],\n namedArea: [],\n area: [],\n },\n});\n\nfunction reduceMapState(state = mapStateInitialState, action = {}) {\n const { type, payload } = action;\n\n // copy existing state\n let newState = { ...state };\n\n let tempArray = [];\n\n switch (type) {\n case \"MAP_SET_DELETE_SELECTIONS_NAMED_AREAS\":\n // #TODO / REVIEW - causes problem with immutable access to nested objects\n console.log(\"FIX THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!\");\n console.log(\"MAP_SET_DELETE_SELECTIONS_NAMED_AREAS\", action.payload);\n tempArray = state.deleteSelected.concat(action.payload);\n return state.setIn([\"deleteSelected\"], Immutable(tempArray));\n case \"MAP_CLEAR_DELETE_SELECTIONS_NAMED_AREAS\":\n // #REVIEW - this is shite but I was having trouble with mutable state. Need to clean this up!\n tempArray = [];\n tempArray = newState.deleteSelected.filter(\n (namedArea) => namedArea.id !== action.payload.id // #REVIEW/TODO - should be action.payload.id as per same below and make common function\n );\n return Immutable(newState).setIn([\"deleteSelected\"], tempArray);\n\n case \"MAP_SET_HIDE_NAMED_AREAS\":\n // #TODO / REVIEW - causes problem with immutable access to nested objects\n console.log(\"FIX THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!\");\n tempArray = state.hideSelected.concat(action.payload);\n return state.setIn([\"hideSelected\"], Immutable(tempArray));\n case \"MAP_CLEAR_HIDE_NAMED_AREAS\":\n // #REVIEW - this is shite but I was having trouble with mutable state. Need to clean this up!\n tempArray = [];\n tempArray = newState.hideSelected.filter(\n (namedArea) => namedArea.id !== action.payload.id // #REVIEW/TODO - see comment above - make common function\n );\n return Immutable(newState).setIn([\"hideSelected\"], tempArray);\n\n case \"MAP_NAMED_AREAS_SET_IS_DIRTY\":\n console.log(\"MAP_NAMED_AREAS_SET_IS_DIRTY\", action.payload);\n return Immutable(\n state.setIn(\n [\"isDirty\", \"namedArea\"],\n state.isDirty.namedArea.concat([action.payload])\n )\n );\n case \"MAP_NAMED_AREAS_CLEAR_IS_DIRTY\":\n // #REVIEW - this is shite but I was having trouble with state corruption. Need to clean this up!\n tempArray = [];\n tempArray = state.isDirty.namedArea.filter(\n (namedArea) => namedArea !== action.payload\n );\n return Immutable(newState).setIn([\"isDirty\", \"namedArea\"], tempArray);\n case \"RESET\":\n console.log(`RESET! - reduceMapState`);\n return mapStateInitialState; //Always return the initial state\n default:\n return state;\n }\n}\n\n// reducer managing outgoing publish messages\nconst publishInitialState = Immutable([]);\n\nfunction reducePublish(state = publishInitialState, action = {}) {\n const { type, payload } = action;\n switch (type) {\n // publish messages\n case \"MQTT_PUBLISH\":\n console.log(\"MQTT_PUBLISH reducer!\", payload);\n return state.concat([action.payload]);\n case \"REMOVE_MQTT_MESSAGE_BY_TOKEN\":\n console.log(\"REMOVE_TOKEN MQTT_PUBLISH payload\", payload);\n // return Immutable(\n // state.asMutable().filter(({ token }) => token !== action.payload)\n // );\n return state;\n case \"CLEAR_MQTT_MESSAGES\":\n console.log(\"CLEAR_MQTT_MESSAGES MQTT_PUBLISH\");\n return publishInitialState;\n case \"REMOVE_MQTT_MESSAGE\":\n return Immutable(\n state.asMutable().filter(({ id }) => id !== action.payload.id)\n );\n case \"RESET\":\n console.log(`RESET! - reducePublish`);\n return publishInitialState; //Always return the initial state\n default:\n return state;\n }\n}\n\n// reducer managing ack messages\nconst ackInitialState = Immutable([]);\n\nfunction reduceAck(state = ackInitialState, action = {}) {\n const { type, payload } = action;\n switch (type) {\n case \"MQTT_ACKS_UPDATE\":\n if (payload !== \"\") {\n //console.log(\"MQTT_ACKS_UPDATE\", JSON.parse(payload));\n return state.concat(payload); //JSON.parse(payload)\n }\n return state;\n case \"REMOVE_ACKS\":\n return Immutable(\n state.asMutable().filter(({ token }) => token !== payload)\n );\n case \"CHECK_RECEIVE_ACKS\":\n console.log(\"isAcksReceived \", payload);\n // process Acks here\n return state;\n case \"CLEAR_ACKS\":\n return ackInitialState;\n case \"RESET\":\n console.log(`RESET! - reduceAck`);\n return ackInitialState; //Always return the initial state\n default:\n return state;\n }\n}\n\nfunction stableOrder(order, items) {\n return Immutable(order.map((k) => items[k]));\n}\n\nexport const getLatestFaultTs = (state) =>\n state.webWorker.general.latestFaultTs;\n\nexport const getMqttMsg = (state) => state.webWorker.general.mqttMsg;\n\nexport const getFaults = (state) => state.webWorker.general.mqttMsg;\n\nexport const getFaultByUpsId = (state, id) => {\n return getMqttMsg(state).find((msg) => msg.id === id);\n};\n\n// railway_application\n\nexport const getExternalTrigger = (state) =>\n state.webWorker.general.externalTrigger;\nexport const getAllExternalTriggerById = (state, id) =>\n state.webWorker.general.externalTrigger[id];\nexport const getAllExternalTrigger = (state) => {\n const byId = state.webWorker.general.externalTrigger;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getButtonTrigger = (state) =>\n state.webWorker.general.buttonTrigger;\nexport const getAllButtonTriggerById = (state, id) =>\n state.webWorker.general.buttonTrigger[id];\nexport const getAllButtonTrigger = (state) => {\n const byId = state.webWorker.general.buttonTrigger;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getMachineStatus = (state) =>\n state.webWorker.general.machineStatus;\nexport const getMachineStatusById = (state, id) =>\n state.webWorker.general.machineStatus[id];\nexport const getAllMachineStatus = (state) => {\n const byId = state.webWorker.general.machineStatus;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getMapState = (state) => state.webWorker.general.mapMessages;\n\n//\nexport const getControllerCoordinates = (state) =>\n state.webWorker.general.controllerCoordinates;\n\nexport const getControllerCoordinatesById = (state, id) => {\n const geoJson = state.webWorker.general.controllerCoordinates;\n if (geoJson === undefined || _isEmpty(geoJson)) return undefined;\n geoJson.getFeaturesByProperty = function (key, value) {\n return this.features.find(function (feature) {\n if (feature.properties[key] === value) {\n return true;\n } else {\n return false;\n }\n });\n };\n const coordinatesUtm = geoJson.getFeaturesByProperty(\"id\", id)?.geometry\n ?.coordinates;\n // transform here from areaStatus information\n // -> coordinatesPixel\n return coordinatesUtm; // <- coordinatesPixel\n};\n\nexport const getControllerCoordinatesByAreaId = (state, id) => {\n const geoJson = state.webWorker?.general?.controllerCoordinates;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.area === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\n// i.e. getAllUPSs = (state)\nexport const getAllControllerStatuses = (state) => {\n const byId = state.webWorker.general.controllerStatuses;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\n// i.e. getUPSById()\nexport const getControllerById = (state, id) =>\n state.webWorker.general.controllerStatuses[id];\n\n// WIP - trash if unused\nexport const getControllerPortsById = (state, id) => {\n const fireflies = getAllFireflyStatuses(state).filter(\n (ff) => ff.getIn([\"topology\", \"ups_id\"]) === id\n );\n\n return fireflies;\n // return getAllFireflyStatuses(state)\n // .filter((ff) => ff.getIn([\"topology\", \"ups_id\"]) === id)\n // .map((ff) => ff.id);\n};\n\n// export const getControllerEmergencyEventSettingsById = (state, id) => {\n// const { emergencyEventSettings } = state.webWorker.general.controllerStatuses[\n// id\n// ]?.topology;\n\n// if (!_isEmpty(emergencyEventSettings)) {\n// let sortEmergencyEventSettings = JSON.parse(\n// JSON.stringify(emergencyEventSettings)\n// );\n// // sort port by id\n// sortEmergencyEventSettings.ports.sort((a, b) => (a.id > b.id ? 1 : -1));\n// return sortEmergencyEventSettings;\n// } else {\n// return undefined;\n// }\n// };\n\nexport const getControllerEmergencyEventSettingsById = (state, id) => {\n return state.webWorker.general.emergencyEventSettings[id];\n};\n\n// export const getControllerTriggerEventSettingsById = (state, id) => {\n// const { triggerEventSettings } = state.webWorker.general.controllerStatuses[\n// id\n// ]?.topology;\n\n// if (!_isEmpty(triggerEventSettings)) {\n// let sortTriggerEventSettings = JSON.parse(\n// JSON.stringify(triggerEventSettings)\n// );\n// // sort port by id\n// sortTriggerEventSettings.ports.sort((a, b) => (a.id > b.id ? 1 : -1));\n// return sortTriggerEventSettings;\n// } else {\n// return undefined;\n// }\n// };\n\nexport const getControllerTriggerEventSettingsById = (state, id) => {\n return state.webWorker.general.triggerEventSettings[id];\n};\n\n// i.e. getUPSIdsForMineLevelId\nexport const getControllerIdsForAreaId = (state, area) => {\n return getAllControllerStatuses(state)\n .filter((ups) => ups.getIn([\"topology\", \"area\"]) === area)\n .map((ups) => ups.id);\n};\n\n// geoJson of fireflies\nexport const getFireflyCoordinates = (state) =>\n state.webWorker.general.fireflyCoordinates;\n\n// coord of particular FF id\nexport const getFireflyCoordinatesById = (state, id) => {\n const geoJson = state.webWorker.general.fireflyCoordinates;\n if (geoJson === undefined || _isEmpty(geoJson)) return undefined;\n geoJson.getFeaturesByProperty = function (key, value) {\n return this.features.find(function (feature) {\n // find -> one id\n if (feature.properties[key] === value) {\n return true;\n } else {\n return false;\n }\n });\n };\n return geoJson.getFeaturesByProperty(\"id\", id)?.geometry?.coordinates;\n};\n\nexport const getFireflyCoordinatesByAreaId = (state, id) => {\n const geoJson = state.webWorker?.general?.fireflyCoordinates;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.area === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getFireflyCoordinatesForcedByAreaId = (state, id) => {\n const geoJson = state.webWorker?.general?.fireflyCoordinates;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.area === id && item.properties.forced === true\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getAllFireflyStatuses = (state) => {\n const byId = state.webWorker.general.fireflyStatuses;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getFireflyById = (state, id) =>\n state.webWorker.general.fireflyStatuses[id];\n\nexport const getFireflyByControllerId = (state, ups_id) => {\n return getAllFireflyStatuses(state).filter(\n (ff) => ff.getIn([\"topology\", \"ups_id\"]) === ups_id\n );\n};\n\nexport const getFireflyIdsForMineLevelId = (state, area) => {\n return getAllFireflyStatuses(state)\n .filter((ff) => ff.getIn([\"topology\", \"area\"]) === area)\n .map((ff) => ff.id);\n};\n\nexport const getFireflyIdsUpdateListByArea = (state, id) => {\n const idArray = state.webWorker?.general?.fireflyIdsUpdateList || [];\n if (idArray !== undefined) {\n return idArray?.filter((item) => item.includes(`${id}:`));\n } else {\n return [];\n }\n};\n\nexport const getFireflyIdsDeleteListByArea = (state, id) => {\n const idArray = state.webWorker?.general?.fireflyIdsDeleteList || [];\n if (idArray !== undefined) {\n return idArray?.filter((item) => item.includes(`${id}:`));\n } else {\n return [];\n }\n};\n\n//\n\nexport const getActiveArea = (state) => state.webWorker.general.activeArea;\n\nexport const getAreaInfos = (state) => state.webWorker.general.areaInfos;\n\nexport const getAllAreaStatuses = (state) => {\n const byId = state.webWorker.general.areaStatuses;\n const keys = Object.keys(byId).sort();\n\n //return stableOrder(keys, byId);\n\n // sort level\n const sortAreas = [...stableOrder(keys, byId)];\n sortAreas.sort((a, b) => a.order - b.order);\n\n return sortAreas;\n};\n\nexport const getAreaStatuses = (state) => {\n return state.webWorker.general.areaStatuses;\n};\n\nexport const getAreaById = (state, id) => {\n return state.webWorker.general.areaStatuses[id];\n};\n\nexport const getAreaStatusesById = (state, id) => {\n return getAllAreaStatuses(state).find((area) => area.id === id);\n};\n\nexport const getIsAreaImagesChanged = (state) => {\n return state.webWorker.general.isAreaImagesChanged;\n};\n\n// #REVIEW - untested\nexport const getAreaByNameSlug = (state, slug) => {\n return getAllAreaStatuses(state).find((level) => toSlug(level.name) === slug);\n};\n\n// #REVIEW - untested\nexport const getAreaBoundsbyId = (state, id) => {\n return state.webWorker.general.areaStatuses[id].image.bounds;\n};\n\n// #REVIEW - untested\nexport const getAreaCentreById = (state, id) => {\n const bounds = getAreaBoundsbyId(state, id);\n const lat = (bounds[0].lat + bounds[1].lat) / 2;\n const lng = (bounds[0].lng + bounds[1].lng) / 2;\n return { lat, lng };\n};\n\n//\nexport const getNamedAreaInfos = (state) =>\n state.webWorker.general.namedAreaInfos;\n\nexport const getNamedAreaInfosById = (state, id) => {\n const geoJson = state.webWorker?.general?.namedAreaInfos;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.id === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getNamedAreaInfosByAreaId = (state, id) => {\n const geoJson = state.webWorker?.general?.namedAreaInfos;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.area === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getNamedAreaInfosByParentId = (state, id) => {\n const geoJson = state.webWorker?.general?.namedAreaInfos;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.parent === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nconst getNamedAreasInNamedAreaGroupByAreaId = (state, id) => {\n const area = getAreaStatusesById(state, id);\n const namedAreaGroup = area?.namedAreaGroup || [];\n\n // get unique namedArea parents from namedAreaGroup\n //\n let namedAreaParentList = [];\n namedAreaGroup.forEach((group) => {\n group.subItems.forEach((level) => {\n level.subItems.forEach((button) => {\n namedAreaParentList.push(button.namedArea.id);\n });\n });\n });\n\n // uniqueAndSortedNamedAreaParentList\n return [...new Set(namedAreaParentList)].sort();\n};\n\n// used to get settings, priorities and other info on the named areas\n// configured in the named area group\nexport const getNamedAreasInfoInNamedAreaGroupByAreaId = (state, id) => {\n const area = getAreaStatusesById(state, id);\n const namedAreaGroup = area?.namedAreaGroup || [];\n\n // get unique namedArea parents from namedAreaGroup\n //\n let namedAreaParentList = [];\n namedAreaGroup.forEach((group) => {\n group.subItems.forEach((level) => {\n level.subItems.forEach((button) => {\n console.log(\n \"xxx getNamedAreasInfoInNamedAreaGroupByAreaId group\",\n group\n );\n console.log(\n \"xxx getNamedAreasInfoInNamedAreaGroupByAreaId level\",\n level\n );\n console.log(\n \"xxx getNamedAreasInfoInNamedAreaGroupByAreaId button\",\n button\n );\n\n namedAreaParentList.push({\n groupLabel: group.label,\n levelLabel: level.label,\n buttonLabel: button.label,\n buttonCustomLabel: button?.settings?.title || \"\", // may not be defined. check for null\n parent: button.namedArea.id,\n priority: button.namedArea.button.priority, // priority comes from the button properties\n permission: button?.settings?.permission || 0, // may not be defined. check for null\n polygonId: button?.id || \"\",\n userRelay: 0, /// userRelay is not saved in the namedAreaGroup - this is added as a default for ....\n });\n });\n });\n });\n\n // uniqueAndSortedNamedAreaParentList\n return [...new Set(namedAreaParentList)].sort();\n};\n\nexport const getButtonPrioritysInNamedAreaGroups = (state) => {\n const areas = getAllAreaStatuses(state);\n\n let buttonPrioritysInNamedAreaGroups = {};\n areas.forEach((area) => {\n const namedAreaGroup = area?.namedAreaGroup || [];\n\n // get unique namedArea parents from namedAreaGroup\n //\n let namedAreaButtonList = [];\n namedAreaGroup.forEach((group) => {\n group.subItems.forEach((level) => {\n level.subItems.forEach((button) => {\n namedAreaButtonList.push({\n id: button.namedArea.button.named_area,\n priority: button.namedArea.button.priority,\n active: button.namedArea.button.active,\n event: button.namedArea.button,\n group: group.id,\n level: level.id,\n });\n });\n });\n });\n\n buttonPrioritysInNamedAreaGroups[area.id] = namedAreaButtonList;\n });\n return buttonPrioritysInNamedAreaGroups;\n};\n\nexport const getButtonPrioritysInNamedAreaGroupByAreaId = (state, id) => {\n const buttonPrioritysInNamedAreaGroups =\n getButtonPrioritysInNamedAreaGroups(state);\n return buttonPrioritysInNamedAreaGroups?.[id];\n};\n\nconst assignDistinctColorToNamedAreasInGroupByAreaId = (state, id) => {\n // array of unique and sorted named areas in the areas\n const namedAreasInNamedAreaGroupByAreaId =\n getNamedAreasInNamedAreaGroupByAreaId(state, id);\n let distinctColorsNamedAreas = {};\n namedAreasInNamedAreaGroupByAreaId.forEach((namedArea, idx) => {\n // if idx exceeds # of available colors start at the beginning again\n distinctColorsNamedAreas[namedArea] =\n distinctColors.length > idx\n ? distinctColors[idx]\n : distinctColors[idx - distinctColors.length];\n });\n return distinctColorsNamedAreas;\n};\n\nexport const getNamedAreaInfosByParentInArray = (\n state,\n array,\n distinctColorsNamedAreas\n) => {\n const geoJson = state.webWorker?.general?.namedAreaInfos;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter((item) =>\n array.includes(item.properties.parent)\n );\n // set namedArea styling to be same per parent\n array.forEach((item, idx) => {\n // get a color based on idx\n\n filteredgeojson.features.forEach((feature) => {\n if (feature.properties.parent === item) {\n feature.properties.style =\n // if idx exceeds # of available colors start at the beginning again\n distinctColorsNamedAreas[item];\n }\n });\n });\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getNamedAreaInfosBySubTypeId = (state, id) => {\n const geoJson = state.webWorker?.general?.namedAreaInfos;\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.sub_type === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getNamedAreaInfosByRegionPreviewByAreaId = (\n state,\n regions,\n id\n) => {\n const namedAreaParents = regions.map((region) => region.spec);\n const distinctColorsNamedAreas =\n assignDistinctColorToNamedAreasInGroupByAreaId(state, id);\n return getNamedAreaInfosByParentInArray(\n state,\n namedAreaParents,\n distinctColorsNamedAreas\n );\n};\n\n// #NOTE - this combines regions into\n// a single multipolygon. The resulting shape cuts out overlapping regions.\n// Not what we want.\n// Instead we need a union of shapes.\n// getNamedAreaParentInfos_MultiPolygon_development\nexport const getNamedAreaParentInfos = (state) => {\n const namedAreas = getAllNamedAreaStatuses(state);\n const uniqueParents = namedAreas\n .map((item) => item.parent)\n .filter((value, index, self) => self.indexOf(value) === index);\n\n const geoJsonNamedAreaByParent = [];\n\n uniqueParents.forEach((uniqueParent, idx) => {\n const nameArray = uniqueParent.split(\":\");\n // if nameArray[1] is undefined then is level wide event\n let name;\n if (nameArray[1] === undefined) {\n name = nameArray[0];\n } else {\n name = nameArray[1];\n }\n\n const namedAreaInfosByParentId = getNamedAreaInfosByParentId(\n state,\n uniqueParent\n );\n let combinedCoords = [];\n let area = \"\";\n let type = \"\";\n let subType = \"\";\n let parent = \"\";\n\n namedAreaInfosByParentId.features.forEach((naInfo, idx) => {\n const {\n properties: {\n area: sameArea,\n type: sameType,\n sub_type: sameSubType,\n parent: sameParent,\n },\n geometry: { coordinates },\n } = naInfo;\n combinedCoords.push(coordinates);\n //\n area = sameArea; // area etc. is the same for each parents. Hack to get it out.\n type = sameType;\n subType = sameSubType;\n parent = sameParent;\n });\n\n // structure geoJSON object\n const geojsonFeature = {\n type: \"Feature\",\n properties: {\n id: uniqueParent,\n name: name,\n area: area,\n type: type,\n sub_type: subType,\n parent: parent,\n },\n geometry: {\n type: \"MultiPolygon\",\n coordinates: combinedCoords,\n },\n };\n\n if (type !== \"LEVEL_WIDE\" && type !== \"ALL_AREAS\") {\n geoJsonNamedAreaByParent.push(geojsonFeature);\n }\n });\n\n return {\n type: \"FeatureCollection\",\n features: geoJsonNamedAreaByParent,\n };\n};\n\nexport const getAllNamedAreaStatuses = (state) => {\n const byId = state.webWorker.general.namedAreaStatuses;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getNamedAreaStatusesByAreaId = (state, area) => {\n return getAllNamedAreaStatuses(state).filter(\n (namedArea) => namedArea.area === area\n );\n};\n\n// returns a combined 'parent' namedArea\nexport const getNamedAreaParentStatusesByAreaId = (state, area) => {\n const namedAreasByAreaId = getNamedAreaStatusesByAreaId(state, area);\n //console.log(\"ppp namedAreasByAreaId\", namedAreasByAreaId);\n const uniqueParents = namedAreasByAreaId\n .map((item) => item.parent)\n .filter((value, index, self) => self.indexOf(value) === index);\n\n // sort the locations so they list in order on the screen\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n const sortedUniqueParents = [...uniqueParents].sort(sortAlphaNum);\n\n // console.log(\"eee uniqueParents\", uniqueParents);\n // console.log(\"eee sortedUniqueParents\", sortedUniqueParents);\n\n let parents = [];\n sortedUniqueParents.forEach(function (uniqueParent, idx) {\n const namedAreaParentInfo = namedAreasByAreaId.find(\n (item) => item.parent === uniqueParent\n );\n\n //console.log(`namedAreaParentInfo`, namedAreaParentInfo);\n\n const {\n area,\n active,\n button,\n type,\n sub_type,\n parent_name: parentName,\n } = namedAreaParentInfo;\n\n const id = uniqueParent;\n const nameArray = uniqueParent.split(\":\");\n\n // if nameArray[1] is undefined then is level wide event\n let name;\n if (parentName.length <= 0) {\n if (nameArray.length < 2) {\n // ALL_AREAS, LEVEL_WIDE named area\n name = `Level Wide (${nameArray[0]})`;\n // exclude ALL_AREAS, LEVEL_WIDE\n // filteredParents[idx] = { ....}\n } else {\n name = nameArray[1];\n // compose new data set\n }\n } else {\n name = parentName;\n }\n\n // massage button properties e.g.\n // icon: \"icon-earthquake0\"\n // color \"green\"\n // ->\n // icon: { color: \"green\", name: \"icon-earthquake0\"}\n //\n // for (let but of button) {\n\n // }\n\n // create button groups\n let groups = new Map();\n\n for (let opt of button) {\n if (!groups.get(opt.group)) {\n groups.set(opt.group, [opt]);\n } else {\n groups.get(opt.group).push(opt);\n }\n }\n\n let groupsArray = [];\n\n for (let operationsValue of groups.values()) {\n groupsArray.push(operationsValue);\n }\n\n // Note:\n // buttons are the same for every named area under a parent group\n // populate the button array by getting the first to match a parent\n\n // compose new data set\n parents[idx] = {\n id: id,\n type: type,\n sub_type: sub_type,\n active: true, // active,\n namedArea: name,\n area: area,\n button: groupsArray,\n };\n });\n\n return parents;\n};\n\nexport const getNamedAreaStatusesById = (state, id) => {\n return state.webWorker.general.namedAreaStatuses[id];\n};\n\n// const sendNamedAreaButtonUpdateByParent = (\n// namedAreaStatuses,\n// parentId,\n// buttons\n// ) => {\n// const namedAreas = Object.values(namedAreaStatuses);\n// const namedAreasByParentId = namedAreas\n// .filter((namedArea) => namedArea.parent === parentId)\n// .sort((a, b) => (a.priority > b.priority ? 1 : -1));\n\n// if (false) {\n// console.log(\"sendNamedAreaButtonUpdateByParent namedAreas\", namedAreas);\n// console.log(\"sendNamedAreaButtonUpdateByParent parentId\", parentId);\n// console.log(\n// \"sendNamedAreaButtonUpdateByParent namedAreasByParentId\",\n// namedAreasByParentId\n// );\n// console.log(\"sendNamedAreaButtonUpdateByParent buttons\", buttons);\n// }\n\n// // send out backwards because controllers overlay based on order received\n\n// let messagePayloads = [];\n\n// namedAreasByParentId.reverse().forEach((namedArea, index) => {\n// let namedAreaClone = JSON.parse(JSON.stringify(namedArea));\n// let newButtons = [];\n\n// //console.log(\"namedAreaClone\", namedAreaClone);\n\n// // massage named area to prep data for sending\n// //\n// // remove from msg\n// delete namedAreaClone.status;\n// delete namedAreaClone.Firefly_List;\n// // change `coordinateUtm` to `shape`\n// let shape;\n// // NOTE - only supports a single polygon shape, not multi-, so get the first shape in coordinates array\n// shape = namedAreaClone.coordinatesUtm[0];\n// // check first point and last should be the same\n// if (shape[0] !== shape[shape.length - 1]) {\n// // or append first to end point to close the polygon ring\n// shape = [...shape, shape[0]];\n// }\n// namedAreaClone.shape = shape;\n// delete namedAreaClone.coordinatesUtm; // remove from msg\n// // change `style` to a string\n// namedAreaClone.style = JSON.stringify(namedAreaClone.style);\n// // update the new buttons with the original area id\n// buttons.forEach((button, idx) => {\n// newButtons[idx] = buttons[idx];\n// newButtons[idx].id = namedArea.id;\n// });\n// namedAreaClone.button = newButtons;\n\n// //console.log(\"namedAreaClone\", namedAreaClone);\n\n// // prepare message token\n// const userSessionIp = getUserSessionIp();\n// const token = messageToken(userSessionIp);\n\n// let updatedNamedArea = {\n// ...namedAreaClone,\n// precanned: 0, // not used ATM\n// token: token,\n// };\n\n// //console.log(\"updatedNamedArea\", updatedNamedArea);\n\n// const namedAreaPayload = {\n// topic: `named_area/${updatedNamedArea.id}/change`,\n// qos: 0,\n// message: updatedNamedArea,\n// retained: false,\n// };\n\n// //console.log(\"namedAreaPayload\", namedAreaPayload);\n\n// messagePayloads.push(namedAreaPayload); // channelBufferPublishMsg(eventPayload, \"MQTT_PUBLISH\");\n// });\n\n// return messagePayloads;\n// };\n\n// ****************************************************************\n//\n// Named area events\n\nexport const getAllAreasButtonState = (state) => {\n let result = 0;\n\n let allAreasObject = state.webWorker.general.namedAreaEventsButtonGroupState[\"ALL_AREAS\"];\n\n if (allAreasObject !== undefined) {\n result = allAreasObject[0];\n }\n\n return result;\n};\n\nexport const getAllNamedAreaEvents = (state) => {\n const byId = state.webWorker.general.namedAreaEvents;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getNamedAreaEventsById = (state, id) => {\n return state.webWorker.general.namedAreaEvents[id];\n};\n\nexport const getNamedAreaEventsByAreaId = (state, area) => {\n return getAllNamedAreaEvents(state).filter((event) => event.area === area);\n};\n\nexport const getNamedAreaEventsByParentId = (state, parentId) => {\n return getAllNamedAreaEvents(state).filter((event) =>\n event.id.includes(parentId)\n );\n};\n\nexport const getNamedAreaEvents = (state) => {\n const namedAreaEvents = state.webWorker.general.namedAreaEvents;\n if (namedAreaEvents !== undefined && !_isEmpty(namedAreaEvents)) {\n return namedAreaEvents;\n } else {\n return {};\n }\n};\n\n// returns a combined 'parent' namedArea\nexport const getNamedAreaEventsParentsByAreaId = (state, area) => {\n const namedAreasEventsByAreaId = getNamedAreaEventsByAreaId(state, area);\n //console.log(\"ppp namedAreasEventsByAreaId\", area, namedAreasEventsByAreaId);\n const uniqueParents = namedAreasEventsByAreaId\n .map((item) => item.parent)\n .filter((value, index, self) => self.indexOf(value) === index);\n\n //console.log(\"ppp uniqueParents\", uniqueParents);\n let parents = [];\n uniqueParents.forEach(function (uniqueParent, idx) {\n const namedAreaEventParentInfo = namedAreasEventsByAreaId.find(\n (item) => item.parent === uniqueParent\n );\n\n const id = uniqueParent;\n const {\n area,\n priority,\n active_color,\n active_alternate_color,\n active_state,\n active,\n button_groups,\n } = namedAreaEventParentInfo;\n\n // compose new data set\n parents[id] = {\n id: id,\n area: area,\n priority: priority,\n active_color: toFireflyColor(active_color),\n active_alternate_color: toFireflyAlternateColor(active_alternate_color),\n active_state: active_state,\n active: active,\n button_groups: button_groups,\n };\n });\n\n return parents;\n};\n\n// event buttons\nexport const getNamedAreaEventButtonGroupState = (state) =>\n state.webWorker.general.namedAreaEventsButtonGroupState;\n\nexport const getNamedAreaEventButtonGroupStateByNamedAreaParentId = (\n state,\n parentId\n) => {\n return state.webWorker.general.namedAreaEventsButtonGroupState[parentId];\n};\n\nexport const getNamedAreaExtTriggerEventInfo = (state) => {\n // convert from [ {area, list}, ] to [ { eventInfo}]\n const areas = state.webWorker.general.namedAreaExtTriggerEventInfo;\n\n let eventInfo = [];\n areas.forEach((area) => {\n area.list &&\n area.list.forEach((item) => {\n // massage keys to naming more suitable to list page\n const {\n id,\n active,\n button_custom_label,\n button_label,\n group_label,\n level_label,\n operator,\n origin,\n parent,\n source,\n reason,\n secure_key,\n priority,\n disable,\n timestamp,\n } = item;\n\n eventInfo.push({\n area: area.area,\n id: id, //parent,\n groupLabel: group_label,\n levelLabel: level_label,\n buttonCustomLabel: button_custom_label,\n buttonLabel: button_label,\n parent,\n source,\n reason,\n operator,\n origin,\n secureKey: secure_key,\n active,\n priority,\n disable,\n timestamp,\n });\n });\n });\n\n return eventInfo;\n};\n\nexport const getNamedAreaScheduledEventInfo = (state) => {\n // convert from [ {area, list}, ] to [ { eventInfo}]\n const areas = state.webWorker.general.namedAreaScheduledEventInfo;\n\n let eventInfo = [];\n areas.forEach((area) => {\n area.list &&\n area.list.forEach((item) => {\n // massage keys to naming more suitable to list page\n const {\n id,\n active,\n button_custom_label,\n button_label,\n group_label,\n level_label,\n operator,\n origin,\n parent,\n source,\n reason,\n secure_key,\n priority,\n disable,\n timestamp,\n } = item;\n\n eventInfo.push({\n area: area.area,\n id: id, //parent,\n groupLabel: group_label,\n levelLabel: level_label,\n buttonCustomLabel: button_custom_label,\n buttonLabel: button_label,\n parent,\n source,\n reason,\n operator,\n origin,\n secureKey: secure_key,\n active,\n priority,\n disable,\n timestamp,\n });\n });\n });\n\n return eventInfo;\n};\n\nexport const getScheduledEventJobInfo = (state) => {\n const jobs = state.webWorker.general.scheduledEventJobInfo;\n\n //console.log(\"xxx getScheduledEventJobInfo jobs\", jobs);\n\n let eventJobInfo = [];\n jobs.forEach((job) => {\n const {\n active,\n area,\n cron,\n cron_active_duration: cronActiveDuration,\n disable,\n event_job_id: eventJobId,\n id: cronId,\n name,\n note,\n password,\n polygon_id: polygonId,\n timestamp,\n user_relay: userRelay,\n info,\n active_job: activeJob,\n } = job;\n\n eventJobInfo.push({\n active,\n activeJob,\n area,\n cron,\n cronActiveDuration,\n disable,\n eventJobId,\n cronId,\n name,\n note,\n password,\n polygonId,\n timestamp,\n userRelay,\n info,\n });\n });\n\n return eventJobInfo;\n};\n\n// *****************************************\n// PUBLISH EVENT EVENTS\n//\n// 'sendNamedAreaEventParent' prepares event messages and prepares the payload for the MQTT message.\n// The payload is concatenated to the 'publish' state of this Webworker reducer. i.e. state.webWorker.general.publish\n//\n// WebWorker (src/components/WebWorker/index.js) ComponentDidUpdate runs periodically (at poll rate),\n// and checks if there are messages to publish in\n// state.webWorker.general.publish (via getAllMqttMessages()).\n//\n// Messages can be published via MQTT (askWebWorker) or via API (saveNewNamedAreaEvent)\n// based on the Config setting `isMqttNotApiPost`\n//\n//\n\nconst sendNamedAreaEventParent = ({\n namedAreaStatuses,\n operation,\n namedAreaEventsButtonGroupState,\n namedAreaEvents,\n active,\n}) => {\n const {\n priority,\n // active_color,\n // active_alternate_color,\n // active_state,\n named_area: parentId,\n relay_active,\n } = operation;\n\n const namedAreas = Object.values(namedAreaStatuses); // namedAreaStatuses\n\n const namedAreasByParentId = namedAreas\n .filter((namedArea) => namedArea.parent === parentId)\n .sort((a, b) => (a.priority > b.priority ? 1 : -1));\n\n const buttonGroupState = namedAreaEventsButtonGroupState[parentId];\n\n // #DEBUG\n const _DEBUG_MSGS = false;\n\n if (_DEBUG_MSGS) {\n console.log(\"sendNamedAreaEventParent namedAreas\", namedAreas);\n console.log(\"sendNamedAreaEventParent parentId\", parentId);\n console.log(\n \"sendNamedAreaEventParent namedAreasByParentId\",\n namedAreasByParentId\n );\n console.log(\"sendNamedAreaEventParent buttonGroupState\", buttonGroupState);\n console.log(\"sendNamedAreaEventParent operation\", operation);\n console.log(\n \"sendNamedAreaEventParent namedAreaEventsButtonGroupState\",\n namedAreaEventsButtonGroupState\n );\n }\n\n // send out backwards because controllers overlay based on order received\n\n let eventPayloads = [];\n\n namedAreasByParentId.reverse().forEach((namedArea, index) => {\n // prepare message token\n const userSessionIp = getUserSessionIp();\n const token = messageToken(userSessionIp);\n\n const active_button = namedArea.button.find(\n (button) => button.priority === priority\n );\n\n if (_DEBUG_MSGS) {\n console.log(\"sendNamedAreaEventParent active_button\", active_button);\n }\n\n let eventMsg = {};\n\n // skip if\n // 1 - there is no button definition for the selected priority\n // 2 - the button is disabled in the named area setup for the button\n if (\n active_button !== undefined &&\n active_button.active // named area has been disabled\n ) {\n // 3 - the button is set to not apply a change to this area\n if (\n active_button.color === \"no_change\" // named area has no effect for this button\n ) {\n // in this case re-send the previous event with an updated 'buttonGroupState'\n\n // #DEBUG\n if (_DEBUG_MSGS) {\n console.log(\n \"sendNamedAreaEventParent buttonActive Single namedAreaEvents[namedArea.id]\",\n namedAreaEvents[namedArea.id]\n );\n }\n\n eventMsg = namedAreaEvents[namedArea.id];\n eventMsg.token = token;\n eventMsg.timestamp = microTime();\n eventMsg.button_groups = JSON.stringify(buttonGroupState);\n //\n // relay_event_active:1\n //eventMsg.relay_event_active\n } else {\n if (_DEBUG_MSGS) {\n console.log(\n \"sendNamedAreaEventParent @eventMsg active_button\",\n active_button\n );\n }\n\n //console.log(\"xxx userSessionIp\", userSessionIp);\n\n eventMsg = {\n id: namedArea.id,\n priority: priority,\n active: active,\n active_color: toFireflyColor(active_button.active_color),\n active_alternate_color: toFireflyAlternateColor(active_button.active_alternate_color),\n active_state: active_button.active_state,\n on_time: active_button.on_time,\n off_time: active_button.off_time,\n train: active_button.train,\n button_groups: JSON.stringify(buttonGroupState),\n timestamp: microTime(),\n precanned: 0, // not used ATM\n relay_event_active: relay_active || 0,\n\n // Set client and operator for the event based on user session creds\n origin: \"CLIENT\",\n operator: userSessionIp || \"session info unknown\",\n token: token,\n };\n }\n\n if (_DEBUG_MSGS) {\n console.log(\n \"sendNamedAreaEventParent @eventMsg eventMsg\",\n JSON.stringify(eventMsg)\n );\n }\n\n const eventPayload = {\n topic: `named_area/${eventMsg.id}/event`,\n qos: 0,\n message: eventMsg,\n retained: true,\n };\n\n eventPayloads.push(eventPayload); // channelBufferPublishMsg(eventPayload, \"MQTT_PUBLISH\");\n }\n });\n\n // #DEBUG\n if (_DEBUG_MSGS) {\n console.log(\"sendNamedAreaEventParent eventPayloads\", eventPayloads);\n }\n\n return eventPayloads;\n};\n\nconst sendNamedAreaEventSingle = (\n namedAreaStatuses,\n operation,\n namedAreaEventsButtonGroupState,\n namedAreaEvents,\n active\n) => {\n // e.g.\n // active: true\n // active_color: \"red\"\n // active_alternate_color: \"off\",\n // active_state: \"on\"\n // alt: \"Level 1\"\n // clickable: true\n // color: \"red\"\n // default: true\n // group: 0\n // hint: \"Level 0\"\n // icon: \"icon-earthquake123\"\n // id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626042755624\"\n // marker: \"RoundMarker\"\n // named_area: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\"\n // off_time: 0\n // on_time: 0\n // priority: 3\n // state: \"on\"\n // title: \"Seismic 1\"\n // train: 0\n // type: \"SEISMIC1_EVENT\"\n\n const {\n priority,\n active: activeButton,\n color,\n active_color,\n active_alternate_color,\n active_state,\n state,\n on_time,\n off_time,\n train,\n named_area: parentId,\n id: namedAreaId, // i.e. event id\n } = operation;\n\n const namedAreas = Object.values(namedAreaStatuses); // namedAreaStatuses\n\n const namedAreasByParentId = namedAreas\n .filter((namedArea) => namedArea.parent === parentId)\n .sort((a, b) => (a.priority > b.priority ? 1 : -1));\n\n // normally when polygons are created the active button group is setup\n let buttonGroupState = namedAreaEventsButtonGroupState[parentId];\n // however if the event is active and there is no button group default to { 0: 1}.\n // This accommodates the case for forced light change where the named area and event are defined but there is no button set.\n if (active && buttonGroupState === undefined) {\n buttonGroupState = { 0: 1 }; // forced light change\n }\n\n if (false) {\n console.log(\"sendNamedAreaEventSingle operation\", operation);\n\n // active: true\n // active_color: \"red\"\n // active_alternate_color: \"off\",\n // active_state: \"on\"\n // alt: \"Level 1\"\n // clickable: true\n // color: \"red\"\n // default: true\n // group: 0\n // hint: \"Level 0\"\n // icon: \"icon-earthquake123\"\n // id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626042755624\"\n // marker: \"RoundMarker\"\n // named_area: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\"\n // off_time: 0\n // on_time: 0\n // priority: 3\n // state: \"on\"\n // title: \"Seismic 1\"\n // train: 0\n // type: \"SEISMIC1_EVENT\"\n\n console.log(\"sendNamedAreaEventSingle namedAreas\", namedAreas);\n\n // 0: {status: \"mqtt\", id: \"DMLZ_Extraction:88175515-d033-4524-a7fb-a11913c1dc7c:1626156898246\", type: \"POLYGON\", name: \"1626156898246\", parent: \"DMLZ_Extraction:88175515-d033-4524-a7fb-a11913c1dc7c\", …}\n // 1: {status: \"mqtt\", id: \"DMLZ_Extraction_BASE\", type: \"LEVEL_WIDE\", name: \"LEVEL_WIDE\", parent: \"DMLZ_Extraction\", …}\n // 2: {status: \"mqtt\", id: \"ALL_AREAS\", type: \"ALL_AREAS\", name: \"ALL_AREAS\", parent: \"ALL_AREAS\", …}\n // 3: {status: \"mqtt\", id: \"ALL_AREAS_BASE\", type: \"LEVEL_WIDE\", name: \"LEVEL_WIDE\", parent: \"ALL_AREAS\", …}\n // 4: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626042755624\", type: \"POLYGON\", name: \"1626042755624\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 5: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626155400253\", type: \"POLYGON\", name: \"1626155400253\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 6: {status: \"mqtt\", id: \"DMLZ_Extraction:96ebaaaa-c85e-4b9b-bd39-0d4f0d36ad42:1626048851076\", type: \"POLYGON\", name: \"1626048851076\", parent: \"DMLZ_Extraction:96ebaaaa-c85e-4b9b-bd39-0d4f0d36ad42\", …}\n // 7: {status: \"mqtt\", id: \"DMLZ_Extraction:4c891f20-de82-45f4-b7ef-b3bb2ed1c5f9:1625717877453\", type: \"POLYGON\", name: \"1625717877453\", parent: \"DMLZ_Extraction:4c891f20-de82-45f4-b7ef-b3bb2ed1c5f9\", …}\n // 8: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626218295018\", type: \"POLYGON\", name: \"1626218295018\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 9: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626218366181\", type: \"POLYGON\", name: \"1626218366181\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 10: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626218556024\", type: \"POLYGON\", name: \"1626218556024\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 11: {status: \"mqtt\", id: \"DMLZ_Extraction:4c891f20-de82-45f4-b7ef-b3bb2ed1c5f9:1626218801483\", type: \"POLYGON\", name: \"1626218801483\", parent: \"DMLZ_Extraction:4c891f20-de82-45f4-b7ef-b3bb2ed1c5f9\", …}\n // length: 12\n\n console.log(\"sendNamedAreaEventSingle parentId\", parentId);\n\n // parentId DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\n\n console.log(\n \"sendNamedAreaEventSingle namedAreasByParentId\",\n namedAreasByParentId\n );\n\n // 0: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626042755624\", type: \"POLYGON\", name: \"1626042755624\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 1: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626155400253\", type: \"POLYGON\", name: \"1626155400253\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 2: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626218295018\", type: \"POLYGON\", name: \"1626218295018\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 3: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626218366181\", type: \"POLYGON\", name: \"1626218366181\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // 4: {status: \"mqtt\", id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1626218556024\", type: \"POLYGON\", name: \"1626218556024\", parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", …}\n // length: 5\n\n console.log(\"sendNamedAreaEventSingle buttonGroupState\", buttonGroupState);\n\n // {0: 3} // denotes button 2 active on 1st group (typically only one group)\n }\n\n // send out backwards because controllers overlay based on order received\n\n let eventPayloads = [];\n\n //namedAreasByParentId.reverse().forEach((namedArea, index) => {\n // const active_button = namedArea.button.find(\n // (button) => button.priority === priority\n // );\n\n const active_button = {\n active: activeButton,\n color,\n active_color,\n active_alternate_color,\n active_state,\n state,\n on_time,\n off_time,\n train,\n };\n\n //console.log(\"sendNamedAreaEventSingle active_button priority\", priority);\n\n // prepare message token\n const userSessionIp = getUserSessionIp();\n const token = messageToken(userSessionIp);\n\n //console.log(\"sendNamedAreaEventSingle token\", token);\n\n let eventMsg = {};\n\n // skip if\n // 1 - the button is disabled in the named area setup for the button\n if (\n active_button !== undefined &&\n active_button.active // named area has been disabled\n ) {\n // 2 - the button is set to not apply a change to this area\n if (\n active_button.color === \"no_change\" // named area has no effect for this button\n // in this case, for a single event, don't do anything\n ) {\n // #DEBUG\n // console.log(\n // \"buttonActive Single namedAreaEvents[namedArea.id]\",\n // namedAreaEvents[namedArea.id]\n // );\n\n eventMsg = namedAreaEvents[namedAreaId]; //namedArea.id\n eventMsg.token = token;\n eventMsg.timestamp = microTime();\n eventMsg.button_groups = JSON.stringify(buttonGroupState);\n } else {\n eventMsg = {\n id: namedAreaId, //namedArea.id,\n priority: priority,\n active: active,\n active_color: toFireflyColor(active_button.active_color),\n active_alternate_color: toFireflyAlternateColor(active_button.active_alternate_color),\n active_state: active_button.active_state,\n on_time: active_button.on_time,\n off_time: active_button.off_time,\n train: active_button.train,\n button_groups: JSON.stringify(buttonGroupState),\n timestamp: microTime(),\n precanned: 0, // not used ATM\n token: token,\n };\n }\n\n const eventPayload = {\n topic: `named_area/${eventMsg.id}/event`,\n qos: 0,\n message: eventMsg,\n retained: true,\n };\n\n eventPayloads.push(eventPayload); // channelBufferPublishMsg(eventPayload, \"MQTT_PUBLISH\");\n }\n //});\n\n console.log(`xxxx sendNamedAreaEventSingle eventPayloads`, eventPayloads);\n\n return eventPayloads;\n};\n\nconst sendNamedAreaEventAllAreas = (\n namedAreaStatuses,\n operation,\n namedAreaEventsButtonGroupState,\n active\n) => {\n // console.log(\n // \"sendNamedAreaEventWholeMine namedAreaStatuses\",\n // namedAreaStatuses\n // );\n\n //console.log(\"sendNamedAreaEventWholeMine operation\", operation);\n\n // console.log(\n // \"sendNamedAreaEventWholeMine namedAreaStatuses\",\n // namedAreaEventsButtonGroupState\n // );\n // console.log(\"sendNamedAreaEventWholeMine active\", active);\n\n const {\n priority,\n active_color,\n active_alternate_color,\n active_state,\n named_area: id,\n state,\n on_time,\n off_time,\n train,\n } = operation;\n\n // prepare message token\n const userSessionIp = getUserSessionIp();\n const token = messageToken(userSessionIp);\n const buttonGroupState = namedAreaEventsButtonGroupState[id];\n\n // Send a named area event equivalent to ALL_AREAS to track the event\n const namedAreaEventAllAreasMsg = {\n id: id,\n priority: priority,\n active: active,\n active_color: toFireflyColor(active_color),\n active_alternate_color: toFireflyAlternateColor(active_alternate_color),\n active_state: active_state,\n on_time: on_time,\n off_time: off_time,\n train: train,\n button_groups: JSON.stringify(buttonGroupState),\n timestamp: microTime(),\n precanned: 0, // not used ATM\n\n // Set client and operator for the event based on user session creds\n origin: \"CLIENT\",\n operator: userSessionIp || \"session info unknown\",\n\n token: token,\n };\n\n const namedAreaEventPayload = {\n topic: `emergency/${namedAreaEventAllAreasMsg.id}/event`,\n qos: 0,\n message: namedAreaEventAllAreasMsg,\n retained: true,\n };\n\n return [namedAreaEventPayload];\n};\n\nexport const getWaitEventTimeout = (state) => state.webWorker.waitEventTimeout;\n\n// SERVER MESSAGES and DEVICE TIMESTAMPS *************************************\n\n//\nexport const getDeviceTimestamps = (state) =>\n state.webWorker.general.deviceTimestamps;\nexport const getTimedOutDevices = (state) =>\n state.webWorker.general.timedOutDevices;\nexport const getServerTimestamp = (state) =>\n state.webWorker.general.serverTimestamp;\nexport const getSystemProcessMsg = (state) =>\n state.webWorker.general.systemProcessMsg;\n\n// ALL DATA *************************\n//\n// Used to update the worker with fetch data\n//\nexport const getAllData = (state) => {\n // const toObject = (arr, key) =>\n // arr?.reduce((a, b) => ({ ...a, [b[key]]: b }), {});\n\n // const areaInfos =\n // toObject(state.webWorker?.general?.areaInfos?.features, \"id\") || {};\n\n // const areaStatuses = state.webWorker?.general?.areaStatuses || {};\n\n // // remove functions, like transforms, before sending data\n // let rawAreaInfos = {};\n // let rawAreaStatuses = {};\n\n // Object.values(areaInfos).forEach((area) => {\n // const {\n // id,\n // geometry,\n // properties: {\n // ceiling,\n // coordinatesUtm,\n // default_color,\n // default_state,\n // floor,\n // image_filename,\n // image_info,\n // name,\n // namedAreaGroup,\n // ref_coord,\n // slug,\n // status = \"api\",\n // },\n // } = area;\n\n // const properties = {\n // ceiling,\n // coordinatesUtm,\n // default_color,\n // default_state,\n // floor,\n // image_filename,\n // image_info,\n // name,\n // namedAreaGroup,\n // ref_coord,\n // slug,\n // status,\n // };\n\n // rawAreaInfos[id] = {\n // geometry,\n // properties: properties,\n // };\n // rawAreaStatuses[id] = properties;\n // });\n\n // const controllerCoordinates =\n // toObject(state.webWorker?.general?.controllerCoordinates?.features, \"id\") ||\n // {};\n // const controllerStatuses = state.webWorker?.general?.controllerStatuses || {};\n // const fireflyCoordinates =\n // toObject(state.webWorker?.general?.fireflyCoordinates?.features, \"id\") ||\n // {};\n // const fireflyStatuses = state.webWorker?.general?.fireflyStatuses || {};\n\n // const namedAreaInfos = state.webWorker?.general?.namedAreaInfos || {};\n // const namedAreaStatuses = state.webWorker?.general?.namedAreaStatuses || {};\n // const namedAreaEvents = state.webWorker?.general?.namedAreaEvents || {};\n\n return {\n // areaStatuses: rawAreaStatuses,\n // areaInfos: rawAreaInfos,\n // controllerCoordinates,\n // controllerStatuses,\n // fireflyCoordinates,\n // fireflyStatuses,\n // namedAreaInfos,\n // namedAreaStatuses,\n // namedAreaEvents,\n areaStatuses: state.webWorker?.general?.areaStatuses,\n areaInfos: state.webWorker?.general?.areaInfos,\n controllerCoordinates: state.webWorker?.general?.controllerCoordinates,\n controllerStatuses: state.webWorker?.general?.controllerStatuses,\n fireflyCoordinates: state.webWorker?.general?.fireflyCoordinates,\n fireflyStatuses: state.webWorker?.general?.fireflyStatuses,\n namedAreaInfos: state.webWorker?.general?.namedAreaInfos,\n namedAreaStatuses: state.webWorker?.general?.namedAreaStatuses,\n namedAreaEvents: state.webWorker?.general?.namedAreaEvents,\n };\n};\n\nexport const getDataFetched = (state) => state.webWorker?.general?.dataFetched;\n\n// ACKS *************************\n\n//\nexport const getAcks = (state) => state.webWorker.ack;\n\nexport const getAckByToken = (state, token) => {\n state.webWorker.ack.filter((ack) => ack.token === token);\n};\n\n// #NOTE\n// see also - src/utils/confirmTokenRxWithRetryAndTimeout.js\n// the difference is this passes in all acks available in this reducer\n//\n\nconst isAckReceivedByTokenAcks = (token, acks) => {\n return new Promise((resolve, reject) => {\n // console.log(\"acks isAckReceived token\", token);\n // console.log(\"acks isAckReceived acks\", JSON.stringify(acks));\n\n // #TODO - have to get updated acks from state HERE!\n // can't pass the acks through as it'll never be updated\n\n const indexInAcks = acks\n .map(function (a) {\n return a.token;\n })\n .indexOf(token);\n\n console.log(\"acks isAckReceived indexInAcks\", indexInAcks, token, acks);\n if (indexInAcks > -1) {\n // found ack\n this.props.removeAcks(token); // delete ack\n resolve(indexInAcks);\n } else {\n reject(indexInAcks);\n // reject(new Error());\n //throw new Error(\"Whoops!\");\n }\n });\n};\n\n// ******************************************************************\n\n//\nexport const getMqttReset = (state) => state.webWorker.general.reset;\n\n//\nexport const getMqttDataLoading = (state) =>\n state.webWorker.general.dataLoading;\n\nexport const getMqttDataLoadingResponseRequestMessageQueue = (state) =>\n state.webWorker.general.dataloadingResponseRequestMessageQueue;\n\n//\nexport const getAllMqttMessages = (state) => state.webWorker.general.publish; //,publish // #REVIEW - change to \"getMqttPublishMessages\"\n\n//\nexport const getNamedAreaDeleteSelections = (state) =>\n state.webWorker.mapState.deleteSelected;\n\nexport const getNamedAreaHideSelections = (state) =>\n state.webWorker.mapState.hideSelected;\n\nexport const getIsDirty = (state) => state.webWorker.mapState.isDirty;\n\n// subset (reduced) of properties for each named area\n// used to directly compare named areas objects excluding geometry etc.\nexport const GetMapNamedAreasReducedProperties = (state) => {\n const namedAreas = state.webWorker?.general?.namedAreaInfos?.features;\n\n let reducedProperties = [];\n\n if (namedAreas !== undefined && !_isEmpty(namedAreas)) {\n namedAreas.forEach(({ properties }, index, arr) => {\n const {\n id,\n name,\n parent,\n origin,\n area,\n priority,\n button,\n coordinatesUtm,\n } = properties;\n\n const reducedProperty = {\n id: id,\n name: name,\n parent: parent,\n origin: origin,\n area: area,\n priority: priority,\n button: button,\n coordinatesUtm: coordinatesUtm,\n };\n\n reducedProperties.push(reducedProperty);\n });\n }\n\n return reducedProperties;\n};\n\nexport default combineReducers({\n general: reduceGeneral,\n //publish: reducePublish,\n mapState: reduceMapState,\n ack: reduceAck,\n});\n","import { channel } from \"redux-saga\";\nimport { put, take, takeEvery, fork } from \"redux-saga/effects\";\n\nexport const downloadFileChannel = channel();\n\nexport const channelBufferPublishMsg = (payload, type) => {\n //console.log(\"putting sent mqtt publish msg to channel buffer ....\", payload);\n downloadFileChannel.put({\n type: type,\n payload: payload,\n });\n};\n\n//https://stackoverflow.com/questions/43031832/how-to-yield-put-in-redux-saga-within-a-callback\n// redux-saga channel\nexport function* watchDownloadFileChannel() {\n try {\n while (true) {\n //console.log(\"watchDownloadFileChannel before take\");\n const action = yield take(downloadFileChannel);\n //console.log(\"watchDownloadFileChannel after take\", action);\n yield put(action);\n //console.log(\"MQTT_PUBLISH watchDownloadFileChannel after put!!!\");\n }\n } catch (error) {\n //console.log(\"MQTT_PUBLISH channel buffer error\", error);\n //yield put(actions.cancelWatch()) // to emit 'CANCEL_WATCH'\n }\n\n // while (true) {\n // const action = yield take(downloadFileChannel);\n // yield put(action);\n // }\n}\n\nfunction* apiSaga() {\n //yield takeEvery(downloadFileChannel, watchDownloadFileChannel);\n yield fork(watchDownloadFileChannel);\n //console.log(\"MQTT_PUBLISH after apiSage takeEvery!!!\");\n}\n\nexport default apiSaga;\n","import Immutable from \"seamless-immutable\";\nimport { createSelector } from \"reselect\";\nimport { combineReducers } from \"redux\";\n\nimport { parseDate } from \"utils/format-date\";\n\nimport {\n getNamedAreaEvents,\n getNamedAreaEventsParentsByAreaId,\n getNamedAreaEventsByParentId,\n} from \"components/WebWorker/reducer\";\n\nimport { channelBufferPublishMsg } from \"apiSaga\";\nimport * as Api from \"api/api\";\nimport { microTime } from \"utils/microTime\";\n\nconst activeOpsInitialState = Immutable({\n remoteButtonClick: [],\n});\n\nfunction reduceActiveOps(state = activeOpsInitialState, action = {}) {\n const newState = { ...state };\n\n const { type, payload } = action;\n switch (type) {\n case `UPDATE_REMOTE_BUTTON_CLICK`:\n newState.remoteButtonClick = payload.array;\n return newState;\n\n case \"REMOVE_REMOTE_BUTTON_CLICK\":\n let newRemoteButtonClick = [...newState.remoteButtonClick];\n newRemoteButtonClick = newRemoteButtonClick.filter(\n (item) => item !== payload.id\n );\n newState.remoteButtonClick = newRemoteButtonClick;\n return newState;\n case \"CLEAR_REMOTE_BUTTON_CLICK\":\n return activeOpsInitialState;\n default:\n return newState;\n }\n}\n\nexport default combineReducers({\n activeOpsChanges: reduceActiveOps,\n});\n\nexport const getRemoteButtonClick = (state) => {\n return state.operationalChanges?.activeOpsChanges?.remoteButtonClick;\n};\n\n//const getStateSlice = (state) => state.operationalChanges;\n\nexport const isActiveEvent = (state, props) => {\n const namedAreaId = props?.area?.spec;\n const areaId = props?.area?.id;\n const namedAreaPriority = props?.operation?.priority;\n\n // console.log(\"isActiveEvent namedAreaId\", namedAreaId);\n // console.log(\"isActiveEvent areaId\", areaId);\n // console.log(\"isActiveEvent namedAreaPriority\", namedAreaPriority);\n\n if (\n namedAreaId !== undefined &&\n namedAreaPriority !== undefined\n //&& areaId !== \"ALL_AREAS\" // #REVIEW - how to handle ALL_AREAS ?????????\n ) {\n // #REVIEW - better as a selector? quicker?\n\n const namedAreaEventsParents = getNamedAreaEventsParentsByAreaId(\n state,\n areaId\n );\n\n //console.log(\"isActiveEvent namedAreaEventsParents\", namedAreaEventsParents);\n\n if (namedAreaEventsParents) {\n const events = Object.keys(namedAreaEventsParents);\n\n //console.log(\"isActiveEvent events\", events);\n if (events.includes(namedAreaId)) {\n // console.log(\n // \"isActiveEvent namedAreaEventsParents[namedAreaId]\",\n // namedAreaEventsParents[namedAreaId]\n // );\n const { priority, active } = namedAreaEventsParents[namedAreaId];\n if (priority === namedAreaPriority && active) {\n return true;\n }\n }\n }\n }\n return false;\n};\n\n// #WIP - left as-is\nexport const getActiveForcedOverride = (state, fireflyId) => {\n const activeChanges = []; // disabled // getActiveOperationalChanges(state);\n\n for (var i = 0; i < activeChanges.length; i++) {\n const change = activeChanges[i];\n const {\n createdFrom: { area, operation },\n } = change;\n if (\n area.type === \"SINGLE_LIGHT\" &&\n operation.type === \"CUSTOM\" &&\n area.spec === fireflyId\n ) {\n return change;\n }\n }\n return null;\n};\n","export function cancelNamedAreaEvent(operation) {\n //console.log(`cancelNamedAreaEvent operation`, operation);\n return { type: \"DEACTIVATE_NAMED_AREA_EVENT\", payload: { operation } };\n}\n\nexport function activateNamedAreaEvent(operation) {\n //console.log(`activateNamedAreaEvent processClick operation`, operation);\n return { type: \"ACTIVATE_NAMED_AREA_EVENT\", payload: { operation } };\n}\n\nexport function activateNamedAreaEventSingle(operation) {\n //console.log(`activateNamedAreaEventSingle processClick operation`, operation);\n return { type: \"ACTIVATE_NAMED_AREA_EVENT_SINGLE\", payload: { operation } };\n}\n\nexport function updateButtonGroupState(buttons) {\n //console.log(\"updateButtonGroupState buttons\", buttons);\n return { type: \"UPDATE_BUTTONS_GROUP_STATE\", payload: { buttons } };\n}\n\nexport function waitEventTimeOut(action) {\n return { type: \"WAIT_EVENT_TIMEOUT\", payload: { action } };\n}\n\nexport function updateRemoteButtonClick(array) {\n return { type: \"UPDATE_REMOTE_BUTTON_CLICK\", payload: { array } };\n}\n\nexport function removeRemoteButtonClick(id) {\n return { type: \"REMOVE_REMOTE_BUTTON_CLICK\", payload: { id } };\n}\n\nexport function clearRemoteButtonClick() {\n return { type: \"CLEAR_REMOTE_BUTTON_CLICK\" };\n}\n\n// ******************\n// OLD\n// *****************\n\n// NOT USED\nexport function fetchActiveOperationalChanges() {\n return { type: \"FETCH_OPERATIONAL_CHANGES_REQUESTED\" };\n}\n\n// NOT USED\nexport function cancelOperationalChange(id) {\n return { type: \"DEACTIVATE_OPERATIONAL_CHANGE\", payload: { id } };\n}\n\n// NOT USED\nexport function fetchPrecannedOperations() {\n return { type: \"FETCH_PRECANNED_OPERATIONS_REQUESTED\" };\n}\n\n// NOT USED\nexport function buildActivateChange(area, operation) {\n return () => {\n return {\n type: \"ACTIVATE_OPERATIONAL_CHANGE\",\n payload: { area, operation },\n };\n };\n}\n\n// NOT USED\nexport function toggleForcedColor(id, color) {\n console.log(\"toggleForcedColor\", id, color);\n return {\n type: \"TOGGLE_FORCED_COLOR\",\n payload: { id, color },\n };\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { formatDateRelativeNow } from \"utils/format-date\";\n\nimport { Table, Container, Button } from \"semantic-ui-react\";\nimport BasicTable from \"components/BasicTable\";\nimport { getActiveOperationalChanges } from \"OperationalChanges/reducer\";\nimport { cancelOperationalChange } from \"OperationalChanges/actions\";\n\nfunction HeaderRow() {\n return (\n \n Id\n Description\n Started\n Created by\n Actions\n \n );\n}\n\nlet ItemRow = ({\n item,\n error = false,\n wholeRowMessage,\n cancelOperationalChange,\n ...props\n}) => {\n if (wholeRowMessage) {\n return (\n \n {wholeRowMessage}\n \n );\n }\n\n const opsChange = item;\n return (\n \n {opsChange.id}\n {opsChange.description}\n {formatDateRelativeNow(opsChange.createdAt)}\n {opsChange.createdBy}\n \n cancelOperationalChange(opsChange.id)}\n />\n \n \n );\n};\nItemRow = connect(null, { cancelOperationalChange })(ItemRow);\n/*\nclass ActiveOperationalChangesList extends Component {\n render () {\n const { activeChanges } = this.props\n return (\n \n

Active Changes

\n item.id}\n />\n
\n )\n }\n}*/\n\nclass ActiveOperationalChangesList extends Component {\n render() {\n const { activeChanges } = this.props;\n return ;\n }\n}\n\nfunction mapStateToProps(state) {\n return {\n activeChanges: null, // set to null as not used //getActiveOperationalChanges(state)\n };\n}\n\nexport default connect(mapStateToProps)(ActiveOperationalChangesList);\n","import React from \"react\";\n\nexport const MineLevelContext = React.createContext();\n\n// This function takes a component...\nexport function withMineLevel(Component) {\n // ...and returns another component...\n return function MineLevelComponent(props) {\n // ... and renders the wrapped component with the context theme!\n // Notice that we pass through any additional props as well\n return (\n \n {(value) => (\n \n )}\n \n );\n };\n}\n\nexport const UPSControllerContext = React.createContext();\n\n// This function takes a component...\nexport function withUPS(Component) {\n // ...and returns another component...\n return function UPSComponent(props) {\n // ... and renders the wrapped component with the context theme!\n // Notice that we pass through any additional props as well\n return (\n \n {(ups) => }\n \n );\n };\n}\n","import Immutable from \"seamless-immutable\";\nimport toSlug from \"utils/toSlug\";\nimport { createSelector } from \"reselect\";\n\nimport L from \"leaflet\";\n\nconst initialState = Immutable({ byId: {}, order: [] });\n\nexport default function reduce(state = initialState, action = {}) {\n switch (action.type) {\n // case \"MINE_LEVELS_FETCH_SUCCEEDED\":\n // console.log(\n // `MQTT_AREA_STATUSES_UPDATE MINE_LEVELS_FETCH_SUCCEEDED`,\n // action.payload\n // );\n\n // return Immutable(action.payload);\n\n default:\n return state;\n }\n}\n\nexport const getAllMineLevels = createSelector(\n (state) => state.mineLevels,\n (mineLevels) =>\n Immutable(mineLevels.order.map((id) => mineLevels.getIn([\"byId\", id])))\n);\n\nexport const getMineLevelById = (state, levelId) => {\n return state.mineLevels.byId[levelId];\n // return getAllMineLevels(state).find(level => level.id === levelId)\n};\n\nexport const getMineLevelById_new = (state, levelId) => {\n const result = state.webWorker.general.areaStatuses[levelId];\n return result;\n};\n\nexport const getMineLevelByNameSlug = (state, slug) => {\n return getAllMineLevels(state).find((level) => toSlug(level.name) === slug);\n};\n\nexport const getMineLevelBounds = createSelector(\n getMineLevelById,\n (mineLevel) => mineLevel.image.bounds\n);\n\n// #WIP #TODO\n// this is used a lot - centralise!!!!!\nvar yx = L.latLng;\nvar xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n};\n\nexport const getMineLevelBounds_new = createSelector(\n getMineLevelById_new,\n (mineLevel) => {\n const { width, height } = mineLevel?.image_info || { width: 0, height: 0 };\n const img = [width, height];\n const bounds = L.latLngBounds([xy(0, 0), xy(img)]);\n return bounds;\n }\n);\n\nexport const getMineLevelCentre = createSelector(\n getMineLevelBounds,\n (bounds) => {\n const lat = (bounds[0].lat + bounds[1].lat) / 2;\n const lng = (bounds[0].lng + bounds[1].lng) / 2;\n return { lat, lng };\n }\n);\n\nexport const getMineLevelTemporaryCoordsProvider = (upsLatLng) => {\n //console.log(\"getMineLevelTemporaryCoordsProvider\", upsLatLng);\n return createSelector(getMineLevelBounds_new, (bounds) => {\n //console.log(\"getMineLevelTemporaryCoordsProvider bounds\", bounds);\n const b = bounds; // L.latLngBounds(bounds);\n const latAbs = Math.abs(b.getNorth() - b.getSouth());\n const lngAbs = Math.abs(b.getEast() - b.getWest());\n const latDelta = latAbs / 200; // 50\n const lngDelta = lngAbs / 200; // 50\n\n const latRef = upsLatLng.lat !== undefined ? upsLatLng.lat : b.getNorth();\n const lngRef = upsLatLng.lng !== undefined ? upsLatLng.lng : b.getWest();\n const latStart = latRef - 1 * latDelta;\n const lngStart = lngRef + 1 * lngDelta;\n\n // console.log(\n // \"getMineLevelTemporaryCoordsProvider latStart,lngStart \",\n // latStart,\n // lngStart\n // );\n\n // const latStart = b.getNorth() - 10 * latDelta;\n // const lngStart = b.getWest() + 10 * lngDelta;\n\n return {\n ups: () => ({ lat: latStart, lng: lngStart }),\n firefly: (portNumber, position) => {\n portNumber = asNumber(portNumber);\n position = asNumber(position);\n return {\n lat: latStart + portNumber * latDelta,\n lng: lngStart + position * lngDelta,\n };\n },\n };\n });\n};\n\nexport const makeTemporaryCoordsFactory = (state) => {\n // console.log(\"makeTemporaryCoordsFactory\");\n // console.log(\n // \"state.webWorker.general.areaInfos\",\n // state.webWorker.general.areaInfos\n // );\n // console.log(\n // \"state.webWorker.general.areaInfos\",\n // state.webWorker.general.areaInfos.features.map(\n // (feature) => feature.properties.id\n // )\n // );\n\n const ZeroProvider = {\n ups: () => ({ lat: 0, lng: 0 }),\n firefly: () => ({ lat: 0, lng: 0 }),\n };\n\n // const providers = state.mineLevels.order.reduce((acc, id) => {\n // acc[id] = getMineLevelTemporaryCoordsProvider(state, id);\n // return acc;\n // }, {});\n\n const passUpsPosition = (upsLatLng) => {\n const areaArray = state.webWorker.general.areaInfos.features.map(\n (feature) => feature?.properties?.id\n );\n return areaArray.reduce((acc, id) => {\n // return state.mineLevels.order.reduce((acc, id) => {\n acc[id] = getMineLevelTemporaryCoordsProvider(upsLatLng)(state, id);\n return acc;\n }, {});\n };\n\n return {\n ForMineLevelId: (id, upsLatLng) => {\n const providers = passUpsPosition(upsLatLng);\n return providers[id] || ZeroProvider;\n },\n };\n};\n\nfunction asNumber(n) {\n switch (typeof n) {\n case \"string\":\n return Number.parseFloat(n);\n default:\n return n;\n }\n}\n","export function fetchMineLevels() {\n return { type: \"MINE_LEVELS_FETCH_REQUESTED\" };\n}\n\nexport function saveNewMineLevel(payload) {\n return { type: \"SAVE_NEW_MINE_LEVEL\", payload };\n}\n\nexport function updateMineLevel(payload) {\n return { type: \"UPDATE_MINE_LEVEL\", payload };\n}\n\n// same ...\n// #WIP #TODO - change all `mine level` to `area`\n\nexport function deleteMineLevel(payload) {\n return { type: \"DELETE_MINE_LEVEL\", payload };\n}\n\nexport function deleteArea(payload) {\n return { type: \"DELETE_MINE_LEVEL\", payload };\n}\n","import Immutable from \"seamless-immutable\";\nimport { LOCATION_CHANGE } from \"react-router-redux\";\n\nconst initialState = Immutable([]);\n\nexport default function reduce(state = initialState, action = {}) {\n switch (action.type) {\n case \"CONTROL_CHANNEL_ESTABLISHED\":\n return Immutable(\n state.asMutable().filter(({ id }) => id !== \"control-channel\")\n );\n case \"CONTROL_CHANNEL_LOST\":\n return state.concat([\n {\n id: \"control-channel\",\n header: \"Control lost\",\n content: \"Server has lost connection to MQTT broker\",\n warning: true,\n // #NOTE - removed size to be consistent with other Flash messages. Search for `addWarningFlashMessageIdColor`\n //size: \"small\",\n },\n ]);\n\n case \"SERVER_CONNECTION_OPENED\":\n console.log(\"SERVER_CONNECTION_OPENED <--------------------------- 😎\");\n return Immutable(\n state.asMutable().filter(({ id }) => id !== \"server-connection\")\n );\n case \"SERVER_CONNECTION_CLOSED\":\n console.log(\"SERVER_CONNECTION_CLOSED <---------------------------- 😫\");\n const closedConnectionDisplayed = state.some(\n ({ id }) => id === \"server-connection\"\n );\n\n if (!closedConnectionDisplayed) {\n return state.concat([\n {\n id: \"server-connection\",\n header: \"Connection to server lost\",\n content: \"The computer has lost connection to the server\",\n warning: true,\n // #NOTE - removed size to be consistent with other Flash messages. Search for `addWarningFlashMessageIdColor`\n //size: \"small\",\n },\n ]);\n } else {\n return state;\n }\n\n case \"ADD_FLASH_MESSAGE\":\n //console.log(\"ADD_FLASH_MESSAGE\");\n return state.concat([action.payload]);\n\n case \"REMOVE_FLASH_MESSAGE\":\n //console.log(\"REMOVE_FLASH_MESSAGE\");\n return Immutable(\n // state.asMutable().filter(({ id }) => id !== action.payload.id)\n state.asMutable().filter(({ id }) => !id.includes(action.payload.id))\n );\n case \"CLEAR_FLASH_MESSAGES\":\n return initialState;\n case LOCATION_CHANGE: // location change clears error message...hmmmm\n const tempStr =\n \"#REVIEW - LOCATION_CHANGE - would normally reset errors to initialState. Disabled to retain across pages\";\n console.log(\"FlashMessages/reducer: \", tempStr);\n return state;\n\n case \"RESET\":\n console.log(\"RESET! - FlashMessages\");\n return initialState; //Always return the initial state\n default:\n return state;\n }\n}\n\nexport function getAllMessages(state) {\n return state.flashMessages;\n}\n","import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { connect } from \"react-redux\";\nimport { Message, Popup } from \"semantic-ui-react\";\n\nimport { getAllMessages } from \"FlashMessages/reducer\";\n\nimport MediaQuery from \"react-responsive\";\n\nimport { removeFlashMessage } from \"FlashMessages/actions\";\nimport { strings } from \"components/App/localisation\";\n\nclass FlashMessagesList extends Component {\n static propTypes = {\n messages: PropTypes.array,\n };\n\n render() {\n let { messages } = this.props;\n\n // This is WIP ....\n // The idea is to truncate the messages to appear on one line only so the text does not wrap.\n\n // Need to keep a long version for the popup tooltip\n let addLongToMessages = [];\n messages.forEach(function (value, idx) {\n const contentLong = value.content;\n addLongToMessages[idx] = {\n ...value,\n contentLong: contentLong,\n }; // spread out the object and update 'content' to be truncated to same length as header with trailing ...\n });\n messages = addLongToMessages;\n\n // Make a version of messages which strips out the content line leaving only the header\n // this is used when multiple messages are displayed in the same line\n let miniMessages = [];\n messages.forEach(function (value, idx) {\n const miniMsg =\n value.content.substring(0, value.header.length * 1.5) + \" ...\"; // content line is a multiple of the header text plus ...\n miniMessages[idx] = { ...value, content: miniMsg }; // spread out the object and update 'content' to be truncated to same length as header with trailing ...\n });\n\n // show the mini message version if there is more than one message box\n if (messages.length - 1) {\n messages = miniMessages;\n }\n\n return (\n <>\n \n {messages.map(({ id, contentLong, ...rest }) => {\n return (\n
\n {\n this.props.removeFlashMessage(id);\n }}\n {...rest}\n />\n }\n />\n
\n );\n })}\n
\n \n
\n {messages.map(({ id, contentLong, ...rest }) => {\n return (\n \n {\n this.props.removeFlashMessage(id);\n }}\n />\n }\n />\n
\n );\n })}\n \n
\n \n );\n }\n}\n\nfunction mapStateToProps(state) {\n return { messages: getAllMessages(state) };\n}\n\nexport default connect(mapStateToProps, { removeFlashMessage })(\n FlashMessagesList\n);\n","import React from \"react\";\nimport L from \"leaflet\";\nimport \"leaflet/dist/leaflet.css\";\nimport { Map, ScaleControl, TileLayer } from \"react-leaflet\";\n\nimport { withMineLevel, MineLevelContext } from \"ApplicationContexts\";\nimport { getMineLevelById } from \"MineLevels/reducer\";\nimport { connect } from \"react-redux\";\n\nconst DEFAULT_MAP_STYLE = {\n height: \"600px\",\n width: \"100%\",\n position: \"relative\",\n zIndex: 0,\n};\nfunction SimpleCRSImageMap({ ...props }) {\n const {\n imageInfo,\n // HACKfix: Use zIndex to stop leaflet map from being above the Semantic-UI dropdown menus!\n style,\n center = [0, 0],\n } = props;\n const { minZoom, bounds, tilepath } = imageInfo;\n const maxBounds = L.latLngBounds(bounds).pad(0.4);\n\n console.log(\"Map - SimpleCRSImageMap: imageInfo \", imageInfo);\n console.log(\"Map - maxBounds\", maxBounds);\n console.log(\"Map - bounds\", bounds);\n\n var yx = L.latLng;\n var xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n };\n console.log(\"xy(bounds)\", xy(bounds));\n\n return (\n {\n if (r) {\n const minZoom = r.leafletElement.getMinZoom();\n r.leafletElement.setMinZoom(0); // MUST set this prior to calculation\n const minZoomCalced = r.leafletElement.getBoundsZoom(bounds, false);\n if (minZoomCalced !== minZoom) {\n r.leafletElement.fitBounds(bounds);\n }\n r.leafletElement.setMinZoom(minZoomCalced);\n r.leafletElement.setMaxZoom(23);\n }\n }}\n center={center}\n bounds={bounds} // sets initial viewport only\n maxBounds={maxBounds}\n attributionControl={false} // not dynamic\n key={`mapMinZoom-${minZoom}`} // include non-dynamic props to force react re-render\n >\n \n {props.children}\n \n \n );\n}\n\nexport function MineLevelMap({ ...props }) {\n const { error, image } = props.mineLevel;\n if (error) {\n return
{error}
;\n }\n\n //console.log(\"MineLevelMap: image \", JSON.stringify(image));\n\n return (\n \n {props.children}\n \n );\n}\n\nconst MineLevelMapWithContext = withMineLevel(MineLevelMap);\nexport default MineLevelMapWithContext;\n\nfunction MineLevelMapViaContext({ mineLevel, ...props }) {\n return (\n \n \n \n );\n}\nexport const MineLevelMapById = connect((state, props) => {\n let mineLevel = getMineLevelById(state, props.mineLevelId);\n if (mineLevel === undefined) {\n mineLevel = { error: \"Unable to find area\" };\n }\n return {\n mineLevel,\n };\n})(MineLevelMapViaContext);\n","const SEMANTIC_DEFAULTS = {\n red: \"#DB2828\",\n orange: \"#F2711C\",\n yellow: \"#FBBD08\",\n amber: \"#FBBD08\", // IOT Addition\n olive: \"#B5CC18\",\n green: \"#21BA45\",\n teal: \"#00B5AD\",\n blue: \"#2185D0\",\n violet: \"#6435C9\",\n purple: \"#A333C8\",\n pink: \"#E03997\",\n brown: \"#A5673F\",\n grey: \"#767676\",\n black: \"#1B1C1D\",\n off: \"#1B1C1D\", // IOT Addition\n white: \"white\", // IOT Addition\n};\n\nfunction getSemanticColor(color, fallback = \"black\") {\n const semantic = SEMANTIC_DEFAULTS[color.toLowerCase()];\n if (semantic) {\n return semantic;\n }\n return SEMANTIC_DEFAULTS[fallback.toLowerCase()];\n}\n\nexport default getSemanticColor;\n\nexport function getEquivalentSemanticColorName(color) {\n return {\n off: \"black\",\n white: \"grey\",\n green: \"green\",\n red: \"red\",\n amber: \"orange\",\n orange: \"orange\",\n blue: \"blue\",\n }[color.toLowerCase()];\n}\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nfunction DeviceName({ id, name, error, ...props }) {\n if (error) {\n return (\n \n {error} - {id}\n \n );\n }\n if (name) {\n return (\n \n {name} ({id})\n \n );\n }\n return {id};\n}\n\nDeviceName.propTypes = {\n id: PropTypes.string.isRequired,\n name: PropTypes.string,\n error: PropTypes.string\n};\n\nexport default DeviceName;\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { Link } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\n\n//import { getFireflyById } from 'UPSPanelControllers/reducer'\nimport { getFireflyById } from \"components/WebWorker/reducer\";\n\nexport function FireflyLink({ id, notFound, ...props }) {\n let to = `/admin/firefly/${id}`;\n if (notFound) {\n to = \"#\";\n }\n return {props.children};\n}\n\nFireflyLink.propTypes = {\n id: PropTypes.string.isRequired,\n notFound: PropTypes.bool,\n};\n\nconst mapStateToProps = (state, props) => {\n const { id } = props;\n const ups = getFireflyById(state, id);\n return { id, notFound: !ups };\n};\n\nexport default connect(mapStateToProps)(FireflyLink);\n","// based on\n// src/admin/firefly/FireflyLightStatus.js\n// src/admin/firefly/FireflyStatusSummary.js\n// #REVIEW - break up reports into smaller components\n//\nimport React from \"react\";\n\nimport { connect } from \"react-redux\";\n//import { getFireflyById } from \"UPSPanelControllers/reducer\";\nimport { getFireflyById } from \"components/WebWorker/reducer\";\n\nimport { Table, Button, Grid, Icon, Popup } from \"semantic-ui-react\";\n\nimport {\n formatDateShort,\n formatDateRelativeNow,\n parseDate,\n formatDuration,\n} from \"utils/format-date\";\n\nimport { getEquivalentSemanticColorName } from \"colorpalette\";\n\nfunction FireflyLightChangeStatus({\n id,\n error,\n color,\n ff,\n isNotResponding,\n lastCommand,\n}) {\n if (error) {\n return
{error}
;\n }\n\n const { timestamp } = ff; // lastStatusReport\n if (!timestamp) {\n //lastStatusReport\n return
No status report available
;\n }\n\n //const { timeReceived, device } = lastStatusReport;\n const timeRxd = parseDate(timestamp);\n // let uptime = \"???\";\n // if (device) {\n // let up = device.uptime || device.up_time || uptime;\n // if (typeof up === \"string\") {\n // up = Number.parseFloat(up);\n // }\n // if (up) {\n // uptime = formatDuration(up);\n // }\n // }\n\n // #REVIEW - disabled until can review need\n let responseIndicator = ;\n if (isNotResponding) {\n responseIndicator = (\n \n \n

\n Has not processed\n
\n last command\n

\n \n }\n flowing\n hoverable\n >\n
{JSON.stringify(lastCommand, null, 2)}
\n \n );\n }\n\n // if there is a lastCommand compose a row to show the target color\n //\n let lastCommandColor;\n let transitionIndicatorIcon;\n let lastCommandRow;\n // #REVEW #TODO\n // work out a method to replace last command\n // for the moment force display of last info\n if (true) {\n // lastCommand\n const { plan: cmdColor } = color; // lastCommand.settings;\n lastCommandColor = (\n \n );\n //transitionIndicatorIcon = ;\n transitionIndicatorIcon = Requested Color;\n lastCommandRow = (\n \n {transitionIndicatorIcon}\n {lastCommandColor}\n \n );\n }\n\n return (\n \n \n \n \n \n {/* \n ID\n {id}\n */}\n \n Latest Report\n \n {formatDateShort(timeRxd)} (\n {formatDateRelativeNow(timeRxd, new Date())})\n \n \n \n Reported Color\n \n \n \n \n {lastCommandRow}\n \n
\n
\n {/* \n {responseIndicator}\n */}\n
\n
\n );\n}\n\nfunction mapStateToProps(state, ownProps) {\n const { id } = ownProps;\n const ff = getFireflyById(state, id);\n\n //console.log(\"FireflyLightChangeStatus\", ff);\n\n if (!ff || !ff.timestamp) {\n // lastStatusReport -> timestamp\n return { error: \"No light information (FireflyLightChangeStatus - #WIP)\" };\n }\n\n let color = \"unknown\",\n brightness = 100,\n on_time = 0,\n off_time = 0,\n offset = 0,\n isNotResponding = false,\n lastCommand = null;\n\n if (ff && ff.timestamp) {\n // lastStatusReport\n ({\n color,\n brightness = 100,\n on_time = 0,\n off_time = 0,\n // offset = 0, // No longer used\n } = ff.light); // ff.lastStatusReport.light\n\n // compare last command and current status\n // originally compared all settings. Changed to just compare color\n\n //\n // if (\n // ff.lastCommand &&\n // hasDifferentColorSettings(\n // ff.lastCommand.settings,\n // ff.lastStatusReport.light\n // )\n // ) {\n // isNotResponding = true;\n // lastCommand = ff.lastCommand;\n // }\n }\n\n return {\n id,\n ff,\n error: ff ? undefined : \"No FireFly for id\",\n color,\n brightness,\n on_time,\n off_time,\n offset,\n isNotResponding,\n lastCommand,\n };\n}\n\n// originally compared all settings. Changed to just compare color\nfunction hasDifferentLightSettings(a, b) {\n return (\n a.color !== b.color ||\n a.brightness !== b.brightness ||\n a.on_time !== b.on_time ||\n a.off_time !== b.off_time ||\n a.offset !== b.offset\n );\n}\n\nfunction hasDifferentColorSettings(a, b) {\n return a.color !== b.color;\n}\n\nexport default connect(mapStateToProps)(FireflyLightChangeStatus);\n","import React from \"react\";\nimport DeviceName from \"components/DeviceName\";\nimport FireflyLink from \"admin/firefly/FireflyLink\";\nimport FireflyLightChangeStatus from \"../admin/firefly/FireflyLightChangeStatus\";\n\nimport { connect } from \"react-redux\";\n//import { getFireflyById } from \"UPSPanelControllers/reducer\";\nimport { getFireflyById } from \"components/WebWorker/reducer\";\nimport { isUserSuper, isUserAdmin } from \"auth/reducer\";\n\nimport { Icon } from \"semantic-ui-react\";\n\nconst Component = ({ includeLink, ...props }) => {\n if (includeLink) {\n return (\n
\n
\n \n \n \n
\n {/*
\n \n \n \n
*/}\n
\n {/* \n \n */}\n
\n
\n );\n }\n return ;\n};\n\nconst mapStateToProps = (state, props) => {\n const { id } = props;\n const obj = getFireflyById(state, id);\n\n if (obj) {\n const statusTimeReceived = obj.lastStatusReport\n ? obj.lastStatusReport.timeReceived\n : \"\";\n const statusColor = obj.lastStatusReport\n ? obj.lastStatusReport.light.color\n : \"\";\n const cmdTimeSent = obj.lastCommand ? obj.lastCommand.updated : \"\";\n const cmdColor = obj.lastCommand ? obj.lastCommand.settings.color : \"\";\n\n return {\n id,\n name: obj.name,\n includeLink: isUserSuper(state) || isUserAdmin(state),\n statusTimeReceived,\n statusColor,\n cmdTimeSent,\n cmdColor,\n };\n }\n return {\n id,\n error: \"no FireFly for id\",\n };\n};\n\nexport default connect(mapStateToProps)(Component);\n","import React, { PureComponent } from \"react\";\nimport L from \"leaflet\";\nimport {\n Circle,\n Rectangle,\n Polygon,\n Popup,\n // ,\n // Polyline,\n // Marker\n} from \"react-leaflet\";\nimport getSemanticColor from \"colorpalette\";\n\nimport FireflyName from \"containers/FireflyName\";\n\n//import TextPath from \"react-leaflet-textpath\";\n\nconst JustId = ({ fireflyId }) => {\n return ;\n};\n\nconst RoundMarker = (props) => ;\n\nconst SquareMarker = ({ center, radius, ...props }) => {\n const bounds = L.latLng(center).toBounds(radius * 2);\n return ;\n};\n\nconst BowtieMarker = ({ center, radius, ...props }) => {\n const bounds = L.latLng(center).toBounds(radius * 2);\n const positions = [\n bounds.getNorthWest(),\n bounds.getCenter(),\n bounds.getNorthEast(),\n bounds.getSouthEast(),\n bounds.getCenter(),\n bounds.getSouthWest(),\n ];\n return ;\n};\n\nconst TriangleMarker = ({ center, radius, ...props }) => {\n const bounds = L.latLng(center).toBounds(radius * 2);\n const c = bounds.getCenter();\n const positions = [\n { ...c, lat: bounds.getNorth() },\n bounds.getSouthEast(),\n bounds.getSouthWest(),\n ];\n return ;\n};\n\nconst StarMarker = ({ center, radius, ...props }) => {\n const boundsOuter = L.latLng(center).toBounds(radius * 2);\n const boundsInner = L.latLng(center).toBounds(radius * 1);\n const c = boundsOuter.getCenter();\n const positions = [\n { ...c, lng: boundsInner.getEast() },\n boundsOuter.getSouthEast(),\n { ...c, lat: boundsInner.getSouth() },\n boundsOuter.getSouthWest(),\n { ...c, lng: boundsInner.getWest() },\n boundsOuter.getNorthWest(),\n { ...c, lat: boundsInner.getNorth() },\n boundsOuter.getNorthEast(),\n { ...c, lng: boundsInner.getEast() },\n ];\n\n return ;\n};\n\n// https://github.com/makinacorpus/Leaflet.TextPath\n// https://leafletjs.com/reference-1.6.0.html#polyline\n// npm install leaflet-textpath --save\n// example source - https://github.com/makinacorpus/Leaflet.TextPath/blob/master/index.html\n// test draws a line from center at 45deg (NE) for 5*radius\n\n// const BowtieMarker_WIP = ({ center, radius, ...props }) => {\n// const bounds = L.latLng(center).toBounds(radius * 2);\n// const positions = [bounds.getCenter(), bounds.getNorthEast()];\n\n// const danger = L.polyline(\n// { positions },\n// {\n// weight: 10,\n// color: \"orange\",\n// opacity: 0.8\n// }\n// ).addTo(map);\n// danger.setText(\"\\u25BA\", {\n// repeat: true,\n// offset: 6,\n// attributes: { fill: \"red\" }\n// });\n\n// return danger;\n// return ;\n// return ;\n//};\n\n// react version\n// https://www.npmjs.com/package/react-leaflet-textpath\n// npm install react-leaflet-textpath --save\n// https://github.com/clementallen/react-leaflet-textpath#readme\n// const BowtieMarker = ({ center, radius, ...props }) => {\n// const bounds = L.latLng(center).toBounds(radius * 2);\n// const positions = [bounds.getCenter(), bounds.getNorthEast()];\n\n// return (\n// \n// );\n// };\n\n// marker using icon\n// https://leafletjs.com/reference-1.6.0.html#icon\n// https://github.com/PaulLeCam/react-leaflet/issues/355\n//https://icons8.com/icons/set/map-marker\n\n// const BowtieMarker_icon = ({ center, radius, ...props }) => {\n// const image = {\n// iconUrl: require(\"./MapMarkerIcons/marker-50.png\"),\n// // shadowUrl: require(\"../public/marker-shadow.png\"),\n// iconSize: [38, 95], // size of the icon\n// shadowSize: [50, 64], // size of the shadow\n// iconAnchor: [22, 94], // point of the icon which will correspond to marker's location\n// shadowAnchor: [4, 62], // the same for the shadow\n// popupAnchor: [-3, -76] // point from which the popup should open relative to the iconAnchor\n// };\n// return ;\n// };\n\n// ******************************\n\nconst HourGlassMarker = ({ center, radius, ...props }) => {\n const bounds = L.latLng(center).toBounds(radius * 2);\n const positions = [\n bounds.getNorthWest(),\n bounds.getNorthEast(),\n bounds.getCenter(),\n bounds.getSouthEast(),\n bounds.getSouthWest(),\n bounds.getCenter(),\n ];\n return ;\n};\n\nconst TravelwayMarker = ({ center, radius, ...props }) => {\n const bounds = L.latLng(center).toBounds(radius * 2);\n const c = bounds.getCenter();\n const positions = [\n bounds.getNorthWest(),\n bounds.getNorthEast(),\n { ...c, lng: bounds.getEast() },\n { ...c, lat: bounds.getSouth() },\n { ...c, lng: bounds.getWest() },\n bounds.getNorthWest(),\n ];\n return ;\n};\n\nconst DiamondMarker = ({ center, radius, ...props }) => {\n const bounds = L.latLng(center).toBounds(radius * 2 * 1.414);\n const c = bounds.getCenter();\n const positions = [\n { ...c, lng: bounds.getWest() },\n { ...c, lat: bounds.getNorth() },\n { ...c, lng: bounds.getEast() },\n { ...c, lat: bounds.getSouth() },\n ];\n return ;\n};\n\nclass FireflyMarker extends PureComponent {\n render() {\n const {\n lat,\n lng,\n statusSettings,\n deviceSettings,\n topologySettings,\n commandSettings,\n PopupContent = JustId,\n id,\n error,\n } = this.props;\n\n let dashArray = null;\n let fillColor = \"grey\";\n let lineColor = \"grey\";\n let Marker = DiamondMarker;\n\n //console.log(\"FireflyMarkers statusSettings \", statusSettings);\n //console.log(\"FireflyMarkers commandSettings \", commandSettings);\n //console.log(\"FireflyMarkers deviceSettings \", deviceSettings);\n //console.log(\"FireflyMarkers topologySettings\", topologySettings);\n\n // definitions\n const isInCommission =\n topologySettings && topologySettings.mode === \"commission\" ? true : false;\n const isInTransition =\n commandSettings &&\n statusSettings &&\n commandSettings.color !== statusSettings.color\n ? true\n : false;\n const isStrobing =\n (commandSettings.on_time && commandSettings.off_time) ||\n commandSettings.led_state === \"STROBE\"\n ? true\n : false;\n\n if (commandSettings) {\n lineColor = getSemanticColor(commandSettings.color);\n\n //console.log(\"isInTransition\", isInTransition, \"id\", id);\n\n switch (isStrobing) {\n case true:\n isInCommission\n ? (Marker = StarMarker)\n : isInTransition\n ? (Marker = TriangleMarker)\n : (Marker = SquareMarker); // normal state of strobbing firefly markers\n\n break;\n case false:\n isInCommission\n ? (Marker = StarMarker)\n : isInTransition\n ? (Marker = TriangleMarker)\n : (Marker = RoundMarker); // normal state of firefly markers\n break;\n default:\n break;\n }\n\n // #REVIEW - keep for ref for moment\n //\n // if (\n // (commandSettings.on_time && commandSettings.off_time) ||\n // commandSettings.led_state === \"STROBE\"\n // ) {\n // Marker = SquareMarker;\n // } else {\n // if (isInCommission) {\n // Marker = StarMarker; // different transition marker\n // } else if (isInTransition) {\n // Marker = TriangleMarker; // standard marker\n // } else {\n // Marker = RoundMarker; // standard marker\n // }\n // }\n }\n\n var status_check = false;\n\n if (deviceSettings) {\n switch (deviceSettings.status) {\n case \"OK\":\n if (!error) {\n if (deviceSettings.travelway === true) {\n Marker = TravelwayMarker;\n fillColor = getSemanticColor(statusSettings.color);\n status_check = true;\n lineColor = \"purple\";\n } else if (statusSettings) {\n fillColor = getSemanticColor(statusSettings.color);\n status_check = true;\n }\n }\n break;\n\n case \"INACTIVE_FIREFLY\":\n lineColor = \"black\";\n fillColor = \"fuchsia\";\n Marker = BowtieMarker;\n status_check = true;\n break;\n\n case \"UPS_TIMEOUT\":\n lineColor = \"fuchsia\";\n fillColor = \"black\";\n Marker = BowtieMarker;\n status_check = true;\n break;\n\n default:\n lineColor = \"fuchsia\";\n fillColor = \"sienna\";\n Marker = HourGlassMarker;\n status_check = true;\n break;\n }\n }\n\n // This is a timeout check that is set in func calcTimeAndStatus() UPSPanelControllers/reducer.js\n if (error && status_check === false) {\n if (error === \"MISSING_STATUS\") {\n status_check = true;\n lineColor = \"black\";\n fillColor = \"fuchsia\";\n Marker = BowtieMarker;\n } else if (error === \"OLD_STATUS\") {\n status_check = true;\n lineColor = \"fuchsia\";\n fillColor = \"black\";\n Marker = BowtieMarker;\n }\n }\n\n if (statusSettings && status_check === false) {\n fillColor = getSemanticColor(statusSettings.color);\n }\n\n if (fillColor === \"white\" && lineColor === \"white\") {\n lineColor = \"darkgrey\";\n dashArray = \"10\";\n }\n\n return (\n \n \n \n \n \n );\n }\n}\nexport default FireflyMarker;\n","// HB_15Mar22 - #OLD_CODE review file pending review and removal.\n//\n// This old code is still used by src/components/StatusChecks/index.js\n//\n\nimport Immutable from \"seamless-immutable\";\nimport isEqual from \"lodash/isEqual\";\nimport { minutesAgo, parseDate } from \"utils/format-date\";\n\nlet initialState = Immutable({\n upsById: {},\n travelwayByLocation: {},\n fireflysById: {},\n isCommissioning: false,\n commissioningError: null,\n discoveryRequests: {},\n upsCommandRequests: {},\n advancedConfigRequests: {},\n});\n\n/*\nfunction foundNewUPS (statusReport) {\n return Immutable({\n id: statusReport.id,\n created: new Date(),\n lastStatusReport: statusReport,\n position: {}\n })\n}\n\nfunction foundNewFirefly (statusReport) {\n return Immutable({\n id: statusReport.id,\n created: new Date(),\n lastStatusReport: statusReport,\n position: {},\n topology: statusReport.topology\n })\n}\n*/\n\nfunction makeHasChanged(item, fields) {\n return function (a, b) {\n for (let i = 0; i < fields.length; i++) {\n const k = fields[i];\n if (a[item][k] !== b[item][k]) {\n return true;\n }\n }\n return false;\n };\n}\n\nexport const hasTopologyChanged = makeHasChanged(\"topology\", [\n \"upsId\",\n \"position\",\n \"portNumber\",\n]);\nexport const hasPositionChanged = makeHasChanged(\"position\", [\n \"mineLevelId\",\n \"lat\",\n \"lng\",\n]);\n\nfunction calcTimeAndStatus(payload) {\n if (payload.lastStatusReport) {\n payload = Immutable.set(\n payload,\n \"lastStatusReceived\",\n parseDate(payload.lastStatusReport.timeReceived)\n );\n }\n\n // console.log(\"FF status \" + payload.device.status )\n\n if (payload.lastStatusReceived) {\n if (minutesAgo(payload.lastStatusReceived) > 14) {\n /*14*/\n //console.log(\"Timeout error Error \" + payload.lastStatusReceived )\n\n payload = Immutable.set(payload, \"statusError\", \"OLD_STATUS\");\n } else {\n payload = Immutable.set(payload, \"statusError\", \"\");\n }\n } else {\n payload = Immutable.set(payload, \"statusError\", \"MISSING_STATUS\");\n }\n\n return payload;\n}\n\nfunction isNotCommissioned(ff) {\n return !ff || !ff.position;\n}\n\nfunction handleFFUpdate(state, payload) {\n payload = calcTimeAndStatus(Immutable(payload));\n\n const existing = state.fireflysById[payload.id];\n // If existing does exist, but has no position, we won't be rendering\n // it or controlling it so update it verbatim?\n if (isNotCommissioned(existing)) {\n return state.setIn([\"fireflysById\", payload.id], payload);\n }\n\n if (existing.topology && existing.position) {\n const topo = hasTopologyChanged(existing, payload);\n const position = hasPositionChanged(existing, payload);\n const name = existing.name !== payload.name;\n if (topo || position || name) {\n return state.setIn([\"fireflysById\", payload.id], payload);\n }\n }\n\n let newState = state;\n if (!isEqual(existing.lastCommand, payload.lastCommand)) {\n newState = newState.setIn(\n [\"fireflysById\", payload.id, \"lastCommand\"],\n payload.lastCommand\n );\n }\n\n // likely just the status report updated\n newState = newState.setIn(\n [\"fireflysById\", payload.id, \"lastStatusReport\"],\n payload.lastStatusReport\n );\n return newState;\n}\n\nfunction updateAllFFStatus(state) {\n let fireflysById = state.fireflysById;\n\n Object.keys(fireflysById).forEach((id) => {\n fireflysById = fireflysById.setIn(\n [id],\n calcTimeAndStatus(fireflysById[id])\n );\n });\n return state.setIn([\"fireflysById\"], fireflysById);\n}\n\nexport default function reduce(state = initialState, action = {}) {\n const { type, payload } = action;\n switch (type) {\n case \"UPS_STATUS_UPDATE\":\n return state.setIn([\"upsById\", payload.id], {\n ...payload,\n });\n\n case \"TRAVELWAY_STATUS_UPDATE\":\n return state.setIn([\"travelwayByLocation\", payload.location], {\n ...payload,\n });\n case \"UPS_DELETED\":\n if (!state.upsById[payload.id]) {\n return state;\n }\n return state.setIn([\"upsById\"], state.upsById.without(payload.id));\n\n case \"FIREFLY_STATUS_UPDATE\":\n return handleFFUpdate(state, payload);\n case \"FIREFLY_DELETED\":\n if (!state.fireflysById[payload.id]) {\n return state;\n }\n return state.setIn(\n [\"fireflysById\"],\n state.fireflysById.without(payload.id)\n );\n case \"STATUS_CHECK_TICK\":\n return updateAllFFStatus(state);\n\n case \"COMMISSION_RECORDS_REQUEST\":\n return state.merge([\n { isCommissioning: true },\n { commissioningError: null },\n ]);\n case \"COMMISSION_RECORDS_SUCCESS\":\n let newState = state\n .merge([{ isCommissioning: false }, { commissioningError: null }])\n .asMutable({ deep: true });\n const { mineLevelId, upsPositions, fireflyPositions } = payload;\n //console.log(\"Updating newState\", newState);\n upsPositions.forEach((ups) => {\n const { id, point } = ups;\n newState.upsById[id].position = { mineLevelId, ...point };\n });\n\n fireflyPositions.forEach((ff) => {\n const { id, point, topology } = ff;\n newState.fireflysById[id].position = { mineLevelId, ...point };\n newState.fireflysById[id].topology = topology;\n });\n\n return Immutable(newState);\n case \"COMMISSION_RECORDS_FAILED\":\n return state.merge([\n { isCommissioning: false },\n { commissioningError: action.payload },\n ]);\n\n case \"UPS_RUN_DISCOVERY\":\n return state.setIn([\"discoveryRequests\", payload.id], true);\n case \"UPS_DISCOVER_SUBMITTED\":\n return state.setIn([\"discoveryRequests\", payload.id], null);\n case \"UPS_DISCOVER_ERROR\":\n return state.setIn([\"discoveryRequests\", payload.id], payload.message);\n\n case \"UPS_SEND_COMMAND\":\n return state.setIn(\n [\"upsCommandRequests\", payload.id],\n payload.cmdPayload\n );\n case \"UPS_COMMAND_SUBMITTED\":\n return state.setIn([\"upsCommandRequests\", payload.id], null);\n case \"UPS_COMMAND_ERROR\":\n return state.setIn([\"upsCommandRequests\", payload.id], {\n error: payload.message,\n });\n\n default:\n return state;\n }\n}\n\nfunction stableOrder(order, items) {\n return Immutable(order.map((k) => items[k]));\n}\n\nexport const getAllUPSs = (state) => {\n const byId = state.upsPanelControllers.upsById;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getAllTravelways = (state) => {\n const byLocation = state.upsPanelControllers.travelwayByLocation;\n const keys = Object.keys(byLocation).sort();\n return stableOrder(keys, byLocation);\n};\n\nexport const getUncommissionedUPSs = (state) => {\n return getAllUPSs(state);\n};\n\nexport const getTravelwayByLocation = (state, location) =>\n state.upsPanelControllers.travelwayByLocation[location];\n\nexport const getUPSById = (state, id) => state.upsPanelControllers.upsById[id];\n\nexport const getFireflyById = (state, id) =>\n state.upsPanelControllers.fireflysById[id];\n\nexport const getAllFireflys = (state) => {\n const byId = state.upsPanelControllers.fireflysById;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getFirefliesForUPS = (state, upsId) => {\n return getAllFireflys(state).filter((ff) => ff.topology.upsId === upsId);\n};\n\nexport const getTopology = (ff, preferFromLastStatus = false) => {\n if (preferFromLastStatus && ff.lastStatusReport) {\n return ff.lastStatusReport.topology;\n }\n return ff.topology;\n};\n\nexport const getFirefliesForUPSId = (\n state,\n upsId,\n preferTopologyFromStatus = true\n) => {\n return getAllFireflys(state).filter(\n (ff) => getTopology(ff, preferTopologyFromStatus).upsId === upsId\n );\n};\n\nexport const getFireflyIdsForMineLevelId = (state, mineLevelId) => {\n return getAllFireflys(state)\n .filter((ff) => ff.getIn([\"position\", \"mineLevelId\"]) === mineLevelId)\n .map((ff) => ff.id);\n};\n\nexport const getFireflysForMineLevelId = (state, mineLevelId) => {\n return getAllFireflys(state).filter(\n (ff) => ff.getIn([\"position\", \"mineLevelId\"]) === mineLevelId\n );\n};\n\nexport const getUPSIdsForMineLevelId = (state, mineLevelId) => {\n return getAllUPSs(state)\n .filter((ups) => ups.getIn([\"position\", \"mineLevelId\"]) === mineLevelId)\n .map((ups) => ups.id);\n};\n\nexport const getUPSDiscoveryRequest = (state, id) => {\n const request = state.upsPanelControllers.discoveryRequests[id];\n if (request === true) {\n return { active: true, error: null };\n }\n\n return { active: false, error: request };\n};\n\nexport const getUPSCommandRequest = (state, id, payload) => {\n const request = state.upsPanelControllers.upsCommandRequests[id];\n if (!request) {\n return { active: false, error: null };\n }\n\n if (isEqual(payload, request)) {\n return { active: true, error: null };\n }\n\n return { active: false, error: request.error };\n};\n\nexport const getUPSIpAddress = (state, id) =>\n state.upsPanelControllers.getIn([\n \"upsById\",\n id,\n \"lastStatusReport\",\n \"topology\",\n \"ip\",\n ]);\n","import { connect } from \"react-redux\";\nimport FireflyMarker from \"components/FireflyMarker\";\nimport { getFireflyById } from \"UPSPanelControllers/reducer\";\n\nconst ConnectedFirefly = connect((state, props) => {\n const ff = getFireflyById(state, props.id);\n\n let error = ff.statusError;\n return {\n lat: ff.position.lat,\n lng: ff.position.lng,\n statusSettings: ff.getIn([\"lastStatusReport\", \"light\"]),\n deviceSettings: ff.getIn([\"lastStatusReport\", \"device\"]),\n\n // get topology block from firefly message\n topologySettings: ff.getIn([\"lastStatusReport\", \"topology\"]),\n\n commandSettings: ff.getIn([\"lastCommand\", \"settings\"]),\n error\n };\n})(FireflyMarker);\n\nexport default ConnectedFirefly;\n","import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { connect } from \"react-redux\";\n\nimport { withMineLevel } from \"ApplicationContexts\";\nimport { FeatureGroup } from \"react-leaflet\";\n\nimport { getFireflyIdsForMineLevelId } from \"components/WebWorker/reducer\";\n\nimport Firefly from \"containers/FireflyMapMarker\";\n\nclass CurrentMineLevelFirefliesFeatureGroup extends Component {\n static propTypes = {\n children: PropTypes.node,\n className: PropTypes.string,\n dispatch: PropTypes.func.isRequired,\n };\n\n shouldComponentUpdate(nextProps, nextState) {\n const current = this.props.fireflies;\n const next = nextProps.fireflies;\n\n if (current.length === next.length) {\n const lookup = current.reduce((acc, id) => {\n acc[id] = true;\n return acc;\n }, {});\n\n const len = next.length;\n for (var i = 0; i < len; i++) {\n if (!lookup[next[i]]) {\n return true;\n }\n }\n return false;\n }\n return true;\n }\n\n render() {\n const { fireflies, PopupContent } = this.props;\n\n return (\n \n {fireflies.map((id) => {\n return (\n \n );\n })}\n \n );\n }\n}\n\nexport function mapStateToProps(state, props) {\n const { mineLevel } = props;\n let fireflies = getFireflyIdsForMineLevelId(state, mineLevel.id);\n\n return {\n fireflies,\n };\n}\n\nexport default withMineLevel(\n connect(mapStateToProps)(CurrentMineLevelFirefliesFeatureGroup)\n);\n","import Immutable from 'seamless-immutable'\nimport { createSelector } from 'reselect'\n\nconst initialState = Immutable({\n byId: {},\n fetchingAll: {},\n fetchingCurrent: {}\n})\n\nconst reduce = (state = initialState, action = {}) => {\n const { type, payload } = action\n switch (type) {\n case 'MINE_LEVEL_ALL_SEISMIC_FETCH_REQUESTED':\n return state.setIn(['fetchingAll', payload.mineLevelId], true)\n case 'MINE_LEVEL_ALL_SEISMIC_FETCH_SUCCEEDED':\n return state\n .setIn(['byId'], state.byId.merge(action.payload.layersById))\n .setIn(['fetchingAll', payload.mineLevelId], false)\n case 'MINE_LEVEL_ALL_SEISMIC_FETCH_FAILED':\n return state.setIn(['fetchingAll', payload.mineLevelId], false)\n\n case 'MINE_LEVEL_CURRENT_SEISMIC_FETCH_REQUESTED':\n return state.setIn(['fetchingCurrent', payload.mineLevelId], true)\n case 'MINE_LEVEL_CURRENT_SEISMIC_FETCH_SUCCEEDED':\n return state\n .setIn(\n ['byId', action.payload.layer.id],\n Immutable(action.payload.layer)\n )\n .setIn(['fetchingCurrent', payload.mineLevelId], false)\n case 'MINE_LEVEL_CURRENT_SEISMIC_FETCH_FAILED':\n return state.setIn(['fetchingCurrent', payload.mineLevelId], false)\n default:\n return state\n }\n}\n\nexport default reduce\n\nexport const getMineLevelHistory = (\n state,\n mineLevelId,\n includeCurrent = true\n) => {\n const obj = state.seismicOverlays.byId\n const layers = Object.keys(obj).map(key => obj[key])\n\n const forMineLevel = layers.filter(layer => layer.mineLevelId === mineLevelId)\n\n return Immutable(\n forMineLevel.sort((a, b) => b.id - a.id).slice(includeCurrent ? 0 : 1)\n )\n}\n\nexport const getCurrentSeismicLayer = createSelector(\n getMineLevelHistory,\n history => history[0]\n)\n\nexport const getIsLoadingSeismicLayersForMineLevel = (state, id) => {\n return (\n state.seismicOverlays.getIn(['fetchingAll', id], false) ||\n state.seismicOverlays.getIn(['fetchingAll', id], false)\n )\n}\n\nexport const getSeismicLayerById = (state, id) =>\n state.seismicOverlays.getIn(['byId', id])\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { FeatureGroup, Polygon } from 'react-leaflet'\nimport getSemanticColor from 'colorpalette'\n\nexport function SeismicMapRegion (props) {\n const { points, lightSettings: { color }, pane = 'overlayPane' } = props\n const semColor = getSemanticColor(color)\n return (\n \n )\n}\n\nfunction pointsFromBounds (bounds) {\n const pt1 = bounds[0]\n const pt2 = bounds[1]\n const lng1 = pt1.lng\n const lat1 = pt1.lat\n const lng2 = pt2.lng\n const lat2 = pt2.lat\n return [[lat1, lng1], [lat1, lng2], [lat2, lng2], [lat2, lng1]]\n}\n\nclass SeismicLayerFeatureGroup extends React.Component {\n static propTypes = {}\n render () {\n const {\n regionSettings,\n levelDefault,\n mineLevelBounds,\n displayDefault = true\n } = this.props\n let defaultRegion\n\n if (displayDefault) {\n const props = {\n lightSettings: levelDefault,\n points: pointsFromBounds(mineLevelBounds)\n }\n defaultRegion = \n }\n\n return (\n \n {defaultRegion}\n {regionSettings\n .asMutable()\n .reverse()\n .map((region, idx) => {\n const { priority = idx } = region\n return (\n \n )\n })}\n \n )\n }\n}\n\nSeismicLayerFeatureGroup.defaultProps = {}\n\nconst LatLngObject = PropTypes.shape({\n lat: PropTypes.number.isRequired,\n lng: PropTypes.number.isRequired\n})\n\nconst LightSettings = PropTypes.shape({ color: PropTypes.string })\nconst RegionSetting = PropTypes.shape({\n settings: LightSettings,\n points: PropTypes.arrayOf(LatLngObject)\n})\n\nSeismicLayerFeatureGroup.propTypes = {\n mineLevelBounds: PropTypes.arrayOf(LatLngObject).isRequired,\n levelDefault: RegionSetting.isRequired,\n regionSettings: PropTypes.arrayOf(RegionSetting).isRequired,\n displayDefault: PropTypes.bool\n}\n\nexport default SeismicLayerFeatureGroup\n","import { connect } from 'react-redux'\nimport { withMineLevel } from 'ApplicationContexts'\nimport { getMineLevelBounds } from 'MineLevels/reducer'\nimport { getSeismicLayerById } from 'seismicOverlays/reducer'\nimport SeismicLayerFeatureGroup from './SeismicLayerFeatureGroup'\n\nfunction mapStateToProps (state, props) {\n const s = getSeismicLayerById(state, props.seismicLayerId)\n return {\n mineLevelBounds: getMineLevelBounds(state, props.mineLevel.id),\n levelDefault: s.levelDefault,\n regionSettings: s.regionSettings\n }\n}\nexport default withMineLevel(connect(mapStateToProps)(SeismicLayerFeatureGroup))\n","export function fetchSeismicLayersForMineLevel (mineLevelId) {\n return {\n type: 'MINE_LEVEL_ALL_SEISMIC_FETCH_REQUESTED',\n payload: { mineLevelId }\n }\n}\n\nexport function fetchCurrentSeismicLayerForMineLevel (mineLevelId) {\n return {\n type: 'MINE_LEVEL_CURRENT_SEISMIC_FETCH_REQUESTED',\n payload: { mineLevelId }\n }\n}\n","import React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport { connect } from 'react-redux'\n\nimport MineLevelSeismicFeatureGroup from 'components/MineLevelSeismicFeatureGroup'\nimport { getCurrentSeismicLayer } from 'seismicOverlays/reducer'\nimport { fetchCurrentSeismicLayerForMineLevel } from 'seismicOverlays/actions'\nimport { withMineLevel } from 'ApplicationContexts'\nimport { FeatureGroup } from 'react-leaflet'\n\nclass CurrentSeismicFeatureGroup extends Component {\n static propTypes = {\n children: PropTypes.node,\n className: PropTypes.string,\n dispatch: PropTypes.func.isRequired\n }\n\n componentDidMount () {\n this.props.dispatch(\n fetchCurrentSeismicLayerForMineLevel(this.props.mineLevel.id)\n )\n }\n componentDidUpdate (prevProps) {\n if (prevProps.mineLevel.id !== this.props.mineLevel.id) {\n this.props.dispatch(\n fetchCurrentSeismicLayerForMineLevel(this.props.mineLevel.id)\n )\n }\n }\n\n render () {\n if (!this.props.currentSeismicLayer) {\n return \n }\n return (\n \n \n \n )\n }\n}\n\nexport function mapStateToProps (state, { mineLevel }) {\n let currentSeismicLayer = getCurrentSeismicLayer(state, mineLevel.id)\n\n return {\n currentSeismicLayer\n }\n}\n\nexport default withMineLevel(\n connect(mapStateToProps)(CurrentSeismicFeatureGroup)\n)\n","export function SetNamedAreaDisplaySettings(options) {\n return { type: \"SET_NAMED_AREA_DISPLAY_SETTINGS\", payload: options };\n}\n\nexport function UpdateNamedAreaDisplaySettings(options) {\n return { type: \"UPDATE_NAMED_AREA_DISPLAY_SETTINGS\", payload: options };\n}\n\nexport const fetchFolderFilesListByFolder = (folder) => {\n return { type: \"FOLDER_FILES_LIST_FETCH_REQUESTED\", payload: folder };\n};\n\nexport const deleteFolderFile = (info) => {\n return { type: \"FOLDER_FILE_DELETE_REQUESTED\", payload: info };\n};\n\nexport const saveFolderFile = (info) => {\n return { type: \"FOLDER_FILE_SAVE_REQUESTED\", payload: info };\n};\n\nexport const fetchServerInfo = (info) => {\n return { type: \"SERVER_INFO_FETCH_REQUESTED\", payload: info };\n};\n\nexport const fetchServerOk = (info) => {\n return { type: \"SERVER_OK_FETCH_REQUESTED\", payload: info };\n};\n\nexport const TurnOnOffPokeTheWorker = (action) => {\n //console.log(`TurnOnOffPokeTheWorker -->`, action);\n return { type: \"SYSTEM_TURN_ON_OFF_POKE_THE_WORKER\", payload: action };\n};\n\nexport const DisablePokeTheWorker = (action) => {\n return { type: \"SYSTEM_DISABLE_POKE_THE_WORKER\", payload: action };\n};\n\nexport const SetPokeTheWorkerPollRate = (milliseconds) => {\n return { type: \"SYSTEM_POLL_RATE_POKE_THE_WORKER\", payload: milliseconds };\n};\n\nexport const SetPollRates = (rates) => {\n return { type: \"SYSTEM_SET_POLL_RATES\", payload: rates };\n};\n\nexport const fetchMqttBroker = () => {\n return { type: \"MQTT_BROKER_FETCH_REQUESTED\" };\n};\n\nexport const fetchCheckService = (action) => {\n return { type: \"SERVER_CHECK_SERVICE_FETCH_REQUESTED\", payload: action };\n};\n\nexport const SetMapImage = (data) => {\n return { type: \"SYSTEM_SET_MAP_IMAGE\", payload: data };\n};\n\n// used to communicate the zoom and center of the currently displayed map\nexport const SetMapSettings = (data) => {\n return { type: \"SYSTEM_SET_MAP_SETTING\", payload: data };\n};\n","import React from \"react\";\nimport { Form, Label, Popup, Dropdown } from \"semantic-ui-react\";\nimport \"admin/form-field.css\";\n\nexport const renderField = ({\n input,\n label,\n placeholder,\n disabled = false,\n type,\n meta: { touched, error, warning },\n className = \"\",\n style,\n //\n min,\n step,\n max,\n}) => {\n return (\n \n \n \n }\n />\n {touched &&\n ((error && (\n \n )) ||\n (warning && (\n \n )))}\n \n );\n};\n\n// see example\n// https://codesandbox.io/s/9445n90wkw?file=/src/components/ProfileForm.js\n// for render suggestions\n\n// particular modification for toggle version\n// see form-field.css\n// for class to change label on select\nexport const renderCheckboxToggle = (field) => (\n field.input.onChange(checked)}\n disabled={field.disabled}\n />\n);\n\nexport const renderCheckbox = (field) => (\n field.input.onChange(checked)}\n disabled={field.disabled}\n />\n);\n\nexport const renderRadio = (field) => (\n field.input.onChange(field.radioValue)}\n disabled={field.disabled}\n />\n);\n\nexport const renderSelect_old = (field) => (\n {\n //console.log(\"BLUR\", value);\n field.input.onChange(value);\n }}\n onChange={(e, { value }) => field.input.onChange(value)}\n options={field.options}\n placeholder={field.placeholder}\n value={field.input.value}\n disabled={field.disabled}\n\n // defaultValue={field.defaultValue}\n //\n // default value does not work on a redux form, instead pass via setting\n // the initialValue of the component\n // https://stackoverflow.com/questions/49267232/set-select-default-value-doesnt-work\n //\n // https://github.com/erikras/redux-form-material-ui#no-default-values\n //\n // No Default Values\n\n // Because of the strict \"controlled component\" nature of redux-form,\n // some of the Material UI functionality related to defaulting of values\n // has been disabled e.g. defaultValue, defaultDate, defaultTime,\n // defaultToggled, defaultChecked, etc.\n // If you need a field to be initialized to a certain state,\n // you should use the initialValues API of redux-form.\n />\n);\n\nexport const renderSelect = ({\n input,\n inline,\n label,\n placeholder,\n disabled = false,\n type,\n meta: { touched, error, warning },\n className = \"\",\n style,\n options,\n multiple = false,\n}) => (\n \n {\n //console.log(\"BLUR\", value);\n input.onChange(value);\n }}\n onChange={(e, { value }) => input.onChange(value)}\n options={options}\n placeholder={placeholder || label}\n value={input.value}\n disabled={disabled}\n // defaultValue={field.defaultValue}\n //\n // default value does not work on a redux form, instead pass via setting\n // the initialValue of the component\n // https://stackoverflow.com/questions/49267232/set-select-default-value-doesnt-work\n //\n // https://github.com/erikras/redux-form-material-ui#no-default-values\n //\n // No Default Values\n\n // Because of the strict \"controlled component\" nature of redux-form,\n // some of the Material UI functionality related to defaulting of values\n // has been disabled e.g. defaultValue, defaultDate, defaultTime,\n // defaultToggled, defaultChecked, etc.\n // If you need a field to be initialized to a certain state,\n // you should use the initialValues API of redux-form.\n />\n // \n }\n />\n);\n\nexport const renderTextArea = (field) => (\n \n);\n\nexport const renderInput = ({\n input,\n label,\n placeholder,\n disabled = false,\n type,\n meta: { touched, error, warning },\n className = \"\",\n icon,\n}) => (\n \n }\n />\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Field, formValueSelector, reduxForm } from \"redux-form\";\n\nimport { Slider } from \"react-semantic-ui-range\";\nimport \"semantic-ui-css/semantic.min.css\";\n\nimport {\n Modal,\n Header,\n Button,\n Form,\n Segment,\n Grid,\n GridColumn,\n GridRow,\n Label,\n} from \"semantic-ui-react\";\n\nimport isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport { renderRadio, renderCheckbox } from \"admin/form-field\";\n\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nclass NamedAreaDisplaySettingsModal extends Component {\n constructor(props) {\n super(props);\n this.state = {\n modalOpen: false,\n columnWidth: props.initialValues.columnWidth,\n };\n }\n\n componentDidMount() {\n const { open } = this.props;\n if (open) {\n this.handleOpen();\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleCancel = () => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.resetModal();\n\n // reset the form\n this.setState({ value: \"\" }, () => this.props.reset());\n // this.props.onCancel();\n };\n\n myHandleSubmit = (values) => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // save the changes\n this.props.handleSettingsSave(values);\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n reset,\n initialValues,\n change,\n role,\n } = this.props;\n\n const { allowOperator } = role;\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n const strSopInterface = \"Lighting Control Layout\"; // \"SOP user interface\"\n const strTitle = \"Lighting Control\"; // operational interface\n\n const { columnWidth } = initialValues;\n\n //console.log(\"modal initialValues\", initialValues);\n\n const settings = {\n start: columnWidth,\n min: 0,\n max: 16,\n step: 2,\n onChange: (value) => {\n //console.log(\"value\", value);\n this.props.change(\"columnWidth\", value);\n\n this.setState({\n columnWidth: value,\n });\n },\n };\n\n return (\n \n
\n \n {\n e.stopPropagation();\n handleSubmit(this.myHandleSubmit)(e);\n }}\n >\n \n \n \n \n {allowOperator && (\n <>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )}\n \n \n \n \n \n \n \n \n this.myHandleSubmit(e)}\n >\n Save\n \n \n \n Reset\n \n \n \n Cancel\n \n \n \n \n \n \n \n \n \n );\n }\n}\n\nNamedAreaDisplaySettingsModal = reduxForm({\n form: \"NamedAreaDisplaySettingsModal\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n})(NamedAreaDisplaySettingsModal);\n\n//const selector = formValueSelector(\"NamedAreaDisplaySettingsModal\");\n\nfunction mapStateToProps(state, props) {\n const { initialValues } = props;\n\n // user roles\n const userSuper = isUserSuper(state);\n const userAdmin = isUserAdmin(state);\n const userUser = isUserUser(state);\n const userGuest = isUserGuest(state);\n const allowGuest = userGuest;\n\n const allowOperator = userSuper || userAdmin || userUser;\n const allowAdmin = userSuper || userAdmin;\n const allowSuper = userSuper;\n\n return {\n initialValues: initialValues, // props passed to redux-form loads these as (predictably), initial values\n role: { allowGuest, allowOperator, allowAdmin, allowSuper },\n };\n}\n\nexport default connect(mapStateToProps, null)(NamedAreaDisplaySettingsModal);\n","// #NOTE\n// This component uses leaflet styling\n// to be consistent with the layer button on the map\n//\n\nimport React from \"react\";\nimport { connect } from \"react-redux\";\nimport \"pages/ControlRoomPage/NamedAreaDisplaySettings/NamedAreaDisplaySettings.css\";\nimport { UpdateNamedAreaDisplaySettings } from \"components/Settings/actions\";\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\nimport SettingsModal from \"pages/ControlRoomPage/NamedAreaDisplaySettings/NamedAreaDisplaySettingsModal\";\nimport { Button, Icon, Popup } from \"semantic-ui-react\";\n\nclass NamedAreaDisplaySettings extends React.Component {\n state = {\n isOpenSettingsModal: false,\n hint: true,\n legend: true,\n view: \"normal\",\n columnWidth: 6,\n sopInterface: true,\n };\n\n componentDidMount() {\n const { hint, legend, view, columnWidth, sopInterface } =\n this.props.namedAreaDisplaySettings;\n\n this.setState({ hint: hint });\n this.setState({ legend: legend });\n this.setState({ view: view });\n this.setState({ columnWidth: columnWidth });\n this.setState({ sopInterface: sopInterface });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { hint, legend, view, columnWidth, sopInterface } = this.state;\n const displaySettings = { hint, legend, view, columnWidth, sopInterface };\n\n const {\n hint: prevHint,\n legend: prevLegend,\n view: prevView,\n columnWidth: prevColumnWidth,\n sopInterface: prevSopInterface,\n } = prevState;\n\n const prevDisplaySettings = {\n hint: prevHint,\n legend: prevLegend,\n view: prevView,\n columnWidth: prevColumnWidth,\n sopInterface: prevSopInterface,\n };\n\n if (\n JSON.stringify(displaySettings) !== JSON.stringify(prevDisplaySettings)\n ) {\n this.props.UpdateNamedAreaDisplaySettings(displaySettings);\n }\n }\n\n showOptions = (value) => {\n this.setState({ isOpenSettingsModal: value });\n };\n\n handleSettingsSave = (value) => {\n const { hint, legend, view, columnWidth, sopInterface } = value;\n this.setState({ hint: hint });\n this.setState({ legend: legend });\n this.setState({ view: view });\n this.setState({ columnWidth: columnWidth });\n this.setState({ sopInterface: sopInterface });\n\n // close the modal and display the cog again...\n this.setState({ isOpenSettingsModal: false });\n };\n\n render() {\n // #NOTE - Main nav config option test format version.\n // This is development code and has never been used.\n if (false) {\n return (\n
\n \n {!this.state.isOpenSettingsModal && (\n this.showOptions(true)}\n >
\n )}\n {this.state.isOpenSettingsModal && (\n this.handleSettingsSave(values)}\n resetModal={() => this.showOptions(false)}\n />\n )}\n \n \n );\n }\n\n const buttonSize = this.props?.size || \"large\";\n\n // #NOTE - Main nav config option has been superceded in favour of per User settings in profile\n // Left here JIC things change again.\n if (true) {\n return (\n <>\n this.showOptions(true)}\n >\n \n \n }\n />\n {this.state.isOpenSettingsModal && (\n this.handleSettingsSave(values)}\n resetModal={() => this.showOptions(false)}\n />\n )}\n \n );\n }\n }\n}\n\nconst mapStateToProps = (state) => {\n const namedAreaDisplaySettings = getNamedAreaDisplaySettings(state);\n\n return {\n namedAreaDisplaySettings,\n };\n};\n\nconst mapDispatchToProps = (dispatch) => ({\n UpdateNamedAreaDisplaySettings: (options) => {\n dispatch(UpdateNamedAreaDisplaySettings(options));\n },\n});\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(NamedAreaDisplaySettings);\n","// see - https://odoe.net/blog/custom-leaflet-control\n// - https://github.com/odoe/leaflet-control-sample\n\nimport L from \"leaflet\";\nimport _ from \"lodash\";\nimport \"leaflet/dist/leaflet.css\";\n//import \"components/Map/bootstrap.css\"; // use for testing old styling if necessary\n\nvar yx = L.latLng;\nvar xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n};\n\nfunction sortId(a, b) {\n var _a = a.feature.properties.id;\n var _b = b.feature.properties.id;\n if (_a < _b) {\n return -1;\n }\n if (_a > _b) {\n return 1;\n }\n return 0;\n}\n\n// L.Control.Search = L.Control.extend({\nconst SearchControl = L.Control.extend({\n options: {\n // topright, topleft, bottomleft, bottomright\n position: \"topleft\",\n placeholder: \"Search...\",\n },\n initialize: function (options /*{ data: {...} }*/) {\n // constructor\n L.Util.setOptions(this, options);\n },\n onAdd: function (map) {\n // happens after added to map\n var container = L.DomUtil.create(\"div\", \"search-container\");\n this.form = L.DomUtil.create(\"form\", \"form\", container);\n var group = L.DomUtil.create(\"div\", \"form-group\", this.form);\n this.input = L.DomUtil.create(\"input\", \"form-control input-sm\", group);\n this.input.type = \"text\";\n this.input.placeholder = this.options.placeholder;\n this.results = L.DomUtil.create(\"div\", \"list-group\", group);\n L.DomEvent.addListener(\n this.input,\n \"keyup\",\n _.debounce(this.keyup, 300),\n this\n );\n L.DomEvent.addListener(this.form, \"submit\", this.submit, this);\n L.DomEvent.disableClickPropagation(container);\n return container;\n },\n onRemove: function (map) {\n // when removed\n L.DomEvent.removeListener(this.input, \"keyup\", this.keyup, this);\n L.DomEvent.removeListener(this.form, \"submit\", this.submit, this);\n },\n keyup: function (e) {\n if (e.keyCode === 38 || e.keyCode === 40) {\n // do nothing\n } else {\n this.results.innerHTML = \"\";\n if (this.input.value.length > 2) {\n var value = this.input.value;\n var results = _.take(\n _.filter(this.options.data, function (x) {\n return (\n x.feature.properties.id\n .toUpperCase()\n .indexOf(value.toUpperCase()) > -1\n );\n }).sort(sortId),\n 10\n );\n _.map(results, (x) => {\n var a = L.DomUtil.create(\"a\", \"list-group-item\");\n a.href = \"\";\n a.setAttribute(\"data-result-name\", x.feature.properties.id);\n a.innerHTML = x.feature.properties.id;\n this.results.appendChild(a);\n L.DomEvent.addListener(a, \"click\", this.itemSelected, this);\n return a;\n });\n }\n }\n },\n itemSelected: function (e) {\n L.DomEvent.preventDefault(e);\n var elem = e.target;\n var value = elem.innerHTML;\n this.input.value = elem.getAttribute(\"data-result-name\");\n var feature = _.find(\n this.options.data,\n function (x) {\n return x.feature.properties.id === value;\n },\n this\n );\n if (feature) {\n // console.log(\n // \"search CLICKED ON feature\",\n // feature,\n // feature?.getLatLng?.(),\n // this._map.getMaxZoom(),\n // feature?.feature?.geometry?.coordinates\n // );\n // check if leaflet layer data used\n if (feature?.getLatLng?.()) {\n this._map.setView(feature?.getLatLng(), this._map.getMaxZoom());\n }\n // check if geoJson data used\n else if (feature?.feature?.geometry?.coordinates) {\n let coords = feature?.feature?.geometry?.coordinates;\n if (L.Util.isArray(coords)) {\n this._map.setView(\n { lat: coords[1], lng: coords[0] },\n 2 // this._map.getMaxZoom()\n );\n }\n }\n }\n this.results.innerHTML = \"\";\n },\n submit: function (e) {\n L.DomEvent.preventDefault(e);\n },\n});\n\nexport default SearchControl;\n\n// L.control.search = function (id, options) {\n// return new L.Control.Search(id, options);\n// };\n","export function UpdateMqttReset(bool) {\n return { type: \"MQTT_RESET\", payload: bool };\n}\n\nexport function UpdateMqttMsg(mqttMsg) {\n return { type: \"MQTT_MSG_UPDATE\", payload: mqttMsg };\n}\n\nexport function UpdateLatestFaultTs(latestFaultTs) {\n return { type: \"MQTT_LATEST_FAULT_TS_UPDATE\", payload: latestFaultTs };\n}\n\n// railway_application\nexport function UpdateExternalTrigger(externalTrigger) {\n return { type: \"MQTT_LATEST_EXTERNAL_TRIGGER\", payload: externalTrigger };\n}\nexport function UpdateButtonTrigger(buttonTrigger) {\n return { type: \"MQTT_LATEST_BUTTON_TRIGGER\", payload: buttonTrigger };\n}\nexport function UpdateMachineStatus(machineStatus) {\n return { type: \"MQTT_LATEST_MACHINE_STATUS_UPDATE\", payload: machineStatus };\n}\n\nexport function UpdateMapMsg(msg) {\n return { type: \"MQTT_MAP_MSG_UPDATE\", payload: msg };\n}\n\nexport function UpdateControllerCoordinates(msg) {\n return { type: \"MQTT_CONTROLLER_COORDINATES_UPDATE\", payload: msg };\n}\nexport function UpdateControllerStatuses(msg) {\n return { type: \"MQTT_CONTROLLER_STATUSES_UPDATE\", payload: msg };\n}\n\nexport function UpdateFireflyCoordinates(fireflyCoordinates, userSettings) {\n return {\n type: \"MQTT_FIREFLY_COORDINATES_UPDATE\",\n payload: { fireflyCoordinates, userSettings },\n };\n}\nexport function UpdateFireflyStatuses(msg) {\n return { type: \"MQTT_FIREFLY_STATUSES_UPDATE\", payload: msg };\n}\n\n// sets the activeArea as the area being actively viewed\nexport function SetActiveArea(area) {\n return { type: \"SET_ACTIVE_AREA\", payload: area };\n}\n\nexport function UpdateAreaInfos(msg) {\n return { type: \"MQTT_AREA_INFOS_UPDATE\", payload: msg };\n}\nexport function UpdateAreaStatuses(msg) {\n return { type: \"MQTT_AREA_STATUSES_UPDATE\", payload: msg };\n}\n\nexport function UpdateNamedAreaInfos(msg) {\n return { type: \"MQTT_NAMED_AREA_INFOS_UPDATE\", payload: msg };\n}\nexport function UpdateNamedAreaStatuses(msg) {\n return { type: \"MQTT_NAMED_AREA_STATUSES_UPDATE\", payload: msg };\n}\n\nexport function UpdateNamedAreaEvents(msg) {\n return { type: \"MQTT_NAMED_AREA_EVENTS_UPDATE\", payload: msg };\n}\n\nexport function UpdateEmergencyEventSettings(msg) {\n return { type: \"MQTT_EMERGENCY_EVENT_SETTINGS_UPDATE\", payload: msg };\n}\n\nexport function UpdateTriggerEventSettings(msg) {\n return { type: \"MQTT_TRIGGER_EVENT_SETTINGS_UPDATE\", payload: msg };\n}\n\nexport function UpdateAcks(msg) {\n return { type: \"MQTT_ACKS_UPDATE\", payload: msg };\n}\n\nexport function removeAcks(token) {\n return { type: \"REMOVE_ACKS\", payload: token };\n}\n\nexport function isAcksReceived(token) {\n return { type: \"CHECK_RECEIVE_ACKS\", payload: token };\n}\n\n// Device Timestamps\nexport function UpdateDeviceTimestamps(msg) {\n return { type: \"MQTT_DEVICE_TIMESTAMPS\", payload: msg };\n}\n\n// Server Timestamp from system/timestamp\nexport function UpdateServerTimestamp(msg) {\n return { type: \"MQTT_SERVER_TIMESTAMP\", payload: msg };\n}\n\n// Server Timestamp from system/timestamp\nexport function UpdateSystemProcessMsg(msg) {\n return { type: \"MQTT_SYSTEM_PROCESS_MSG_UPDATE\", payload: msg };\n}\n\n// Server Timestamp from system/timestamp\nexport function ClearSystemProcessMsg(msg) {\n return { type: \"MQTT_SYSTEM_PROCESS_MSG_CLEAR\", payload: msg };\n}\n\n// trigger recalc\nexport function UpdateRecalcState(msg) {\n return { type: \"MQTT_RECALC_STATE\", payload: msg };\n}\n\n// publishing message actions\n\nexport function mqttPublish(mqttMsg) {\n return { type: \"MQTT_PUBLISH\", payload: mqttMsg };\n}\n\n// WIP - not used ATM\nexport function removeMqttMessage(id) {\n return { type: \"REMOVE_MQTT_MESSAGE\", payload: { id } };\n}\n\nexport function removeMqttMessageByToken(token) {\n return { type: \"REMOVE_MQTT_MESSAGE_BY_TOKEN\", payload: token };\n}\n\nexport function clearMqttMessages() {\n return { type: \"CLEAR_MQTT_MESSAGES\" };\n}\n\n// passes list of named areas to be removed from the maps\n// this is done:\n// * to avoid the delay of waiting for the named area to be deleted by mqtt/broker\n// * accommodate removal of named area polygons created locally but never saved to the system (db)\n\nexport function namedAreaSetDeleteSelections(deleteSelections) {\n return {\n type: \"MAP_SET_DELETE_SELECTIONS_NAMED_AREAS\",\n payload: deleteSelections,\n };\n}\n\nexport function namedAreaClearDeleteSelections(id) {\n return { type: \"MAP_CLEAR_DELETE_SELECTIONS_NAMED_AREAS\", payload: id };\n}\n\nexport function namedAreaSetShowHideSelections(hideSelections) {\n return { type: \"MAP_SET_HIDE_NAMED_AREAS\", payload: hideSelections };\n}\n\nexport function namedAreaClearShowHideSelections(hideSelections) {\n return { type: \"MAP_CLEAR_HIDE_NAMED_AREAS\", payload: hideSelections };\n}\n\n// id = parent id for namedArea group\nexport function namedAreasSetIsDirty(id) {\n return { type: \"MAP_NAMED_AREAS_SET_IS_DIRTY\", payload: id };\n}\n\n// id = parent id for namedArea group\nexport function namedAreasClearIsDirty(id) {\n return { type: \"MAP_NAMED_AREAS_CLEAR_IS_DIRTY\", payload: id };\n}\n\n// data loading\nexport function UpdateDataLoadingResponseRequestQueue(queueArray) {\n return {\n type: \"MQTT_DATA_LOADING_RESPONSE_REQUEST_MESSAGE_QUEUE\",\n payload: queueArray,\n };\n}\n\n// data loading\nexport function fireflyIdsUpdateListDeleteId(id) {\n // fireflyIdsUpdateList\n // console.log(\n // `fireflyIdsUpdateList MQTT_FIREFLY_STATUSES_UPDATE_LIST_DELETE_ID`,\n // id\n // );\n return {\n type: \"MQTT_FIREFLY_STATUSES_UPDATE_LIST_DELETE_ID\",\n payload: id,\n };\n}\n\n// clear API data fetch flag\nexport function clearDataFetched(key) {\n return { type: \"CLEAR_DATA_FETCHED\", payload: key };\n}\n\n// set flag to reload area images\nexport function setAreaImageChanged(bool) {\n return { type: \"SET_AREA_IMAGES_CHANGED\", payload: bool };\n}\n","// see - src/components/RegionPreview/reducer.js\n// see main reducer at src/reducers.js\n//\n\nimport Immutable from \"seamless-immutable\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n\nlet initialState = Immutable({\n localMapState: {},\n movingMap: false, // state of current map. If moving (zoom, drag etc.) don't update data\n draggingMarker: false,\n});\n\nexport default function reduce(state = initialState, action = {}) {\n // copy existing state\n const newState = { ...state };\n\n const { type, payload } = action;\n switch (type) {\n case \"UPDATE_LOCAL_MAP\":\n newState.localMapState = payload;\n return newState;\n case \"CLEAR_LOCAL_MAP\":\n return initialState;\n case \"UPDATE_MOVING_MAP\":\n // state of current map. If moving (zoom, drag etc.) don't update data.\n // Also used to track activity on polygon edits.\n newState.movingMap = payload;\n return newState;\n\n case \"UPDATE_DRAGGING_MARKER\":\n // Used to track markers being dragged/edited\n newState.draggingMarker = payload;\n return newState;\n\n case \"RESET\":\n console.log(\"RESET! - Map\");\n return initialState; //Always return the initial state\n\n default:\n return state;\n }\n}\n\nexport const GetLocalMap = (state) => state.map.localMapState;\n\nexport const isMapMoving = (state) => state.map.movingMap;\n\nexport const isDraggingMarker = (state) => state.map.draggingMarker;\n\n// Selectors\n\n// subset (reduced) of properties for each named area\n// used to directly compare named areas objects excluding geometry etc.\nexport const GetLocalMapNamedAreasReducedProperties = (state) => {\n const namedAreas = state.map.localMapState?.namedAreas?.features;\n\n let reducedProperties = [];\n\n if (namedAreas !== undefined && !_isEmpty(namedAreas)) {\n namedAreas.forEach(({ properties }, index, arr) => {\n const {\n id,\n name,\n parent,\n origin,\n area,\n priority,\n button,\n coordinatesUtm,\n } = properties;\n\n const reducedProperty = {\n id: id,\n name: name,\n parent: parent,\n origin: origin,\n area: area,\n priority: priority,\n button: button,\n coordinatesUtm: coordinatesUtm,\n };\n\n reducedProperties.push(reducedProperty);\n });\n }\n\n return reducedProperties;\n};\n","export function UpdateLocalMap(mapState) {\n return { type: \"UPDATE_LOCAL_MAP\", payload: mapState };\n}\n\nexport function ClearLocalMap() {\n return { type: \"CLEAR_LOCAL_MAP\" };\n}\n\nexport function SetMapMoving(bool) {\n return { type: \"UPDATE_MOVING_MAP\", payload: bool };\n}\n\nexport function SetMapMarkerDragging(bool) {\n return { type: \"UPDATE_DRAGGING_MARKER\", payload: bool };\n}\n","// sort the locations so they list in order on the screen\nexport const sortAlphaNum = (a, b) =>\n a.localeCompare(b, \"en\", { numeric: true });\n","export function round(val, places = 4) {\n switch (typeof val) {\n case \"number\":\n const rnd = Math.pow(10, places);\n return Math.round(val * rnd) / rnd;\n case \"string\":\n return round(Math.parseFloat(val), places);\n default:\n return val;\n }\n}\n","// see - https://github.com/lodash/lodash/issues/723#issuecomment-332321054\n// see - https://gist.github.com/Billy-/d94b65998501736bfe6521eadc1ab538\nexport function omitDeep(value, key) {\n if (Array.isArray(value)) {\n return value.map((i) => omitDeep(i, key));\n } else if (typeof value === \"object\" && value !== null) {\n return Object.keys(value).reduce((newObject, k) => {\n if (k == key) return newObject;\n return Object.assign({ [k]: omitDeep(value[k], key) }, newObject);\n }, {});\n }\n return value;\n}\n","export function upsStatusUpdate(id, status) {\n return { type: \"UPS_STATUS_UPDATE\", payload: { id, ...status } };\n}\n\nexport function travelwayStatusUpdate(id, status) {\n return { type: \"TRAVELWAY_STATUS_UPDATE\", payload: { id, ...status } };\n}\n\nexport function fireflyStatusUpdate(id, status) {\n return { type: \"FIREFLY_STATUS_UPDATE\", payload: { id, ...status } };\n}\n\nexport function savePositions(payload) {\n return {\n type: \"COMMISSION_RECORDS_REQUEST\",\n payload,\n };\n}\n\nexport function saveUPS(payload) {\n return { type: \"SAVE_UPS\", payload };\n}\n\nexport function saveFirefly(payload) {\n return { type: \"SAVE_FIREFLY\", payload };\n}\n\n// #NOTE - no longer used for direct control of lights\n// Left in place for historic reference ATM\nexport function saveFireflyLed(payload) {\n return { type: \"SAVE_FIREFLY_LED\", payload };\n}\n\nexport function saveEmergencyEventSettings(payload) {\n return { type: \"SAVE_EMERGENCY_EVENT_SETTINGS\", payload };\n}\n\nexport function saveTriggerEventSettings(payload) {\n return { type: \"SAVE_TRIGGER_EVENT_SETTINGS\", payload };\n}\n\nexport const fetchUPSs = () => ({ type: \"UPS_FETCH_REQUESTED\" });\n\nexport const fetchFireflys = (payload) => ({\n type: \"FIREFLY_FETCH_REQUESTED\",\n payload,\n});\n\nexport function fetchFireflyAreaLightingplan(payload) {\n return { type: \"FIREFLY_AREA_LIGHTINGPLAN_FETCH_REQUESTED\", payload };\n}\n\n// #REVIEW - not used?\nexport const fetchFireflyNotes = () => ({\n type: \"FIREFLY_NOTE_FETCH_REQUESTED\",\n});\n\nexport function deleteUPS(payload) {\n return { type: \"DELETE_UPS\", payload };\n}\n\nexport function deleteFirefly(payload) {\n return { type: \"DELETE_FIREFLY\", payload };\n}\n\nexport function runDiscoveryUPS(id) {\n return { type: \"UPS_RUN_DISCOVERY\", payload: { id } };\n}\n\nexport function UPSSendAdvancedConfig(payload) {\n return { type: \"UPS_SEND_ADVANCED_CONFIG\", payload };\n}\n\nexport function sendTravelway(cmdPayload) {\n return { type: \"TRAVELWAY_SEND_COMMAND\", payload: { cmdPayload } };\n}\n\nexport function sendUPSCommand(id, cmdPayload) {\n return { type: \"UPS_SEND_COMMAND\", payload: { id, cmdPayload } };\n}\n","// change colors to web colors\nexport function toWebColor(color) {\n const lowerCaseColor = color?.toLowerCase();\n // catch the exceptions 1st\n switch (lowerCaseColor) {\n case \"amber\":\n return \"orange\";\n case \"white\":\n return \"grey\";\n // return everything else as-is\n case lowerCaseColor:\n return lowerCaseColor;\n default:\n return \"grey\";\n }\n}\n","import L from \"leaflet\";\n\nconst worker = `\n\n \n\n`;\n\nconst fillColor = `rgb(255, 165, 0)`;\n\nconst fireflySvg = `\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 8\n \n \n 9\n \n \n 10\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n`;\n\nconst loaderSvg = `\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n`;\n\n// Stuart tag tracking icon test files\n//\n// create icon\nexport const _hackedFireFly = L.icon({\n iconName: \"TagUnknownMarker\",\n iconUrl: `data:image/svg+xml;base64, ${btoa(worker)}`,\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [50, 50],\n className: null,\n});\n\nexport const hackedFireFly = L.icon({\n iconName: \"TagUnknownMarker\",\n iconUrl: `data:image/svg+xml;base64, ${btoa(fireflySvg)}`,\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [25, 25],\n className: null,\n});\n\nexport const hackedLoader = L.icon({\n iconName: \"TagUnknownMarker\",\n iconUrl: `data:image/svg+xml;base64, ${btoa(loaderSvg)}`,\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [50, 50],\n className: null,\n});\n\n// Ambulance\n// Light_Vehicle\n// Loader\n// Truck\n// Jumbo\n\n// TagAmbulanceMarker\n// TagLightVehicleMarker\n// TagLoaderMarker\n// TagTruckMarker\n// TagJumboMarker\n\nexport const hackedAmbulancePng = L.icon({\n iconName: \"TagAmbulanceMarker\",\n iconUrl: process.env.PUBLIC_URL + \"/images/Ambulance.png\",\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [50, 50],\n className: null,\n});\n\n// \"TagLightVehicleMarker\",\n\nexport const hackedLightVehiclePng = L.icon({\n iconName: \"TagLightVehicleMarker\",\n iconUrl: process.env.PUBLIC_URL + \"/images/Light_Vehicle.png\",\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [50, 50],\n className: null,\n});\n\nexport const hackedLoaderPng = L.icon({\n iconName: \"TagLoaderMarker\",\n iconUrl: process.env.PUBLIC_URL + \"/images/Loader.png\",\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [50, 50],\n className: null,\n});\n\nexport const hackedTruckPng = L.icon({\n iconName: \"TagTruckMarker\",\n iconUrl: process.env.PUBLIC_URL + \"/images/Truck.png\",\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [50, 50],\n className: null,\n});\n\nexport const hackedJumboPng = L.icon({\n iconName: \"TagJumboMarker\",\n iconUrl: process.env.PUBLIC_URL + \"/images/Jumbo.png\",\n iconColor: { stroke: \"green\", fill: \"green\", text: \"\" }, // hacked the position into color property\n iconSize: [50, 50],\n className: null,\n});\n","import React, { Component } from \"react\";\nimport L from \"leaflet\";\n//import \"leaflet.awesome-markers/dist/leaflet.awesome-markers.css\";\n//import \"leaflet.awesome-markers/dist/leaflet.awesome-markers\";\n\nimport { toWebColor } from \"utils/toWebColor\";\nimport { markerSize as IconMarkerSize } from \"components/ConfigJs\";\n\n// TESTING - pulsating effect\n// #NOTE - 7Dec21 - having this present (and the icon var defined)\n// cause major re-rendering with \"Recalculate Style\" issues on the freeport bomgar Chrome jump point demo.\n//\n//import \"components/Map/leafletIconPulse.css\";\n//import \"components/Map/leafletIconPulse.js\";\n\n// TESTING - MARIO\n//import \"components/Map/mario_1.scss\";\n//import \"components/Map/mario_1.js\";\n\nimport \"components/Map/mario_2.css\";\n\n// TESTING - SVG icons from illustrator\n\nimport {\n hackedLoaderPng,\n hackedJumboPng,\n hackedAmbulancePng,\n hackedLightVehiclePng,\n hackedTruckPng,\n} from \"components/Map/MakeIconSvgIcons.js\";\n\n// #NOTE - Instructions on how to make SVG icons.\n//\n// Open boxy svg (see - https://boxy-svg.com/)\n//\n// Create (from new or open existing & mod) an SVG.\n// Save to /icon/filename.svg e.g. triangle.svg\n// Open svg file with text editor.\n\n// e.g.\n\n// \n// \n// \n// \n// \n// \n\n// Save to object file in js.\n// Make sure width and height are correct since all paths are relative to these values.\n\n// Replace fill and stroke variables.\n\n// e.g.\n\n// if (name === \"triangle\") {\n// icon = `\n// \n// \n// \n// `;\n// }\n\nconst { marker: markerSize, tag: tagSize } = IconMarkerSize();\n\nexport const makeIcon = (name, style, zoom) => {\n\n // Icons inspired by:\n // https://stackoverflow.com/questions/51850249/leaflet-js-too-slow-with-custom-svg-markers-and-a-lot-of-points\n // ToDo: Analyze the above document.\n\n const { stroke, fill, text = \"\", opacity = \"1\" } = style;\n const strokeColor = toWebColor(stroke);\n const alternateStrokeColor = (style.alternate_stroke !== undefined) ? toWebColor(style.alternate_stroke) : strokeColor;\n const fillColor = toWebColor(fill);\n const alternateFillColor = (style.alternate_fill !== undefined) ? toWebColor(style.alternate_fill) : fillColor;\n\n const forcedIcon = ``;\n\n const stdText_1 = (text) => {\n return `${text}`;\n };\n\n let icon;\n let iconClass = null;\n let isForced = true;\n \n // Note: Some of the following SVG definitions are based on http://www.smiffysplace.com/stars.html\n if (name === \"6-pointed-star\") {\n\n icon = `\n \n `;\n } else if (name === \"CrossMarker\") {\n\n // Cross\n icon = ` \n \n `;\n } else if (name === \"Cross45Marker\") {\n\n // Cross45\n icon = ` \n \n `;\n } else if (name === \"OffMarker\") {\n\n // Round\n icon = `\n \n \n `;\n } else if (name === \"RoundMarker\") {\n\n // Round\n icon = `\n \n ${text !== \"\" ? stdText_1(text) : null}\n `;\n } else if (name === \"MultiStrobeMarker\") {\n\n // MultiStrobe\n icon = `\n \n \n `;\n } else if (name === \"RoundMarkerForced\") {\n\n // Round\n icon = `\n \n ${stdText_1(\"F\")}\n `;\n } else if (name === \"TypicalNumberedMapMarker\") {\n\n // Typical Map Marker\n const posnText =\n text < 10\n ? `${text}`\n : `${text}`;\n\n icon = `\n \n \t \n \n ${posnText}\n `;\n } else if (name === \"SquareMarker\") {\n\n // Square\n icon = `\n \n ${text !== \"\" ? stdText_1(text) : null}\n `;\n // Note: To make SquareMarker blink enable the iconClass = \"iconBlinking\"\n if (false) {\n iconClass = \"iconBlinking\";\n }\n } else if (name === \"SquareMarkerHandle\") {\n\n // Square\n icon = `\n \n `;\n iconClass = \"iconEditable\";\n } else if (name === \"DiamondMarker\") {\n\n // Square `rotate(<45degrees> )`\n icon = `\n \n `;\n } else if (name === \"DiamondMarker2\") {\n\n // Diamond\n icon = ` \n \n `;\n } else if (name === \"TravelwayMarker\") {\n\n // Travelway\n icon = `\n \n \n `;\n } else if (name === \"StarMarker\") {\n\n // Star\n icon = `\n \n `;\n } else if (name === \"HourGlassMarker\") {\n\n // HourGlass\n icon = `\n \n \n `;\n } else if (name === \"BowTieMarker\") {\n\n // BowTie\n icon = `\n \n \n `;\n } else if (name === \"TriangleMarker\") {\n \n // Triangle\n icon = `\n \n \n \n `;\n } else if (name === \"ForwardMarker\") {\n\n // Triangle\n icon = `\n \n \n `;\n } else if (name === \"BackwardMarker\") {\n \n // Triangle\n icon = `\n \n \n `;\n } else if (name === \"WorkerMarker\") {\n\n icon = `\n \n \n \n `;\n }\n\n // Here's the trick, base64 encode the URL\n var svgURL = \"data:image/svg+xml;base64,\" + btoa(icon);\n\n function between(x, min, max) {\n return x >= min && x <= max;\n }\n\n let scaleIcon = 6;\n\n // Note: This seems ridiculous, but I wanted the option to cap out the size.\n\n // switch (true) {\n // case zoom < -5:\n // scaleIcon = 2;\n // break;\n // case zoom < -4:\n // scaleIcon = 4;\n // break;\n // case zoom < -3:\n // scaleIcon = 6;\n // break;\n // case zoom < -2:\n // scaleIcon = 8;\n // break;\n // case zoom < -1:\n // scaleIcon = 10;\n // break;\n // case zoom < 0:\n // scaleIcon = 12;\n // break;\n // case zoom < 1:\n // scaleIcon = 14;\n // break;\n // case zoom < 2:\n // scaleIcon = 16;\n // break;\n // case zoom < 3:\n // scaleIcon = 18;\n // break;\n // case zoom < 4:\n // scaleIcon = 20;\n // break;displayTagTypes\n // default:\n // scaleIcon = 6;\n // break;\n // }\n\n scaleIcon = Math.trunc(2 * zoom + 12); // Trunc to integer\n\n if (name === \"WorkerMarker\") {\n scaleIcon = scaleIcon * 3; // Note: Worker should be bigger\n }\n\n // create default icon type\n var svgIcon = L.icon({\n iconName: name,\n iconUrl: svgURL,\n iconColor: { stroke: strokeColor, fill: fillColor, text },\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize],\n //shadowSize: [12, 10],\n //iconAnchor: [5, 5],\n //popupAnchor: [5, -5],\n //\n className: iconClass,\n });\n\n // ****************************************************\n //\n // TESTING - animated icons\n //\n //\n\n // currently supports circular icons only\n // https://github.com/mapshakers/leaflet-icon-pulse\n // var _test_pulse = L.icon.pulse({\n // //#WIP - need to add name support for leaflet!\n\n // iconName: name,\n // // ^^^^^^^^^^^^\n // iconSize: [scaleIcon * markerSize, scaleIcon * markerSize],\n // color: strokeColor,\n // fillColor: fillColor,\n // heartbeat: 1,\n // });\n\n // https://stackoverflow.com/questions/41884070/how-to-make-markers-in-leaflet-blinking\n var _tests_2_pulse = L.divIcon({\n iconName: name,\n // Specify a class name we can refer to in CSS.\n className: \"css-icon\",\n html: '
',\n // Set marker width and height\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize],\n // ,iconAnchor: [11,11]\n });\n\n // transition between colors?\n // https://stackoverflow.com/questions/48619314/animated-transition-of-leaflet-marker-icon\n\n // mario_1 animation\n // see - https://codepen.io/thatianepisco/pen/JrYMBK\n // see - https://stackoverflow.com/questions/64625050/error-node-sass-version-5-0-0-is-incompatible-with-4-0-0\n //\n // npm uninstall node-sass\n // npm install node-sass@4.14.1\n //\n var _tests_3_mario_1 = L.divIcon({\n // Specify a class name we can refer to in CSS.\n className: \"css-icon\",\n html: `
`,\n // Set marker width and height\n iconName: name,\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize],\n // ,iconAnchor: [11,11]\n });\n\n // mario_2 animation\n // see - https://codepen.io/LantareCode/pen/dOXmBJ\n // This proves any spritesheet will work OK! ;)\n //\n //\n var _tests_3_mario_2 = L.divIcon({\n iconName: name,\n // Specify a class name we can refer to in CSS.\n className: \"css-icon\",\n html: '
',\n // these have no impact on image but are necessary for code\n // sizing is done through scaling, see css\n // see also - https://stackoverflow.com/questions/2430206/how-can-i-scale-an-image-in-a-css-sprite\n //\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize],\n // sets the anchor point relative to the scaled size - see CSS. Image is 70 (as per sprite sheet), scale is 50%\n iconAnchor: [15, -15], // [+ve = left, -ve = down]\n\n // these have no impact on image but are necessary for code\n iconColor: { stroke: strokeColor, fill: fillColor },\n });\n\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n // create icon\n var typicalNumberedMapMarker = L.icon({\n iconName: name,\n iconUrl: svgURL,\n iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n iconSize: [50, 70],\n iconAnchor: [25, 58],\n className: iconClass,\n });\n\n //https://www.npmjs.com/package/leaflet.awesome-markers\n // var redMarker = L.AwesomeMarkers.icon({\n // iconName: name,\n // prefix: \"fa\",\n // icon: \"coffee\",\n // markerColor: \"pink\",\n // iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n // //className: \"awesome-marker awesome-marker-square\",\n // });\n\n // for styling and stacking see\n // https://fontawesome.com/v5.15/how-to-use/on-the-web/styling/stacking-icons\n // offset idea - https://stackoverflow.com/questions/52773353/putting-a-number-inside-a-font-awesome-icon-marker-for-google-maps-marker-label\n // for layers see - // https://fontawesome.com/v5.15/how-to-use/on-the-web/styling/layering\n\n // color options - see https://www.html-color-names.com/color-chart.php\n\n // hardhat tag markers\n // tagHardHatMarker\n var tagHardHatMarker0deg = L.divIcon({\n iconName: name,\n // Note - below offsets the flag to ~center on top section of the marker\n // - fa-map-marker-alt <-- has circle on map marker\n // user-hard-hat\n // hard-hat\n html: ` ${text}`,\n iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize], // [50, 20],\n // _OLD - off centre positioning\n // iconAnchor: [\n // scaleIcon * markerSize * (1 - 0.15), // slightly off centre to the right\n // scaleIcon * markerSize * (1 + 0.5), //\n // ],\n iconAnchor: [\n scaleIcon * markerSize * (1 - 0.15), // slightly off centre to the right\n scaleIcon * markerSize * (1 + 0.5), //\n ],\n className: \"myDivIcon\", // <<--- see .css for color property\n });\n\n // heavy vehicle marker\n // fa-truck-plow tag marker\n // Note - this uses an rotated map-marker with different offsets\n // tagTruckPlowMarker\n var tagTruckPlowMarker180deg = L.divIcon({\n iconName: name,\n html: ` ${text}`,\n iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize], // [50, 20],\n iconAnchor: [\n scaleIcon * markerSize * (1 - 0.15), //\n scaleIcon * markerSize * (1 - 1.3), //\n ],\n className: \"myDivIcon\", // <<--- see .css for color property\n });\n\n // light vehicle marker\n // \n // Note - this uses an rotated map-marker with different offsets\n // tagTruckPickupMarker\n var tagTruckPickupMarker180deg = L.divIcon({\n iconName: name,\n //html: '',\n // Note - below offsets the flag to ~center on top section of the marker\n // - fa-map-marker-alt <-- has circle on map marker\n html: ` ${text}`,\n iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize], // [50, 20],\n iconAnchor: [\n scaleIcon * markerSize * (1 - 0.15), // X axis\n scaleIcon * markerSize * (1 - 1.3), // Y axis\n ],\n className: \"myDivIcon\", // <<--- see .css for color property\n });\n\n // unknown tag type marker\n // Note - this uses an rotated map-marker with different offsets\n // tagTruckPickupMarker\n var tagUnknownMarker270deg = L.divIcon({\n iconName: name,\n //html: '',\n // Note - below offsets the flag to ~center on top section of the marker\n // - fa-map-marker-alt <-- has circle on map marker\n html: ` ${text}`,\n iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize], // [50, 20],\n iconAnchor: [\n scaleIcon * markerSize * (1 + 0.75), // slightly off centre to the left\n scaleIcon * markerSize * (1 - 0.35), //\n ],\n\n className: \"myDivIcon\", // <<--- see .css for color property\n });\n\n // marker custom tag icons\n // #Note - when marker clustering was introduced it was no longer necessary (or desireable) to\n // rotate the markers for positioning, so a generalised icon was introduced.\n\n function tagMarkerIcon(\n markerType,\n name,\n tagSize,\n markerSize,\n scaleIcon,\n fillColor,\n strokeColor,\n text\n ) {\n return L.divIcon({\n iconName: name,\n html: ` ${text}`,\n iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize], // [50, 20],\n iconAnchor: [\n scaleIcon * markerSize * (1 - 0.15), // slightly off centre to the right\n scaleIcon * markerSize * (1 + 0.25), //\n ],\n className: \"myDivIcon\", // <<--- see .css for color property\n });\n }\n\n // siren marker\n // \n // \n var relaySirenMarker = L.divIcon({\n iconName: name,\n html: ``,\n iconColor: { stroke: strokeColor, fill: fillColor, text }, // hacked the position into color property\n iconSize: [scaleIcon * markerSize, scaleIcon * markerSize], // [50, 20],\n iconAnchor: [scaleIcon * markerSize, scaleIcon * markerSize], //[30, 55]\n className: \"myDivIcon\", // <<--- see .css for color property\n });\n\n // special case makeIcon return\n if (false && name === \"RoundMarkerForced\") {\n // #TESTING - temporary disable separate marker for Forced lights\n return _tests_3_mario_2; // _test_pulse;\n } else if (name === \"TypicalNumberedMapMarker\") {\n return typicalNumberedMapMarker;\n } else if (name === \"TagHardHat\") {\n return tagMarkerIcon(\n \"fa-hard-hat\",\n name,\n tagSize,\n markerSize,\n scaleIcon,\n fillColor,\n strokeColor,\n text\n ); // tagHardHatMarker;\n } else if (name === \"TagTruckPickupMarker\") {\n return tagMarkerIcon(\n \"fa-truck-pickup\",\n name,\n tagSize,\n markerSize,\n scaleIcon,\n fillColor,\n strokeColor,\n text\n ); // tagTruckPickupMarker;\n } else if (name === \"TagUnknownMarker\") {\n return tagMarkerIcon(\n \"fa-question\",\n name,\n tagSize,\n markerSize,\n scaleIcon,\n fillColor,\n strokeColor,\n text\n ); // tagUnknownMarker;\n }\n\n // TagAmbulanceMarker\n // TagLightVehicleMarker\n // TagLoaderMarker\n // TagTruckMarker\n // TagJumboMarker\n\n // TESTING - illustrator as source for SVG icons\n // .. comment out working tag markers\n // Stuart test icons\n else if (name === \"RelaySirenMarker\") {\n return relaySirenMarker;\n } else if (name === \"TagAmbulanceMarker\") {\n return hackedAmbulancePng;\n } else if (name === \"TagLightVehicleMarker\") {\n return hackedLightVehiclePng;\n } else if (name === \"TagLoaderMarker\") {\n return hackedLoaderPng;\n } else if (name === \"TagTruckMarker\") {\n return hackedTruckPng;\n } else if (name === \"TagJumboMarker\") {\n return hackedJumboPng;\n } else if (name === \"TagJumboMarker\") {\n return hackedJumboPng;\n }\n\n // default makeIcon return\n return svgIcon;\n};\n\n// ***********************************************************************\n//\n// React versions of above SVGs\n//\n// see - https://stackoverflow.com/questions/19484707/how-can-i-make-an-svg-scale-with-its-parent-container\n//\n// ***********************************************************************\n\nconst CrossMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n );\n};\n\nconst Cross45Marker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n );\n};\n\nconst RoundMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n );\n};\n\nconst SquareMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n );\n};\n\nconst DiamondMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n );\n};\n\nconst TravelwayMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n \n );\n};\n\nconst StarMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n );\n};\n\nconst HourGlassMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n \n );\n};\n\nconst BowTieMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n \n );\n};\n\nconst TriangleMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n \n \n );\n};\n\nconst ForwardMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n \n );\n};\n\nconst BackwardMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n \n \n \n \n );\n};\n\nconst WorkerMarker = (fillColor, strokeColor, size, markerClass) => {\n return (\n \n \n {/* \n */}\n {\" \"}\n \n \n );\n};\n\nexport class RenderSvgIcon extends Component {\n render() {\n const { name, strokeColor, fillColor, size, markerClass } = this.props;\n let svg;\n\n const forced = true;\n\n switch (name) {\n case \"CrossMarker\":\n svg = CrossMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"Cross45Marker\":\n svg = Cross45Marker(fillColor, strokeColor, size, markerClass);\n break;\n case \"RoundMarker\":\n svg = RoundMarker(fillColor, strokeColor, size, markerClass, forced);\n break;\n\n case \"SquareMarker\":\n svg = SquareMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"DiamondMarker\":\n svg = DiamondMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"TravelwayMarker\":\n svg = TravelwayMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"StarMarker\":\n svg = StarMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"TriangleMarker\":\n svg = TriangleMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"HourGlassMarker\":\n svg = HourGlassMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"BowTieMarker\":\n svg = BowTieMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"ForwardMarker\":\n svg = ForwardMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"BackwardMarker\":\n svg = BackwardMarker(fillColor, strokeColor, size, markerClass);\n break;\n case \"WorkerMarker\":\n svg = WorkerMarker(fillColor, strokeColor, size, markerClass);\n break;\n default:\n svg = RoundMarker(fillColor, strokeColor, size, markerClass, false);\n break;\n }\n return svg;\n }\n}\n","import React from \"react\";\nimport { Button, Popup, Icon, Grid } from \"semantic-ui-react\";\nimport { round } from \"utils/number-utils.js\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nexport const NamedAreaPolygonPopup = ({ id, data }) => {\n const { parent, parentName, sub_type } = data;\n\n // APP_TERMINOLOGY\n let strNamedArea = \"Region\";\n\n switch (sub_type) {\n case \"tagzone\":\n strNamedArea = \"Tag Zone\";\n break;\n case \"forced\":\n strNamedArea = \"Forced FireFly\";\n break;\n case null:\n default:\n break;\n }\n\n // #NOTE - the `dataid` passed to the Butotn is used to attach an eventListener to the rendered string.\n // This is how the onClick event is setup.\n // See - src/components/Map/MineLevelMapLeaflet.js\n // \"... .addEventListener(\"click\", (e) => { ...\"\n\n //\n //\n // #NOTE - `dataid` is places on both button and icon, as it is not possible to guarantee only one click target.\n\n // console.log(\n // \"NamedAreaPolygonPopup parent, parentName, sub_type\",\n // parent,\n // parentName,\n // sub_type\n // );\n\n return (\n \n \n \n \n {strNamedArea}: \n \n \n {parentName || \"unknown\"}{\" \"}\n \n \n \n \n \n \n );\n};\n","import Immutable from \"seamless-immutable\";\n\nconst initialState = Immutable([]);\n\nexport default function reduce(state = initialState, action = {}) {\n const { type, payload } = action;\n\n switch (type) {\n case \"SHOW_AREA_PREVIEW\":\n return Immutable(payload);\n case \"CLEAR_AREA_PREVIEW\":\n case \"STOP_AREA_PREVIEW\":\n return initialState;\n case \"ADD_AREA_PREVIEW\":\n // console.log(`xxxx ADD_AREA_PREVIEW payload`, payload);\n return Immutable(state.asMutable().concat([payload]));\n case \"ADD_ALL_AREA_PREVIEW\":\n //console.log(`xxxx ADD_ALL_AREA_PREVIEW payload`, payload);\n let newState = [...state];\n payload.forEach((element) => {\n // console.log(`xxxx element`, element);\n // console.log(`xxxx newState`, newState);\n if (!newState.find((preview) => preview?.spec === element?.spec)) {\n newState.push(element);\n }\n });\n // console.log(`xxxx newState`, newState);\n return Immutable(newState);\n case \"REMOVE_AREA_PREVIEW\":\n //console.log(`xxxx REMOVE_AREA_PREVIEW payload`, payload);\n return Immutable(\n state.asMutable().filter((preview) => preview?.spec !== payload?.spec)\n );\n default:\n return state;\n }\n}\n\nexport const getRegionPreviewList = (state) => {\n return state.regionPreview;\n};\n\nexport const getRegionPreviewListByAreaId = (state, id) => {\n return state.regionPreview?.filter?.((preview) => preview.id === id);\n};\n","export function fetchNamedAreas() {\n return { type: \"NAMED_AREAS_FETCH_REQUESTED\" };\n}\n\nexport function fetchNamedAreaEvents() {\n return { type: \"NAMED_AREA_EVENTS_FETCH_REQUESTED\" };\n}\n\nexport function fetchNamedAreaTriggers() {\n return { type: \"NAMED_AREA_TRIGGERS_FETCH_REQUESTED\" };\n}\n\nexport function fetchNamedAreaExtTriggerEventInfo() {\n return { type: \"NAMED_AREA_EXT_TRIGGER_EVENT_INFO_FETCH_REQUESTED\" };\n}\n\nexport function fetchNamedAreaScheduledEventInfo() {\n return { type: \"NAMED_AREA_SCHEDULED_EVENT_INFO_FETCH_REQUESTED\" };\n}\n\nexport function saveNewNamedArea(payload) {\n return { type: \"SAVE_NEW_NAMED_AREA\", payload };\n}\n\nexport function saveNewNamedAreaEvent(payload) {\n return { type: \"SAVE_NEW_NAMED_AREA_EVENT\", payload };\n}\n\nexport function saveNewEmergencyEvent(payload) {\n return { type: \"SAVE_NEW_EMERGENCY_EVENT\", payload };\n}\n\n// export function updateNamedArea(payload) {\n// return { type: \"UPDATE_NAMED_AREA\", payload };\n// }\n\nexport function deleteNamedArea(payload) {\n return { type: \"DELETE_NAMED_AREA\", payload };\n}\n\nexport function saveNewScheduledEvent(payload) {\n return { type: \"SAVE_NEW_SCHEDULED_EVENT\", payload };\n}\n\nexport function fetchScheduledEventJobs() {\n return { type: \"SCHEDULED_EVENT_JOBS_FETCH_REQUESTED\" };\n}\n\nexport function deleteScheduledEventJobs() {\n return { type: \"DELETE_SCHEDULED_EVENT_JOBS_REQUESTED\" };\n}\n\nexport function deleteScheduledEventJob(payload) {\n return { type: \"DELETE_SCHEDULED_EVENT_JOB_REQUESTED\", payload };\n}\n","export function isKthBitSet(n, k) {\n if ((n & (1 << (k - 1))) > 0) return true;\n else return false;\n}\n\nexport function bit_test(num, bit) {\n return (num >> bit) % 2 != 0;\n}\n\nexport function bit_set(num, bit) {\n return num | (1 << bit);\n}\n\nexport function bit_clear(num, bit) {\n return num & ~(1 << bit);\n}\n\nexport function bit_toggle(num, bit) {\n return bit_test(num, bit) ? bit_clear(num, bit) : bit_set(num, bit);\n}\n","export const showAreaPreview = (area) => ({\n type: \"SHOW_AREA_PREVIEW\",\n payload: area,\n});\n\nexport const stopAreaPreview = (area) => ({\n type: \"STOP_AREA_PREVIEW\",\n payload: area,\n});\n\nexport const addAreaPreview = (area) => ({\n type: \"ADD_AREA_PREVIEW\",\n payload: area,\n});\n\nexport const removeAreaPreview = (area) => ({\n type: \"REMOVE_AREA_PREVIEW\",\n payload: area,\n});\n\nexport const clearAreaPreview = () => ({\n type: \"CLEAR_AREA_PREVIEW\",\n});\n\nexport const addAllAreaPreview = (allPolygonsArray) => ({\n type: \"ADD_ALL_AREA_PREVIEW\",\n payload: allPolygonsArray,\n});\n","export const newNamedAreaTemplate = (\n id,\n name,\n parent,\n parentName,\n area,\n shape,\n color,\n lightState,\n namedAreaSubType,\n priority = 0,\n style\n) => {\n // #NOTE #TODO #WIP - MOVE DEFAULT SETUP TO CONFIG\n const { active_state, on_time = 20, off_time = 20, train = 20 } = lightState;\n\n // console.log(\n // `forcedLight xxxxxxxxxxxxx`,\n // id,\n // name,\n // parent,\n // parentName,\n // area,\n // shape,\n // color,\n // lightState,\n // style\n // );\n\n let marker = \"RoundMarker\";\n\n if (id.includes(\"FORCED\")) {\n marker = \"RoundMarkerForced\";\n }\n\n switch (active_state) {\n case \"strobe\":\n marker = \"SquareMarker\";\n break;\n case \"forward\":\n marker = \"ForwardMarker\";\n break;\n case \"backward\":\n marker = \"BackwardMarker\";\n break;\n case \"off\":\n marker = \"OffMarker\";\n break;\n case \"on\":\n break;\n\n default:\n // \"on\"\n break;\n }\n\n // #NOTE - there must be a button defined for the priority level selected for the namedArea\n //\n // if 'priority' is passed, create a button with this priority\n const makeButton = (priority) => {\n let result = [];\n for (let idx = 0; idx < priority; idx++) {\n result.push({});\n }\n result.push({\n priority: 0,\n type: \"SEISMIC0_EVENT\",\n clickable: true,\n icon: \"icon-earthquake0\",\n color: color,\n hint: \"Level 0\",\n title: \"Seismic 0\",\n alt: \"Level 0\",\n id: id,\n named_area: parent,\n group: 0,\n default: true,\n active: true,\n column: 0,\n state: active_state,\n active_color: color,\n active_state: active_state,\n on_time,\n off_time,\n train,\n marker,\n siren_state: \"off\",\n operator: \"client2\",\n });\n return result;\n };\n\n const result = {\n id: id,\n area: area,\n name: name,\n shape: shape,\n type: \"Polygon\",\n sub_type: namedAreaSubType,\n priority: 1,\n parent: parent,\n parent_name: parentName,\n // #WIP #TODO - set a central location for dummy buttons - used in a few places\n button: makeButton(priority),\n active_color: color,\n active_state,\n style: style,\n };\n\n // console.log(`forcedLight: NewNamedAreaTemplate `, result);\n\n return result;\n};\n","import { v4 as uuid } from \"uuid\";\nimport { newNamedAreaTemplate } from \"admin/named-area-simple/NewNamedAreaTemplate\";\n\nexport const createFireflyNamedAreaId = (fireflyId) => {\n // 'id'\n // normally namedAreas have an 'id' based on the time they are created.\n // For Firefly named areas, the id is based on the area:location:position of the firefly\n // except with - delimiters instead of colon, after all '-' are stripped prior to making the id\n //\n // e.g. id: \"DMLZ_Extraction:8429b438-2109-40b3-9084-54fb5f1feb59:DMLZ_Extraction-P17-1\"\n\n let id = fireflyId.replace(/-/g, \"\");\n id = id.replace(/:/g, \"-\");\n\n return `FORCED-${id}`;\n};\n\nexport const createNamedAreaAroundFirefly = (\n fireflyId,\n point,\n areaId,\n color,\n state,\n priority\n) => {\n // console.log(\n // `forcedLight: createNamedAreaAroundFirefly`,\n // fireflyId,\n // point,\n // areaId,\n // color,\n // state\n // );\n\n // 'point' is an object {easting, northing}\n //\n const areaName = uuid();\n\n const id = createFireflyNamedAreaId(fireflyId);\n const threshold = 1;\n const { easting, northing } = point;\n\n const shape = [\n [easting - threshold, northing + threshold],\n [easting + threshold, northing + threshold],\n [easting + threshold, northing - threshold],\n [easting - threshold, northing - threshold],\n // repeat 1st point\n [easting - threshold, northing + threshold],\n ];\n\n const namedAreaId = `${areaId}:${areaName}:${id}`;\n const name = `${id}`;\n const parent = `${areaId}:${areaName}`;\n const parentName = `${id}`; // there is only one polygon\n\n return newNamedAreaTemplate(\n namedAreaId,\n name,\n parent,\n parentName,\n areaId,\n shape,\n color,\n { active_state: state },\n \"forced\", //namedAreaSubType\n priority\n );\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n createNamedAreaAroundFirefly,\n createFireflyNamedAreaId,\n} from \"NamedAreas/createNamedAreaAroundFirefly\";\n\nimport { lightingEventPriority } from \"components/ConfigJs\";\n\n// #NOTE - DEFAULT PRIORITY SETTINGS\n//\n// MAX_PRIORITY = 10000 // <<--- see 'manager/manager.go'\n//const DEFAULT_START_FORCED_LIGHT_PRIORITY = 5000;\n\n// FireFly lights colors are 'forced' by creating a polygon around the light coordinate and applying a lighting\n// event for the color and state required.\n//\n// This function creates a new namedArea (Set) or deleted an existing namedArea (Clear).\n//\n\n// Parameters:\n//\n// action - \"clear\", \"lightState\", \"lightColor\"\n// fireflyId - e.g. \"DMLZ_Extraction:Panel1:1\"\n// easting - easting coordinate the FireFly e.g. 57.22\n// northing - northing coordinate the FireFly e.g. 94.54\n// area - area of the FireFly e.g. \"DMLZ_Exraction\"\n// color - color object for FireFly e.g. {status: {... }, plan: {...}}\n// setFireflyColor - target color to be forced e.g. \"red\"\n// newSetFireflyState - target state to be forced e.g. \"strobe\"\n\nexport const ForceSingleLightManageNamedArea = ({\n //properties\n action,\n fireflyId,\n area,\n easting,\n northing,\n color,\n setFireflyColor,\n setFireflyState,\n // functions\n namedAreaEvents,\n deleteNamedArea,\n saveNewNamedArea,\n activate,\n}) => {\n // create a namedAreaId for the firefly\n const fireflyNamedAreaId = createFireflyNamedAreaId(fireflyId);\n\n const namedAreaEventForFirefly = namedAreaEvents?.find((event) =>\n event.id.includes(fireflyNamedAreaId)\n );\n\n console.log(\n `FORCED LIGHT: setForceLight action,\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor,\n setFireflyState,\n fireflyNamedAreaId,\n namedAreaEventForFirefly`,\n action,\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor,\n setFireflyState,\n fireflyNamedAreaId,\n namedAreaEventForFirefly\n );\n\n let promiseArray = [];\n let operationButton = {};\n let isActivate = false;\n\n if (action === \"clear\") {\n // if there are existing events, delete them ...........\n if (namedAreaEventForFirefly) {\n //\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({\n values: { id: namedAreaEventForFirefly.id },\n resolve,\n reject,\n })\n )\n );\n }\n }\n // process the changes ...................\n else {\n // get strobe checkBox from State if it is not passed through the parameters\n let newSetFireflyState = \"on\";\n if (setFireflyState !== null) {\n newSetFireflyState = setFireflyState;\n } else {\n newSetFireflyState = \"on\";\n\n // #WIP\n\n //if find record in state array === strobe\n // this.state.forcedLightState.some((state) => state === fireflyId)\n // ? \"strobe\"\n // : \"on\";\n }\n\n // console.log(\n // `forcedLight: newSetFireflyState this.state.forcedLightState namedAreaEventForFirefly`,\n // newSetFireflyState,\n // this.state.forcedLightState,\n // fireflyId,\n // namedAreaEventForFirefly\n // );\n\n const currentNamedAreaEventForFireflyColor =\n namedAreaEventForFirefly?.active_color?.toLowerCase?.();\n\n const currentNamedAreaEventForFireflyState =\n namedAreaEventForFirefly?.active_state?.toLowerCase?.();\n\n let isStateChanged = newSetFireflyState !== \"on\";\n if (currentNamedAreaEventForFireflyState) {\n isStateChanged =\n currentNamedAreaEventForFireflyState !== newSetFireflyState;\n }\n\n let isColorChanged = color.status !== setFireflyColor;\n if (currentNamedAreaEventForFireflyColor) {\n isColorChanged = currentNamedAreaEventForFireflyColor !== setFireflyColor;\n }\n\n console.log(\n `forcedLight namedAreaEventForFirefly `,\n namedAreaEventForFirefly,\n newSetFireflyState\n );\n console.log(`forcedLight isColorChanged `, isColorChanged);\n console.log(`forcedLight isStateChanged `, isStateChanged);\n\n // Explanation\n //\n // In all cases delete the current namedArea\n // If color has not changed state, do not add a new namedArea (i.e. toggle OFF)\n // If color changed state, add a new namedArea\n // If state has changed, add a new namedAra\n\n // In all cases just delete the current namedArea\n //\n if (namedAreaEventForFirefly) {\n if (false && !isColorChanged && !isStateChanged) {\n // if toggle color OFF remove any existing strobe setting for deleted namdArea\n // i.e. color has changed the state has not changed\n\n console.log(\n `forcedLight: <<---DELETE--->> newForcedLightState fireflyId`,\n fireflyId\n );\n\n let newForcedLightState = this.state.forcedLightState;\n newForcedLightState = newForcedLightState.filter(\n (id) => id !== fireflyId\n );\n this.setState({ forcedLightState: newForcedLightState });\n }\n\n // console.log(\n // `forcedLight: <<---DELETE--->> deleteNamedArea id`,\n // namedAreaEventForFirefly.id\n // );\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({\n values: { id: namedAreaEventForFirefly.id },\n resolve,\n reject,\n })\n )\n );\n }\n\n // Get the next ForcedLight priority\n const allForcedNamedAreas = namedAreaEvents?.filter((event) =>\n event.id.includes(\"FORCED-\")\n );\n\n const highestForcedNamedAreaPriority = Math.max(\n ...allForcedNamedAreas.map((o) => o.priority),\n lightingEventPriority()?.forced || 5000\n );\n\n // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n // #NOTE - there must be a button at the priority level\n // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n const newNamedArea = createNamedAreaAroundFirefly(\n fireflyId,\n { easting, northing },\n area,\n setFireflyColor,\n newSetFireflyState,\n 1 // highestForcedNamedAreaPriority + 1\n );\n\n operationButton = newNamedArea.button?.[1]; // 1st, and only button, not highestForcedNamedAreaPriority + 1\n // get next highest\n operationButton.priority = highestForcedNamedAreaPriority + 1;\n\n //console.log(`forcedLight xxx operationButton`, operationButton);\n //console.log(`forcedLight xxx newNamedArea`, newNamedArea);\n\n // if toggle to change color, or change state, or there is a new color\n // #NOTE - below stops denies creating new event if same color,\n // however this is now superseded for forcing any color, even currently displayed color.\n //if (isColorChanged || isStateChanged) {\n\n // make a new event under all situations\n if (true) {\n // make a new event\n //\n isActivate = true;\n console.log(\n `forcedLight: <<---ADD--->> saveNewNamedArea newNamedArea`,\n newNamedArea\n );\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n saveNewNamedArea({\n values: newNamedArea,\n resolve,\n reject,\n })\n )\n );\n }\n }\n\n if (promiseArray.length) {\n return Promise.all(promiseArray)\n .then((result) => {\n console.log(`FORCELIGHT: saveNewNamedArea `, result);\n if (isActivate) {\n activate(operationButton); // -> sendNamedAreaEventSingle\n }\n })\n .catch((error) => {\n console.log(\n `forcedLight: saveFireflyLedData saveNewNamedAre failed `,\n error\n );\n // #WIP - do something if fails!???\n });\n }\n /////////////////////\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Segment,\n Icon,\n Button,\n Checkbox,\n Popup,\n Grid,\n} from \"semantic-ui-react\";\n\nimport { getNamedAreaEventsByAreaId } from \"components/WebWorker/reducer\";\nimport { saveNewNamedArea, deleteNamedArea } from \"NamedAreas/actions\";\nimport {\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n} from \"OperationalChanges/actions\";\n\nimport { allowedLightColors as _allowedLightColors } from \"components/ConfigJs\";\n\nimport { getEquivalentSemanticColorName } from \"colorpalette\";\nimport { toFireflyColor } from \"utils/toFireflyColor\";\nimport { ForceSingleLightManageNamedArea } from \"components/Map/ForceSingleLightManageNamedArea\";\n\nlet SingleColorOperation = ({ lightSetting, isEnabled, onClick, disabled }) => {\n //console.log(`xxxxxxxxxxxxxx lightSetting`, lightSetting);\n\n let semanticColorName = getEquivalentSemanticColorName(lightSetting);\n semanticColorName = lightSetting === \"white\" ? \"grey\" : semanticColorName;\n\n const popMsgForceButton = !isEnabled\n ? `Select to force the light color to ${lightSetting}`\n : `Select to clear the forced light color`;\n return (\n \n \n \n }\n />\n );\n};\n\nclass ForceSingleLight extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n isForcedActive: false,\n checkedStrobe: false,\n checkedOff: false,\n buttonColor: \"\", /// default to not selected\n allowedLightColors: [\"red\", \"amber\", \"white\", \"green\", \"blue\"], // default options\n //\n };\n }\n\n componentDidMount() {\n const { currentForcedColor, isCurrentForcedActive, isStrobe, isOff } =\n this.props;\n\n const allowedLightColors = _allowedLightColors();\n\n if (allowedLightColors) {\n const newAllowedLightColors = allowedLightColors.map(\n (color) => color.key\n );\n\n this.setState({\n allowedLightColors: newAllowedLightColors,\n });\n }\n this.setState({ buttonColor: currentForcedColor });\n this.setState({ checkedStrobe: isStrobe });\n this.setState({ checkedOff: isOff });\n this.setState({ isForcedActive: isCurrentForcedActive });\n }\n\n onChangeCheckboxStrobe = (e) => {\n const {\n //properties\n fireflyId,\n easting,\n northing,\n area,\n color,\n namedAreaEvents,\n // functions\n deleteNamedArea,\n saveNewNamedArea,\n activate,\n //\n } = this.props;\n\n // toggle from current state\n const isNewForcedStrobe = !this.state.checkedStrobe;\n const buttonColor = this.state.buttonColor;\n\n ForceSingleLightManageNamedArea({\n action: \"lightState\",\n fireflyId: fireflyId,\n area: area,\n easting: easting,\n northing: northing,\n color: color,\n setFireflyColor: buttonColor,\n setFireflyState: isNewForcedStrobe ? \"strobe\" : \"on\",\n\n namedAreaEvents: namedAreaEvents,\n deleteNamedArea: deleteNamedArea,\n saveNewNamedArea: saveNewNamedArea,\n activate: activate,\n });\n\n this.setState({ checkedStrobe: isNewForcedStrobe });\n\n this.props.onChange({ isDirty: true });\n //\n };\n\n onChangeCheckboxOff = (e) => {\n const {\n //properties\n fireflyId,\n easting,\n northing,\n area,\n color,\n namedAreaEvents,\n // functions\n deleteNamedArea,\n saveNewNamedArea,\n activate,\n //\n } = this.props;\n\n // toggle from current state\n const isNewForcedOff = !this.state.checkedOff;\n const buttonColor = this.state.buttonColor;\n\n if (isNewForcedOff) {\n ForceSingleLightManageNamedArea({\n action: \"lightState\",\n fireflyId: fireflyId,\n area: area,\n easting: easting,\n northing: northing,\n color: color,\n setFireflyColor: buttonColor,\n setFireflyState: isNewForcedOff ? \"off\" : \"on\",\n\n namedAreaEvents: namedAreaEvents,\n deleteNamedArea: deleteNamedArea,\n saveNewNamedArea: saveNewNamedArea,\n activate: activate,\n });\n } else {\n ForceSingleLightManageNamedArea({\n action: \"clear\",\n fireflyId: fireflyId,\n area: area,\n easting: easting,\n northing: northing,\n color: color,\n setFireflyColor: buttonColor,\n setFireflyState: isNewForcedOff ? \"off\" : \"on\",\n\n namedAreaEvents: namedAreaEvents,\n deleteNamedArea: deleteNamedArea,\n saveNewNamedArea: saveNewNamedArea,\n activate: activate,\n });\n }\n\n this.setState({ buttonColor: \"\" });\n this.setState({ checkedStrobe: false });\n this.setState({ checkedOff: isNewForcedOff });\n\n this.props.onChange({ isDirty: true });\n };\n\n onToggleColor = (evt, data) => {\n const {\n //properties\n fireflyId,\n easting,\n northing,\n area,\n color,\n namedAreaEvents,\n // functions\n deleteNamedArea,\n saveNewNamedArea,\n activate,\n //\n isCurrentForcedActive,\n } = this.props;\n\n const isCurrentForcedStrobe = this.state.checkedStrobe;\n\n const buttonColor = toFireflyColor(data.color);\n\n // console.log(\n // \"onToggleColor fireflyId,easting,northing,area,color, namedAreaEvents, data, isCurrentForcedActive, isCurrentForcedStrobe\",\n // fireflyId,\n // easting,\n // northing,\n // area,\n // color,\n // namedAreaEvents,\n // data,\n // isCurrentForcedActive,\n // isCurrentForcedStrobe\n // );\n\n // toggle OFF\n // forced color is active and color is current state -> toggle off\n if (isCurrentForcedActive && color.status === buttonColor) {\n ForceSingleLightManageNamedArea({\n action: \"clear\",\n fireflyId: fireflyId,\n area: area,\n easting: easting,\n northing: northing,\n color: color,\n setFireflyColor: buttonColor,\n setFireflyState: isCurrentForcedStrobe ? \"strobe\" : \"on\",\n\n namedAreaEvents: namedAreaEvents,\n deleteNamedArea: deleteNamedArea,\n saveNewNamedArea: saveNewNamedArea,\n activate: activate,\n });\n\n this.setState({ buttonColor: \"\" });\n this.setState({ checkedStrobe: false });\n }\n // toggle ON\n // forced color is active and color is different -> toggle on\n else {\n ForceSingleLightManageNamedArea({\n action: \"lightColor\",\n fireflyId: fireflyId,\n area: area,\n easting: easting,\n northing: northing,\n color: color,\n setFireflyColor: buttonColor,\n setFireflyState: isCurrentForcedStrobe ? \"strobe\" : \"on\",\n\n namedAreaEvents: namedAreaEvents,\n deleteNamedArea: deleteNamedArea,\n saveNewNamedArea: saveNewNamedArea,\n activate: activate,\n });\n\n this.setState({ buttonColor: buttonColor });\n }\n\n this.props.onChange({ isDirty: true });\n };\n\n render() {\n const {\n // local prop\n fireflyId,\n // redux prop\n currentForcedColor,\n isOff,\n } = this.props;\n\n const { allowedLightColors, buttonColor, checkedStrobe, checkedOff } =\n this.state;\n\n // console.log(\"hhh currentForcedColor\", currentForcedColor);\n // console.log(\"hhh allowedLightColors\", allowedLightColors);\n // console.log(\"hhh checkedStrobe\", checkedStrobe);\n // console.log(\"hhh checkedOff\", checkedOff);\n\n const popupMsgStrobe = isOff\n ? \"Light is off. Turn the light on before activating strobe\"\n : buttonColor !== \"\"\n ? \"Enable/disable strobing of the forced light color\"\n : \"Force a light color before activating strobe\";\n\n return (\n <>\n \n \n
\n \n \n Off\n \n }\n />\n \n {allowedLightColors.map((color, idx) => (\n this.onToggleColor(evt, data)}\n disabled={isOff}\n />\n ))}\n \n \n \n Strobe\n \n }\n />\n
\n
\n
\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const namedAreaEvents = getNamedAreaEventsByAreaId(state, props.area);\n\n return {\n namedAreaEvents,\n };\n};\n\nconst mapDispatchToProps = (dispatch) => ({\n saveNewNamedArea: (data) => dispatch(saveNewNamedArea(data)),\n deleteNamedArea: (id) => {\n dispatch(deleteNamedArea(id));\n },\n //\n // see - src/pages/ControlRoomPage/PrecannedOperations.js\n activate: (operation) => dispatch(activateNamedAreaEventSingle(operation)),\n cancel: (operation) => dispatch(cancelNamedAreaEvent(operation)),\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(ForceSingleLight);\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { Link } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\n//import { getUPSById } from 'UPSPanelControllers/reducer'\nimport { getControllerById } from \"components/WebWorker/reducer\";\n\nexport function UPSLink({ id, notFound, ...props }) {\n // let to = `/admin/ups/${id}`;\n let to = `/admin/controller/${id}`;\n if (notFound) {\n to = \"#\";\n }\n return {props.children};\n}\n\nUPSLink.propTypes = {\n id: PropTypes.string.isRequired,\n notFound: PropTypes.bool,\n};\n\nconst mapStateToProps = (state, props) => {\n const { id } = props;\n const ups = getControllerById(state, id);\n return { id, notFound: !ups };\n};\n\nexport default connect(mapStateToProps)(UPSLink);\n","// see - src/admin/named-area-group/NamedAreaGroupSettingsModal.js\n\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Segment,\n Grid,\n Modal,\n Header,\n Icon,\n Button,\n Ref,\n} from \"semantic-ui-react\";\nimport isEqual from \"lodash/isEqual\";\nimport { formatRelative, parseISO } from \"date-fns\";\n\nimport { getEquivalentSemanticColorName } from \"colorpalette\";\nimport { StatusEnumToReadable } from \"utils/StatusEnum\";\nimport { getMapMarkerDisplayOptions } from \"components/ConfigJs\";\n\nimport ForceSingleLight from \"components/Map/ForceSingleLight\";\n\nimport {\n getFireflyById,\n getControllerById,\n getFireflyCoordinatesById,\n} from \"components/WebWorker/reducer\";\n\nimport { getNamedAreaEventsByAreaId } from \"components/WebWorker/reducer\";\n\nimport { createFireflyNamedAreaId } from \"NamedAreas/createNamedAreaAroundFirefly\";\n\nimport UPSLink from \"admin/ups/UPSLink\";\nimport FireflyLink from \"admin/firefly/FireflyLink\";\n\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nimport { allowedLightColors as _allowedLightColors } from \"components/ConfigJs\";\n\nclass FireflyMarkerPopupModal extends Component {\n constructor(props) {\n super(props);\n this.state = {\n modalOpen: false,\n getMapMarkerDisplayOptions: {},\n allowedLightColors: [\"red\", \"amber\", \"white\", \"green\", \"blue\"],\n isDirty: false,\n isChanging: false,\n };\n }\n\n componentDidMount() {\n const { open, isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n\n if (open) {\n this.handleOpen();\n }\n\n if (isPokeTheWorker) {\n TurnOnOffPokeTheWorker(false);\n }\n\n this.setState({ getMapMarkerDisplayOptions: getMapMarkerDisplayOptions() });\n\n const allowedLightColors = _allowedLightColors();\n\n if (allowedLightColors) {\n const newAllowedLightColors = allowedLightColors.map(\n (color) => color.key\n );\n\n this.setState({\n allowedLightColors: newAllowedLightColors,\n });\n }\n }\n\n componentWillUnmount() {\n const { isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n TurnOnOffPokeTheWorker(true);\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n\n // check if still processing/updating from change request\n const { light } = this.props;\n const { color, lightState, event_id } = light;\n const { status: colorStatus, plan: colorPlan } = color;\n const { status: lightStatus, plan: lightPlan } = lightState;\n\n // if the form is dirty\n if (this.state.isDirty) {\n // we need a way to wait for the changes to start getting underway.\n //\n // The changes can take a few seconds to get underway (around the system) so\n // to record the start of changes i.e. when something has started changing.\n // This avoids a timer.\n //\n // test for a change...\n\n // if isChanging flag is not set\n if (\n !this.state.isChanging &&\n (colorPlan !== colorStatus ||\n lightPlan?.led_state !== lightStatus?.led_state ||\n prevProps?.light?.event_id !== event_id)\n ) {\n // set it\n this.setState({ isChanging: true });\n }\n\n // if isChanging has been set, but now everything is OK\n if (\n this.state.isChanging &&\n colorPlan === colorStatus &&\n lightPlan?.led_state === lightStatus?.led_state &&\n prevProps?.light?.event_id === event_id\n ) {\n // clear everything\n this.setState({ isDirty: false });\n this.setState({ isChanging: false });\n }\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleCancel = () => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.resetModal();\n\n // reset the form\n //this.setState({ value: \"\" }, () => this.props.reset());\n };\n\n handleForceSingleLightChange = (value) => {\n console.log(\"handleForceSingleLightChange\", value); //\n const { isDirty } = value;\n this.setState({ isDirty: isDirty });\n };\n\n render() {\n const {\n id,\n ups_id,\n area,\n easting,\n northing,\n X,\n Y,\n z,\n utm_zone_number,\n utm_zone_letter,\n fireflyNote = \"\",\n //color, // No longer used, see 'light' below\n //led_state, // No longer used, see 'light' below\n lastStatusReport,\n light,\n namedAreaEvents,\n role,\n ffMac,\n deviceStatus,\n forcedClickList,\n namedAreaEventForFirefly,\n } = this.props;\n\n const { allowAdmin } = role;\n\n //const { getMapMarkerDisplayOptions } = this.state;\n\n // default display options\n const {\n firefly: {\n showMac = false,\n showStatus = true,\n showUtm = false,\n showEventInfo = false,\n showForced = true,\n },\n } = getMapMarkerDisplayOptions();\n\n // #NOTE - this should be \"namedAreaEventForForcedFirefly\"\n\n const {\n id: currentForcedId = \"\",\n active: isCurrentForcedActive = false,\n active_color: currentForcedColor = \"\",\n active_state: currentForcedState = \"on\",\n } = namedAreaEventForFirefly;\n\n // console.log(\"fff namedAreaEventForForcedFirefly\", namedAreaEventForFirefly);\n\n const isStrobe = [\"STROBE\", \"FORWARD\", \"BACKWARD\"].includes?.(\n currentForcedState?.toUpperCase?.()\n );\n const isOff = [\"OFF\"].includes?.(currentForcedState?.toUpperCase?.()); // || led_state?.toUpperCase?.() === \"OFF\";\n\n //console.log(`LIGHT DETAILS FOR FIREFLY `, JSON.stringify(light));\n\n // In #DEMO_MODE some of these properties may not exist on 1st load so define all ...\n const color = light?.color || { status: \"\", plan: \"\" };\n const lightState = light?.lightState || { status: \"\", plan: \"\" };\n const event_id = light?.event_id || \"unknown\";\n\n const { status: colorStatus, plan: colorPlan } = color;\n const { status: lightStatus, plan: lightPlan } = lightState;\n\n const controllerLink = {ups_id};\n const controllerNoLink = {ups_id || \"unknown\"} ;\n\n const fireflyLink = {id};\n const fireflyNoLink = {id.replaceAll(\"_\", \" \")};\n\n const deviceStatusString =\n deviceStatus?.length > 0\n ? deviceStatus.map((status) => StatusEnumToReadable[status])?.join(\", \")\n : \"OK\";\n\n const showForcedStyleDisplayHidden = !showForced\n ? { display: \"none\" }\n : null;\n\n const isProcessingRequest = this.state.isDirty;\n\n return (\n \n
\n \n \n \n \n FireFly\n \n \n {allowAdmin ? fireflyLink : fireflyNoLink}\n \n \n \n \n Controller\n \n \n {allowAdmin ? controllerLink : controllerNoLink}\n \n \n {showMac && (\n \n \n MAC\n \n {ffMac}\n \n )}\n {showUtm && (\n \n \n UTM\n \n \n Easting: {easting}
\n Northing: {northing}
\n Zone: {utm_zone_number} / {utm_zone_letter}\n
\n \n )}\n \n \n Color\n \n \n Requested: \n \n {isOff\n ? \"OFF\"\n : colorPlan === \"orange\"\n ? \"AMBER\"\n : colorPlan.toUpperCase()}\n \n
\n Reported: \n \n {isOff\n ? \"OFF\"\n : colorStatus === \"orange\"\n ? \"AMBER\"\n : colorStatus.toUpperCase()}\n {colorPlan !== colorStatus ? (\n \n ...updating...\n \n ) : null}\n \n
\n
\n \n \n \n State\n \n \n Requested: \n \n {isOff ? \"OFF\" : lightPlan?.led_state?.toUpperCase()}\n \n
\n Reported: \n \n {isOff ? \"OFF\" : lightStatus?.led_state?.toUpperCase()}\n {lightPlan?.led_state !== lightStatus?.led_state ? (\n \n ...updating...\n \n ) : null}\n \n
\n \n {showEventInfo && event_id !== \"\" && event_id !== currentForcedId && (\n \n \n Event Info\n \n \n ID: {event_id}
\n
\n \n )}\n {showForced && currentForcedId !== \"\" && (\n \n \n Forced Info\n \n \n ID: {currentForcedId}
\n COLOR: {isOff ? \"OFF\" : currentForcedColor}{\" \"}\n
\n STATE: {currentForcedState}\n
\n \n )}\n {isProcessingRequest && (\n \n \n Changed\n \n \n Change requested. Processing ...\n \n \n )}\n \n \n Last Report\n \n {lastStatusReport}\n \n\n {showForced && allowAdmin && (\n \n \n Force Light\n \n \n \n \n \n )}\n \n \n Notes\n \n \n {fireflyNote !== \"\"\n ? fireflyNote\n : \"There are no notes for this firefly.\"}\n \n \n
\n
\n \n \n \n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const {\n initialValues: { id, area },\n } = props;\n\n // user roles\n const userSuper = isUserSuper(state);\n const userAdmin = isUserAdmin(state);\n const userUser = isUserUser(state);\n const userGuest = isUserGuest(state);\n const allowGuest = userGuest;\n\n const allowOperator = userSuper || userAdmin || userUser;\n const allowAdmin = userSuper || userAdmin;\n const allowSuper = userSuper;\n\n const namedAreaEvents = getNamedAreaEventsByAreaId(state, area);\n\n // #NOTE - this should be \"createForcedFireflyNamedAreaId\"\n const fireflyNamedAreaId = createFireflyNamedAreaId(id);\n\n // #NOTE - this should be \"namedAreaEventForForcedFirefly\"\n const namedAreaEventForFirefly =\n namedAreaEvents?.find((event) => event.id.includes(fireflyNamedAreaId)) ||\n {};\n\n const firefly = getFireflyById(state, id);\n const fireflyCoords = getFireflyCoordinatesById(state, id);\n\n // console.log(`fff fireflyNamedAreaId`, fireflyNamedAreaId);\n // console.log(`fff namedAreaEvents`, namedAreaEvents);\n // console.log(`fff namedAreaEventForFirefly`, namedAreaEventForFirefly);\n // console.log(`fff firefly`, firefly);\n\n const {\n light,\n fireflyNote,\n utm: { northing, easting, utm_zone_letter, utm_zone_number, z },\n topology: { ups_id, deviceStatus },\n // device: { mac: ffMac },\n timestamp,\n } = firefly;\n\n // #TODO - when data is similated there is no device object so get error\n // \"TypeError: Cannot read properties of undefined (reading 'mac')\"\n // This patches the problem, but this should be resolved by making a proper\n // default 'device' property in the 'firefly' object.\n const ffMac = firefly?.device?.mac || \"\";\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n\n return {\n id,\n ups_id,\n area,\n easting,\n northing,\n z,\n X: fireflyCoords?.[0],\n Y: fireflyCoords?.[1],\n utm_zone_number,\n utm_zone_letter,\n fireflyNote,\n lastStatusReport,\n namedAreaEventForFirefly,\n light,\n namedAreaEvents,\n role: {\n allowGuest: allowGuest,\n allowOperator: allowOperator,\n allowAdmin: allowAdmin,\n allowSuper: allowSuper,\n },\n ffMac,\n deviceStatus,\n // forcedClickList,\n isPokeTheWorker: isOnOffPokeTheWorker(state),\n };\n}\n\nexport default connect(mapStateToProps, {\n TurnOnOffPokeTheWorker,\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n})(FireflyMarkerPopupModal);\n","// see - src/admin/named-area-group/NamedAreaGroupSettingsModal.js\n\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Grid, Modal, Header, Icon, Button } from \"semantic-ui-react\";\nimport isEqual from \"lodash/isEqual\";\nimport { formatRelative, parseISO } from \"date-fns\";\n\nimport { getControllerById } from \"components/WebWorker/reducer\";\nimport UPSLink from \"admin/ups/UPSLink\";\n\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nclass ControllerMarkerPopupModal extends Component {\n constructor(props) {\n super(props);\n this.state = { modalOpen: false };\n }\n\n componentDidMount() {\n const { open, isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n\n if (open) {\n this.handleOpen();\n }\n\n if (isPokeTheWorker) {\n TurnOnOffPokeTheWorker(false);\n }\n }\n\n componentWillUnmount() {\n const { isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n TurnOnOffPokeTheWorker(true);\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleCancel = () => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display \n\n this.props.resetModal();\n\n // reset the form\n //this.setState({ value: \"\" }, () => this.props.reset());\n };\n\n render() {\n const {\n ups_id,\n easting,\n northing,\n X,\n Y,\n z,\n utm_zone_number,\n utm_zone_letter,\n color,\n location,\n lastStatusReport,\n user_relay,\n role,\n network_name,\n } = this.props;\n\n //console.log(`ControllerMarkerPopupModal`, this.props);\n\n const { allowAdmin } = role;\n\n const controllerLabel = `${network_name} (${ups_id})`;\n const controllerLink = {controllerLabel};\n const controllerNoLink = {controllerLabel || \"unknown\"} ;\n\n return (\n \n
\n \n \n \n \n Controller\n \n \n {allowAdmin ? controllerLink : controllerNoLink}\n \n \n {location?.map((loc, idx) => {\n const locString = JSON.stringify(loc)?.replaceAll('\"', \"\");\n return (\n \n \n {idx > 0 ? null : Location}\n \n {locString}\n \n );\n })}\n \n \n User Relay\n \n {user_relay || 0}\n \n\n \n \n Last Report\n \n {lastStatusReport}\n \n \n \n \n \n \n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const {\n initialValues: { id },\n } = props;\n\n // user roles\n const userSuper = isUserSuper(state);\n const userAdmin = isUserAdmin(state);\n const userUser = isUserUser(state);\n const userGuest = isUserGuest(state);\n const allowGuest = userGuest;\n\n const allowOperator = userSuper || userAdmin || userUser;\n const allowAdmin = userSuper || userAdmin;\n const allowSuper = userSuper;\n\n const controller = getControllerById(state, id);\n\n const {\n topology: { location, network_name },\n system,\n timestamp,\n } = controller;\n\n //console.log(`ControllerMarkerPopupModal xxx controller`, controller);\n\n // user_relay is undefined when in DEMO_MODE\n const user_relay = system?.user_relay || 0;\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n\n return {\n ups_id: id,\n location,\n user_relay,\n network_name,\n role: {\n allowGuest: allowGuest,\n allowOperator: allowOperator,\n allowAdmin: allowAdmin,\n allowSuper: allowSuper,\n },\n lastStatusReport,\n isPokeTheWorker: isOnOffPokeTheWorker(state),\n };\n}\n\nexport default connect(mapStateToProps, { TurnOnOffPokeTheWorker })(\n ControllerMarkerPopupModal\n);\n","import { isDemoMode, markerAcceptableEventLabels } from \"components/ConfigJs\";\nimport { getEquivalentSemanticColorName } from \"colorpalette\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { StatusEnum } from \"utils/StatusEnum\";\n\n// FireFly marker definition\nexport const markerDefinition = (feature, userSettings) => {\n const { properties } = feature;\n\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_number,\n utm_zone_letter,\n z,\n light,\n controllerMode,\n deviceStatus,\n timestamp,\n ups_id,\n forced,\n } = properties;\n\n const {\n color,\n alternate_color,\n lightState,\n marker, // defaults to 'RoundMarker'\n led_state,\n off_time,\n on_time,\n train,\n brightness,\n event_id,\n } = light;\n\n // Default marker\n let svgIcon = marker || \"DiamondMarker\";\n\n const { plan: ColorPlan, status: ColorStatus } = color;\n const AlternateColorPlan = (alternate_color !== undefined) ? alternate_color.plan : ColorPlan;\n const AlternateColorStatus = (alternate_color !== undefined) ? alternate_color.status : ColorStatus;\n const { plan: StatePlan, status: StateStatus } = lightState;\n\n // FireFly is in transition is states are changing. Test for color change and for state change.\n // Ignore the other statuses i.e. off_time, on_time, train, brightness.\n const isInTransition =\n ColorPlan !== ColorStatus ||\n StatePlan?.led_state !== StateStatus?.led_state;\n\n const isInCommission = controllerMode.toLowerCase() === \"commission\";\n\n // Label the icons with a text character designating the source\n let textLabel = \"\";\n if (forced) {\n textLabel = \"F\";\n }\n\n const eventIdLabel = event_id?.charAt(0);\n\n if (markerAcceptableEventLabels()?.includes(eventIdLabel)) {\n textLabel = eventIdLabel;\n } \n\n // Note: If the light is off force it to be \"grey\" to account for\n // when a colored marker is defined. Color is meaningless when it is off.\n // A special marker like the 'OffMarker' has no color fill so it not impacted.\n \n let svgStyle = {\n stroke:\n StatePlan?.led_state === \"off\"\n ? \"black\"\n : getEquivalentSemanticColorName(ColorPlan),\n alternate_stroke:\n StatePlan?.led_state === \"off\"\n ? \"black\"\n : getEquivalentSemanticColorName(AlternateColorPlan),\n fill:\n StateStatus?.led_state === \"off\"\n ? \"black\"\n : getEquivalentSemanticColorName(ColorStatus),\n alternate_fill:\n StateStatus?.led_state === \"off\"\n ? \"black\"\n : getEquivalentSemanticColorName(AlternateColorStatus),\n text: textLabel,\n };\n\n // Status checks\n let status = \"OK\"; // Lets assume everything is OK.\n\n if (deviceStatus.includes(StatusEnum.API_FETCH)) {\n status = \"API_FETCH\";\n }\n\n if (deviceStatus.includes(StatusEnum.NO_STATUS_REPORT) ||\n deviceStatus.includes(StatusEnum.TIMEOUT) ||\n deviceStatus.includes(StatusEnum.INACTIVE)) {\n \n status = \"INACTIVE_FIREFLY\";\n }\n\n if (_isEmpty(ups_id)) {\n status = \"DEAD_FIREFLY\";\n }\n\n // Override fault checks if demo mode.\n if (userSettings?.feature?.includes(\"showDemoMode\") || isDemoMode()) {\n status = \"OK\";\n }\n\n switch (status) {\n case \"OK\":\n if (marker.toLowerCase() === \"travelwaymarker\") {\n svgIcon = \"TravelwayMarker\";\n // travelways have a special color\n svgStyle = {\n stroke: \"purple\",\n fill: getEquivalentSemanticColorName(ColorStatus),\n };\n } else if (marker.toLowerCase() === \"travelwaymarker\") {\n svgIcon = \"TravelwayMarker\";\n // travelways have a special color\n svgStyle = {\n stroke: \"purple\",\n fill: getEquivalentSemanticColorName(ColorStatus),\n };\n } else {\n isInCommission\n ? (svgIcon = \"StarMarker\") // special commission marker\n : isInTransition\n ? (svgIcon = \"TriangleMarker\") // special transition marker\n : (svgIcon = marker); // ...otherwise use the marker type passed in the message\n }\n break;\n\n case \"API_FETCH\":\n svgIcon = \"TriangleMarker\";\n break;\n\n case \"INACTIVE_FIREFLY\":\n svgStyle = { stroke: \"black\", fill: \"fuchsia\" };\n svgIcon = \"HourGlassMarker\";\n break;\n\n case \"UPS_TIMEOUT\":\n // ToDo: Clarify use of this color for controller.\n svgStyle = { stroke: \"fuchsia\", fill: \"black\" };\n svgIcon = \"HourGlassMarker\";\n break;\n\n case \"DEAD_FIREFLY\":\n default:\n svgStyle = { stroke: \"fuchsia\", fill: \"sienna\" };\n svgIcon = \"BowTieMarker\";\n break;\n }\n\n return { svgIcon, svgStyle };\n};\n","export function fetchAllUsers() {\n return { type: \"ALL_USERS_FETCH_REQUESTED\" };\n}\n\nexport const getAllUsers = (data) => {\n return { type: \"GET_ALL_USERS\", payload: data };\n};\n\nexport function saveUser(payload) {\n return { type: \"SAVE_USER\", payload };\n}\n\nexport const deleteUser = (id) => {\n return { type: \"DELETE_USER\", payload: id };\n};\n\nexport const changeRole = (payload) => {\n return { type: \"CHANGE_USER_ROLE\", payload };\n};\n\nexport const changePassword = (payload) => {\n return { type: \"CHANGE_USER_PASSWORD\", payload };\n};\n\nexport const changeName = (payload) => {\n return { type: \"CHANGE_USER_NAME\", payload };\n};\n\nexport const changeLanguage = (payload) => {\n return { type: \"CHANGE_USER_LANGUAGE\", payload };\n};\n\nexport const changeSettings = (payload) => {\n return { type: \"CHANGE_USER_SETTINGS\", payload };\n};\n\nexport const saveUserSettingsComponentState = (payload) => {\n return { type: \"SAVE_USER_SETTINGS_COMPONENT_STATE\", payload };\n};\n","// #MINELEVELMAPLEAFLET\n\nimport React, { Component, useState } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport L from \"leaflet\";\nimport \"leaflet/dist/leaflet.css\";\nimport \"leaflet-draw\";\nimport \"leaflet-contextmenu\";\nimport \"leaflet.smoothwheelzoom\";\n\nimport \"leaflet-groupedlayercontrol\";\nimport \"leaflet-groupedlayercontrol/dist/leaflet.groupedlayercontrol.min.css\";\nimport \"components/Map/MapIcons.css\";\n\nimport \"leaflet-easybutton/src/easy-button.css\";\nimport \"leaflet-easybutton\";\n\n//import \"components/leaflet-search-control/leaflet-search-control\";\nimport SearchControl from \"../leaflet-search-control/leaflet-search-control\";\n\nimport {\n transformGeoJsonUtmToPixels,\n transformGeoJsonPixelsToUtm,\n} from \"components/Map/util-geoJsonToPixels\";\n\nimport {\n getAreaById,\n getMapState,\n getFireflyCoordinatesByAreaId,\n getControllerCoordinatesByAreaId,\n getNamedAreaInfosByRegionPreviewByAreaId,\n getIsDirty,\n getFaults,\n getFireflyIdsUpdateListByArea,\n getFireflyIdsDeleteListByArea,\n} from \"components/WebWorker/reducer\";\n\nimport {\n namedAreaClearDeleteSelections,\n namedAreasSetIsDirty,\n mqttPublish,\n fireflyIdsUpdateListDeleteId,\n} from \"components/WebWorker/actions\";\n\nimport { GetLocalMap } from \"components/Map/reducer\";\nimport { UpdateLocalMap } from \"components/Map/actions\";\n\nimport { sortAlphaNum } from \"utils/sortAlphaNum\";\nimport { round } from \"utils/number-utils.js\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _isEqual from \"lodash/isEqual\";\nimport { omitDeep } from \"utils/omitDeep\";\n\nimport { formatRelative, parseISO } from \"date-fns\";\n\nimport { saveFirefly } from \"UPSPanelControllers/actions\";\nimport { saveUPS } from \"UPSPanelControllers/actions\";\n\n// import plugin's css (if present)\n// note, that this is only one of possible ways to load css\nimport \"leaflet-contextmenu/dist/leaflet.contextmenu.css\";\n\nimport { makeIcon } from \"components/Map/MakeIcon\";\n\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport { renderToString } from \"react-dom/server\";\n\n//import { FireflyMarkerPopup } from \"components/Map/FireflyMarkerPopup\";\n//import { ControllerMarkerPopup } from \"components/Map/ControllerMarkerPopup\";\nimport { NamedAreaPolygonPopup } from \"components/Map/NamedAreaPolygonPopup\";\n\nimport { StatusEnum } from \"utils/StatusEnum\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\n\nimport { getRegionPreviewListByAreaId } from \"components/RegionPreview/reducer\";\n\nimport {\n getTimedOutDevices,\n getNamedAreaEventsByAreaId,\n} from \"components/WebWorker/reducer\";\n\n// >>>>> flash message support\nimport {\n isConfigJs,\n faultMessageBannerDisplay,\n faultMessageBannerText,\n isDemoMode,\n getMapDisplayOptions,\n markerAcceptableEventLabels,\n isTagTracking,\n isDataCollectionDuringMarkerPopupOpen,\n} from \"components/ConfigJs\";\n\nimport {\n addWarningFlashMessageIdColor,\n removeFlashMessage,\n clearFlashMessages,\n SetMessageBanner,\n} from \"FlashMessages/actions\";\n\nimport cuid from \"cuid\";\n// <<<<< flash message support\n\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { SetMapMoving, SetMapMarkerDragging } from \"components/Map/actions\";\nimport { saveNewNamedArea, deleteNamedArea } from \"NamedAreas/actions\";\n\nimport {\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n waitEventTimeOut,\n} from \"OperationalChanges/actions\";\n\nimport { isKthBitSet } from \"utils/bit-operations\";\n\nimport {\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n getUserSettings,\n} from \"auth/reducer\";\n\nimport {\n addAreaPreview,\n removeAreaPreview,\n} from \"components/RegionPreview/actions\";\n\nimport { getMapImageById } from \"components/Settings/reducer\";\n\nimport FireflyMarkerPopupModal from \"components/Map/FireflyMarkerPopupModal\";\nimport ControllerMarkerPopupModal from \"components/Map/ControllerMarkerPopupModal\";\n\nimport { ForceSingleLightManageNamedArea } from \"components/Map/ForceSingleLightManageNamedArea\";\nimport { markerDefinition } from \"components/Map/FireflyMarkerDefinition\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\n//import { info } from \"console\";\n\n// -----------------------------------------------\n// DEFAULT AND DEBUG\n//\n// -----------------------------------------------\n\n// #DEBUG\n// DISABLE code sections under development and prototyped\nconst DEBUG_ENABLED_FALSE = false;\nconst DEBUG_ENABLED_TRUE = true;\nconst DEBUG_SHOW_COUNT_OF_MARKERS_EACH_LAYER = false; // #WIP - was working a long time ago but broken now?!\n\n//\n\n// #REVIEW - Need this? This is setup to be able to draw linestrings etc,\n// but are there too many layers as-is?\n// This adds a group for each location. i.e. The 'location' is the port, e.g. \"Panel 1\"\n// This allows the turning on/off of individual locations.\n// #REVIEW\n//\n// * move this.locationGroupLayers etc. to state rather than forced via \"this.\"\n// use setState to update once groups are defined\n\nconst mapDisplayOptions = getMapDisplayOptions();\nconst { controllerLocations, controllerCables, tagTrackingFFsMarkers } =\n mapDisplayOptions;\n\n// Disabled for now to reduce load on leaflet\nconst DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER = controllerLocations;\nconst DEFAULT_SHOW_FIREFLY_POLYLINE_GROUP_LAYER =\n controllerCables && DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER;\n// << needs location group above to also be enabled\n\n//\n// -----------------------------------------------\n\n//\n\nclass Map extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n refPts: {},\n thislocalMapState: {},\n map: { area: \"defaultArea\" },\n heartBeat: true,\n isMapLoading: true,\n isMapLoaded: false,\n mapSrc: \"\",\n //\n layerControlState: {},\n // marker popup state\n isPopupOpen: false,\n // map view state\n mapViewState: { id: undefined, center: undefined, zoom: undefined },\n savedMapViewState: {},\n\n // #NOTE -\n // * set when componentDidMount is run.\n // Used to determine if map regionPreview should be updated\n\n isMapComponentDidMount: false,\n //\n isPokeTheWorkerLocal: true, // local record of whether to collect data, stops updates immediately instead of waiting for redux response\n //\n markerPositionChanges: {},\n forceMapRefreshFireflys: false, // used to force map refresh if markers moved\n forceMapRefreshControllers: false, // used to force map refresh if markers moved\n isMoving: false,\n isMarkerDragging: false,\n //\n // tags\n isTagTracking: false,\n showTags: [\"unknown\", \"personnel\", \"vehicle\"],\n //\n // tracks which forced markers have been clicked\n forcedClickList: [],\n //\n // tracks if map move in use\n isMapView: false,\n // tracks if edit tools in use\n isMoveMarkerPositions: false,\n // tracks activeLayers so can toggle on/off\n activeLayersList: [],\n // modal for details of the marker\n isOpenFireflyMarkerPopupModal: { active: false, id: \"\", area: \"\" },\n isOpenControllerMarkerPopupModal: { active: false, id: \"\", area: \"\" },\n //\n isDataCollectionDuringMarkerPopupOpen:\n isDataCollectionDuringMarkerPopupOpen(),\n ctrlKey: false,\n fireflySelection: [],\n isEnableSearchBox: true, // #WIP - pass from configJs\n isShowSearchBox: false,\n searchBoxContent: [\"List...\"],\n };\n }\n\n static contextTypes = {\n router: PropTypes.object.isRequired,\n };\n\n // #WIP - #TODO - MAKE COMMON\n // see - src/pages/ControlRoomPage/MineLevelOpsControl.js\n // message banner support\n //\n //\n faultMessageBannerId = (faultType) => {\n // check if a message of this type exists\n\n // get the id for the flash message\n const messageBanners = this.props.messageBanners; // from redux state\n\n console.log(`messageBanners`, messageBanners);\n return messageBanners[faultType].id;\n };\n\n clearFaultMessageBanner = (faultType) => {\n // get the id for the flash message\n const bannerId = this.faultMessageBannerId(faultType);\n\n console.log(`message bannerId`, bannerId);\n if (bannerId) {\n this.props.removeFlashMessage(bannerId);\n //#REVIEW - make this a function..........\n // delete this banner message from state\n let tmpObj = {};\n tmpObj.faultType = faultType;\n tmpObj.display = false;\n tmpObj.id = \"\";\n\n this.props.SetMessageBanner(tmpObj);\n }\n };\n\n areaImageNotFoundMessage = (areaImageNotFound, imageFilename) => {\n const messageBanners = this.props.messageBanners;\n\n if (messageBanners === undefined) return;\n\n // console.log(`messageBanners`, messageBanners);\n // console.log(`message imageFilename`, imageFilename);\n // console.log(`message areaImageNotFound`, areaImageNotFound);\n\n // #NOTE - old comment, but still applies. Need to centralise function.\n //#REVIEW - force to one type for now - this needs to be merged with AlarmButtons and other messaging\n\n const bannerDisplayed = messageBanners[\"areaImageNotFound\"]?.display;\n let bannerInfo = messageBanners[\"areaImageNotFound\"]?.info || [];\n const isBannerDisplayedForThisImageFilename =\n bannerInfo?.includes(imageFilename);\n\n if (isConfigJs() && faultMessageBannerDisplay()) {\n const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n // if this fault type allows message banner display (in config)\n // and there hasn't been a message banner displayed previously\n\n if (isMessageBannerForFaultType[\"areaImageNotFound\"]) {\n if (areaImageNotFound) {\n // set\n if (bannerDisplayed) {\n // banner already exists\n if (!isBannerDisplayedForThisImageFilename) {\n // update banner\n // clear current banner\n this.clearFaultMessageBanner(\"areaImageNotFound\");\n // set a new banner\n this.setFaultMessageBanner([...bannerInfo, imageFilename]);\n }\n } else {\n // no current banner\n // set a new banner\n this.setFaultMessageBanner([...bannerInfo, imageFilename]);\n }\n } else {\n // clear banner\n if (bannerDisplayed) {\n if (isBannerDisplayedForThisImageFilename) {\n // clear just this banner\n // clear current banner\n this.clearFaultMessageBanner(\"areaImageNotFound\");\n // set a new banner\n this.setFaultMessageBanner(\n bannerInfo.filter((file) => file !== \"B\")\n );\n }\n //\n }\n }\n }\n }\n };\n\n setFaultMessageBanner = (bannerInfo) => {\n console.log(`message bannerInfo`, bannerInfo);\n // set a new banner\n // create a unique ID for the banner\n const id = cuid();\n // display a new banner\n this.displayErrors(id, \"areaImageNotFound\", bannerInfo);\n\n // record the update state of banner including the id (needed to delete this particular banner)\n let tmpObj = {};\n tmpObj.faultType = \"areaImageNotFound\"; // #REVIEW - force to one status check type for now\n tmpObj.display = true;\n tmpObj.id = id;\n // multiple files : same\n tmpObj.info = bannerInfo;\n\n this.props.SetMessageBanner(tmpObj);\n };\n\n // get the text for the fault message banner from config.js or set default\n getFaultMessageBannerText = (faultType) => {\n let header;\n let message;\n let color;\n\n if (isConfigJs() && faultMessageBannerText()) {\n const messageBannerText = faultMessageBannerText(); // from config.js file\n header = messageBannerText[faultType].header;\n message = messageBannerText[faultType].message;\n color = messageBannerText[faultType].color;\n } else {\n // default messages if config.js object is stuffed\n switch (faultType) {\n case \"areaImageNotFound\":\n header = \"Area Image Can Not Be Found\";\n message =\n \"An area image can not be found on the server, or the server connection has failed. Check the server operation then log out/in.\";\n color = \"red\";\n break;\n default:\n break;\n }\n }\n\n return { header, message, color };\n };\n\n // loads header and message to display on control screen page\n // depending on significance of the error\n // All cases go to the Browser Logger page\n //\n displayErrors(id, faultType, info) {\n const { header, message, color } =\n this.getFaultMessageBannerText(faultType);\n\n // set color from highest fault_level for the faultType\n // const color = this.setColorMessageBanner(faultType);\n\n this.props.addWarningFlashMessageIdColor(\n id,\n color,\n header,\n message + \" \" + info.join(\", \") || \"Unknown problem\"\n );\n //console.log(\"message displayErrors - \" + header + \"-\" + message);\n }\n\n // styling for polygons\n geojsonPolygonStyle = (feature) => {\n return {\n fillColor: feature.properties?.style || \"grey\",\n color: feature.properties?.style || \"grey\",\n weight: 2,\n opacity: 0.5,\n fillOpacity: 0.2,\n };\n };\n\n // support for map leaflet.contextmenu\n showCoordinates = (e) => {\n alert(e.latlng);\n };\n\n centerMap = (e) => {\n this.map.panTo(e.latlng);\n };\n\n fitMap = (e, bounds) => {\n this.map.fitBounds(bounds);\n };\n\n zoomIn = (e) => {\n this.map.zoomIn();\n };\n\n zoomOut = (e) => {\n this.map.zoomOut();\n };\n\n // draw\n drawTheMap = (\n mapId,\n mineLevel,\n geoJSONMarkersData,\n geoJSONNamedAreas,\n geoJSONControllers\n ) => {\n const {\n id: mineLevelId,\n image_filename,\n image_info: { width = 10000, height = 8000 },\n } = mineLevel;\n\n //console.log(\"mapViewState\", mapViewState);\n const { center: setCenter, zoom: setZoom } = this.state.mapViewState;\n\n let url = process.env.PUBLIC_URL + \"/areas/\" + image_filename; // \"extraction.png\";\n\n let isMapLoading = true;\n // console.log(\"loaded isMapLoading @ entry to drawTheMap \", isMapLoading);\n this.setState({ isMapLoading: true });\n this.setState({ mapSrc: url });\n\n // if (this.state.isMapLoaded) {\n // console.log(`loaded isMapLoaded TRUE `, url);\n // }\n\n // // setup a dummy image and load the map image in the background\n // // create a replacement image using known dimensions\n // let canvas = document.createElement(\"canvas\");\n // // set desired size of transparent image\n // canvas.width = width;\n // canvas.height = height;\n\n // // extract as new image (data-uri)\n // const url = canvas.toDataURL();\n\n ////////////////////////////////////////////////////////////////////////////\n // Conversion from (x, y) raster image coordinates to equivalent of latLng\n // Taken from Leaflet tutorial \"Non-geographical maps\"\n // http://leafletjs.com/examples/crs-simple/crs-simple.html\n ////////////////////////////////////////////////////////////////////////////\n var yx = L.latLng;\n var xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n };\n\n const img = [\n width, // original width of image `level.jpg` - undercut 800 conversion example => x / ~longitude (0 is left, width, 13234 is right)\n height, // original height of image => y / ~ reverse of latitude (0 is top, height, 9356 is bottom)\n ];\n\n // if a center has been passed to component use it, else recalc\n let center = [width / 2, height / 2]; // center calculation based on original pixel dimensions\n if (setCenter) center = Object.values(setCenter); // .reverse();\n\n let zoom = -4;\n if (setZoom) zoom = setZoom;\n\n // console.log(\n // \"mapViewState center setCenter setZoom\",\n // mineLevelId,\n // center,\n // setCenter,\n // setCenter ? Object.values(setCenter).reverse() : \"????\",\n // zoombounds\n // );\n\n var bounds = L.latLngBounds([xy(0, 0), xy(img)]);\n\n let base = L.tileLayer(url, {\n bounds: bounds,\n noWrap: true,\n });\n\n // #REVEW / #WIP - put up 'loading' banners\n // events to show loading progress\n // https://stackoverflow.com/questions/27378572/leaflet-fire-event-when-tile-layer-loading-begins-and-ends\n\n //base.on(\"loading\", this.setState({ isMapLoading: true }));\n //base.on(\"load\", this.setState({ isMapLoading: false }));\n\n // #REVIEW - not used\n base.on(\"tileload\", function () {\n console.log(\"base loaded\");\n });\n\n base.on(\"tileerror\", (error, tile) => {\n console.log(`Error ${error} loading tile ${tile}`);\n });\n\n this.map = null;\n\n // define the map\n this.map = L.map(mapId, {\n crs: L.CRS.Simple,\n\n //maxBounds: bounds.pad(0.5), // http://leafletjs.com/reference-1.0.3.html#map-maxbounds\n // center: center,\n // zoom: zoom,\n\n // #WIP - add these to config options\n minZoom: -5,\n maxZoom: 5,\n // in setView(point, zoom), zoom will only go to the resolution designated by\n // zoomSnap.\n // see - https://stackoverflow.com/questions/61233935/leaflet-setview-zoom-level-to-non-integer-decimal-value-in-r\n zoomSnap: 0.01,\n\n // removes the zoom controls. These are display via easyButtons\n zoomControl: false,\n\n // disable double click zoom\n doubleClickZoom: false,\n\n attributionControl: false,\n contextmenu: true, // context menu plugin `npm i leaflet-contextmenu`\n contextmenuWidth: 140,\n contextmenuItems: [\n // {\n // text: \"Show coordinates\",\n // callback: this.showCoordinates,\n // },\n {\n text: \"Center map here\",\n callback: this.centerMap,\n },\n {\n text: \"Show all\",\n callback: (e) => this.fitMap(e, bounds),\n },\n // #REVIEW - this is disabled in favour of the control which enables zoom-in/zoom-out\n //\n \"-\",\n {\n text: \"Zoom in\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-in.png\",\n callback: this.zoomIn,\n },\n {\n text: \"Zoom out\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-out.png\",\n callback: this.zoomOut,\n },\n ],\n // scroll wheel zoom smoothing\n scrollWheelZoom: false, // disable original zoom function\n smoothWheelZoom: false, // enable smooth zoom // see - 'disableMapMovement'\n smoothSensitivity: 1.5, // zoom speed. default is 1\n });\n\n // ------------------------------------------------------\n // set single image background\n\n let overlayUrl;\n\n // check file exists on server\n if (this.props.folderFilesList?.includes(image_filename)) {\n overlayUrl = url;\n\n // does not apply to default.png\n if (!image_filename.includes(\"default.png\")) {\n this.areaImageNotFoundMessage(false, image_filename);\n // console.log(\n // `removing a message banner!!!! - areaImageNotFoundMessage`,\n // mineLevelId,\n // image_filename\n // );\n }\n } else {\n // setup a dummy image and load the map image in the background\n // create a replacement image using known dimensions\n let canvas = document.createElement(\"canvas\");\n // set desired size of transparent image\n canvas.width = width;\n canvas.height = height;\n // extract as new image (data-uri)\n overlayUrl = canvas.toDataURL();\n\n // #NOTE #WIP #TODO\n // SET A MESSAGE IF THE MAP FILE IS NOT AVAILABLE\n\n // doe not apply to default.png\n if (!image_filename.includes(\"default.png\")) {\n this.areaImageNotFoundMessage(true, image_filename);\n // console.log(\n // `displaying a message banner!!!! - areaImageNotFoundMessage`,\n // mineLevelId,\n // image_filename\n // );\n }\n }\n\n // ************************************************************************************\n // ************************************************************************************\n\n // --------------------------------\n // #WIP #TESTING\n // see - https://gis.stackexchange.com/questions/183872/leaflet-custom-info-control-update-with-extra-parameters\n //\n // Simple custom control to display a list of text\n // -\n // - displays after map move so that data is updated\n // - lists all FireFly in the current bounds (view)\n // - text list has click eventlistener\n //\n // - use as basis/testing to accumulate control+ select on FireFly 'SHOW_CONTOL_SELECT'\n //\n // --------------------------------\n\n const SHOW_CONTROL_SELECT = true;\n const SHOW_CUSTOM_CONTROL_EVENT = SHOW_CONTROL_SELECT\n ? \"popupclose\"\n : \"move\";\n\n var MyCustomControl = L.Control.extend({\n options: {\n // Default control position\n position: \"bottomright\",\n },\n onAdd: function (map) {\n // Create a container with classname and return it\n this._div = L.DomUtil.create(\"div\", \"my-custom-control\");\n\n L.DomEvent.on(this._div, \"click\", this._click);\n L.DomEvent.disableClickPropagation(this._div);\n return this._div;\n },\n _click: (e) => {\n // console.log(\n // \"clicked myCustomControl: \",\n // e,\n // \"target: \",\n // e.target,\n // \"data-key = \",\n // e.target.dataset.key,\n // \"this.layerlistFireflies \",\n // this.layerlistFireflies\n // );\n\n const id = e.target.dataset.key;\n if (!_isEmpty(id)) {\n const marker = this?.layerlistFireflies?.[id];\n this.map.setView(marker?.getLatLng(), this.map.getMaxZoom());\n }\n },\n setContent: function (content) {\n // Set the innerHTML of the container\n this.getContainer().innerHTML = content;\n },\n });\n\n // Assign to a variable so you can use it later and add it to your map\n var myCustomControl = new MyCustomControl().addTo(this.map);\n\n if (SHOW_CONTROL_SELECT) {\n // display the control+select FireFly lists\n myCustomControl.setContent(this.state.fireflySelection);\n }\n // display the FireFly in the current view\n else {\n myCustomControl.setContent(this.state.searchBoxContent);\n }\n\n // update list after map moves\n this.map.on(SHOW_CUSTOM_CONTROL_EVENT, () => {\n if (SHOW_CONTROL_SELECT) {\n // display the control+select FireFly lists\n myCustomControl.setContent(this.state.fireflySelection.join(\"
\\n\"));\n }\n // display the FireFly in the current view\n else {\n // construct an empty list to fill with onscreen markers\n const inBounds = [];\n // get the map bounds - the top-left and bottom-right locations\n const bounds = this.map.getBounds();\n\n // for each marker, consider whether it is currently visible by comparing\n // with the current map bounds\n if (this.geoJSONGroupLayer) {\n this.geoJSONGroupLayer.eachLayer((layer) => {\n if (bounds.contains(layer.getLatLng())) {\n //inBounds.push(layer?.feature?.properties?.id);\n const id = layer?.feature?.properties?.id;\n inBounds.push(\n `\n ${id}\n `\n );\n }\n });\n }\n\n // display a list of markers.\n myCustomControl.setContent(inBounds.join(\"
\\n\"));\n }\n });\n\n if (false) {\n // --------------------------------\n // #WIP #TESTING\n // see - https://gis.stackexchange.com/questions/183872/leaflet-custom-info-control-update-with-extra-parameters\n //\n // Simple custom control to display a list of text\n // -\n // - displays after map move so that data is updated\n // - text list has click eventlistener\n //\n // See - src/components/Map/leaflet-search-control.js\n // -----------------------------------------------\n\n // load empty panel to place control\n let items = [];\n var searchControl = L.control\n .search({\n data: items,\n })\n .addTo(this.map);\n\n // data is not initially available so\n // remove and redraw the control after the map has moved\n // see - https://gis.stackexchange.com/questions/142773/how-to-update-data-in-leaflet-control\n //\n\n this.map.on(\"move\", () => {\n // remove previous control\n searchControl.remove();\n\n // reload control with fresh data set\n // data is drawn from geoJson layers\n let items = [];\n if (this.geoJSONGroupLayer) {\n this.geoJSONGroupLayer.eachLayer((layer) => {\n items.push(layer);\n });\n }\n // pass data items as geoJson\n searchControl = L.control\n .search({\n data: items,\n })\n .addTo(this.map);\n });\n }\n\n // ************************************************************************************\n // ************************************************************************************\n // ************************************************************************************\n\n let isMapImageFromState = false;\n // if the image is available from the reducer Settings state load this instead\n if (!_isEmpty(this.props.mapImageFromState)) {\n overlayUrl =\n \"data:image/png;base64,\" + this.props.mapImageFromState.imageData;\n isMapImageFromState = true;\n }\n\n const image = L.imageOverlay(overlayUrl, bounds);\n image.addTo(this.map);\n\n // image load events\n image.on(\"load\", (event) => {\n // console.log(\n // \"LOADED NEW BACKGROUND IMAGE \",\n // url,\n // \"** isMapLoading FALSE ** <<<<<\"\n // );\n //console.log(\"LOADED NEW BACKGROUND IMAGE event\", event);\n\n // check if image is loaded from the url or via the state image\n if (event?.target?._url == url || isMapImageFromState) {\n isMapLoading = false;\n // console.log(\"loaded isMapLoading\", isMapLoading);\n this.setState({ isMapLoading: false });\n }\n });\n\n image.on(\"error\", (error, tile) => {\n console.log(`Error ${error} loading imageOverlay ${tile}`);\n });\n\n // console.log(\n // `xxxxx newMapViewState - setCenter, setZoom, center, zoom, bounds`,\n // setCenter,\n // \"-\",\n // setZoom,\n // \"-\",\n // center,\n // \"-\",\n // zoom,\n // \"-\",\n // bounds\n // );\n\n // #NOTE - this defines if the map loads with the previously saved view settings\n if (true) {\n if (!_isEmpty(setCenter) || !_isEmpty(setZoom)) {\n // if mapViewState has been set\n this.map.setView(xy(center), zoom);\n } else {\n // new page load so fit to bounds\n this.map.fitBounds(bounds);\n }\n } else {\n // new page load so fit to bounds\n this.map.fitBounds(bounds);\n }\n\n // record the current zoom level\n this.previousZoom = this.map.getZoom();\n\n // record the current map\n this.previousCenter = this.map.getCenter();\n\n // ****************************************************\n //\n // Setup and draw the Fireflies\n //\n // ****************************************************\n\n //\n this.layerlistFireflies = {};\n\n //\n this.testExternalStr = \"Point: \"; // test passing variable outside into ....\n\n // add popup information\n const onEachFeatureFirefly = (feature, layer) => {\n const { properties } = feature;\n const { id, area } = properties;\n if (id && area) {\n this.layerlistFireflies[id] = layer;\n\n //#TODO - make this the same as how 'NamedAreaPolygonPopup' is implemented.\n // Make Controller, NamedArea and FireFly popups all same process\n\n const popupInfo = `
FireFly:
`;\n layer.bindPopup(popupInfo);\n layer.on(\"popupclose\", (event) => {\n this.setState({ isPopupOpen: false });\n\n // if the map view is moving then do not re-enable data collection on close\n // unless config says 'isDataCollectionDuringMarkerPopupOpen'\n\n if (!this.state.isMarkerDragging || !this.state.isMapView) {\n if (!this.state.isDataCollectionDuringMarkerPopupOpen) {\n this.enableDataCollect();\n }\n }\n });\n\n layer.on(\"popupopen\", (a) => {\n // track of marker popup is opened\n this.setState({ isPopupOpen: true });\n\n // if the map view is already moving don't bother disabling data collection again\n // unless config says 'isDataCollectionDuringMarkerPopupOpen'\n\n if (!this.state.isMarkerDragging && !this.state.isMapView) {\n if (!this.state.isDataCollectionDuringMarkerPopupOpen) {\n this.disableDataCollect();\n }\n }\n\n var popUp = a.target.getPopup();\n popUp\n .getElement()\n .querySelector(`.button-edit`)\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"data-key \",\n // e.target.dataset.key\n // );\n\n const id = e.target.dataset.key;\n if (!_isEmpty(id)) {\n const newModal = {\n active: true,\n id: id,\n area: area,\n };\n // if the map marker is being moved disable the modal dlg display\n // as this is confusing to the user\n if (!this.state.isMarkerDragging) {\n this.setState(\n {\n isOpenFireflyMarkerPopupModal: newModal,\n },\n () =>\n console.log(\n `CLICK ON FF ID: `,\n newModal,\n properties?.light?.event_id\n )\n );\n }\n }\n });\n });\n\n // #WIP - testing control + click event to add to list\n layer.on(\"popupopen\", (e) => {\n const marker = e.target;\n const id = marker?.feature?.id;\n\n let newFireFlySelection = this.state.fireflySelection;\n // if the control key is held down\n if (this.state.ctrlKey) {\n // and the FF id is not already in the selection list\n if (!newFireFlySelection.includes(id)) {\n // add it\n newFireFlySelection.push(id);\n this.setState({ fireflySelection: newFireFlySelection });\n } else {\n newFireFlySelection = newFireFlySelection.filter(\n (list) => list !== id\n );\n this.setState({ fireflySelection: newFireFlySelection });\n }\n }\n // if the control key is not down\n else {\n // and if the FF select list has FFs ... clear the list\n if (newFireFlySelection.length) {\n this.setState({ fireflySelection: [] });\n }\n }\n\n //\n console.log(\n \"CLICKED ON MARKER marker\",\n marker?.feature?.id,\n \" -- ctrlKey : \",\n this.state.ctrlKey,\n \" -- ctrlKey : \",\n this.state.fireflySelection\n );\n });\n }\n\n //----------------------------------------------------\n //\n // MAP MARKER MOVE FIREFLY POSITIONS - DRAG EVENTS\n //\n //----------------------------------------------------\n\n layer.on(\"dragstart\", (e) => {\n //\n });\n\n // markerPositionChanges\n\n layer.on(\"dragend\", (e) => {\n const marker = e.target;\n const position = marker.getLatLng();\n const markerProperties = marker.feature.properties;\n const { id, forced } = markerProperties;\n\n console.log(\"xxx dragend Firefly position\", id, position);\n console.log(\n \"xxx dragend Firefly fire off FF update!!!! markerProperties\",\n marker,\n markerProperties\n );\n // console.log(\n // \"xxx dragend Firefly fire off FF update!!!! forced\",\n // forced ? \"FORCED!!!!!!!!!!!!!!!!\" : \"Not forced\",\n // id\n // );\n\n if (forced) {\n // if Markers has a FORCED- event_id, clear it\n ForceSingleLightManageNamedArea({\n action: \"clear\",\n fireflyId: id,\n area: area,\n easting: null,\n northing: null,\n color: null,\n setFireflyColor: null,\n setFireflyState: null,\n\n namedAreaEvents: this.props.namedAreaEvents,\n deleteNamedArea: this.props.deleteNamedArea,\n saveNewNamedArea: this.props.saveNewNamedArea,\n activate: this.props.activate,\n });\n }\n\n let newMarkerPositionChanges = this.state.markerPositionChanges;\n newMarkerPositionChanges[id] = {\n id: id,\n type: \"firefly\",\n properties: markerProperties,\n position: position,\n };\n this.setState({ markerPositionChanges: newMarkerPositionChanges });\n });\n };\n\n // This is very important! Use a canvas otherwise the chart is too heavy for the browser when\n // the number of points is too high, as in this case where we have around 300K points to plot\n var myRenderer = L.canvas({\n padding: 0.5,\n });\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayerFirefly = (feature, latlng) => {\n // ####SVG Marker###\n\n // #DEBUG\n // #KEEP THIS...\n const iconColor = { stroke: \"grey\", fill: \"grey\" };\n const markerColor = {\n stroke: feature.properties.color.plan,\n fill: feature.properties.color.status,\n };\n\n const { svgIcon, svgStyle } = markerDefinition(\n feature,\n this.props.userSettings\n );\n const currentZoom = this.map.getZoom();\n\n return L.marker(latlng, {\n renderer: myRenderer,\n //icon: makeIcon(\"CrossMarker\", iconColor, 1), // default to 'cross' on first write of coordinate message\n //icon: makeIcon(\"CrossMarker\", markerColor, currentZoom), // default to 'cross' on first write of coordinate message\n icon: makeIcon(svgIcon, svgStyle, currentZoom),\n draggable: false,\n });\n };\n\n // TESTING_DRAG\n\n // set style of firefly markers\n const fireflyStyle = (feature) => {\n let setFillColor;\n if (feature.properties.color) {\n const color = feature.properties.color;\n switch (color.status) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"orange\";\n break;\n case \"white\":\n setFillColor = \"white\";\n break;\n case \"red\":\n setFillColor = \"red\";\n break;\n default:\n setFillColor = \"green\";\n break;\n }\n }\n\n return {\n radius: 6,\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n };\n\n // determine unique properties array from geoJson\n //\n let uniqueProperties = geoJSONMarkersData.features.reduce(\n (acc, { properties }) => {\n Object.entries(properties).forEach(([key, val]) => {\n acc[key] = acc[key] || new Set();\n acc[key].add(val);\n });\n\n return acc;\n },\n {}\n );\n\n if (DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER) {\n let locations = [];\n this.locationGroupLayers = {};\n\n if (uniqueProperties[\"location\"]) {\n locations = [...uniqueProperties[\"location\"]].sort(sortAlphaNum);\n locations.forEach((value, idx) => {\n //console.log(\"locations[idx]\", value);\n\n this[value] = L.featureGroup().addTo(this.map);\n // -> this makes firefly location group a separate layer\n // disabled for now so does not crowd the layer control\n this.locationGroupLayers[value] = this[value];\n });\n }\n }\n\n // #REVIEW - Issue is that with growing array location groups are not created on startup.\n // Need to make these with each update of the state geoJson\n // constrain to area\n const filterArea = (feature, layer) => {\n return feature.properties.area === mineLevelId; //\"DMLZ_Undercut\"; //this.state.map.area; // \"DMLZ_Extraction\";\n };\n\n // add firefly markers to the map\n // Note - Only Controllers and Fireflies are add to map by default (.addTo(this.map))\n this.geoJSONGroupLayer = L.geoJSON(geoJSONMarkersData, {\n pointToLayer: pointToLayerFirefly,\n onEachFeature: onEachFeatureFirefly, // #NOTES - Essential as it defines this.layerlistFireflies\n style: fireflyStyle, //#DEBUG - DISABLED FOR RECTANGLE TESTING ###DEFAULT_MARKER####\n //coordsToLatLng: coordsToLatLng, // <<--- #REVIEW I still don't underestand what this does\n filter: filterArea,\n }).addTo(this.map);\n\n // display the layer when the map is loaded\n // if (!isMapLoading) {\n // this.geoJSONGroupLayer.addTo(this.map);\n // }\n\n // ********************************************************************************\n //\n // Setup and draw the controller markers\n //\n // ********************************************************************************\n\n // list of controller layers\n this.layerlistControllers = {};\n\n // add popup information\n const onEachFeatureController = (feature, layer) => {\n const { properties } = feature;\n const { id, area, network_name } = properties;\n\n const controllerLabel = `${network_name} (${id})`;\n\n if (id && area) {\n //#TODO - make this the same as how 'NamedAreaPolygonPopup' is implemented.\n // Make Controller, NamedArea and FireFly popups all same process\n\n const popupInfo = `
Controller:
`;\n layer.bindPopup(popupInfo);\n layer.on(\"popupclose\", (event) => {\n this.setState({ isPopupOpen: false });\n // if the map view is moving then do not re-enable data collection on close\n if (!this.state.isMarkerDragging || !this.state.isMapView) {\n if (!this.state.isDataCollectionDuringMarkerPopupOpen) {\n this.enableDataCollect();\n }\n }\n });\n layer.on(\"popupopen\", (a) => {\n // track of marker popup is opened\n this.setState({ isPopupOpen: true });\n // if the map view is already moving don't bother disabling data collection again\n if (!this.state.isMarkerDragging && !this.state.isMapView) {\n if (!this.state.isDataCollectionDuringMarkerPopupOpen) {\n this.disableDataCollect();\n }\n }\n\n var popUp = a.target.getPopup();\n popUp\n .getElement()\n .querySelector(`.button-edit`)\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"data-key \",\n // e.target.dataset.key\n // );\n\n const id = e.target.dataset.key;\n if (!_isEmpty(id)) {\n const newModal = {\n active: true,\n id: id,\n area: area,\n };\n // if the map marker is being moved disable the modal dlg display\n // as this is confusing to the user\n if (!this.state.isMarkerDragging) {\n this.setState(\n {\n isOpenControllerMarkerPopupModal: newModal,\n },\n () => console.log(`CLICK ON Controller ID: `, newModal)\n );\n }\n }\n });\n });\n }\n if (feature.properties && feature.properties.id) {\n this.layerlistControllers[feature.properties.id] = layer;\n }\n\n // #REVIEW - can't do this as-is b/c location is an array of positions.\n // Is this a duplication from FF which has never worked?\n // if (feature.properties && feature.properties.location) {\n // // adds a separate layer specifically for location\n // this[`${feature.properties.location}`].addLayer(layer);\n // }\n\n //----------------------------------------------------\n //\n // MAP MARKER MOVE CONTROLLER POSITIONS - DRAG EVENTS\n //\n //----------------------------------------------------\n\n layer.on(\"dragstart\", (e) => {\n //\n });\n\n // markerPositionChanges\n\n layer.on(\"dragend\", (e) => {\n const marker = e.target;\n const position = marker.getLatLng();\n const markerProperties = marker.feature.properties;\n const { id } = markerProperties;\n\n let newMarkerPositionChanges = this.state.markerPositionChanges;\n newMarkerPositionChanges[id] = {\n id: id,\n type: \"controller\",\n properties: markerProperties,\n position: position,\n };\n this.setState({ markerPositionChanges: newMarkerPositionChanges });\n });\n };\n\n // This is very important! Use a canvas otherwise the chart is too heavy for the browser when\n // the number of points is too high, as in this case where we have around 300K points to plot\n // var myRenderer = L.canvas({\n // padding: 0.5,\n // });\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayerController = (feature, latlng) => {\n // #KEEP THIS...\n const iconColor = { stroke: \"blue\", fill: \"blue\" };\n const currentZoom = this.map.getZoom();\n\n return L.marker(latlng, {\n renderer: myRenderer,\n icon: makeIcon(\"SquareMarker\", iconColor, currentZoom), // default to 'cross' on first write of coordinate message\n draggable: false,\n });\n };\n\n // set style of controller markers\n const controllerStyle = (feature) => {\n let setFillColor = \"green\";\n if (feature.properties.color) {\n const color = feature.properties.color;\n switch (color.status) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"orange\";\n break;\n case \"white\":\n setFillColor = \"white\";\n break;\n case \"red\":\n setFillColor = \"red\";\n break;\n default:\n setFillColor = \"green\";\n break;\n }\n }\n\n return {\n radius: 6,\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n };\n\n // add controller markers to the map\n // Note - Only Controllers and Fireflies are add to map by default (.addTo(this.map))\n this.geoJSONControllerGroupLayer = L.geoJSON(geoJSONControllers, {\n pointToLayer: pointToLayerController,\n onEachFeature: onEachFeatureController,\n style: controllerStyle,\n //coordsToLatLng: coordsToLatLng, // <<--- #REVIEW I still don't underestand what this does\n filter: filterArea,\n }).addTo(this.map);\n\n // display the layer when the map is loaded\n // if (!isMapLoading) {\n // this.geoJSONControllerGroupLayer.addTo(this.map);\n // }\n\n // ********************************************************************************\n //\n // Setup and draw the named area polygons\n //\n // ********************************************************************************\n\n // list of named area polygons\n this.layerlistNamedAreas = {};\n\n const onEachFeatureNamedAreas = (feature, layer) => {\n if (feature.properties && feature.properties.id) {\n this.layerlistNamedAreas[feature.properties.id] = layer;\n }\n\n const { properties } = feature;\n const { id, parent, parent_name, sub_type } = properties;\n const namedAreaPolygonPopup = renderToString(\n \n );\n layer.bindPopup(namedAreaPolygonPopup);\n layer.on(\"popupclose\", (event) => {\n this.setState({ isPopupOpen: false });\n });\n layer.on(\"popupopen\", (event) => {\n this.setState({ isPopupOpen: true });\n\n var popUp = event.target.getPopup();\n\n // added eventListener to controller marker content\n // see - src/components/Map/NamedAreaPolygonPopup.js\n popUp\n .getElement()\n .querySelector(\".popupNamedAreaPolygon\")\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on polygon: \",\n // e,\n // \"target: \",\n // e.target,\n // \"dataid \",\n // e.target.getAttribute(\"dataid\")\n // );\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n this.props.goto(`/admin/named-area/${id}`);\n } else {\n this.props.goto(`/admin/named-area/`);\n }\n });\n });\n };\n\n // add named area polygons to the map\n this.geoJSONNamedAreaGroupLayer = L.geoJSON(geoJSONNamedAreas, {\n style: this.geojsonPolygonStyle,\n onEachFeature: onEachFeatureNamedAreas,\n coordsToLatLng: function (coords) {\n // swaps the coordinate references around so when polygons are created the pixel refer are [x,y] , not [y,x]\n // latitude , longitude, altitude\n return new L.LatLng(coords[1], coords[0], coords[2]); // <--------- Normal behavior\n //return new L.LatLng(coords[0], coords[1], coords[2]);\n },\n }).addTo(this.map);\n // #Note - adding to the map before adding to layer will set [x] default .addTo(this.map);\n\n // update leaflet id to properties (used to delete.edit shapes in local state)\n this.geoJSONNamedAreaGroupLayer.eachLayer(function (layer) {\n layer.feature.properties._leaflet_id = layer._leaflet_id; //#TODO - change to L.Stamp()\n });\n\n //#TODO - change to L.Stamp()\n // Also note that .getLayers() works for LayerGroup (and FeatureGroup and GeoJson), but not for L.Map.\n // Usage of \"private\" properties and methods like _layers or _leaflet_id or _latlng is discouraged.\n\n // add layers to the local maps state\n const geoJsonPixels = this.geoJSONNamedAreaGroupLayer.toGeoJSON();\n\n //const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n\n //console.log(\"qqq add layers to the local maps state geoJson\", geoJsonUtm);\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // push layer to back layer.bringToFront()\n this.geoJSONNamedAreaGroupLayer.bringToBack();\n\n // console.log(\n // \"xxx this.geoJSONNamedAreaGroupLayer\",\n // this.geoJSONNamedAreaGroupLayer\n // );\n\n // ********************************************************************************\n //\n // Setup the map layers into control groups and display controls\n //\n // ********************************************************************************\n\n // APP_TERMINOLOGY\n const strNamedAreas = \"Polygons\";\n\n //\n // Use the custom grouped layer control, not \"L.control.layers\"\n // https://github.com/ismyrnow/leaflet-groupedlayercontrol\n // see also - https://stackoverflow.com/questions/34384905/leaflet-how-to-toggle-all-layers-either-off-or-on-at-once/34392545#34392545\n let groupedOverlays = {\n Markers: {\n FireFlys: this.geoJSONGroupLayer,\n Controllers: this.geoJSONControllerGroupLayer,\n Polygons: this.geoJSONNamedAreaGroupLayer,\n },\n };\n\n const options = {\n collapsed: true,\n //exclusiveGroups: [\"Named Areas\"],\n groupsCollapsable: true, // see - https://github.com/ismyrnow/leaflet-groupedlayercontrol/pull/46\n // Show a checkbox next to non-exclusive group labels for toggling all\n groupCheckboxes: true,\n };\n\n // Use the custom grouped layer control, not \"L.control.layers\"\n // https://github.com/ismyrnow/leaflet-groupedlayercontrol\n // see also - https://stackoverflow.com/questions/34384905/leaflet-how-to-toggle-all-layers-either-off-or-on-at-once/34392545#34392545\n this.controller = L.control\n .groupedLayers(null, groupedOverlays, options)\n .addTo(this.map);\n\n //----------------------------------------------------\n //\n // MAP MOVEMENT - DRAG ZOOM ETC\n //\n // see - https://gis.stackexchange.com/questions/54454/disable-leaflet-interaction-temporary\n //----------------------------------------------------\n\n const disableMapMovement = (map) => {\n map.dragging.disable();\n map.touchZoom.disable();\n map.doubleClickZoom.disable();\n //map.scrollWheelZoom.disable();\n map.smoothWheelZoom.disable();\n map.boxZoom.disable();\n map.keyboard.disable();\n if (map.tap) map.tap.disable();\n };\n\n const enableMapMovement = (map) => {\n map.dragging.enable();\n map.touchZoom.enable();\n map.doubleClickZoom.enable();\n //map.scrollWheelZoom.enable();\n map.smoothWheelZoom.enable();\n map.boxZoom.enable();\n map.keyboard.enable();\n if (map.tap) map.tap.enable();\n };\n\n // on startup disable map movement by user\n //console.log(`123simple disableMapMovement`);\n disableMapMovement(this.map);\n\n //----------------------------------------------------\n //\n // MAP VIEW MOVE - CONTROLS - function\n //\n //\n // At least of one of these is called by the map lock\n // so needs to be defined here beforehand\n //\n //----------------------------------------------------\n\n const moveMapViewButtonClick = (control, map) => {\n // show the zoom controls\n moveMapViewButton.disable();\n zoomOutButton.enable();\n zoomInButton.enable();\n cancelMapViewButton.enable();\n\n // disable the move button\n moveMarkerPositionsButton.disable();\n\n // disable the view buttons\n saveMapViewStateButton.disable();\n restoreMapViewStateButton.disable();\n\n // disable the search control\n searchButton.disable();\n\n // enable map movement\n enableMapMovement(this.map);\n\n // map has started moving so disable data collection\n // ...at this point isMarkerDragging should be false to stop data collection\n mapStartMoving();\n\n // #NOTE - toogle map layers AFTER mapStartMoving\n // ...sets isMarkerDragging to true\n toggleMapLayers(control, map, true);\n\n // change the markers to look 'editable'\n // fireflys\n changeMarkerStyle(\n this.geoJSONGroupLayer,\n this.layerlistFireflies,\n \"dummyRoundMarker\"\n );\n // controllers\n changeMarkerStyle(\n this.geoJSONControllerGroupLayer,\n this.layerlistControllers,\n \"dummyRoundMarker\"\n );\n\n // show unlock button state\n mapMoveLockButton.state(\"mapMoveLock-unlock\");\n mapMoveLockButton.button.style.backgroundColor = \"orange\";\n\n this.setState({ isMapView: true });\n };\n\n const cancelMapViewButtonClick = (control, map) => {\n map.closePopup();\n\n // show the zoom controls\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n moveMarkerPositionsButton.enable();\n\n // enabled the view buttons\n saveMapViewStateButton.enable();\n setRestoreMapViewStateButton(\"enable\");\n\n // enable the search button\n searchButton.enable();\n\n // #NOTE - toogle map layers BEFORE mapStopMoving\n // ...sets isMarkerDragging to false\n toggleMapLayers(control, map, false);\n\n // disable map movement\n disableMapMovement(this.map);\n\n // map has stopped moving so enable data collection\n // ...at this point isMarkerDragging should be false to stop data collection\n mapStopMoving();\n\n // // map has stopped moving so enable data collection\n // this.setState({ isPokeTheWorkerLocal: true });\n // const { isPokeTheWorker } = this.props;\n\n // console.log(\n // `123simple disableMapMovement, isPokeTheWorker`,\n // isPokeTheWorker\n // );\n\n // if (!isPokeTheWorker) {\n // // turn on data collection\n // this.props.TurnOnOffPokeTheWorker(true);\n // }\n\n // show lock button state\n mapMoveLockButton.state(\"mapMoveLock-lock\");\n mapMoveLockButton.button.style.backgroundColor = \"white\";\n\n this.setState({ isMapView: false });\n\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshFireflys: true });\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshControllers: true });\n };\n\n //----------------------------------------------------\n //\n // MAP MARKER ZOOM - CONTROLS - MAP LOCK INDICATOR\n //\n //\n // Indicates if map is locked\n //\n //----------------------------------------------------\n\n const mapMoveLockIcon = ``;\n const mapMoveUnLockIcon = ``;\n\n const mapMoveLockButton = L.easyButton({\n states: [\n {\n stateName: \"mapMoveLock-lock\",\n icon: mapMoveLockIcon,\n title:\n \"Map movement is locked. Click the Pan control to modify the map display.\",\n onClick: moveMapViewButtonClick,\n },\n {\n stateName: \"mapMoveLock-unlock\",\n icon: mapMoveUnLockIcon,\n title: \"Map movement is unlocked. Map drag and zoom is enabled.\",\n },\n ],\n });\n\n //let mapMoveLockBar = L.easyBar([mapMoveLock], { position: \"topleft\" });\n //mapMoveLockBar.addTo(this.map);\n\n //----------------------------------------------------\n //\n // MAP MARKER ZOOM - CONTROLS\n //\n //\n // Custom zoom controls\n //\n //----------------------------------------------------\n\n // listeners for disabling buttons\n this.map.on(\"zoomend\", (e) => {\n const map = e.target,\n max = map.getMaxZoom(),\n min = map.getMinZoom(),\n current = map.getZoom(),\n isMapView = this.state.isMapView;\n\n if (current < max) {\n if (isMapView) {\n zoomInButton.enable();\n }\n }\n if (current >= max) {\n if (isMapView) {\n zoomInButton.disable();\n }\n }\n if (current > min) {\n if (isMapView) {\n zoomOutButton.enable();\n }\n }\n if (current <= min) {\n if (isMapView) {\n zoomOutButton.disable();\n }\n }\n });\n\n const moveMapViewZoomIn = ``;\n const moveMapViewZoomOut = ``;\n\n const zoomInButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-in-move-map-view\",\n icon: moveMapViewZoomIn,\n title: \"Zoom in\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() + 1);\n },\n },\n ],\n });\n\n const zoomOutButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-out-move-map-view\",\n icon: moveMapViewZoomOut,\n title: \"Zoom out\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() - 1);\n },\n },\n ],\n });\n //const zoomBar = L.easyBar([zoomInButton, zoomOutButton]);\n //zoomBar.addTo(this.map);\n\n //----------------------------------------------------\n //\n // MAP VIEW MOVE - CONTROLS\n //\n //----------------------------------------------------\n\n const moveMapViewShow = ``;\n const moveMapViewHide = ``;\n\n const disableActiveLayer = (layer, layerName, activeLayersList) => {\n let newActiveLayersList = [activeLayersList];\n if (this.map.hasLayer(layer)) {\n if (!newActiveLayersList.includes(layerName)) {\n newActiveLayersList.push(layerName);\n\n this.map.removeLayer(layer);\n }\n }\n\n return newActiveLayersList;\n };\n\n const enableActiveLayer = (layer, layerName, activeLayersList) => {\n let newActiveLayersList = activeLayersList;\n if (!this.map.hasLayer(layer)) {\n if (newActiveLayersList.includes(layerName)) {\n newActiveLayersList.filter((layer) => layer !== layerName);\n\n layer.addTo(this.map);\n }\n }\n\n return newActiveLayersList;\n };\n\n // remove all layers\n\n const disableAllActiveLayers = (activeLayersList) => {\n let newActiveLayerList = [...activeLayersList];\n\n // remove all layers\n newActiveLayerList = disableActiveLayer(\n this.geoJSONGroupLayer,\n \"geoJSONGroupLayer\",\n newActiveLayerList\n );\n\n // newActiveLayerList = disableActiveLayer(\n // this.geoJSONGroupLayerFireflyTooltips,\n // \"geoJSONGroupLayerFireflyTooltips\",\n // newActiveLayerList\n // );\n // newActiveLayerList = disableActiveLayer(\n // this.geoJSONGroupLayerFireflyForcedTooltips,\n // \"geoJSONGroupLayerFireflyForcedTooltips\",\n // newActiveLayerList\n // );\n newActiveLayerList = disableActiveLayer(\n this.geoJSONControllerGroupLayer,\n \"geoJSONControllerGroupLayer\",\n newActiveLayerList\n );\n // newActiveLayerList = disableActiveLayer(\n // this.geoJSONGroupLayerTags,\n // \"geoJSONGroupLayerTags\",\n // newActiveLayerList\n // );\n // newActiveLayerList = disableActiveLayer(\n // this.geoJSONTagTrackingFFsGroupLayer,\n // \"geoJSONTagTrackingFFsGroupLayer\",\n // newActiveLayerList\n // );\n // newActiveLayerList = disableActiveLayer(\n // this.geoJSONTagTrackingFFsGroupLayerVehicle,\n // \"geoJSONTagTrackingFFsGroupLayerVehicle\",\n // newActiveLayerList\n // );\n\n return newActiveLayerList;\n };\n\n const enableAllActiveLayers = (activeLayersList) => {\n let newActiveLayerList = [...activeLayersList];\n\n // add all layers\n this.geoJSONGroupLayer.addTo(this.map);\n\n // add layers which were displayed\n newActiveLayerList = enableActiveLayer(\n this.geoJSONGroupLayer,\n \"geoJSONGroupLayer\",\n newActiveLayerList\n );\n\n newActiveLayerList = enableActiveLayer(\n this.geoJSONControllerGroupLayer,\n \"geoJSONControllerGroupLayer\",\n newActiveLayerList\n );\n\n return newActiveLayerList;\n };\n\n //\n\n const toggleMapLayers = (control, map, moveMap) => {\n const { isPokeTheWorker, TurnOnOffPokeTheWorker, SetMapMarkerDragging } =\n this.props;\n\n let newActiveLayerList = [...this.state.activeLayersList];\n\n switch (moveMap) {\n case true:\n // turn off data collection\n SetMapMarkerDragging(true);\n this.setState({ isMarkerDragging: true });\n\n break;\n case false:\n // restore/refresh the layer control\n SetMapMarkerDragging(false);\n this.setState({ isMarkerDragging: false });\n\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshFireflys: true });\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshControllers: true });\n\n break;\n\n default:\n break;\n }\n\n this.setState({ activeLayerList: newActiveLayerList });\n };\n\n const moveMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"show-move-map-view\",\n icon: moveMapViewShow,\n title: \"Pan and Zoom\",\n onClick: moveMapViewButtonClick,\n },\n {\n stateName: \"hide-move-map-view\",\n icon: moveMapViewHide,\n title: \"Disable move view\",\n },\n ],\n });\n\n const cancelMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"cancel-move-map-view\",\n icon: \"fa fa-times\",\n title: \"Disable Pan and Zoom\",\n onClick: cancelMapViewButtonClick,\n },\n ],\n });\n\n let moveMapViewBar = L.easyBar(\n [\n mapMoveLockButton,\n moveMapViewButton,\n zoomInButton,\n zoomOutButton,\n cancelMapViewButton,\n ],\n { position: \"topleft\" }\n );\n moveMapViewBar.addTo(this.map);\n\n // startup hide - zoom buttons\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER MOVE POSITIONS - CONTROLS\n //\n //----------------------------------------------------\n\n // Alternate methods to display icons:\n // \n // ''\n //\n // see - https://github.com/CliffCloud/Leaflet.EasyButton/issues/82\n // see - http://danielmontague.com/projects/easyButton.js/v1/examples/#fancier-disable\n // see custom.css 'easyButton' section for styling\n\n const enableFeatureGroupDraggable = (featureGroup, action) => {\n featureGroup.eachLayer(function (layer) {\n if (layer instanceof L.Marker) {\n //console.log(`123 layer`, action, layer);\n if (action) {\n // if (layer.feature.id === \"GBC_Extraction:P26E:1\") {\n // console.log(`123 layer`, layer);\n // }\n layer.dragging.enable();\n } else if (!action) {\n layer.dragging.disable();\n }\n }\n });\n };\n\n const changeMarkerStyle = (featureGroup, layerlist, markerName) => {\n // #DEBUG - color_change\n // console.log(`123SIMPLE changeMarkerStyle featureGroup`, featureGroup);\n // console.log(`123SIMPLE this.layerlistFireflies`, this.layerlistFireflies);\n\n const currentZoom = this.map.getZoom();\n featureGroup.eachLayer(function (layer) {\n if (layer instanceof L.Marker) {\n const id = layer?.feature?.properties?.id;\n const position = layer?.feature?.properties?.position || 0;\n const color =\n layer?.feature?.properties?.light?.color?.status || \"grey\";\n\n const newColor = { stroke: color, fill: color, text: position };\n\n //#DEBUG - color_change\n // console.log(\n // `123SIMPLE layer?.feature?.properties?.`,\n // color,\n // newColor,\n // layer?.feature?.properties\n // );\n switch (markerName) {\n case \"typicalNumberedMapMarker\":\n layer.setIcon(\n makeIcon(\n \"TypicalNumberedMapMarker\",\n newColor, // hack position into color object for numbered markers\n currentZoom\n )\n );\n break;\n case \"dummyRoundMarker\":\n layer.setIcon(\n makeIcon(\n \"RoundMarker\",\n {\n stroke: \"purple\",\n fill: \"purple\",\n text: \"\",\n }, // hack position into color object for numbered markers\n currentZoom\n )\n );\n break;\n default:\n break;\n }\n }\n });\n };\n\n const moveMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"move-marker-positions\",\n icon: \"fas fa-edit\",\n title: \"Edit FireFly or Controller positions\",\n onClick: (control, map) => {\n // lock the move buttons\n mapMoveLockButton.disable();\n moveMarkerPositionsButton.disable();\n saveMarkerPositionsButton.enable();\n cancelMarkerPositionsButton.enable();\n\n // disable the view buttons\n saveMapViewStateButton.disable();\n setRestoreMapViewStateButton(\"disable\");\n\n // disable the search button\n searchButton.disable();\n\n // disable move\n moveMapViewButton.disable();\n\n let newActiveLayerList = [...this.state.activeLayersList];\n // remove all the active layers\n newActiveLayerList = disableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n // make sure FFs and Controller layers are enabled\n this.geoJSONGroupLayer.addTo(this.map);\n this.geoJSONControllerGroupLayer.addTo(this.map);\n\n // enable dragging of markers\n enableFeatureGroupDraggable(this.geoJSONGroupLayer, true);\n enableFeatureGroupDraggable(this.geoJSONControllerGroupLayer, true);\n\n // change the markers to look 'editable'\n // fireflys\n changeMarkerStyle(\n this.geoJSONGroupLayer,\n this.layerlistFireflies,\n \"typicalNumberedMapMarker\"\n );\n // controllers\n changeMarkerStyle(\n this.geoJSONControllerGroupLayer,\n this.layerlistControllers,\n \"typicalNumberedMapMarker\"\n );\n\n // turn off data collection\n const {\n isPokeTheWorker,\n TurnOnOffPokeTheWorker,\n SetMapMarkerDragging,\n } = this.props;\n\n SetMapMarkerDragging(true);\n // console.log(`debug data on/off isMarkerDragging: true`);\n this.setState({ isMarkerDragging: true });\n\n if (isPokeTheWorker) {\n // console.log(\n // `TurnOnOffPokeTheWorker moveMarkerPositionsButton -->`,\n // false\n // );\n TurnOnOffPokeTheWorker(false);\n }\n this.setState({ isPokeTheWorkerLocal: false });\n },\n },\n ],\n });\n\n const saveMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"save-marker-positions\",\n icon: \"fas fa-save\",\n title: \"Save position changes\",\n onClick: (e) => {\n const markerPositionChanges = this.state.markerPositionChanges;\n\n // console.log(\n // ` markerPositionChanges markerPositionChanges`,\n // markerPositionChanges\n // );\n\n if (!_isEmpty(markerPositionChanges)) {\n const {\n saveFirefly,\n saveUPS,\n transformPixelsToUtm,\n mineLevelId,\n } = this.props;\n\n let promiseArray = [];\n\n for (const change in markerPositionChanges) {\n const {\n id,\n type,\n properties,\n position: changedPosition,\n } = markerPositionChanges[change];\n\n const objLatLng = transformPixelsToUtm.transform({\n lat: changedPosition.lat,\n lng: changedPosition.lng,\n });\n\n // transform position to UTM\n const newPosition = {\n mineLevelId: mineLevelId,\n lat: objLatLng.lat,\n lng: objLatLng.lng,\n };\n\n // console.log(\n // ` markerPositionChanges id, type, properties, newPosition`,\n // id,\n // type,\n // properties,\n // changedPosition,\n // newPosition\n // );\n\n switch (type) {\n case \"firefly\":\n const {\n id: fireflyId,\n position: fireflyPosition,\n location: fireflyLocation,\n mac: fireflyMac,\n note: fireflyNote,\n } = properties;\n\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveFirefly({\n values: {\n id: fireflyId,\n position: newPosition,\n fireflyLocation,\n fireflyPosition,\n fireflyMac,\n fireflyNote,\n },\n resolve,\n reject,\n });\n })\n );\n break;\n case \"controller\":\n const { id: upsId, network_name } = properties;\n\n console.log(\"controller saveUPS properties \", properties);\n\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveUPS({\n values: {\n id: upsId,\n position: newPosition,\n name: network_name, // need to save name for DEMO_MODE updates as real message is not available\n },\n resolve,\n reject,\n });\n })\n );\n break;\n default:\n break;\n }\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"UPDATING CONTROLLER/FIREFLY POSITIONS\", results);\n })\n .then(\n () => {\n let newActiveLayerList = [...this.state.activeLayersList];\n // enable all the active layers\n newActiveLayerList =\n enableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n closeMarkerPositionButtons();\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n }\n closeMarkerPositionButtons();\n },\n },\n ],\n });\n\n const closeMarkerPositionButtons = () => {\n // clear all position changes\n this.setState({ markerPositionChanges: {} });\n // disable marker drag\n enableFeatureGroupDraggable(this.geoJSONGroupLayer, false);\n enableFeatureGroupDraggable(this.geoJSONControllerGroupLayer, false);\n\n let newActiveLayerList = [...this.state.activeLayersList];\n // enable all the active layers\n newActiveLayerList = enableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n // enable the move buttons\n mapMoveLockButton.enable();\n moveMarkerPositionsButton.enable();\n saveMarkerPositionsButton.disable();\n cancelMarkerPositionsButton.disable();\n\n // enabled the view buttons\n saveMapViewStateButton.enable();\n setRestoreMapViewStateButton(\"enable\");\n\n // enable the search button\n searchButton.enable();\n\n // enable move\n moveMapViewButton.enable();\n\n // turn on data collection\n this.setState({ isPokeTheWorkerLocal: true });\n const { isPokeTheWorker, TurnOnOffPokeTheWorker, SetMapMarkerDragging } =\n this.props;\n\n SetMapMarkerDragging(false);\n\n //console.log(`debug data on/off isMarkerDragging: false`);\n this.setState({ isMarkerDragging: false });\n\n if (!isPokeTheWorker) {\n // console.log(\n // `TurnOnOffPokeTheWorker closeMarkerPositionButtons -->`,\n // true\n // );\n TurnOnOffPokeTheWorker(true);\n }\n this.setState({ isPokeTheWorkerLocal: true });\n\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshFireflys: true });\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshControllers: true });\n };\n\n const cancelMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"cancel-marker-positions\",\n icon: \"fa fa-times\",\n title: \"Cancel position changes\",\n onClick: (e) => {\n // clear all position changes\n this.setState({ markerPositionChanges: {} });\n // disable dragging of markers\n enableFeatureGroupDraggable(this.geoJSONGroupLayer, false);\n enableFeatureGroupDraggable(\n this.geoJSONControllerGroupLayer,\n false\n );\n\n let newActiveLayerList = [...this.state.activeLayersList];\n // enable all the active layers\n newActiveLayerList = enableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n // disable the move buttons\n moveMarkerPositionsButton.enable();\n saveMarkerPositionsButton.disable();\n cancelMarkerPositionsButton.disable();\n\n // enable the view buttons\n saveMapViewStateButton.enable();\n restoreMapViewStateButton.enable();\n\n // enable the search button\n searchButton.enable();\n\n // enable move\n moveMapViewButton.enable();\n\n // turn on data collection\n this.setState({ isPokeTheWorkerLocal: true });\n const {\n isPokeTheWorker,\n TurnOnOffPokeTheWorker,\n SetMapMarkerDragging,\n } = this.props;\n\n SetMapMarkerDragging(false);\n //console.log(`debug data on/off isMarkerDragging: false`);\n this.setState({ isMarkerDragging: false });\n\n if (!isPokeTheWorker) {\n // console.log(\n // `TurnOnOffPokeTheWorker cancelMarkerPositionsButton -->`,\n // true\n // );\n TurnOnOffPokeTheWorker(true);\n }\n this.setState({ isPokeTheWorkerLocal: true });\n\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshFireflys: true });\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshControllers: true });\n },\n },\n ],\n });\n\n let editBar = L.easyBar([\n moveMarkerPositionsButton,\n saveMarkerPositionsButton,\n cancelMarkerPositionsButton,\n ]);\n\n if (this.props.role.allowAdmin) {\n editBar.addTo(this.map);\n }\n\n // startup hide - save and cancel buttons\n moveMarkerPositionsButton.enable();\n saveMarkerPositionsButton.disable();\n cancelMarkerPositionsButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER RESET VIEW - CONTROLS\n //\n //----------------------------------------------------\n // #NOTE - with current leaflet need to do action to setView\n // https://stackoverflow.com/questions/65322670/change-center-position-of-react-leaflet-map\n\n const mapViewRestoreShow = ``;\n const restoreMapViewStateButton = L.easyButton({\n states: [\n {\n stateName: \"map-view-restore\",\n icon: mapViewRestoreShow,\n title: \"Restore saved view\",\n onClick: (e) => {\n const savedMapViewState = this.state.savedMapViewState;\n const center = savedMapViewState?.center;\n const zoom = savedMapViewState?.zoom;\n if (Array.isArray(center) && !isNaN(zoom)) {\n this.map.setView({ lat: center[1], lng: center[0] }, zoom, {\n animation: false,\n });\n }\n },\n },\n ],\n });\n\n const saveMapViewStateButton = L.easyButton({\n states: [\n {\n stateName: \"map-view-save\",\n icon: \"fas fa-save\",\n title: \"Save view\",\n onClick: (e) => {\n // get the current map center and zoom\n const coords = this.map.getCenter();\n const center = Object?.values?.(coords)?.reverse?.();\n const zoom = this.map.getZoom();\n\n const newMapViewState = {\n id: mineLevel.id,\n center: center,\n zoom: zoom,\n };\n\n // set the new system saved mapViewState\n\n const settings = {\n section: \"mapViewState\",\n key: mineLevel?.id,\n data: { ...newMapViewState },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n\n // this.props.componentstate.set(\n // \"mapViewState\",\n // mineLevel.id,\n // newMapViewState\n // );\n },\n },\n ],\n });\n\n let restoreMapViewStateBar = L.easyBar(\n [restoreMapViewStateButton, saveMapViewStateButton],\n {\n position: \"topleft\",\n id: \"horizontaleasybar\",\n }\n );\n\n restoreMapViewStateBar.addTo(this.map);\n // disable the restore button on startup until check restore properties exist\n restoreMapViewStateButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER REFRESH - CONTROLS\n //\n //----------------------------------------------------\n\n const refreshMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"reset-marker-positions\",\n icon: \"fa fa-redo\",\n title: \"Show all\",\n onClick: (e) => {\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefreshFireflys: true });\n this.setState({ forceMapRefreshControllers: true });\n //console.log(\"clicked Refresh Map : bounds\", bounds);\n this.map.fitBounds(bounds);\n },\n },\n ],\n });\n\n let refreshMapBar = L.easyBar([\n //restoreMapViewStateButton,\n refreshMarkerPositionsButton,\n ]);\n refreshMapBar.addTo(this.map);\n\n //----------------------------------------------------\n //\n // MAP MARKER SEARCH - CONTROLS\n //\n //----------------------------------------------------\n\n const mapSearchShow = ``;\n const mapSearchHide = ``;\n\n const searchButtonClick = (control, map) => {\n const isNewShowSearchBox = !this.state.isShowSearchBox;\n\n // toggle state\n this.setState({ isShowSearchBox: isNewShowSearchBox });\n\n // --------------------------------\n // #WIP #TESTING\n // see - https://gis.stackexchange.com/questions/183872/leaflet-custom-info-control-update-with-extra-parameters\n //\n // Simple custom control to display a list of text\n // -\n // - displays after map move so that data is updated\n // - text list has click eventlistener\n //\n // See - src/components/Map/leaflet-search-control.js\n // -----------------------------------------------\n\n if (isNewShowSearchBox) {\n searchButton.state(\"mapSearch-hide\");\n // reload control with fresh data set\n // data is drawn from geoJson layers\n let items = [];\n if (this.geoJSONGroupLayer) {\n this.geoJSONGroupLayer.eachLayer((layer) => {\n items.push(layer);\n });\n //console.log(\"xxx items\", items);\n }\n searchControl = new SearchControl({ data: items }).addTo(this.map);\n } else {\n searchButton.state(\"mapSearch-show\");\n searchControl.remove();\n }\n };\n\n const searchButton = L.easyButton({\n states: [\n {\n stateName: \"mapSearch-show\",\n icon: mapSearchShow,\n title: \"Search for FireFlys\",\n onClick: searchButtonClick,\n },\n {\n stateName: \"mapSearch-hide\",\n icon: mapSearchHide,\n title: \"Hide Search\",\n onClick: searchButtonClick,\n },\n ],\n });\n\n let searchBar = L.easyBar([searchButton]);\n searchBar.addTo(this.map);\n\n //----------------------------------------------------\n //\n //\n //\n //----------------------------------------------------\n\n const setRestoreMapViewStateButton = (action) => {\n // action = enable / disable\n\n switch (action) {\n case \"enable\":\n // if the savedMapViewState has a center and zoom then\n if (\n this.state?.savedMapViewState?.center &&\n this.state?.savedMapViewState?.zoom\n ) {\n // enable the restore button\n restoreMapViewStateButton.enable();\n }\n break;\n case \"disable\":\n restoreMapViewStateButton.disable();\n break;\n\n default:\n break;\n }\n };\n\n //----------------------------------------------------\n //\n // MAP EVENTS\n //\n //----------------------------------------------------\n\n // map manipulation and moving events\n const mapStartMoving = () => {\n this.props.SetMapMoving(true);\n this.setState({ isMoving: true });\n\n // console.log(\n // `debug data on/off mapStartMoving this.state.isMarkerDragging `,\n // this.state.isMarkerDragging\n // );\n\n if (!this.state.isMarkerDragging) {\n this.setState({ isPokeTheWorkerLocal: false });\n\n const { isPokeTheWorker } = this.props;\n if (isPokeTheWorker) {\n //console.log(`TurnOnOffPokeTheWorker mapStartMoving -->`, false);\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n }\n };\n\n const mapStopMoving = () => {\n this.props.SetMapMoving(false);\n this.setState({ isMoving: false });\n\n // console.log(\n // `nextState. debug data on/off mapStopMoving this.state.isMarkerDragging `,\n // this.state.isMarkerDragging\n // );\n\n if (!this.state.isMarkerDragging) {\n this.setState({ isPokeTheWorkerLocal: true });\n const { isPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n //console.log(`TurnOnOffPokeTheWorker mapStopMoving -->`, true);\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n }\n };\n\n // #WIP\n // if mousedown/movestart on map while pan tool is inactive advise user\n // that need to enable pan tool for mouse\n // this.map.on(\"mousedown movestart\", function () {\n // alert(\"mousedown\");\n // });\n\n //disable_simple\n // if implement 'pan' tool then no longer need this to start/stop\n if (false) {\n // fires when map starts moving: dragging map, zooming etc.\n this.map.on(\"movestart zoomstart \", mapStartMoving); // mousedown?\n\n // fires when map is moving\n this.map.on(\"move\", (e) => {\n //console.log(`COLLECTING DATA ... move `);\n\n this.props.SetMapMoving(true);\n\n const { isPokeTheWorker } = this.props;\n // reinforce turning off data collection!\n // this should never happen....but....\n if (isPokeTheWorker) {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n this.setState({ isPokeTheWorkerLocal: false });\n });\n\n // fires when map stops moving: dragging map, zooming etc.\n this.map.on(\"moveend zoomend \", mapStopMoving); // mouseup?\n }\n // *****************************************************************************************\n // #REVIEW - setup ordering layers for all levels with toggle\n // setup layer control events\n // https://stackoverflow.com/questions/14103489/leaflet-layer-control-events\n this.map.on(\"overlayadd\", onOverlayAdd);\n\n function onOverlayAdd(e) {\n // https://gis.stackexchange.com/questions/137061/how-to-change-layer-order-in-leaflet-js\n // push layer to back layer.bringToFront()\n\n if (e.name === \"Polygon\") {\n e.layer.bringToBack();\n }\n //console.log(\"onOverlayAdd e\", e);\n }\n\n //----------------------------------------------------\n //\n // MAP EVENTS (more :-)\n //\n //----------------------------------------------------\n\n // This manages the size of the marker icons after the map has zoomed\n const zoomend = () => {\n const currentZoom = this.map.getZoom();\n console.log(\"zoomend currentZoom\", currentZoom);\n\n // Tracking whether zooming in or out\n // only update icon if size has changed\n let diffZoom = this.previousZoom - currentZoom;\n\n // diffZoom > 0 - console.log(\"zoomend zoomed out\");\n // iffZoom < 0 - console.log(\"zoomend zoomed in\");\n if (diffZoom !== 0) {\n const firefliesIdInLayer = Object.keys(this.layerlistFireflies);\n firefliesIdInLayer.forEach((fireflyId, idx) => {\n const iconOptions =\n this.layerlistFireflies[fireflyId].getIcon().options;\n const { iconName, iconSize, iconColor } = iconOptions;\n\n // only update icon if size has changed\n\n this.layerlistFireflies[fireflyId].setIcon(\n makeIcon(iconName, iconColor, currentZoom)\n );\n });\n }\n\n this.previousZoom = currentZoom;\n };\n\n this.map.on(\"zoomend\", zoomend);\n\n const moveend = () => {\n // do nothing\n };\n this.map.on(\"moveend\", moveend);\n\n // add 'dummy' map click event to maintain the buttonStates\n this.map.on(\"click\", (e) => {\n // e.latLng is undefined then the 'click' event has been fired by this.map.fire() elsewhere\n if (e.latLng === undefined) {\n const { isMarkerDragging, savedMapViewState } = this.state;\n\n // if map is stationary (no drag etc)\n if (!isMarkerDragging) {\n // if the savedMapViewState has a center and zoom then\n if (savedMapViewState?.center && savedMapViewState?.zoom) {\n // enable the restore button\n restoreMapViewStateButton.enable();\n }\n }\n }\n });\n\n // initialise the map view state on map load\n this.setState({ savedMapViewState: this.props.savedMapViewState }, () =>\n this.map.fire(\"click\")\n );\n\n // +++++++++++++++++++++++++++++++++++++++++++++++++++++\n //\n // Finally! map drawn!!!!!!!!\n //\n // ++++++++++++++++++++++++++++++++++++++++++++++\n };\n\n //----------------------------------------------------\n //\n //\n //----------------------------------------------------\n\n convertGeoJsonPixelsToUtm = (geoJsonPixels, mineLevel) => {\n // Output coordinates of shape in UTM\n // returns geoJSON\n\n // convert pixel coordinates in geoJson Pixels to utm\n // deep clone - to stop geometry being converted on raw *utm data\n geoJsonPixels = JSON.parse(JSON.stringify(geoJsonPixels));\n const geoJsonUtm = transformGeoJsonPixelsToUtm(geoJsonPixels, mineLevel);\n\n // #TODO - NOTE: 'drawnItemsToJSON' below strips out the properties!\n // - needs to be updated to preserve PROPERTIES\n // - do not use until fixed\n\n // preserve styling of polygon in geoJson\n //\n //geoJson = this.drawnItemsToJSON(this.editableLayers);\n return geoJsonUtm;\n };\n\n shouldComponentUpdate(nextProps, nextState) {\n const { mineLevel, isPokeTheWorker } = nextProps;\n const {\n isPokeTheWorkerLocal,\n isOpenFireflyMarkerPopupModal,\n isOpenControllerMarkerPopupModal,\n isMarkerDragging,\n } = nextState;\n\n // console.log(`nextState. ........`);\n // console.log(`nextState.isPokeTheWorkerLocal`, isPokeTheWorkerLocal);\n // console.log(`nextState.isMarkerDragging`, isMarkerDragging);\n\n if (\n mineLevel === undefined ||\n // if not collecting data and the modal popup is triggered then re-render component\n (!isPokeTheWorkerLocal &&\n isOpenFireflyMarkerPopupModal.active === false &&\n isOpenControllerMarkerPopupModal.active === false)\n ) {\n return false;\n } else {\n return true;\n }\n }\n\n ctrlKeyDown = (e) => {\n if (e.keyCode === 17) {\n this.setState({ ctrlKey: true });\n }\n };\n\n ctrlKeyUp = (e) => {\n if (e.keyCode === 17) {\n this.setState({ ctrlKey: false });\n }\n };\n\n componentDidMount() {\n const { mineLevel, savedMapViewState, userSettings } = this.props;\n\n this.setState({\n isTagTracking:\n userSettings?.application?.includes(\"tagTracking\") || isTagTracking(),\n });\n document.addEventListener(\"keydown\", this.ctrlKeyDown, false);\n document.addEventListener(\"keyup\", this.ctrlKeyUp, false);\n\n if (!_isEmpty(mineLevel)) {\n this.setState({ map: { area: mineLevel?.id } });\n\n this.setState({ isMapComponentDidMount: true });\n\n if (!_isEmpty(savedMapViewState)) {\n // wait for state change before mounting the map\n this.setState({ mapViewState: savedMapViewState }, () => {\n //console.log(\"newMapViewState updated\");\n this.mapMount();\n });\n } else {\n this.mapMount();\n }\n } else {\n // #NOTE - this should never happen, but on rapid reload of the page\n // I experienced mineLevel undefined.\n\n console.log(`LOAD ERROR: AREA IS EMPTY `, mineLevel);\n }\n }\n\n componentWillUnmount() {\n const { mineLevel } = this.props;\n\n document.removeEventListener(\"keydown\", this.ctrlKeyDown, false);\n document.removeEventListener(\"keyup\", this.ctrlKeyUp, false);\n\n // clear out map\n if (this.map && this.map.remove) {\n this.map.off();\n this.map.remove();\n }\n }\n\n mapMount = () => {\n const { render } = this.props;\n\n const mapId = \"map-\" + render;\n\n const { mineLevel } = this.props;\n\n const {\n geoJSONMarkersDataUtm,\n geoJSONNamedAreasUtm,\n geoJSONControllersUtm,\n } = this.props;\n\n let geoJSONMarkersData;\n let geoJSONControllers;\n\n // ***************************************************************\n //\n // Update fireflies geoJson\n //\n // ***************************************************************\n\n if (\n typeof geoJSONMarkersDataUtm.features !== \"undefined\" &&\n geoJSONMarkersDataUtm.features.length\n ) {\n // #REVIEW - this now happens in WebWorker reducer for fireflies\n // deep clone - to stop geometry being converted on raw *utm data\n //geoJSONMarkersData = JSON.parse(JSON.stringify(geoJSONMarkersDataUtm));\n //geoJSONMarkersData = this.transformGeoJsonUtmToPixels(geoJSONMarkersData);\n\n geoJSONMarkersData = geoJSONMarkersDataUtm;\n } else {\n // add an empty geoJson featurecollection\n geoJSONMarkersData = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // ***************************************************************\n //\n // Update Controllers geoJson\n //\n // ***************************************************************\n\n if (\n typeof geoJSONControllersUtm.features !== \"undefined\" &&\n geoJSONControllersUtm.features.length\n ) {\n geoJSONControllers = geoJSONControllersUtm;\n } else {\n // add an empty geoJson featurecollection\n geoJSONControllers = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // ***************************************************************\n //\n // Update named area geoJson\n //\n // ***************************************************************\n\n let geoJSONNamedAreas;\n\n if (\n typeof geoJSONNamedAreasUtm.features !== \"undefined\" &&\n geoJSONNamedAreasUtm.features.length\n ) {\n // deep clone - to stop geometry being converted on raw *utm data\n geoJSONNamedAreas = JSON.parse(JSON.stringify(geoJSONNamedAreasUtm));\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n geoJSONNamedAreas = transformGeoJsonUtmToPixels(\n geoJSONNamedAreas,\n mineLevelObj,\n 1,\n false\n );\n } else {\n // add an empty geoJson featurecollection\n geoJSONNamedAreas = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // ***************************************************************\n //\n // draw the map\n //\n // ***************************************************************\n\n this.drawTheMap(\n mapId,\n mineLevel,\n geoJSONMarkersData,\n geoJSONNamedAreas,\n geoJSONControllers\n );\n };\n\n // disable data collection while map is moving\n mapStartMoving = () => {\n this.props.SetMapMoving(true);\n this.setState({ isMoving: true });\n\n // if isMarkerDragging is false do not turn off data collection\n if (!this.state.isMarkerDragging) {\n this.setState({ isPokeTheWorkerLocal: false });\n\n const { isPokeTheWorker } = this.props;\n if (isPokeTheWorker) {\n //console.log(`TurnOnOffPokeTheWorker mapStopMoving -->`, false);\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n }\n };\n\n // enable data collection while map is moving\n mapStopMoving = () => {\n this.props.SetMapMoving(false);\n this.setState({ isMoving: false });\n\n // if isMarkerDragging is false do not turn off data collection\n if (!this.state.isMarkerDragging) {\n this.setState({ isPokeTheWorkerLocal: true });\n const { isPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n //console.log(`TurnOnOffPokeTheWorker mapStopMoving -->`, true);\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n }\n };\n\n disableDataCollect = () => {\n this.props.SetMapMoving(true);\n this.setState({ isMoving: true });\n\n this.setState({ isPokeTheWorkerLocal: false });\n const { isPokeTheWorker } = this.props;\n if (isPokeTheWorker) {\n //console.log(`TurnOnOffPokeTheWorker disableDataCollect -->`, false);\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n };\n\n enableDataCollect = () => {\n this.props.SetMapMoving(false);\n this.setState({ isMoving: false });\n\n this.setState({ isPokeTheWorkerLocal: true });\n const { isPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n //console.log(`TurnOnOffPokeTheWorker enableDataCollect -->`, true);\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n };\n\n componentDidUpdate(prevProps, prevState) {\n // check if the saved map view state has changed\n if (\n JSON.stringify(this.props.savedMapViewState) !==\n JSON.stringify(prevProps.savedMapViewState)\n ) {\n //console.log(\"savedMapViewState componentDidUpdate this.state changed\");\n this.setState({ savedMapViewState: this.props.savedMapViewState }, () =>\n this.map.fire(\"click\")\n );\n }\n\n // check if marker is clicked to show popup, and the area is the same.\n // If so, do not re-draw the map layers, just return to re-render and pop the dlg\n // #Note - if the FF or Controller Popup is open, or the modal dlg is open,\n // then don't process any updates.\n if (\n this.state?.isPopupOpen === true ||\n this.state?.isOpenFireflyMarkerPopupModal.active === true\n ) {\n return;\n }\n\n // #NOTE - keep in mind they there could be multiple maps Areas loaded. Each as a state.\n\n // check if map is now visible\n if (prevProps.showMap !== this.props.showMap && this.props.showMap) {\n // reinitialise map\n // see - https://gis.stackexchange.com/questions/289975/toggling-leaflet-map-on-click\n this.map.invalidateSize();\n }\n\n const { mineLevel } = this.props;\n\n // if the area (mine level) has changed, remove the map and remount it all again\n if (\n prevProps.mineLevelId !== this.props.mineLevelId &&\n !_isEmpty(mineLevel)\n ) {\n if (this.map && this.map.remove) {\n this.map.off();\n this.map.remove();\n }\n\n // console.log(\"hhh mineLevel\", mineLevel);\n\n this.setState({ map: { area: mineLevel.id } });\n // reset map load state pending reload of area background image\n\n // console.log(\"loaded isMapLoading\", true);\n this.setState({ isMapLoading: true });\n\n // set saved map view state to local state when initialised\n const newMapViewState = this.props.savedMapViewState;\n\n if (!_isEmpty(newMapViewState)) {\n this.setState({ mapViewState: newMapViewState });\n }\n\n this.mapMount();\n }\n\n // delay update until background map image has loaded\n if (this.state.isMapLoading) {\n console.log(\n `WARNING.....Map is loading...updates are not rendering!!!!!!!!!`\n );\n return;\n }\n\n // ****************************************************************************************\n //\n // Update Firefly markers\n //\n // ****************************************************************************************\n //\n\n if (\n !_isEmpty(this.props.geoJSONMarkersDataUtm) && //#WIP - disabled to test rendering update for lightingplan changes\n this.props.geoJSONMarkersDataUtm.features && // features propertie exists but does not have to have any FFs\n // #NOTE - ATM this state is not used (i.e. not set). Leave in place for #REVIEW\n !this.state.isPopupOpen && // don't update if a marker popup is open, because redraw clobber eventListener is open dlg\n (this.props.fireflyIdsUpdateList.length > 0 ||\n this.state.forceMapRefreshFireflys)\n ) {\n // console.log(\n // `123simple this.props.fireflyIdsUpdateList`,\n // this.props.fireflyIdsUpdateList\n // );\n\n if (this.state.forceMapRefreshFireflys)\n console.log(`------------> FORCED REFRESH - FireFly markers`);\n\n // keep a copy of the previous state\n // #REVIEW #TODO - is this necesary since we have already compared at the reducer?\n let prevGeoJSONMarkersData = {};\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONMarkersData = JSON.parse(\n JSON.stringify(this.props.geoJSONMarkersDataUtm)\n );\n\n //\n // update the fireflies.\n\n // make a local copy\n let newFireflyIdsUpdateList = [...this.props.fireflyIdsUpdateList];\n\n // check for deleted FFs\n if (\n !_isEmpty(this.props.fireflyIdsUpdateList) &&\n !_isEmpty(this.props.fireflyIdsDeleteList)\n ) {\n // check if there are any FFs for deletion and if so delete it from\n // the firefly layers - this.layerlistFireflies[id]\n if (this.props.fireflyIdsDeleteList.length > 0) {\n let newLayerListFireflies = {};\n let updatedFireflyIds = [];\n\n for (const [key, value] of Object.entries(this.layerlistFireflies)) {\n if (this.props.fireflyIdsDeleteList.includes(key)) {\n this.map.removeLayer(value);\n // if we delete the ID don't update it\n newFireflyIdsUpdateList = newFireflyIdsUpdateList.filter(\n (ff) => ff === key\n );\n\n // remove FF Id from fireflyIdsUpdateList after it's been processed\n //\n updatedFireflyIds.push(key);\n } else {\n newLayerListFireflies[key] = value;\n }\n }\n\n // console.log(\n // `map xxx fireflyIdsUpdateList updatedFireflyIds`,\n // updatedFireflyIds\n // );\n\n // remove FF Id from fireflyIdsUpdateList\n this.props.fireflyIdsUpdateListDeleteId(updatedFireflyIds);\n this.layerlistFireflies = newLayerListFireflies;\n }\n }\n\n // check - if there are firefly for update but the layer does not exist,\n // which can happen if fireflies have been deleted from the controller\n // or firefly page, then just remove these from the update list.\n\n // console.log(`map fireflyIdsUpdateList -----------------------------`);\n\n // console.log(\n // `map fireflyIdsUpdateList this.props.fireflyIdsUpdateList`,\n // this.props.fireflyIdsUpdateList\n // );\n\n // console.log(\n // `map fireflyIdsUpdateList this.props.fireflyIdsDeleteList`,\n // this.props.fireflyIdsDeleteList\n // );\n\n //\n\n let currentLayerlistFireflies = [];\n\n for (const [key, value] of Object.entries(this.layerlistFireflies)) {\n currentLayerlistFireflies.push(key);\n // console.log(`map fireflyIdsUpdateList layerlistFireflies key`, key);\n }\n\n // console.log(\n // `map fireflyIdsUpdateList newFireflyIdsUpdateList`,\n // newFireflyIdsUpdateList\n // );\n\n let newFireflyIdsUpdateListInCurrentLayers = [];\n let newFireflyIdsUpdateListNotInCurrentLayers = [];\n\n newFireflyIdsUpdateList.forEach((id) => {\n // if the current layer list of fireflies does not include the update id,\n // remove it from the update list as there is no point in updating a layer which\n // does not exist\n if (!currentLayerlistFireflies?.includes(id)) {\n // is not a current layer\n newFireflyIdsUpdateListNotInCurrentLayers.push(id);\n } else {\n newFireflyIdsUpdateListInCurrentLayers.push(id);\n }\n });\n\n if (newFireflyIdsUpdateListNotInCurrentLayers.length) {\n this.props.fireflyIdsUpdateListDeleteId(\n newFireflyIdsUpdateListNotInCurrentLayers\n );\n }\n // console.log(`map fireflyIdsUpdateList -----------------------------`);\n\n // now manage the FF updates - this.geoJSONMarkersData\n if (\n !_isEmpty(this.props.fireflyIdsUpdateList) ||\n this.state.forceMapRefreshFireflys\n ) {\n // console.log(\n // `123simple updatedFireflyIds fireflyIdsUpdateList, newFireflyIdsUpdateList`,\n // this.props.fireflyIdsUpdateList,\n // newFireflyIdsUpdateList\n // );\n\n // update markers for geoJSON\n this.updateFireflyMarkersGeoJSON(\n this.map,\n geoJSONMarkersData,\n prevGeoJSONMarkersData,\n this.props.mineLevelId,\n newFireflyIdsUpdateListInCurrentLayers, //newFireflyIdsUpdateList,\n this.state.forceMapRefreshFireflys\n );\n }\n\n // if doing forced map refresh reset flag\n if (this.state.forceMapRefreshFireflys) {\n this.setState({ forceMapRefreshFireflys: false });\n }\n }\n\n // ****************************************************************************************\n //\n // Update controller markers\n //\n // ****************************************************************************************\n\n if (\n (!_isEmpty(this.props.geoJSONControllersUtm) &&\n !_isEmpty(this.props.geoJSONControllersUtm?.features) &&\n this.props.geoJSONControllersUtm !== prevProps.geoJSONControllersUtm &&\n // #WIP?????????????????????????\n // is this really why???????//\n !this.state.isPopupOpen) || // don't update if a marker popup is open, because redraw clobber eventListener is open dlg\n this.state.forceMapRefreshControllers\n ) {\n if (this.state.forceMapRefreshControllers)\n console.log(`------------> FORCED REFRESH - Controller Markers`);\n\n // keep a copy of the previous state\n let prevGeoJSONControllers = {};\n if (prevProps.geoJSONControllersUtm !== undefined) {\n prevGeoJSONControllers = JSON.parse(\n JSON.stringify(prevProps.geoJSONControllersUtm)\n );\n }\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONControllers = JSON.parse(\n JSON.stringify(this.props.geoJSONControllersUtm)\n );\n\n //update markers for geoJSON\n this.updateControllerMarkersGeoJSON(\n this.map,\n geoJSONControllers,\n prevGeoJSONControllers,\n this.props.mineLevelId,\n this.state.forceMapRefreshControllers\n );\n\n // if doing forced map refresh reset flag\n if (this.state.forceMapRefreshControllers) {\n this.setState({ forceMapRefreshControllers: false });\n }\n }\n\n // ****************************************************************************************\n //\n // update named area polygons\n //\n // ****************************************************************************************\n\n // #NOTE - geoJSONNamedAreasUtm can exist but .features could be empty if no polygons are displayed\n if (\n !_isEmpty(this.props.geoJSONNamedAreasUtm) &&\n JSON.stringify(this.props.geoJSONNamedAreasUtm) !==\n JSON.stringify(prevProps.geoJSONNamedAreasUtm)\n ) {\n // console.log(\n // \"xxx updateNamedAreasGeoJSON this.props.geoJSONNamedAreasUtm\",\n // this.props.geoJSONNamedAreasUtm\n // );\n // console.log(\n // \"xxx updateNamedAreasGeoJSON prevProps.geoJSONNamedAreasUtm\",\n // prevProps.geoJSONNamedAreasUtm\n // );\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONNamedAreas = JSON.parse(\n JSON.stringify(this.props.geoJSONNamedAreasUtm)\n );\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n // transform the coordinates to pixel image references\n geoJSONNamedAreas = transformGeoJsonUtmToPixels(\n geoJSONNamedAreas,\n mineLevelObj,\n 1,\n false\n );\n\n this.updateNamedAreasGeoJSON(\n this.map,\n geoJSONNamedAreas,\n this.props.mineLevelId\n );\n\n // if doing forced map refresh reset flag\n if (this.state.forceMapRefreshControllers) {\n this.setState({ forceMapRefreshControllers: false });\n }\n }\n }\n\n // If the FireFlys are changed the visual changes (on the main map screen) are:\n // * POSITION - updated with setLatLng()\n // * LIGHT light characteristics - e.g. color, state, event_id (used for tracking forced lights)\n // * ICON the icon drawn - update here with setIcon()\n // * FORCED - keep track of lights which have been forced\n\n updateFireflyMarkersGeoJSON(\n map,\n geoJSONMarkersData,\n prevGeoJSONMarkersData,\n mineLevelId,\n fireflyIdsUpdateList,\n forceUpdate\n ) {\n // tracks fireflies which have been updated. These should be deleted from the list.\n let updatedFireflyIds = [];\n // update....\n geoJSONMarkersData.features.map((feature, idx) => {\n const { properties } = feature;\n const { id } = properties;\n\n // if the layer exist for the id\n if (this.layerlistFireflies[id]) {\n // if it is has had a change or there is a forced update\n if (fireflyIdsUpdateList.includes(id) || forceUpdate) {\n // ...update it.\n\n // accumulate a list of updated fireflys as it is being processed\n updatedFireflyIds.push(id);\n\n //\n // update the POSITION\n const { geometry } = feature;\n const { light, timestamp } = properties;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n var newLatLng = new L.LatLng(Y, X);\n this.layerlistFireflies[id].setLatLng(newLatLng);\n\n // update the ICON\n const { svgIcon, svgStyle } = markerDefinition(\n feature,\n this.props.userSettings\n );\n const currentZoom = this.map.getZoom();\n this.layerlistFireflies[id].setIcon(\n makeIcon(svgIcon, svgStyle, currentZoom)\n );\n\n // update the LIGHT information\n this.layerlistFireflies[id].feature.properties.light = light;\n\n // update the FORCED information from any recent updates to event_id\n if (light?.event_id?.includes(\"FORCED\")) {\n this.layerlistFireflies[id].feature.properties.forced = true;\n }\n\n //\n }\n\n //??????????????????????\n } else if (feature.properties.area === mineLevelId) {\n //console.log(\"FF_UPDATE -> ADD TO LAYER LIST ...\", id);\n // if it's not in the layer list, and is in the area i.e. `mineLevelId` add it..........\n //\n // Note - pointToLayer and onEachFeature are defined in ComponentDidMount() and\n // .addData() runs `onEachFeatureFirefly` which adds the feature to layerlistFireflies[]\n\n this.geoJSONGroupLayer.addData(geoJSONMarkersData.features[idx]);\n }\n });\n\n //console.log(`xx8xx updatedFireflyIds`, updatedFireflyIds);\n\n if (updatedFireflyIds.length) {\n // after processing the list send a delete processed items from the update list\n this.props.fireflyIdsUpdateListDeleteId(updatedFireflyIds);\n }\n }\n\n updateControllerMarkersGeoJSON(\n map,\n geoJSONControllers,\n prevJSONControllers,\n mineLevelId,\n forceUpdate\n ) {\n // map the geoJSONControllers and delete all the markers who have changed propertie\n // and accumulate these markers and\n // add them all at the end\n\n // convert previous marker data to keyed object\n let prevMarkerData = {};\n if (prevJSONControllers?.features !== undefined) {\n prevJSONControllers.features.map((feature, idx) => {\n const {\n properties: { id },\n } = feature;\n prevMarkerData[id] = feature;\n });\n }\n\n // find the fireflies which have changed in geojsonMarkerOptions object\n geoJSONControllers.features.map((feature, idx) => {\n const { properties } = feature;\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_number,\n utm_zone_letter,\n z,\n color,\n timestamp,\n mode,\n master,\n //\n deviceStatus,\n user_relay,\n } = properties;\n\n //console.log(\"xxx deviceStatus\", deviceStatus);\n\n let isChanged = !_isEqual(\n omitDeep(prevMarkerData[id], [\"timestamp\"]),\n omitDeep(feature, [\"timestamp\"])\n );\n\n //console.log(`MARKER_REDRAW isChanged`, isChanged);\n // if (true) {\n // // isChanged\n // console.log(\n // `MARKER_REDRAW isChanged prevMarkerData[id]`,\n // prevMarkerData[id]\n // );\n // console.log(`MARKER_REDRAW isChanged feature`, feature);\n // }\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n // status checks\n let status = \"OK\"; // lets assume everything is OK. Ever the optimist eh?!\n\n if (deviceStatus.includes(StatusEnum.API_FETCH)) {\n status = \"API_FETCH\";\n }\n\n if (\n deviceStatus.includes(StatusEnum.NO_STATUS_REPORT) ||\n deviceStatus.includes(StatusEnum.TIMEOUT)\n ) {\n status = \"INACTIVE_CONTROLLER\";\n }\n\n let isUpsBatteryOnFault = false;\n if (deviceStatus.includes(StatusEnum.CONTROLLER_ON_BATTERY)) {\n isUpsBatteryOnFault = true;\n }\n\n let isUpsNetworkFault = false;\n if (deviceStatus.includes(StatusEnum.CONTROLLER_NETWORK_FAULT)) {\n isUpsNetworkFault = true;\n }\n\n const isSirenActive = isKthBitSet(user_relay, 1);\n if (isSirenActive) {\n status = \"RELAY_SIREN\";\n }\n\n // _#DEMO_MODE - force regular updates irrespective of real changes\n if (\n !isSirenActive &&\n (this.props.userSettings?.feature?.includes(\"showDemoMode\") ||\n isDemoMode())\n ) {\n status = \"OK\";\n }\n\n // console.log(`Controller MARKER_REDRAW id`, id);\n // console.log(\n // `Controller MARKER_REDRAW this.layerlistControllers[id]`,\n // this.layerlistControllers[id]\n // );\n // console.log(`Controller MARKER_REDRAW isChanged`, isChanged);\n // console.log(`Controller MARKER_REDRAW status !== \"OK\"`, status !== \"OK\");\n // console.log(`Controller MARKER_REDRAW forceUpdate`, forceUpdate);\n // console.log(`Controller MARKER_REDRAW -------------`);\n\n // controller color is set but whether there are faults and mode settings\n //let upsFaultmsg = this.props.faults;\n\n //console.log(\"xxx Controller MARKER_REDRAW upsFaultmsg\", upsFaultmsg);\n\n // const isUpsNetworkFault = upsFaultmsg.some(\n // (fault) =>\n // fault.type === \"network\" &&\n // fault.active &&\n // fault.id === id &&\n // fault.area === area\n // );\n\n // // #Note - this is probably overkill to detect battery ON for controller\n // // but making sure!\n // const isUpsBatteryOnFault = upsFaultmsg.some(\n // (fault) =>\n // fault.type === \"battery\" &&\n // fault.active &&\n // fault.subtype === \"charge\" &&\n // fault.description.includes(\"ON\") &&\n // fault.id === id &&\n // fault.area === area\n // );\n\n //console.log(`Controller MARKER_REDRAW -------------`);\n\n if (this.layerlistControllers[id]) {\n if (isChanged || status !== \"OK\" || forceUpdate) {\n // console.log(\n // `xxx Controller MARKER_REDRAW forceUpdate >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`,\n // status,\n // forceUpdate\n // );\n\n // ####SVG Marker###\n // default\n let svgIcon = \"SquareMarker\";\n let svgStyle = { stroke: \"grey\", fill: \"grey\" };\n\n // CONTROLLER UPS MODE SETTINGS\n // * isInCommission\n // * isMaster\n const isInCommission = mode.toLowerCase() === \"commission\";\n const isMaster = master ? true : false;\n\n // isInCommission - change icon\n isInCommission\n ? (svgIcon = \"StarMarker\")\n : (svgIcon = \"SquareMarker\");\n\n // isMaster - change color\n switch (isMaster) {\n case true:\n default:\n svgStyle = { stroke: \"blue\", fill: \"blue\" };\n break;\n case false:\n svgStyle = { stroke: \"brown\", fill: \"brown\" };\n break;\n }\n\n // CONTROLLER UPS FAULT SETTINGS\n // * isUpsNetworkFault\n // * isUpsBatteryOnFault i.e. status === \"CONTROLLER_ON_BATTERY\"\n // override color if network fault &/or battery fault\n // ups icon normal = blue/blue\n // network fault = outline red, fill blue, SquareMarker\n // battery fault = outline red, fill orange, DiamondMarker\n\n if (isUpsNetworkFault) {\n if (isUpsBatteryOnFault) {\n svgIcon = \"DiamondMarker\";\n svgStyle = { stroke: \"red\", fill: \"orange\" };\n } else {\n svgIcon = \"SquareMarker\";\n svgStyle = { stroke: \"blue\", fill: \"red\" };\n }\n } else {\n if (isUpsBatteryOnFault) {\n svgIcon = \"DiamondMarker\";\n svgStyle = { stroke: \"blue\", fill: \"orange\" };\n }\n }\n\n // #NOTE\n // #WIP\n // Status switch is used for firefly. The checks above should be moved\n // into the case below.\n\n switch (status) {\n case \"RELAY_SIREN\":\n svgIcon = \"RelaySirenMarker\";\n break;\n case \"API_FETCH\":\n svgIcon = \"TriangleMarker\";\n break;\n\n case \"INACTIVE_CONTROLLER\": // aka UPS_TIMEOUT\n svgStyle = { stroke: \"fuchsia\", fill: \"black\" };\n svgIcon = \"HourGlassMarker\";\n break;\n default:\n break;\n }\n\n const currentZoom = this.map.getZoom();\n\n this.layerlistControllers[id].setIcon(\n makeIcon(svgIcon, svgStyle, currentZoom)\n );\n }\n } else if (properties.area === mineLevelId) {\n // if it's not in the layer list, and is in the area i.e. `mineLevelId` add it..........\n //\n // Note - pointToLayer and onEachFeature are defined in ComponentDidMount() and\n // .addData() runs `onEachFeatureController` which adds the feature to layerlistControllers[]\n this.geoJSONControllerGroupLayer.addData(\n geoJSONControllers.features[idx]\n );\n }\n });\n }\n\n updateNamedAreasGeoJSON(map, geoJSONPolygonData, mineLevelId) {\n // #TODO - !\n // map the geoJSONPolygonData and delete all the shapes who have changed propertie\n // and accumulate these shapes\n // add them all at the end\n\n // check if a named area has been removed\n // get list of IDs for current named area (i.e. layers)\n const layersIds = Object.keys(this.layerlistNamedAreas);\n\n // get the Ids for the incoming update of named area data\n let namedAreaIds = [];\n for (const namedArea in geoJSONPolygonData.features) {\n namedAreaIds.push(geoJSONPolygonData.features[namedArea].properties.id);\n }\n\n // check for a difference\n // filter each item and return it if it is *not* in the namedAreas\n const inLayerNotInNamedArea = layersIds.filter(\n (i) => !namedAreaIds.includes(i)\n );\n\n inLayerNotInNamedArea.forEach((layer, idx) => {\n // delete any layers which are in layersIds but *not* in namedAreaIds\n // remove the layer from layer groups\n this.geoJSONNamedAreaGroupLayer.removeLayer(\n this.layerlistNamedAreas[layer]\n );\n // to be really sure remove it from the map completely\n this.map.removeLayer(this.layerlistNamedAreas[layer]);\n // delete the layer from the list\n delete this.layerlistNamedAreas[layer];\n });\n\n if (true) {\n // find the named areas which have changed in geoJSONPolygonData object\n geoJSONPolygonData.features.map(({ properties }, idx) => {\n const {\n id,\n area,\n parent,\n type,\n name,\n parent_name,\n sub_type = \"region\",\n style,\n } = properties;\n\n //console.log(\"xxx >>> geoJSONPolygonData properties\", properties);\n\n // if the shape is not in the layer list\n if (!this.layerlistNamedAreas[id]) {\n // add it\n // note pointToLayer and onEachFeature are defined in ComponentDidMount() <--- #REVIEW - is it? i.e. for namedArea?\n this.geoJSONNamedAreaGroupLayer.addData(\n geoJSONPolygonData.features[idx]\n );\n } else {\n // if the shape exists but has changed, update it\n\n // #WIP - should also review updates to shape coordinates\n\n // AFAIK the only way to update is to go through every layer until finding the match!\n // thankfully there are not many layers for namedAreas\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n if (layer === this.layerlistNamedAreas[id]) {\n layer.feature.properties = properties;\n }\n });\n }\n });\n }\n }\n\n resetModalFirefly = () => {\n this.setState({\n isOpenFireflyMarkerPopupModal: { active: false, id: \"\", area: \"\" },\n });\n };\n\n resetModalController = () => {\n this.setState({\n isOpenControllerMarkerPopupModal: { active: false, id: \"\", area: \"\" },\n });\n };\n\n render() {\n const { render, showMap, mineLevel = {} } = this.props;\n const { isMapLoading } = this.state;\n\n const mapId = \"map-\" + render;\n\n const { legend: isShowLegend } = this.props.namedAreaDisplaySettings;\n\n const visibility =\n showMap !== true ? { display: \"none\" } : { display: \"block\" };\n\n const showLegend = isShowLegend\n ? undefined\n : { minHeight: \"calc(95vh - 320px)\" };\n\n const {\n image_info: { backgroundColor },\n } = mineLevel;\n\n const bgColor = backgroundColor\n ? `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`\n : \"green\";\n\n const isOpenFireflyMarkerPopupModal =\n this.state.isOpenFireflyMarkerPopupModal.active === true;\n const isOpenControllerMarkerPopupModal =\n this.state.isOpenControllerMarkerPopupModal.active === true;\n\n return (\n <>\n {isOpenFireflyMarkerPopupModal && (\n this.handleSettingsSave(values)}\n resetModal={() => this.resetModalFirefly(false)}\n />\n )}\n {isOpenControllerMarkerPopupModal && (\n this.handleSettingsSave(values)}\n resetModal={() => this.resetModalController(false)}\n />\n )}\n \n
\n {/*
*/}\n \n {/*
*/}\n
\n \n\n {/* testing loading image by having image in a separte part of the dom */}\n {/* {\n console.log(`loaded image `, this.state.mapSrc);\n this.setState({ isMapLoaded: true });\n }}\n /> */}\n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n // track changes to the saved map view state\n const savedMapViewState = props.componentstate.get(\n \"mapViewState\",\n `${props?.mineLevelId}`\n ) || {\n id: `${props?.mineLevelId}`,\n options: [],\n };\n\n const mineLevel = getAreaById(state, props.mineLevelId);\n\n const transformPixelsToUtm = mineLevel?.transformPixelsToUtm;\n\n const markersData = getMapState(state);\n\n // Firefly coordinates\n let geoJSONMarkersDataUtm = getFireflyCoordinatesByAreaId(\n state,\n props.mineLevelId\n );\n\n // #DEBUG - setup empty layer\n //geoJSONMarkersDataUtm = [];\n\n // Firefly update changes\n const fireflyIdsUpdateList = getFireflyIdsUpdateListByArea(\n state,\n props.mineLevelId\n );\n\n // Firefly deletetions\n const fireflyIdsDeleteList = getFireflyIdsDeleteListByArea(\n state,\n props.mineLevelId\n );\n\n // Controller coordinates\n const geoJSONControllersUtm = getControllerCoordinatesByAreaId(\n state,\n props.mineLevelId\n );\n\n // returns a list of polygon regions to 'show' on the map\n const regionPreview =\n getRegionPreviewListByAreaId(state, props.mineLevelId) || []; // e.g. [{id: \"test_area\", name: \"polygon\", namedArea: \"uglyBear\", spec: \"test_area:a2d9282e-4b41-446f-b100-922fefbceeb9\", type: \"Polygon\"}]\n\n // Named Area polygons\n //\n // #NOTE - we are only displaying the polygons selected by the show/hide context menu for\n // the SOP button interface. These areas are returned in 'regionPreview'.\n //\n // returns the geoJson of the polygons (named area) based on the regionList\n let geoJSONNamedAreasUtm = getNamedAreaInfosByRegionPreviewByAreaId(\n state,\n regionPreview,\n props.mineLevelId\n );\n\n const localMapState = GetLocalMap(state);\n const isDirty = getIsDirty(state);\n\n const namedAreaDisplaySettings = getNamedAreaDisplaySettings(state);\n\n const faults = getFaults(state) || [];\n\n // check for image files\n const folderFilesList = getFolderFileNamesListById(state, \"areas\");\n\n // message banner support\n const { messageBanners } = state.alarmButton;\n\n // deviceTimestamps for checking timeout\n\n const timedOutDevices = getTimedOutDevices(state);\n\n const isPokeTheWorker = isOnOffPokeTheWorker(state);\n\n const namedAreaEvents = getNamedAreaEventsByAreaId(state, props.mineLevelId);\n\n // user roles\n\n const userSuper = isUserSuper(state);\n const userAdmin = isUserAdmin(state);\n const userUser = isUserUser(state);\n const userGuest = isUserGuest(state);\n\n // map image from state\n // this has previously been loaded and saved to the Settings reducer state\n const mapImageFromState = getMapImageById(state, props.mineLevelId);\n\n return {\n mineLevel,\n markersData,\n geoJSONMarkersDataUtm,\n localMapState,\n geoJSONNamedAreasUtm,\n isDirty,\n namedAreaDisplaySettings,\n geoJSONControllersUtm,\n //\n faults,\n regionPreview,\n //\n fireflyIdsUpdateList,\n fireflyIdsDeleteList,\n folderFilesList,\n //\n messageBanners,\n //\n timedOutDevices,\n //\n isPokeTheWorker,\n //\n namedAreaEvents,\n //\n transformPixelsToUtm,\n // user roles\n role: {\n allowGuest: userGuest,\n allowOperator: userSuper || userAdmin || userUser,\n allowAdmin: userSuper || userAdmin,\n allowSuper: userSuper,\n },\n //\n // map image from state\n mapImageFromState,\n //\n savedMapViewState,\n //\n userSettings: getUserSettings(state) || {},\n };\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n UpdateLocalMap: (mapState) => {\n dispatch(UpdateLocalMap(mapState));\n },\n namedAreaClearDeleteSelections: (parentId) => {\n dispatch(namedAreaClearDeleteSelections(parentId));\n },\n namedAreasSetIsDirty: (id) => {\n dispatch(namedAreasSetIsDirty(id));\n },\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n goto: (path) => dispatch(push(path)),\n fireflyIdsUpdateListDeleteId: (id) =>\n dispatch(fireflyIdsUpdateListDeleteId(id)),\n // flash message support\n clearFlashMessages: () => {\n dispatch(clearFlashMessages());\n },\n removeFlashMessage: (id) => {\n dispatch(removeFlashMessage(id));\n },\n addWarningFlashMessageIdColor: (id, color, header, message) => {\n dispatch(addWarningFlashMessageIdColor(id, color, header, message));\n },\n SetMessageBanner: (messageState) => {\n dispatch(SetMessageBanner(messageState));\n },\n TurnOnOffPokeTheWorker: (action) => {\n dispatch(TurnOnOffPokeTheWorker(action));\n },\n SetMapMoving: (bool) => dispatch(SetMapMoving(bool)),\n SetMapMarkerDragging: (bool) => dispatch(SetMapMarkerDragging(bool)),\n\n //\n saveNewNamedArea: (data) => dispatch(saveNewNamedArea(data)),\n deleteNamedArea: (id) => {\n dispatch(deleteNamedArea(id));\n },\n //\n // see - src/pages/ControlRoomPage/PrecannedOperations.js\n activate: (operation) => dispatch(activateNamedAreaEventSingle(operation)),\n cancel: (operation) => dispatch(cancelNamedAreaEvent(operation)),\n waitEventTimeOut: (action) => dispatch(waitEventTimeOut(action)),\n saveFirefly: (data) => dispatch(saveFirefly(data)),\n saveUPS: (data) => dispatch(saveUPS(data)),\n //\n // region preview\n addAreaPreview: (area) => dispatch(addAreaPreview(area)),\n removeAreaPreview: (area) => dispatch(removeAreaPreview(area)),\n //\n saveUserSettingsComponentState: (data) =>\n dispatch(saveUserSettingsComponentState(data)),\n});\n\nexport default withComponentStateCache(\n connect(mapStateToProps, mapDispatchToProps)(Map)\n);\n","import React from \"react\";\nimport { Button, Icon, Grid, Segment } from \"semantic-ui-react\";\n\n// #WIP #TODO\n//import { ALLOWED_LIGHT_COLORS } from 'firefly_light_colors'\n// get light colors from server config\n// see `src/firefly_light_colors.js`\n// export const ALLOWED_LIGHT_COLORS = getConfigItem()\n//\n// function getConfigItem () {\n// try {\n// const val = getCookie('available-colors')\n// const serverValues = JSON.parse(atob(val))\n// return serverValues\n// } catch (e) {\n// return ['off', 'white', 'red', 'amber', 'green']\n// }\n// }\n\nimport { getEquivalentSemanticColorName } from \"colorpalette\";\nimport { StatusEnumToReadable } from \"utils/StatusEnum\";\nimport { getMapMarkerDisplayOptions } from \"components/ConfigJs\";\n\n// removed \"off\" as a color -> state\nconst ALLOWED_LIGHT_COLORS = [\"red\", \"amber\", \"white\", \"green\", \"blue\"];\n\n// let SingleColorOperation = ({ lightSetting, isEnabled, onClick }) => {\n// let semanticColorName = getEquivalentSemanticColorName(lightSetting);\n// semanticColorName = lightSetting === \"white\" ? \"grey\" : semanticColorName;\n// return (\n// \n// );\n// };\n\nexport const FireflyMarkerPopup = ({ id, data }) => {\n const {\n ups_id,\n easting,\n northing,\n X,\n Y,\n z,\n utm_zone_number,\n utm_zone_letter,\n fireflyNote = \"\",\n //color, // No longer used, see 'light' below\n //led_state, // No longer used, see 'light' below\n lastStatusReport,\n namedAreaEventForFirefly = {},\n light,\n role,\n ffMac,\n deviceStatus,\n forcedClickList,\n } = data;\n\n //console.log(`xxxx deviceStatus`, deviceStatus);\n //console.log(`xxxx forcedClickList`, forcedClickList);\n\n const { allowAdmin } = role;\n\n // default display options\n const {\n firefly: {\n showMac = false,\n showStatus = true,\n showUtm = false,\n showEventInfo = false,\n showForced = true,\n },\n } = getMapMarkerDisplayOptions();\n\n // console.log(\n // `FireflyMarkerPopup props`,\n // id,\n // ups_id,\n // easting,\n // northing,\n // X,\n // Y,\n // z,\n // utm_zone_number,\n // utm_zone_letter,\n // fireflyNote,\n // lastStatusReport,\n // namedAreaEventForFirefly,\n // light\n // );\n\n const {\n id: currentForcedId = \"\",\n active: isCurrentForcedActive = false,\n active_color: currentForcedColor = \"\",\n active_state: currentForcedState = \"ON\",\n } = namedAreaEventForFirefly;\n\n const isStrobe = [\"STROBE\", \"FORWARD\", \"BACKWARD\"].includes?.(\n currentForcedState?.toUpperCase?.()\n );\n const isOff = [\"OFF\"].includes?.(currentForcedState?.toUpperCase?.()); // || led_state?.toUpperCase?.() === \"OFF\";\n\n const { color, lightState, event_id } = light;\n const { status: colorStatus, plan: colorPlan } = color;\n const { status: lightStatus, plan: lightPlan } = lightState;\n\n //console.log(`forcedLight isStrobe`, isStrobe);\n\n // #NOTE - the `dataid` passed to the Button is used to attach an eventListener to the rendered string.\n // This is how the onClick event is setup.\n // See - src/components/Map/MineLevelMapLeaflet.js\n // \"...\n // .querySelector(\".popupFireflyMarkerLink\")\n // .addEventListener(\"click\", (e) => {\n //...\"\n\n //\n //\n // #NOTE - `dataid` is places on both button and icon, as it is not possible to guarantee only one click target.\n\n const controllerLink = (\n \n {ups_id || \"unknown\"} \n \n );\n\n const controllerNoLink = {ups_id || \"unknown\"} ;\n\n const fireflyLink = (\n \n );\n const fireflyNoLink = {id.replaceAll(\"_\", \" \")};\n\n const deviceStatusString =\n deviceStatus?.length > 0\n ? deviceStatus.map((status) => StatusEnumToReadable[status])?.join(\", \")\n : \"OK\";\n\n const showForcedStyleDisplayHidden = !showForced ? { display: \"none\" } : null;\n\n const isProcessingRequest = forcedClickList.includes(id);\n\n return (\n
\n \n \n \n {/* */}\n Controller\n \n \n {allowAdmin ? controllerLink : controllerNoLink}\n \n \n \n \n {/* */}\n FireFly\n \n \n {allowAdmin ? fireflyLink : fireflyNoLink}\n \n \n {showMac && (\n \n \n MAC\n \n {ffMac}\n \n )}\n {showStatus && (\n \n \n Status\n \n {deviceStatusString}\n \n )}\n {showUtm && (\n \n \n UTM\n \n \n Easting: {easting}
\n Northing: {northing}
\n Zone: {utm_zone_number} / {utm_zone_letter}\n
\n \n )}\n \n \n Color\n \n \n Requested: \n \n {isOff\n ? \"OFF\"\n : colorPlan === \"orange\"\n ? \"AMBER\"\n : colorPlan.toUpperCase()}\n \n\n
\n Reported: \n \n {isOff\n ? \"OFF\"\n : colorStatus === \"orange\"\n ? \"AMBER\"\n : colorStatus.toUpperCase()}\n {colorPlan !== colorStatus ? (\n \n ...updating...\n \n ) : null}\n \n
\n
\n \n \n \n State\n \n \n Requested: \n \n {isOff ? \"OFF\" : lightPlan?.led_state?.toUpperCase()}\n \n
\n Reported: \n \n {isOff ? \"OFF\" : lightStatus?.led_state?.toUpperCase()}\n {lightPlan?.led_state !== lightStatus?.led_state ? (\n \n ...updating...\n \n ) : null}\n \n
\n \n {showEventInfo && event_id !== \"\" && event_id !== currentForcedId && (\n \n \n Event Info\n \n \n ID: {event_id}
\n
\n \n )}\n\n \n \n Forced\n \n \n \n \n \n \n\n {showForced && currentForcedId !== \"\" && (\n \n \n Forced Info\n \n \n ID: {currentForcedId}
\n COLOR: {currentForcedColor}
\n STATE: {currentForcedState}\n
\n \n )}\n {isProcessingRequest && (\n \n \n Changed\n \n \n Change requested. Processing ...\n \n \n )}\n \n {/* \n Last Report\n \n {lastStatusReport} */}\n \n \n \n \n \n \n {ALLOWED_LIGHT_COLORS.map((color, idx) => {\n let semanticColorName = getEquivalentSemanticColorName(color);\n\n let isEnabled = false;\n let isSameColor =\n color === currentForcedColor || color === colorStatus;\n\n // if strobe is set and it's the same is the same color then this is a forced event\n // if strobe is not set and it is the same color there is no forced event\n\n if (isSameColor) {\n isEnabled = true;\n }\n\n semanticColorName =\n color === \"white\" ? \"grey\" : semanticColorName;\n\n // console.log(\n // `forcedLight FireflyMarkerPopup light , isEnabled, isSameColor, isStrobe`,\n // isEnabled,\n // isSameColor,\n // isStrobe,\n // \"currentForcedColor\",\n // currentForcedColor,\n // \"color\",\n // color\n // );\n\n const buttonBackgroundStyle = !isEnabled\n ? {\n backgroundColor: `${semanticColorName}!important`,\n opacity: 0.2,\n }\n : {\n opacity: 1,\n borderColor: \"#333\",\n borderStyle: \"solid\",\n };\n\n return (\n \n  \n \n );\n })}\n \n \n \n \n Strobe\n \n \n \n Off\n \n
\n \n \n \n\n \n \n Notes\n \n \n {fireflyNote !== \"\"\n ? fireflyNote\n : \"There are no notes for this firefly.\"}\n \n \n \n \n );\n};\n","import React from \"react\";\nimport { Button, Popup, Icon, Grid } from \"semantic-ui-react\";\nimport { round } from \"utils/number-utils.js\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nexport const ControllerMarkerPopup = ({ id, data }) => {\n const {\n id: ups_id,\n easting,\n northing,\n X,\n Y,\n z,\n utm_zone_number,\n utm_zone_letter,\n color,\n location,\n lastStatusReport,\n user_relay,\n role,\n } = data;\n\n const { allowAdmin } = role;\n\n // #NOTE - the `dataid` passed to the Butotn is used to attach an eventListener to the rendered string.\n // This is how the onClick event is setup.\n // See - src/components/Map/MineLevelMapLeaflet.js\n // \"... .addEventListener(\"click\", (e) => { ...\"\n\n //\n //\n // #NOTE - `dataid` is places on both button and icon, as it is not possible to guarantee only one click target.\n\n // disable link for operator\n const buttonLink = (\n \n {ups_id || \"unknown\"} \n \n );\n\n const noLink = {ups_id || \"unknown\"} ;\n\n return (\n
\n \n \n \n {/* */}\n Controller\n \n \n {allowAdmin ? buttonLink : noLink}\n \n \n {location?.map((loc, idx) => {\n const locString = JSON.stringify(loc)?.replaceAll('\"', \"\");\n return (\n \n \n {idx > 0 ? null : Location}\n \n {locString}\n \n );\n })}\n \n \n User Relay\n \n {user_relay || 0}\n \n \n {/* \n Last Report\n \n {lastStatusReport} */}\n \n \n
\n );\n};\n","// #MINELEVELMAPLEAFLET\n\nimport React, { Component, useState } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport L from \"leaflet\";\nimport \"leaflet/dist/leaflet.css\";\nimport \"leaflet-draw\";\nimport \"leaflet-contextmenu\";\nimport \"leaflet.smoothwheelzoom\";\n\nimport \"leaflet-groupedlayercontrol\";\nimport \"leaflet-groupedlayercontrol/dist/leaflet.groupedlayercontrol.min.css\";\nimport \"components/Map/MapIcons.css\";\n\nimport \"leaflet-easybutton/src/easy-button.css\";\nimport \"leaflet-easybutton\";\n\nimport {\n transformGeoJsonUtmToPixels,\n transformGeoJsonPixelsToUtm,\n} from \"components/Map/util-geoJsonToPixels\";\n\nimport {\n getAreaById,\n getMapState,\n getFireflyCoordinatesByAreaId,\n getFireflyCoordinatesForcedByAreaId,\n getControllerCoordinatesByAreaId,\n getNamedAreaInfos,\n getNamedAreaDeleteSelections,\n getNamedAreaHideSelections,\n getIsDirty,\n getFaults,\n getNamedAreaParentInfos,\n getFireflyIdsUpdateListByArea,\n getFireflyIdsDeleteListByArea,\n} from \"components/WebWorker/reducer\";\n\nimport {\n namedAreaClearDeleteSelections,\n namedAreasSetIsDirty,\n mqttPublish,\n fireflyIdsUpdateListDeleteId,\n} from \"components/WebWorker/actions\";\n\nimport { GetLocalMap } from \"components/Map/reducer\";\nimport { UpdateLocalMap } from \"components/Map/actions\";\n\nimport { sortAlphaNum } from \"utils/sortAlphaNum\";\nimport { round } from \"utils/number-utils.js\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _isEqual from \"lodash/isEqual\";\nimport { omitDeep } from \"utils/omitDeep\";\n\nimport * as turf from \"@turf/turf\";\n\nimport { formatRelative, parseISO } from \"date-fns\";\n\nimport { saveFirefly } from \"UPSPanelControllers/actions\";\nimport { saveUPS } from \"UPSPanelControllers/actions\";\n\n// import plugin's css (if present)\n// note, that this is only one of possible ways to load css\nimport \"leaflet-contextmenu/dist/leaflet.contextmenu.css\";\nimport { messageToken } from \"utils/messageToken\";\n\nimport { makeIcon } from \"components/Map/MakeIcon\";\n\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport { renderToString } from \"react-dom/server\";\nimport FireflyName from \"containers/FireflyName\";\nimport FireflyLink from \"admin/firefly/FireflyLink\";\n\nimport { FireflyMarkerPopup } from \"components/Map/FireflyMarkerPopup\";\nimport { ControllerMarkerPopup } from \"components/Map/ControllerMarkerPopup\";\n\nimport { NamedAreaPolygonPopup } from \"components/Map/NamedAreaPolygonPopup\";\n\nimport { StatusEnum } from \"utils/StatusEnum\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\n\nimport { getRegionPreviewListByAreaId } from \"components/RegionPreview/reducer\";\n\nimport {\n getTimedOutDevices,\n getNamedAreaEventsByAreaId,\n} from \"components/WebWorker/reducer\";\n\n// >>>>> flash message support\nimport {\n isConfigJs,\n faultMessageBannerDisplay,\n faultMessageBannerText,\n isDemoMode,\n getMapDisplayOptions,\n markerAcceptableEventLabels,\n} from \"components/ConfigJs\";\n\nimport {\n addWarningFlashMessageIdColor,\n removeFlashMessage,\n clearFlashMessages,\n SetMessageBanner,\n} from \"FlashMessages/actions\";\n\nimport cuid from \"cuid\";\n// <<<<< flash message support\n\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { SetMapMoving, SetMapMarkerDragging } from \"components/Map/actions\";\n\nimport {\n createNamedAreaAroundFirefly,\n createFireflyNamedAreaId,\n} from \"NamedAreas/createNamedAreaAroundFirefly\";\n\nimport { saveNewNamedArea, deleteNamedArea } from \"NamedAreas/actions\";\n\nimport {\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n waitEventTimeOut,\n} from \"OperationalChanges/actions\";\nimport { id } from \"date-fns/locale\";\nimport { propTypes } from \"redux-form\";\n\nimport { getEquivalentSemanticColorName } from \"colorpalette\";\n\nimport { isKthBitSet } from \"utils/bit-operations\";\n\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nimport {\n addAreaPreview,\n removeAreaPreview,\n} from \"components/RegionPreview/actions\";\n\nimport { getObjectDiff } from \"utils/getObjectDiff\";\n\nimport { getMapImageById } from \"components/Settings/reducer\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nimport { getUserSettings } from \"auth/reducer\";\n\n// -----------------------------------------------\n// DEFAULT AND DEBUG\n//\n// -----------------------------------------------\n//\n// #NOTE - DEFAULT PRIORITY SETTINGS\n//\n// MAX_PRIORITY = 10000 // <<--- see 'manager/manager.go'\nconst DEFAULT_EMERGENCY_PRIORITY = 9900;\nconst DEFAULT_LEVEL_WIDE_PRIORITY = 9800;\nconst DEFAULT_START_FORCED_LIGHT_PRIORITY = 5000;\n\n// #DEBUG\n// DISABLE code sections under development and prototyped\nconst DEBUG_ENABLED_FALSE = false;\nconst DEBUG_ENABLED_TRUE = true;\nconst DEBUG_SHOW_COUNT_OF_MARKERS_EACH_LAYER = false; // #WIP - was working a long time ago but broken now?!\n\n//\n\n// #REVIEW - Need this? This is setup to be able to draw linestrings etc,\n// but are there too many layers as-is?\n// This adds a group for each location. i.e. The 'location' is the port, e.g. \"Panel 1\"\n// This allows the turning on/off of individual locations.\n// #REVIEW\n//\n// * move this.locationGroupLayers etc. to state rather than forced via \"this.\"\n// use setState to update once groups are defined\n\nconst mapDisplayOptions = getMapDisplayOptions();\nconst { controllerLocations, controllerCables } = mapDisplayOptions;\n\n// Disabled for now to reduce load on leaflet\nconst DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER = controllerLocations;\nconst DEFAULT_SHOW_FIREFLY_POLYLINE_GROUP_LAYER =\n controllerCables && DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER;\n// << needs location group above to also be enabled\n\n//\n// -----------------------------------------------\n\nfunction unify(polyList) {\n var options = { tolerance: 0.0001, highQuality: true };\n\n for (var i = 0; i < polyList.length; ++i) {\n if (i === 0) {\n var unionTemp = polyList[i].toGeoJSON();\n } else {\n try {\n // clean the coordinates\n unionTemp = turf.cleanCoords(turf.simplify(unionTemp, options));\n // check for kinks\n var kinks = turf.kinks(unionTemp);\n if (kinks.features.length) {\n unionTemp = turf.unkinkPolygon(unionTemp);\n }\n unionTemp = turf.union(unionTemp, polyList[i].toGeoJSON());\n } catch (error) {\n console.log(`DATA ERROR: MapLeaflet turf union `, error);\n }\n }\n }\n return L.geoJson(unionTemp);\n}\n\nconst CustomReactPopup = ({ id }) => {\n return (\n
\n

{`A pretty React Popup ${id}`}

\n
\n );\n};\n\n// firefly marker definition\nconst markerDefinition = (feature) => {\n const { properties } = feature;\n\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_number,\n utm_zone_letter,\n z,\n //color,\n light,\n controllerMode,\n deviceStatus,\n timestamp,\n ups_id,\n forced,\n } = properties;\n\n const {\n color,\n lightState,\n marker, // defaults to 'RoundMarker'\n led_state,\n off_time,\n on_time,\n train,\n brightness,\n event_id,\n } = light;\n\n // default\n let svgIcon = marker || \"DiamondMarker\";\n\n const { plan: ColorPlan, status: ColorStatus } = color;\n const { plan: StatePlan, status: StateStatus } = lightState;\n\n // FF is in transition is states are changing. Test for color change and for state change.\n // Ignore the other statuses i.e. off_time, on_time, train, brightness.\n //\n const isInTransition =\n ColorPlan !== ColorStatus ||\n StatePlan?.led_state !== StateStatus?.led_state;\n\n // #REVIEW\n const isStrobing = [\"strobe\", \"forward\", \"backward\"].includes(\n led_state.toLowerCase()\n );\n\n const isInCommission = controllerMode.toLowerCase() === \"commission\";\n\n // label the icons with a text character designating the source\n\n let textLabel = \"\";\n if (forced) textLabel = \"F\";\n // event_id labels\n const eventIdLabel = event_id?.charAt(0);\n\n if (markerAcceptableEventLabels()?.includes(eventIdLabel))\n textLabel = eventIdLabel;\n\n // #Note - if the light is off force it to be \"grey\" to account for\n // when a colored marker is defined. Color is meaningless when it is off.\n // A special marker like the 'OffMarker' has no color fill so it not impacted.\n //\n\n let svgStyle = {\n stroke:\n StatePlan?.led_state === \"off\"\n ? `rgba(0,0,0,.2)`\n : getEquivalentSemanticColorName(ColorPlan),\n fill:\n StateStatus?.led_state === \"off\"\n ? `rgba(0,0,0,.1)`\n : getEquivalentSemanticColorName(ColorStatus),\n text: textLabel,\n };\n\n // status checks\n let status = \"OK\"; // lets assume everything is OK. Ever the optimist eh?!\n\n if (deviceStatus.includes(StatusEnum.API_FETCH)) {\n status = \"API_FETCH\";\n }\n\n if (\n deviceStatus.includes(StatusEnum.NO_STATUS_REPORT) ||\n deviceStatus.includes(StatusEnum.TIMEOUT) ||\n deviceStatus.includes(StatusEnum.INACTIVE)\n ) {\n status = \"INACTIVE_FIREFLY\";\n }\n\n if (_isEmpty(ups_id)) {\n status = \"DEAD_FIREFLY\";\n }\n\n // OVERRIDE FAULT CHECKS IF DEMO MODE\n if (\n this.props.userSettings?.feature?.includes(\"showDemoMode\") ||\n isDemoMode()\n ) {\n // _#DEMO_MODE\n status = \"OK\";\n }\n\n //console.log(`xxx FIREFLY status`, id, deviceStatus, status);\n\n switch (status) {\n case \"OK\":\n if (marker.toLowerCase() === \"travelwaymarker\") {\n svgIcon = \"TravelwayMarker\";\n // travelways have a special color\n svgStyle = {\n stroke: \"purple\",\n fill: getEquivalentSemanticColorName(ColorStatus),\n };\n } else if (marker.toLowerCase() === \"travelwaymarker\") {\n svgIcon = \"TravelwayMarker\";\n // travelways have a special color\n svgStyle = {\n stroke: \"purple\",\n fill: getEquivalentSemanticColorName(ColorStatus),\n };\n } else {\n isInCommission\n ? (svgIcon = \"StarMarker\") // special commission marker\n : isInTransition\n ? (svgIcon = \"TriangleMarker\") // special transition marker\n : (svgIcon = marker); // ...otherwise use the marker type passed in the message\n }\n break;\n\n // case \"OK\":\n // if (marker.toLowerCase() === \"TravelwayMarker\") {\n // svgIcon = \"TravelwayMarker\";\n // svgStyle = { stroke: \"purple\", fill: ColorStatus };\n // } else {\n // switch (isStrobing) {\n // case true:\n // isInCommission\n // ? (svgIcon = \"StarMarker\")\n // : isInTransition\n // ? (svgIcon = \"TriangleMarker\")\n // : (svgIcon = setStrokeMarkers(led_state.toLowerCase()));\n\n // break;\n // case fINACTIVE_FIREFLYalse:\n // isInCommission\n // ? (svgIcon = \"StarMarker\")\n // : isInTransition\n // ? (svgIcon = \"TriangleMarker\")\n // : (svgIcon = marker); // ....marker state passed in the message\n // break;\n // default:\n // break;\n // }\n // }\n\n // break;\n case \"API_FETCH\":\n svgIcon = \"TriangleMarker\";\n break;\n\n case \"INACTIVE_FIREFLY\":\n svgStyle = { stroke: \"black\", fill: \"fuchsia\" };\n svgIcon = \"HourGlassMarker\";\n break;\n // #WIP - used for Controller??????\n case \"UPS_TIMEOUT\":\n svgStyle = { stroke: \"fuchsia\", fill: \"black\" };\n svgIcon = \"HourGlassMarker\";\n break;\n case \"DEAD_FIREFLY\":\n default:\n svgStyle = { stroke: \"fuchsia\", fill: \"sienna\" };\n svgIcon = \"BowTieMarker\";\n break;\n }\n\n return { svgIcon, svgStyle };\n};\n\nclass Map extends React.Component {\n constructor(props) {\n super(props);\n\n this.state = {\n refPts: {},\n thislocalMapState: {},\n map: { area: \"defaultArea\" },\n heartBeat: true,\n isMapLoading: true,\n isMapLoaded: false,\n mapSrc: \"\",\n regionGroupLayersCount: 0,\n parentsUnionGroupLayersCount: 0,\n //\n layerControlState: {},\n // marker popup state\n isPopupOpen: false,\n // map view state\n mapViewState: { center: undefined, zoom: undefined },\n\n // #NOTE -\n // * set when componentDidMount is run.\n // Used to determine if map regionPreview should be updated\n\n isMapComponentDidMount: false,\n //\n forcedLightState: [],\n //\n isPokeTheWorkerLocal: true, // local record of whether to collect data, stops updates immediately instead of waiting for redux response\n //\n markerPositionChanges: {},\n forceMapRefresh: false, // used to force map refresh if markers moved\n isMoving: false,\n isMarkerDragging: false,\n //\n // tracks which forced markers have been clicked\n forcedClickList: [],\n //\n // tracks if map move in use\n isMapView: false,\n // tracks if edit tools in use\n isMoveMarkerPositions: false,\n // tracks activeLayers so can toggle on/off\n activeLayersList: [],\n };\n }\n\n static contextTypes = {\n router: PropTypes.object.isRequired,\n };\n\n // #WIP - #TODO - MAKE COMMON\n // see - src/pages/ControlRoomPage/MineLevelOpsControl.js\n // message banner support\n //\n //\n faultMessageBannerId = (faultType) => {\n // check if a message of this type exists\n\n // get the id for the flash message\n const messageBanners = this.props.messageBanners; // from redux state\n\n console.log(`messageBanners`, messageBanners);\n return messageBanners[faultType].id;\n };\n\n clearFaultMessageBanner = (faultType) => {\n // get the id for the flash message\n const bannerId = this.faultMessageBannerId(faultType);\n\n console.log(`message bannerId`, bannerId);\n if (bannerId) {\n this.props.removeFlashMessage(bannerId);\n //#REVIEW - make this a function..........\n // delete this banner message from state\n let tmpObj = {};\n tmpObj.faultType = faultType;\n tmpObj.display = false;\n tmpObj.id = \"\";\n\n this.props.SetMessageBanner(tmpObj);\n }\n };\n\n areaImageNotFoundMessage = (areaImageNotFound, imageFilename) => {\n const messageBanners = this.props.messageBanners;\n\n if (messageBanners === undefined) return;\n\n // console.log(`messageBanners`, messageBanners);\n // console.log(`message imageFilename`, imageFilename);\n // console.log(`message areaImageNotFound`, areaImageNotFound);\n\n // #NOTE - old comment, but still applies. Need to centralise function.\n //#REVIEW - force to one type for now - this needs to be merged with AlarmButtons and other messaging\n\n const bannerDisplayed = messageBanners[\"areaImageNotFound\"]?.display;\n let bannerInfo = messageBanners[\"areaImageNotFound\"]?.info || [];\n const isBannerDisplayedForThisImageFilename =\n bannerInfo?.includes(imageFilename);\n\n // console.log(\n // `isBannerDisplayedForThisImageFilename`,\n // isBannerDisplayedForThisImageFilename\n // );\n\n // // set\n // if (areaImageNotFound) {\n // if (isConfigJs() && faultMessageBannerDisplay()) {\n // const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n // // if this fault type allows message banner display (in config)\n // // and there hasn't been a message banner displayed previously\n\n // //#REVIEW - need to check fault type as per review comment above\n // if (\n // isMessageBannerForFaultType[\"areaImageNotFound\"] &&\n // !bannerDisplayed\n // ) {\n // // create a unique ID for the banner\n // const id = cuid();\n\n // // display a new banner\n // this.displayErrors(id, \"areaImageNotFound\", \"????????\");\n\n // // record the update state of banner including the id (needed to delete this particular banner)\n // let tmpObj = {};\n // tmpObj.faultType = \"areaImageNotFound\"; // #REVIEW - force to one status check type for now\n // tmpObj.display = true;\n // tmpObj.id = id;\n // // multiple files : same\n // tmpObj.info = \"info\";\n\n // this.props.SetMessageBanner(tmpObj);\n // }\n // }\n // } else {\n // // clear it\n // if (bannerDisplayed) {\n // //this.clearFaultMessageBanner(\"areaImageNotFound\");\n // }\n // }\n\n //\n if (isConfigJs() && faultMessageBannerDisplay()) {\n const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n // if this fault type allows message banner display (in config)\n // and there hasn't been a message banner displayed previously\n\n if (isMessageBannerForFaultType[\"areaImageNotFound\"]) {\n if (areaImageNotFound) {\n // set\n if (bannerDisplayed) {\n // banner already exists\n if (!isBannerDisplayedForThisImageFilename) {\n // update banner\n // clear current banner\n this.clearFaultMessageBanner(\"areaImageNotFound\");\n // set a new banner\n this.setFaultMessageBanner([...bannerInfo, imageFilename]);\n }\n } else {\n // no current banner\n // set a new banner\n this.setFaultMessageBanner([...bannerInfo, imageFilename]);\n }\n } else {\n // clear banner\n if (bannerDisplayed) {\n if (isBannerDisplayedForThisImageFilename) {\n // clear just this banner\n // clear current banner\n this.clearFaultMessageBanner(\"areaImageNotFound\");\n // set a new banner\n this.setFaultMessageBanner(\n bannerInfo.filter((file) => file !== \"B\")\n );\n }\n //\n }\n }\n }\n }\n };\n\n setFaultMessageBanner = (bannerInfo) => {\n console.log(`message bannerInfo`, bannerInfo);\n // set a new banner\n // create a unique ID for the banner\n const id = cuid();\n // display a new banner\n this.displayErrors(id, \"areaImageNotFound\", bannerInfo);\n\n // record the update state of banner including the id (needed to delete this particular banner)\n let tmpObj = {};\n tmpObj.faultType = \"areaImageNotFound\"; // #REVIEW - force to one status check type for now\n tmpObj.display = true;\n tmpObj.id = id;\n // multiple files : same\n tmpObj.info = bannerInfo;\n\n this.props.SetMessageBanner(tmpObj);\n };\n\n // get the text for the fault message banner from config.js or set default\n getFaultMessageBannerText = (faultType) => {\n let header;\n let message;\n let color;\n\n if (isConfigJs() && faultMessageBannerText()) {\n const messageBannerText = faultMessageBannerText(); // from config.js file\n header = messageBannerText[faultType].header;\n message = messageBannerText[faultType].message;\n color = messageBannerText[faultType].color;\n } else {\n // default messages if config.js object is stuffed\n switch (faultType) {\n case \"areaImageNotFound\":\n header = \"Area Image Can Not Be Found\";\n message =\n \"An area image can not be found on the server, or the server connection has failed. Check the server operation then log out/in.\";\n color = \"red\";\n break;\n default:\n break;\n }\n }\n\n return { header, message, color };\n };\n\n // loads header and message to display on control screen page\n // depending on significance of the error\n // All cases go to the Browser Logger page\n //\n displayErrors(id, faultType, info) {\n const { header, message, color } =\n this.getFaultMessageBannerText(faultType);\n\n // set color from highest fault_level for the faultType\n // const color = this.setColorMessageBanner(faultType);\n\n this.props.addWarningFlashMessageIdColor(\n id,\n color,\n header,\n message + \" \" + info.join(\", \") || \"Unknown problem\"\n );\n //console.log(\"message displayErrors - \" + header + \"-\" + message);\n }\n\n // styling for polygons\n geojsonPolygonStyle = (feature) => {\n let setFillColor;\n if (feature.properties.active_color) {\n const color = feature.properties.active_color;\n switch (color) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"orange\";\n break;\n case \"white\":\n setFillColor = \"white\";\n break;\n case \"red\":\n setFillColor = \"red\";\n break;\n\n default:\n setFillColor = \"grey\";\n break;\n }\n }\n\n return {\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.1,\n };\n };\n\n markerPts = (img) => {\n const { width, height } = img;\n\n // image pixel positions = lat,lng\n // geometric refernece coord = easting, northing, zoneNum, zoneLetter,\n // {lat, lng, easting, northing, zoneNum, zoneLetter}\n\n const markerOrigin = {\n id: \"corner\",\n lat: 0,\n lng: 0,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n const markerMiddle = {\n id: \"center\",\n lat: height / 2,\n lng: width / 2,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n const markerMax = {\n id: \"corner\",\n lat: height,\n lng: width,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n\n return [markerOrigin, markerMiddle, markerMax];\n };\n\n // creates a geoJson object for the map reference points\n // pass in map pixel ref lat,lng and the coord reference easting, northing\n // geometry coordinats are in pixels\n //\n // e.g. localPtsGeoJson([{ lat: 0, lng: 0, easting: 0, northing: 0, zoneNum: 53, zoneLetter: \"M\", z: 0 },...[...]);\n //\n // still using lat and lng because leaflet uses these references.\n //\n localPtsGeoJson = (points) => {\n let localPtsGeoJson = [];\n points.map(\n ({ lat, lng, easting, northing, zoneNum, zoneLetter, id }, idx) => {\n const objLatLng = { lat: lng, lng: lat }; // #REVIEW - have swapped around lat and long **ADRESS THIS**\n const point = Object.values(objLatLng);\n\n // structure geoJSON object\n\n const geojsonFeature = {\n type: \"Feature\",\n properties: {\n index: idx,\n id: id,\n area: \"refArea\",\n location: \"refPt\",\n position: idx,\n easting: easting,\n northing: northing,\n utm_zone_number: zoneNum,\n utm_zone_letter: zoneLetter,\n z: 0,\n color: \"toBeDone\",\n },\n geometry: {\n type: \"Point\",\n coordinates: point,\n },\n };\n localPtsGeoJson.push(geojsonFeature);\n }\n );\n return {\n type: \"FeatureCollection\",\n features: localPtsGeoJson,\n };\n };\n\n // create geojson markerData\n markerToGeoJSON = (markersData, transform) => {\n const geoJSONMarkersData = [];\n\n markersData.map(\n ({ id, lat, lng, name, color, position, location }, idx) => {\n // transform the point from latlng to pixels\n const objLatLng = { lat: lat, lng: lng };\n const point = Object.values(transform.transform(objLatLng));\n\n // structure geoJSON object\n const geojsonFeature = {\n type: \"Feature\",\n properties: {\n id: id,\n name: name,\n color: color,\n position: position,\n location: location,\n },\n geometry: {\n type: \"Point\",\n coordinates: point,\n },\n };\n geoJSONMarkersData.push(geojsonFeature);\n }\n );\n return {\n type: \"FeatureCollection\",\n features: geoJSONMarkersData,\n };\n };\n\n // support for map leaflet.contextmenu\n showCoordinates = (e) => {\n alert(e.latlng);\n };\n\n centerMap = (e) => {\n this.map.panTo(e.latlng);\n };\n\n fitMap = (e, bounds) => {\n this.map.fitBounds(bounds);\n };\n\n zoomIn = (e) => {\n this.map.zoomIn();\n };\n\n zoomOut = (e) => {\n this.map.zoomOut();\n };\n\n // draw\n drawTheMap = (\n mapId,\n mineLevel,\n geoJSONMarkersData,\n geoJSONMarkersDataForced,\n geoJSONNamedAreas,\n geoJSONNamedAreaParents,\n geoJSONControllers,\n //\n mapViewState\n ) => {\n const {\n id: mineLevelId,\n image_filename,\n image_info: { width = 10000, height = 8000 },\n localPtsX,\n } = mineLevel;\n\n //console.log(\"mapViewState\", mapViewState);\n const { center: setCenter, zoom: setZoom } = this.state.mapViewState;\n\n let url = process.env.PUBLIC_URL + \"/areas/\" + image_filename; // \"extraction.png\";\n\n let isMapLoading = true;\n // console.log(\"loaded isMapLoading @ entry to drawTheMap \", isMapLoading);\n this.setState({ isMapLoading: true });\n this.setState({ mapSrc: url });\n\n // if (this.state.isMapLoaded) {\n // console.log(`loaded isMapLoaded TRUE `, url);\n // }\n\n // // setup a dummy image and load the map image in the background\n // // create a replacement image using known dimensions\n // let canvas = document.createElement(\"canvas\");\n // // set desired size of transparent image\n // canvas.width = width;\n // canvas.height = height;\n\n // // extract as new image (data-uri)\n // const url = canvas.toDataURL();\n\n ////////////////////////////////////////////////////////////////////////////\n // Conversion from (x, y) raster image coordinates to equivalent of latLng\n // Taken from Leaflet tutorial \"Non-geographical maps\"\n // http://leafletjs.com/examples/crs-simple/crs-simple.html\n ////////////////////////////////////////////////////////////////////////////\n var yx = L.latLng;\n var xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n };\n\n const img = [\n width, // original width of image `level.jpg` - undercut 800 conversion example => x / ~longitude (0 is left, width, 13234 is right)\n height, // original height of image => y / ~ reverse of latitude (0 is top, height, 9356 is bottom)\n ];\n\n // if a center has been passed to component use it, else recalc\n let center = [width / 2, height / 2]; // center calculation based on original pixel dimensions\n if (setCenter) center = Object.values(setCenter).reverse();\n\n let zoom = -4;\n if (setZoom) zoom = setZoom;\n\n // console.log(\n // \"mapViewState center setCenter setZoom\",\n // mineLevelId,\n // center,\n // setCenter,\n // setCenter ? Object.values(setCenter).reverse() : \"????\",\n // zoombounds\n // );\n\n var bounds = L.latLngBounds([xy(0, 0), xy(img)]);\n\n let base = L.tileLayer(url, {\n bounds: bounds,\n noWrap: true,\n });\n\n // #REVEW / #WIP - put up 'loading' banners\n // events to show loading progress\n // https://stackoverflow.com/questions/27378572/leaflet-fire-event-when-tile-layer-loading-begins-and-ends\n\n //base.on(\"loading\", this.setState({ isMapLoading: true }));\n //base.on(\"load\", this.setState({ isMapLoading: false }));\n\n // #REVIEW - not used\n base.on(\"tileload\", function () {\n console.log(\"base loaded\");\n });\n\n base.on(\"tileerror\", (error, tile) => {\n console.log(`Error ${error} loading tile ${tile}`);\n });\n\n this.map = null;\n\n // define the map\n this.map = L.map(mapId, {\n crs: L.CRS.Simple,\n\n //maxBounds: bounds.pad(0.5), // http://leafletjs.com/reference-1.0.3.html#map-maxbounds\n // center: center,\n // zoom: zoom,\n minZoom: -5,\n //maxZoom: maxZoom,\n zoomControl: false,\n\n attributionControl: false,\n contextmenu: true, // context menu plugin `npm i leaflet-contextmenu`\n contextmenuWidth: 140,\n contextmenuItems: [\n // {\n // text: \"Show coordinates\",\n // callback: this.showCoordinates,\n // },\n {\n text: \"Center map here\",\n callback: this.centerMap,\n },\n {\n text: \"Show all\",\n callback: (e) => this.fitMap(e, bounds),\n },\n // #REVIEW - this is disabled in favour of the control which enables zoom-in/zoom-out\n //\n // \"-\",\n // {\n // text: \"Zoom in\",\n // icon: process.env.PUBLIC_URL + \"/images/zoom-in.png\",\n // callback: this.zoomIn,\n // },\n // {\n // text: \"Zoom out\",\n // icon: process.env.PUBLIC_URL + \"/images/zoom-out.png\",\n // callback: this.zoomOut,\n // },\n ],\n // scroll wheel zoom smoothing\n scrollWheelZoom: false, // disable original zoom function\n smoothWheelZoom: false, // enable smooth zoom\n smoothSensitivity: 1.5, // zoom speed. default is 1\n });\n\n // ------------------------------------------------------\n //\n // dummy image load testing\n //\n // ------------------------------------------------------\n // console.log(\n // \"loaded isMapLoading new background image \",\n // url,\n // \" ** isMapLoading TRUE ** >>>>>\"\n // );\n // // set state to loading while get new background\n\n // console.log(\"loaded dummyImage new background image LOADING ** >>>>>\");\n // // set dummy image background\n // // setup a dummy image and load the map image in the background\n // // create a replacement image using known dimensions\n // let dummyCanvas = document.createElement(\"canvas\");\n // // set desired size of transparent image\n // dummyCanvas.width = width;\n // dummyCanvas.height = height;\n\n // // extract as new image (data-uri)\n // const dummyUrl = dummyCanvas.toDataURL();\n\n // // set single image background\n // const dummyImage = L.imageOverlay(dummyUrl, bounds);\n // dummyImage.addTo(this.map);\n\n // // image load events\n // dummyImage.on(\"load\", (event) => {\n // console.log(\"loaded dummyImage new background image LOADED ** <<<<<\");\n // //console.log(\"loaded event\", event);\n // if (event?.target?._url === url) {\n // isMapLoading = false;\n // console.log(\"loaded dummyImage isMapLoading\", isMapLoading);\n // this.setState({ isMapLoading: false });\n // }\n // });\n // ------------------------------------------------------\n // set single image background\n\n let overlayUrl;\n\n // check file exists on server\n if (this.props.folderFilesList?.includes(image_filename)) {\n overlayUrl = url;\n\n // does not apply to default.png\n if (!image_filename.includes(\"default.png\")) {\n this.areaImageNotFoundMessage(false, image_filename);\n // console.log(\n // `removing a message banner!!!! - areaImageNotFoundMessage`,\n // mineLevelId,\n // image_filename\n // );\n }\n } else {\n // setup a dummy image and load the map image in the background\n // create a replacement image using known dimensions\n let canvas = document.createElement(\"canvas\");\n // set desired size of transparent image\n canvas.width = width;\n canvas.height = height;\n // extract as new image (data-uri)\n overlayUrl = canvas.toDataURL();\n\n // #NOTE #WIP #TODO\n // SET A MESSAGE IF THE MAP FILE IS NOT AVAILABLE\n\n // doe not apply to default.png\n if (!image_filename.includes(\"default.png\")) {\n this.areaImageNotFoundMessage(true, image_filename);\n // console.log(\n // `displaying a message banner!!!! - areaImageNotFoundMessage`,\n // mineLevelId,\n // image_filename\n // );\n }\n }\n\n let isMapImageFromState = false;\n // if the image is available from the reducer Settings state load this instead\n if (!_isEmpty(this.props.mapImageFromState)) {\n overlayUrl =\n \"data:image/png;base64,\" + this.props.mapImageFromState.imageData;\n isMapImageFromState = true;\n }\n\n const image = L.imageOverlay(overlayUrl, bounds);\n image.addTo(this.map);\n\n // image load events\n image.on(\"load\", (event) => {\n console.log(\n \"LOADED NEW BACKGROUND IMAGE \",\n url,\n \"** isMapLoading FALSE ** <<<<<\"\n );\n console.log(\"LOADED NEW BACKGROUND IMAGE event\", event);\n\n // check if image is loaded from the url or via the state image\n if (event?.target?._url == url || isMapImageFromState) {\n isMapLoading = false;\n // console.log(\"loaded isMapLoading\", isMapLoading);\n this.setState({ isMapLoading: false });\n }\n });\n\n image.on(\"error\", (error, tile) => {\n console.log(`Error ${error} loading imageOverlay ${tile}`);\n });\n\n // console.log(\n // `xxxxx newMapViewState - setCenter, setZoom, center, zoom, bounds`,\n // setCenter,\n // \"-\",\n // setZoom,\n // \"-\",\n // center,\n // \"-\",\n // zoom,\n // \"-\",\n // bounds\n // );\n\n if (!_isEmpty(setCenter) || !_isEmpty(setZoom)) {\n // if mapViewState has been set\n this.map.setView(xy(center), zoom);\n } else {\n // new page load so fit to bounds\n this.map.fitBounds(bounds);\n }\n\n // record the current zoom level\n this.previousZoom = this.map.getZoom();\n\n // record the current map\n this.previousCenter = this.map.getCenter();\n\n // ****************************************************\n // Setup a holding pen for waylaid fireflies\n //\n // ****************************************************\n //\n // #WIP - pen\n // #REVIEW\n // - https://www.npmjs.com/package/@turf/boolean-point-in-polygon\n // - http://turfjs.org/\n //\n //\n // #REVIEW - would have put pen in top right but points random location in pen is defined in\n // src/components/Map/util-geoJsonToPixels.js\n // and this does not have image height and width ATM to define\n\n const holdingPenPolygon_topRight = [\n [height, width * 0.85],\n [height, width],\n [height * 0.85, width],\n [height * 0.85, width * 0.85],\n ];\n\n const holdingPenPolygon_bottomLeft = [\n [0, 0],\n [height * 0.15, 0],\n [height * 0.15, width * 0.15],\n [0, width * 0.15],\n ];\n\n if (DEBUG_ENABLED_FALSE) {\n this.holdingPen = L.polygon(holdingPenPolygon_bottomLeft).addTo(this.map);\n }\n // -> see randomPointInPoly function\n\n // ****************************************************\n //\n // Setup and draw the Fireflies\n //\n // ****************************************************\n\n //\n this.layerlistFireflies = {};\n\n //\n this.testExternalStr = \"Point: \"; // test passing variable outside into ....\n\n // force light change\n //\n const setForceLight = (\n action,\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor,\n rxSetFireflyState // returned for Strobe click, not for Color click\n ) => {\n console.log(\n `forcedLight: setForceLight action,\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor,\n rxSetFireflyState`,\n action,\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor,\n rxSetFireflyState\n );\n\n const fireflyNamedAreaId = createFireflyNamedAreaId(fireflyId);\n\n const namedAreaEventForFirefly = this.props.namedAreaEvents?.find(\n (event) => event.id.includes(fireflyNamedAreaId)\n );\n\n let promiseArray = [];\n let operationButton = {};\n let isActivate = false;\n\n if (action === \"clear\") {\n // if there are existing events, delete them ...........\n if (namedAreaEventForFirefly) {\n //\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.deleteNamedArea({\n values: { id: namedAreaEventForFirefly.id },\n resolve,\n reject,\n })\n )\n );\n }\n }\n // process the changes ...................\n else {\n // get strobe checkBox from State if it is not passed through the parameters\n let setFireflyState = \"on\";\n if (rxSetFireflyState !== null) {\n setFireflyState = rxSetFireflyState;\n } else {\n setFireflyState =\n //if find record in state array === strobe\n this.state.forcedLightState.some((state) => state === fireflyId)\n ? \"strobe\"\n : \"on\";\n }\n\n // console.log(\n // `forcedLight: setFireflyState this.state.forcedLightState namedAreaEventForFirefly`,\n // setFireflyState,\n // this.state.forcedLightState,\n // fireflyId,\n // namedAreaEventForFirefly\n // );\n\n const currentNamedAreaEventForFireflyColor =\n namedAreaEventForFirefly?.active_color?.toLowerCase?.();\n\n const currentNamedAreaEventForFireflyState =\n namedAreaEventForFirefly?.active_state?.toLowerCase?.();\n\n let isStateChanged = setFireflyState !== \"on\";\n if (currentNamedAreaEventForFireflyState) {\n isStateChanged =\n currentNamedAreaEventForFireflyState !== setFireflyState;\n }\n\n let isColorChanged = color.status !== setFireflyColor;\n if (currentNamedAreaEventForFireflyColor) {\n isColorChanged =\n currentNamedAreaEventForFireflyColor !== setFireflyColor;\n }\n\n // console.log(\n // `forcedLight namedAreaEventForFirefly `,\n // namedAreaEventForFirefly,\n // setFireflyState\n // );\n // console.log(`forcedLight isColorChanged `, isColorChanged);\n // console.log(`forcedLight isStateChanged `, isStateChanged);\n\n // Explanation\n //\n // In all cases delete the current namedArea\n // If color has not changed state, do not add a new namedArea (i.e. toggle OFF)\n // If color changed state, add a new namedArea\n // If state has changed, add a new namedAra\n\n // In all cases just delete the current namedArea\n //\n if (namedAreaEventForFirefly) {\n if (!isColorChanged && !isStateChanged) {\n // if toggle color OFF remove any existing strobe setting for deleted namdArea\n // i.e. color has changed the state has not changed\n\n // console.log(\n // `forcedLight: <<---DELETE--->> newForcedLightState fireflyId`,\n // fireflyId\n // );\n\n let newForcedLightState = this.state.forcedLightState;\n newForcedLightState = newForcedLightState.filter(\n (id) => id !== fireflyId\n );\n this.setState({ forcedLightState: newForcedLightState });\n }\n\n // console.log(\n // `forcedLight: <<---DELETE--->> deleteNamedArea id`,\n // namedAreaEventForFirefly.id\n // );\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.deleteNamedArea({\n values: { id: namedAreaEventForFirefly.id },\n resolve,\n reject,\n })\n )\n );\n }\n\n // Get the next ForcedLight priority\n const allForcedNamedAreas = this.props.namedAreaEvents?.filter(\n (event) => event.id.includes(\"FORCED-\")\n );\n\n const highestForcedNamedAreaPriority = Math.max(\n ...allForcedNamedAreas.map((o) => o.priority),\n DEFAULT_START_FORCED_LIGHT_PRIORITY\n );\n\n // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n // #NOTE - there must be a button at the priority level\n // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n const newNamedArea = createNamedAreaAroundFirefly(\n fireflyId,\n { easting, northing },\n area,\n setFireflyColor,\n setFireflyState,\n 1 // highestForcedNamedAreaPriority + 1\n );\n\n operationButton = newNamedArea.button?.[1]; // 1st, and only button, not highestForcedNamedAreaPriority + 1\n // get next highest\n operationButton.priority = highestForcedNamedAreaPriority + 1;\n\n //console.log(`forcedLight xxx operationButton`, operationButton);\n //console.log(`forcedLight xxx newNamedArea`, newNamedArea);\n\n // if toggle to change color, or change state, or there is a new color\n // #NOTE - below stops denies creating new event if same color,\n // however this is now superseded for forcing any color, even currently displayed color.\n //if (isColorChanged || isStateChanged) {\n\n // make a new event under all situations\n if (true) {\n // make a new event\n //\n isActivate = true;\n console.log(\n `forcedLight: <<---ADD--->> saveNewNamedArea newNamedArea`,\n newNamedArea\n );\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.saveNewNamedArea({\n values: newNamedArea,\n resolve,\n reject,\n })\n )\n );\n }\n }\n\n if (promiseArray.length) {\n return Promise.all(promiseArray)\n .then((result) => {\n console.log(`FORCELIGHT: saveNewNamedArea `, result);\n if (isActivate) {\n this.props.activate(operationButton); // -> sendNamedAreaEventSingle\n }\n })\n .catch((error) => {\n console.log(\n `forcedLight: saveFireflyLedData saveNewNamedAre failed `,\n error\n );\n // #WIP - do something if fails!???\n });\n }\n /////////////////////\n };\n\n // add popup information\n const onEachFeatureFirefly = (feature, layer) => {\n // #REVIEW - does this feature have a property named popupContent?\n\n const { properties } = feature;\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n z,\n utm_zone_number,\n utm_zone_letter,\n fireflyNote,\n color,\n timestamp,\n ups_id,\n //\n light, // #NOTE #REVIEW - if passing `light` to get 'led_state', why use `color`?\n event_id,\n mac,\n deviceStatus,\n } = properties;\n\n //console.log(`xxx properties`, properties);\n\n //console.log(`onEachFeatureFirefly feature`, feature);\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n // #NOTE #REVIEW - if passing `light` to get 'led_state', why use `color`?\n const {\n // brightness,\n // color,\n // marker,\n led_state,\n // off_time,\n // on_time,\n // train,\n } = light;\n\n if (feature.properties && feature.properties.id) {\n if (false) {\n layer.bindPopup(\n `
FireFly: ${id}
\n
Controller: ${ups_id}
\n
\n
${this.testExternalStr} ${area}:${location}:${position}
\n
Geom: E:${round(easting, 2)} N:${round(\n northing,\n 2\n )} Z${Math.trunc(z)} ${utm_zone_number} ${utm_zone_letter}
\n
Image: X:${X} Y:${Y}
\n
Color: Requested ${color.plan}, Reported ${\n color.status\n }
\n
Last Report: ${lastStatusReport}
`\n );\n } else if (false) {\n const popupInfo = `${id}
${id}

`;\n layer.bindPopup(popupInfo);\n // https://stackoverflow.com/questions/42599445/adding-buttons-inside-leaflet-popup\n layer.on(\"popupopen\", (a) => {\n console.log(\"popup open\", a.target);\n var marker = a.popup._source.feature.properties.id;\n console.log(\"popup marker\", marker);\n\n console.log(\"popup open\", a.target);\n var popUp = a.target.getPopup();\n console.log(\"popup popup\", popUp);\n\n popUp\n .getElement()\n .querySelector(`.button-1`)\n .addEventListener(\"click\", (e) => {\n console.log(\n \"clicked edit on marker: \",\n e,\n \"target: \",\n e.target,\n \"data-key \",\n e.target.dataset.key\n );\n\n const id = e.target.dataset.key;\n if (!_isEmpty(id)) {\n this.props.goto(`/admin/firefly/${id}`);\n }\n });\n });\n } else if (false) {\n layer.bindPopup(renderToString());\n } else {\n //\n\n // #WIP\n // collect events for this ff.\n // This is used to indicate which light is toggled in the popup and to\n // know which priority event to fire in the attached eventListener.\n const fireflyNamedAreaId = createFireflyNamedAreaId(id);\n\n const namedAreaEventForFirefly = this.props.namedAreaEvents?.find(\n (event) => event.id.includes(fireflyNamedAreaId)\n );\n\n // console.log(\n // `fireflyMarkerPopup ONE fireflyNamedAreaId`,\n // fireflyNamedAreaId,\n // namedAreaEventForFirefly,\n // this.props.namedAreaEvents,\n // properties,\n // layer\n // );\n\n const fireflyMarkerPopup = renderToString(\n \n );\n\n // after sending forcedClickList to the popup, clear it\n // acknowledge click while processing\n let newForcedClickList = [...this.state.forcedClickList];\n if (newForcedClickList.includes(id)) {\n newForcedClickList = newForcedClickList.filter(\n (item) => item !== id\n );\n this.setState({ forcedClickList: newForcedClickList });\n }\n\n layer.bindPopup(fireflyMarkerPopup, {\n maxWidth: \"400\", // auto // #REVIEW - FIXED SIZE OF POPUP #DEFAULT_\n });\n\n // #WIP - tool tip implementation integrated with the main FF marker\n //\n // This has been moved to a separate layer to enable display via 'layer control'\n // see also the 'zoomend' dynamic change of zoom\n //\n // #REVIEW - tooltip label for FF\n // * - could be used for TAGS?\n // * - could show which markers have Slough meters etc\n // see - https://stackoverflow.com/questions/49852157/add-custom-bindtooltip-class\n //\n // if (false) {\n\n // const TooltipClass = {\n // className: \"class-tooltip\",\n // };\n\n // // #REVIEW - style popup\n // var PopupClass = {\n // className: \"class-popup\",\n // };\n\n // //layer.bindPopup(\"Test Popup\", PopupClass);\n\n // layer.bindTooltip(\n // `${location}:${position}`,\n // {\n // direction: \"bottom\",\n // permanent: true,\n // offset: [0, 20],\n // //className: \"transparent-tooltip\",\n // ...TooltipClass,\n // },\n // TooltipClass\n // );\n // }\n\n layer.on(\"popupclose\", (event) => {\n this.setState({ isPopupOpen: false });\n });\n layer.on(\"popupopen\", (event) => {\n //console.log(\"popup event.target\", event.target);\n\n //\n // #WIP - disable popup open re-rendering?\n if (false) {\n this.setState({ isPopupOpen: true });\n }\n\n var marker = event.popup._source.feature.properties.id;\n\n //console.log(\"popup marker\", marker);\n\n var popUp = event.target.getPopup();\n // console.log(\"popup popup\", popUp);\n // console.log(\"popup getElement\", popUp.getElement());\n // console.log(\n // \"popup getElement.querySelector\",\n // popUp.getElement().querySelector(\".popupFireflyMarkerLink\")\n // );\n\n // console.log(\n // 'popUp.getElement().querySelector(\".popupFireflyMarkerLink\")',\n // popUp.getElement().querySelector(\".popupFireflyMarkerLink\").innerHTML\n // );\n\n // added eventListener to firefly marker content\n // see - src/components/Map/FireflyMarkerPopup.js\n this.props.role.allowAdmin &&\n popUp\n .getElement()\n .querySelector(\".popupFireflyMarkerLink\")\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"dataid \",\n // e.target.getAttribute(\"dataid\")\n // );\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n this.props.goto(`/admin/firefly/${id}`);\n } else {\n this.props.goto(`/admin/firefly/`);\n }\n });\n // *************************\n\n // console.log(\n // 'popUp.getElement().querySelector(\".popupControllerMarkerLink\")',\n // popUp.getElement().querySelector(\".popupControllerMarkerLink\")\n // ); // .innerHTML\n\n this.props.role.allowAdmin &&\n popUp\n .getElement()\n .querySelector(\".popupControllerMarkerLink\")\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"dataid \",\n // e.target.getAttribute(\"dataid\")\n // );\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n this.props.goto(`/admin/controller/${id}`);\n } else {\n this.props.goto(`/admin/controller/`);\n }\n });\n\n // =======================================\n //\n // FORCE LIGHT CONTROL\n //\n // =======================================\n //\n // FORCE LIGHT CONTROL - RESET - popupFireflyMarkerToggleForcedClear\n //\n // Debug\n //\n\n // console.log(\n // 'popUp.getElement().querySelector(\".popupFireflyMarkerToggleForcedClear\")',\n // popUp\n // .getElement()\n // .querySelector(\".popupFireflyMarkerToggleForcedClear\")\n // ); // .innerHTML\n //\n\n popUp\n .getElement()\n .querySelector(\".popupFireflyMarkerToggleForcedClear\")\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"dataid \",\n // e.target.getAttribute(\"dataid\")\n // );\n\n if (!_isEmpty(id)) {\n const IdArray = id.split(\"+\");\n const fireflyId = IdArray[0];\n const setFireflyAction = IdArray[1];\n // console.log(\n // \"forcedLight: CLEAR fireflyId, setFireflyAction\",\n // fireflyId,\n // setFireflyAction\n // );\n\n // acknowledge click while processing\n let newForcedClickList = [...this.state.forcedClickList];\n if (!newForcedClickList.includes(fireflyId)) {\n newForcedClickList.push(fireflyId);\n this.setState({ forcedClickList: newForcedClickList });\n this.setState({ forceMapRefresh: true });\n }\n\n // clear all forceLightStat\n this.setState({ forcedLightState: [] });\n\n // clear any events on the light\n setForceLight(\n \"clear\",\n fireflyId,\n null,\n null,\n null,\n null,\n null,\n null\n );\n }\n });\n\n //\n // FORCE LIGHT CONTROL - popupFireflyMarkerToggleForcedStateStrobe\n //\n // Debug\n //\n\n // console.log(\n // 'popUp.getElement().querySelector(\".popupFireflyMarkerToggleForcedStateStrobe\")',\n // popUp\n // .getElement()\n // .querySelector(\".popupFireflyMarkerToggleForcedStateStrobe\")\n // ); // .innerHTML\n //\n //\n // ****************************************\n popUp\n .getElement()\n .querySelector(\".popupFireflyMarkerToggleForcedStateStrobe\")\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"click to checkbox state: \",\n // e,\n // \"target: \",\n // e.target,\n // \"dataid \",\n // e.target.getAttribute(\"dataid\")\n // );\n\n // Explanation\n //\n // After adding popup text to leafletjs, this attachs an eventListener to the class.\n //\n // Here we process events from the checkbox click for force light changes.\n // Because clicks on labels are processed first, so wait for a timeout before getting the check state.\n // If check exists it is CHECKED.\n // see - https://stackoverflow.com/questions/40496291/javascript-event-listener-on-a-checkbox\n //\n // When the checkbox changes update state with the current id / check state.\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n const IdArray = id.split(\"+\");\n const fireflyId = IdArray[0];\n const setFireflyColor = IdArray[1];\n // console.log(\n // \"forcedLight: STROBE fireflyId, setFireflyColor\",\n // fireflyId,\n // setFireflyColor\n // );\n //console.log(\"forcedLight: fireflyId id\", fireflyId);\n\n setTimeout(() => {\n const checkingCheck = popUp\n .getElement()\n .querySelector(\n \".popupFireflyMarkerToggleForcedStateStrobe:checked\"\n );\n\n let newForcedLightState = this.state.forcedLightState;\n let isStrobe = false;\n if (checkingCheck !== null) {\n isStrobe = true;\n newForcedLightState.push(fireflyId);\n } else {\n isStrobe = false;\n newForcedLightState = newForcedLightState.filter(\n (id) => id !== fireflyId\n );\n }\n //console.log(\"forcedLight: STROBE isStrobe\", isStrobe);\n\n // #WIP - may need to callback or sleep() until the state propogates\n\n this.setState({ forcedLightState: newForcedLightState });\n\n // acknowledge click while processing\n let newForcedClickList = [...this.state.forcedClickList];\n if (!newForcedClickList.includes(fireflyId)) {\n newForcedClickList.push(fireflyId);\n this.setState({ forcedClickList: newForcedClickList });\n this.setState({ forceMapRefresh: true });\n }\n\n // OLD VERSION WHICH ONLY CHANGES STROBE IF A FORCE EVENT IS GOING\n if (false) {\n const fireflyNamedAreaId =\n createFireflyNamedAreaId(fireflyId);\n const namedAreaEventForFirefly =\n this.props.namedAreaEvents?.find((event) =>\n event.id.includes(fireflyNamedAreaId)\n );\n\n // console.log(\n // \"forcedLight STROBE: namedAreaEventForFirefly, newForcedLightState\",\n // namedAreaEventForFirefly,\n // newForcedLightState\n // );\n\n if (namedAreaEventForFirefly) {\n const { id: existingNamedAreaId, active } =\n namedAreaEventForFirefly;\n\n if (existingNamedAreaId?.includes(\"FORCED\") && active) {\n const { active_color } = namedAreaEventForFirefly;\n\n // console.log(\n // \"forcedLight STROBE: fireflyId,easting,northing,area,active_color,isStrobe\",\n // fireflyId,\n // easting,\n // northing,\n // area,\n // active_color,\n // isStrobe\n // );\n\n setForceLight(\n \"lightState\",\n fireflyId,\n easting,\n northing,\n area,\n active_color,\n isStrobe ? \"strobe\" : \"on\"\n );\n }\n }\n }\n\n if (true) {\n // console.log(\n // \"forcedLight: STROBE: fireflyId,easting,northing,area,color, color.state,isStrobe\",\n // fireflyId,\n // easting,\n // northing,\n // area,\n // color,\n // setFireflyColor,\n // isStrobe\n // );\n\n setForceLight(\n \"lightState\",\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor, //setForceLight,\n isStrobe ? \"strobe\" : \"on\" //setForceState\n );\n }\n });\n }\n });\n\n //\n // FORCE LIGHT CONTROL - popupFireflyMarkerToggleForcedStateOff\n //\n // Debug\n //\n\n // console.log(\n // 'popUp.getElement().querySelector(\".popupFireflyMarkerToggleForcedStateOff\")',\n // popUp\n // .getElement()\n // .querySelector(\".popupFireflyMarkerToggleForcedStateOff\")\n // ); // .innerHTML\n //\n //\n // ****************************************\n\n // ****************************************\n popUp\n .getElement()\n .querySelector(\".popupFireflyMarkerToggleForcedStateOff\")\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"click to checkbox state: \",\n // e,\n // \"target: \",\n // e.target,\n // \"dataid \",\n // e.target.getAttribute(\"dataid\")\n // );\n\n // Explanation\n //\n // After adding popup text to leafletjs, this attachs an eventListener to the class.\n //\n // Here we process events from the checkbox click for force light changes.\n // Because clicks on labels are processed first, so wait for a timeout before getting the check state.\n // If check exists it is CHECKED.\n // see - https://stackoverflow.com/questions/40496291/javascript-event-listener-on-a-checkbox\n //\n // When the checkbox changes update state with the current id / check state.\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n const IdArray = id.split(\"+\");\n const fireflyId = IdArray[0];\n const setFireflyColor = IdArray[1];\n // console.log(\n // \"forcedLight: STROBE fireflyId, setFireflyColor\",\n // fireflyId,\n // setFireflyColor\n // );\n //console.log(\"forcedLight: fireflyId id\", fireflyId);\n\n setTimeout(() => {\n const checkingCheck = popUp\n .getElement()\n .querySelector(\n \".popupFireflyMarkerToggleForcedStateOff:checked\"\n );\n\n let isOff = false; // not used ATM\n if (checkingCheck !== null) {\n isOff = true;\n // console.log(\n // \"forcedLight: OFF: fireflyId,easting,northing,area,color, color.state\",\n // fireflyId,\n // easting,\n // northing,\n // area,\n // color,\n // setFireflyColor,\n // \"off\"\n // );\n\n setForceLight(\n \"lightState\",\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor, //setForceLight,\n \"off\"\n );\n } else {\n isOff = false;\n // console.log(\n // \"forcedLight: ON: fireflyId,easting,northing,area,color, color.state\",\n // fireflyId,\n // easting,\n // northing,\n // area,\n // color,\n // setFireflyColor,\n // \"on\"\n // );\n\n setForceLight(\n \"lightState\",\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor, //setForceLight,\n \"on\"\n );\n }\n\n // acknowledge click while processing\n let newForcedClickList = [...this.state.forcedClickList];\n if (!newForcedClickList.includes(fireflyId)) {\n newForcedClickList.push(fireflyId);\n this.setState({ forcedClickList: newForcedClickList });\n this.setState({ forceMapRefresh: true });\n }\n });\n }\n });\n // ****************************************\n\n // =======================================\n //\n // FORCE LIGHT CONTROL - popupFireflyMarkerToggleForcedColor\n //\n // DEBUG ....\n //\n // console.log(\n // 'popUp.getElement().querySelector(\".popupFireflyMarkerToggleForcedColor\")',\n // popUp.getElement().querySelector(\".popupFireflyMarkerToggleForcedColor\")\n // ); // .innerHTML\n\n const toggleFireflyLed = popUp\n .getElement()\n .querySelectorAll(\".popupFireflyMarkerToggleForcedColor\");\n\n for (let i = 0; i < toggleFireflyLed.length; i++) {\n toggleFireflyLed[i].addEventListener(\"click\", (e) => {\n console.log(\n \"forcedLight: LIGHT clicked edit on marker: \",\n e,\n \"target: \",\n e.target,\n \"dataid \",\n e.target.getAttribute(\"dataid\"),\n new Date().getTime()\n );\n\n // Explanation\n //\n // After adding popup text to leafletjs, this attachs an eventListener to the class.\n //\n // Here we process events from the button clicks for force light changes.\n // Check for any existing namedAreas (and therefore events) based on the fireflyId (createFireflyNamedAreaId)\n // We don't try to update the existing namedArea, instead we delete the current namedArea and add another one.\n // If the color has changed, delete the named area and make a new one.\n // If the color has toggled off, just delete the namedArea.\n //\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n const IdArray = id.split(\"+\");\n const fireflyId = IdArray[0];\n const setFireflyColor = IdArray[1];\n\n const isActiveForcedButton =\n setFireflyColor !== \"FORCED_DISABLED\";\n\n console.log(\n \"forcedLight: LIGHT fireflyId, setFireflyColor, geoJSONMarkersData\",\n fireflyId,\n setFireflyColor,\n geoJSONMarkersData\n );\n\n // acknowledge click while processing\n let newForcedClickList = [...this.state.forcedClickList];\n if (!newForcedClickList.includes(fireflyId)) {\n newForcedClickList.push(fireflyId);\n this.setState({ forcedClickList: newForcedClickList });\n this.setState({ forceMapRefresh: true });\n }\n\n /// +++++++++++++++++++++++++++++++++++++++++++++++++++\n\n const currentFireflyLight = geoJSONMarkersData?.features.find(\n (ff) => ff.properties.id === fireflyId\n )?.properties?.light;\n\n console.log(\n \"forcedLight: LIGHT currentFireflyLight, isActiveForcedButton\",\n currentFireflyLight,\n isActiveForcedButton,\n geoJSONMarkersData?.features\n );\n\n if (isActiveForcedButton && !_isEmpty(currentFireflyLight)) {\n console.log(\n \"forcedLight: LIGHT: id,easting,northing,area,active_color, color.status\",\n fireflyId,\n easting,\n northing,\n area,\n setFireflyColor,\n color.status\n );\n\n setForceLight(\n \"lightColor\",\n fireflyId,\n easting,\n northing,\n area,\n color,\n setFireflyColor,\n null // setFireflyState\n );\n }\n\n if (false) {\n // console.log(\"currentFireflyLight\", currentFireflyLight);\n if (!_isEmpty(currentFireflyLight)) {\n const fireflyNamedAreaId =\n createFireflyNamedAreaId(fireflyId);\n\n const namedAreaEventForFirefly =\n this.props.namedAreaEvents?.find((event) =>\n event.id.includes(fireflyNamedAreaId)\n );\n\n // get strobe checkBox state\n const isStrobe = this.state.forcedLightState.some(\n (state) => state === fireflyId\n );\n\n // console.log(\n // `xxxx isStrobe this.state.forcedLightState`,\n // isStrobe,\n // this.state.forcedLightState,\n // fireflyId\n // );\n\n const newNamedArea = createNamedAreaAroundFirefly(\n fireflyId,\n { easting, northing },\n area,\n setFireflyColor,\n isStrobe\n ? { active_state: \"strobe\" }\n : { active_state: \"on\" }\n );\n\n let operationButton = newNamedArea.button[0]; // 1st, and only button\n\n const isToggle =\n namedAreaEventForFirefly?.active_color?.toLowerCase() ===\n setFireflyColor;\n\n // console.log(\n // `forcedLight isToggle fireflyColor operationButton, namedAreaEventForFirefly`,\n // isToggle,\n // fireflyColor,\n // operationButton,\n // namedAreaEventForFirefly\n // );\n\n let promiseArray = [];\n // in all cases just delete the current namedArea\n if (namedAreaEventForFirefly) {\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.deleteNamedArea({\n values: { id: namedAreaEventForFirefly.id },\n resolve,\n reject,\n })\n )\n );\n }\n\n // if toggle to a new color, or there is a new color\n if (!isToggle) {\n // make a new event\n //\n // Get the next ForcedLight priority\n\n const allForcedNamedAreas =\n this.props.namedAreaEvents?.filter((event) =>\n event.id.includes(\"FORCED-\")\n );\n\n const highestForcedNamedAreaPriority = Math.max(\n ...allForcedNamedAreas.map((o) => o.priority),\n DEFAULT_START_FORCED_LIGHT_PRIORITY\n );\n\n // console.log(\n // `YYYY namedAreaEventForFirefly`,\n // namedAreaEventForFirefly\n // );\n // console.log(\n // `YYYY highestForcedNamedAreaPriority`,\n // highestForcedNamedAreaPriority\n // );\n\n // get next highest\n operationButton.priority =\n highestForcedNamedAreaPriority + 1;\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.saveNewNamedArea({\n values: newNamedArea,\n resolve,\n reject,\n })\n )\n );\n\n return Promise.all(promiseArray)\n .then((result) => {\n console.log(\n `saveFireflyLedData saveNewNamedArea SUCESSFULL! `,\n result\n );\n this.props.activate(operationButton); // -> sendNamedAreaEventSingle\n //\n // #WIP!!!!!!!!!!!!!!!!1\n // set the popup flag as FALSE - this allows updating of dlg\n //this.setState({ isPopupOpen: false });\n // reload the popup\n // https://stackoverflow.com/questions/51732698/leaflet-popup-update-resizing-solution-recreating-a-popup-everytime-unable\n // if (toggleFireflyLed && !toggleFireflyLed._updated) {\n // toggleFireflyLed._updated = true; // Set flag to prevent looping.\n // toggleFireflyLed.update();\n // }\n })\n .catch((error) => {\n console.log(\n `saveFireflyLedData saveNewNamedAre failed `,\n error\n );\n // #WIP - do something if fails!???\n });\n }\n }\n }\n\n /// +++++++++++++++++++++++++++++++++++++++++++++++++++\n }\n });\n }\n\n // *************************\n });\n }\n\n this.layerlistFireflies[feature.properties.id] = layer;\n }\n\n if (DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER) {\n if (feature.properties && feature.properties.location) {\n // adds a separate layer specifically for location\n this[`${feature.properties.location}`].addLayer(layer);\n }\n }\n\n //----------------------------------------------------\n //\n // MAP MARKER MOVE FIREFLY POSITIONS - DRAG EVENTS\n //\n //----------------------------------------------------\n\n layer.on(\"dragstart\", (e) => {\n //\n });\n\n // markerPositionChanges\n\n layer.on(\"dragend\", (e) => {\n const marker = e.target;\n const position = marker.getLatLng();\n const markerProperties = marker.feature.properties;\n const { id, forced } = markerProperties;\n\n // console.log(\"xxx dragend Firefly position\", id, position);\n // console.log(\n // \"xxx dragend Firefly fire off FF update!!!! markerProperties\",\n // marker,\n // markerProperties\n // );\n // console.log(\n // \"xxx dragend Firefly fire off FF update!!!! forced\",\n // forced ? \"FORCED!!!!!!!!!!!!!!!!\" : \"Not forced\",\n // id\n // );\n\n if (forced) {\n // if Markers has a FORCED- event, clear it\n // clear all forceLightStat\n this.setState({ forcedLightState: [] });\n // clear any events on the light\n setForceLight(\"clear\", id, null, null, null, null, null, null);\n }\n\n let newMarkerPositionChanges = this.state.markerPositionChanges;\n newMarkerPositionChanges[id] = {\n id: id,\n type: \"firefly\",\n properties: markerProperties,\n position: position,\n };\n this.setState({ markerPositionChanges: newMarkerPositionChanges });\n });\n };\n\n // This is very important! Use a canvas otherwise the chart is too heavy for the browser when\n // the number of points is too high, as in this case where we have around 300K points to plot\n var myRenderer = L.canvas({\n padding: 0.5,\n });\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayerFirefly = (feature, latlng) => {\n // ####SVG Marker###\n\n // #DEBUG\n // #KEEP THIS...\n const iconColor = { stroke: \"grey\", fill: \"grey\" };\n const markerColor = {\n stroke: feature.properties.color.plan,\n fill: feature.properties.color.status,\n };\n\n const { svgIcon, svgStyle } = markerDefinition(feature);\n const currentZoom = this.map.getZoom();\n\n return L.marker(latlng, {\n renderer: myRenderer,\n //icon: makeIcon(\"CrossMarker\", iconColor, 1), // default to 'cross' on first write of coordinate message\n //icon: makeIcon(\"CrossMarker\", markerColor, currentZoom), // default to 'cross' on first write of coordinate message\n icon: makeIcon(svgIcon, svgStyle, currentZoom),\n draggable: false,\n });\n };\n\n // TESTING_DRAG\n\n // set style of firefly markers\n const fireflyStyle = (feature) => {\n let setFillColor;\n if (feature.properties.color) {\n const color = feature.properties.color;\n switch (color.status) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"orange\";\n break;\n case \"white\":\n setFillColor = \"white\";\n break;\n\n case \"red\":\n setFillColor = \"red\";\n break;\n\n default:\n setFillColor = \"green\";\n break;\n }\n }\n\n return {\n radius: 6,\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n };\n\n // determine unique properties array from geoJson\n //\n let uniqueProperties = geoJSONMarkersData.features.reduce(\n (acc, { properties }) => {\n Object.entries(properties).forEach(([key, val]) => {\n acc[key] = acc[key] || new Set();\n acc[key].add(val);\n });\n\n return acc;\n },\n {}\n );\n\n if (DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER) {\n let locations = [];\n this.locationGroupLayers = {};\n\n if (uniqueProperties[\"location\"]) {\n locations = [...uniqueProperties[\"location\"]].sort(sortAlphaNum);\n locations.forEach((value, idx) => {\n //console.log(\"locations[idx]\", value);\n\n this[value] = L.featureGroup().addTo(this.map);\n // -> this makes firefly location group a separate layer\n // disabled for now so does not crowd the layer control\n this.locationGroupLayers[value] = this[value];\n });\n }\n }\n\n // #REVIEW - Issue is that with growing array location groups are not created on startup.\n // Need to make these with each update of the state geoJson\n // constrain to area\n const filterArea = (feature, layer) => {\n return feature.properties.area === mineLevelId; //\"DMLZ_Undercut\"; //this.state.map.area; // \"DMLZ_Extraction\";\n };\n\n // add firefly markers to the map\n // Note - Only Controllers and Fireflies are add to map by default (.addTo(this.map))\n this.geoJSONGroupLayer = L.geoJSON(geoJSONMarkersData, {\n pointToLayer: pointToLayerFirefly,\n onEachFeature: onEachFeatureFirefly,\n style: fireflyStyle, //#DEBUG - DISABLED FOR RECTANGLE TESTING ###DEFAULT_MARKER####\n //coordsToLatLng: coordsToLatLng, // <<--- #REVIEW I still don't underestand what this does\n filter: filterArea,\n }).addTo(this.map);\n\n // display the layer when the map is loaded\n // if (!isMapLoading) {\n // this.geoJSONGroupLayer.addTo(this.map);\n // }\n\n // WHY? Why do this.....?\n if (false) {\n let updatedFireflyIds = [];\n // remove marker from the update list\n geoJSONMarkersData.features.map((feature, idx) => {\n const {\n properties: { id },\n } = feature;\n // remove FF Id from fireflyIdsUpdateList after it's been processed\n //\n updatedFireflyIds.push(id);\n });\n // remove FF Id from fireflyIdsUpdateList\n this.props.fireflyIdsUpdateListDeleteId(updatedFireflyIds);\n }\n\n // ********************************************************************************\n //\n // Setup and draw the Fireflies - tooltips\n //\n // These are drawn on a separate layer\n //\n // ********************************************************************************\n\n // add popup information\n const onEachFeatureFireflyTooltip = (feature, layer) => {\n const { properties } = feature;\n const { location, position } = properties;\n\n if (feature.properties && feature.properties.id) {\n // #REVIEW - tooltip label for FF\n // * - could be used for TAGS?\n // * - could show which markers have Slough meters etc\n // see - https://stackoverflow.com/questions/49852157/add-custom-bindtooltip-class\n\n const TooltipClass = {\n className: \"class-tooltip\",\n };\n\n layer.bindTooltip(\n `${location}:${position}`,\n {\n direction: \"bottom\",\n permanent: true,\n offset: [0, 20],\n //className: \"transparent-tooltip\",\n ...TooltipClass,\n },\n TooltipClass\n );\n }\n };\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayerFireflyTooltip = (feature, latlng) => {\n return L.circleMarker(latlng, {\n renderer: myRenderer,\n clickable: false,\n // make marker ~invisible\n radius: 5,\n opacity: 0,\n fillOpacity: 0.2,\n });\n };\n\n // add firefly tooltip markers to the map\n this.geoJSONGroupLayerFireflyTooltips = L.geoJSON(geoJSONMarkersData, {\n pointToLayer: pointToLayerFireflyTooltip,\n onEachFeature: onEachFeatureFireflyTooltip,\n filter: filterArea,\n }); // .addTo(this.map);\n\n // ********************************************************************************\n //\n // Setup and draw the Fireflies - simple\n //\n // This is a very simple layer to show marker positions when the map is moved\n //\n // These are drawn on a separate layer\n //\n // ********************************************************************************\n\n // add popup information\n const onEachFeatureFireflySimple = (feature, layer) => {\n const { properties } = feature;\n const { location, position } = properties;\n\n if (feature.properties && feature.properties.id) {\n // #REVIEW - tooltip label for FF\n // * - could be used for TAGS?\n // * - could show which markers have Slough meters etc\n // see - https://stackoverflow.com/questions/49852157/add-custom-bindtooltip-class\n\n const TooltipClass = {\n className: \"class-tooltip\",\n };\n\n layer.bindTooltip(\n `${location}:${position}`,\n {\n direction: \"bottom\",\n permanent: true,\n offset: [0, 20],\n //className: \"transparent-tooltip\",\n ...TooltipClass,\n },\n TooltipClass\n );\n }\n };\n\n // see - 'pointToLayerFirefly'\n const pointToLayerFireflySimple = (feature, latlng) => {\n const { svgIcon, svgStyle } = markerDefinition(feature);\n const currentZoom = this.map.getZoom();\n\n // for simple markers make icon opaque to emphasise markers are only 'indicators' of position\n const simpleSvgStyle = { ...svgStyle, opacity: \"0.6\" };\n\n return L.marker(latlng, {\n renderer: myRenderer,\n //icon: makeIcon(\"CrossMarker\", iconColor, 1), // default to 'cross' on first write of coordinate message\n //icon: makeIcon(\"CrossMarker\", markerColor, currentZoom), // default to 'cross' on first write of coordinate message\n icon: makeIcon(svgIcon, simpleSvgStyle, currentZoom),\n draggable: false,\n });\n };\n\n // add firefly tooltip markers to the map\n this.geoJSONGroupLayerFireflySimple = L.geoJSON(geoJSONMarkersData, {\n pointToLayer: pointToLayerFireflySimple,\n //onEachFeature: onEachFeatureFireflySimple,\n filter: filterArea,\n }); // .addTo(this.map);\n\n // ********************************************************************************\n //\n // Setup and draw the Fireflies - Forced lights\n //\n // These Forced light tooltips used as an indicator of where forced lights are located\n //\n // ********************************************************************************\n\n this.layerlistFirefliesForced = {};\n\n // add popup information\n const onEachFeatureFireflyForcedToolTips = (feature, layer) => {\n const { properties } = feature;\n const { location, position } = properties;\n\n if (feature.properties && feature.properties.id) {\n // #REVIEW - tooltip label for FF\n // * - could be used for TAGS?\n // * - could show which markers have Slough meters etc\n // see - https://stackoverflow.com/questions/49852157/add-custom-bindtooltip-class\n\n const TooltipClass = {\n className: \"class-tooltip\",\n };\n\n layer.bindTooltip(\n `${location}:${position}`,\n {\n direction: \"bottom\",\n permanent: true,\n offset: [0, 20],\n //className: \"transparent-tooltip\",\n ...TooltipClass,\n },\n TooltipClass\n );\n }\n\n this.layerlistFirefliesForced[feature.properties.id] = layer;\n };\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayerFireflyForcedToolTips = (feature, latlng) => {\n return L.circleMarker(latlng, {\n renderer: myRenderer,\n clickable: false,\n // make marker ~invisible\n radius: 5,\n opacity: 0,\n fillOpacity: 0.2,\n });\n };\n\n // add firefly tooltip markers to the map\n this.geoJSONGroupLayerFireflyForcedTooltips = L.geoJSON(\n geoJSONMarkersDataForced,\n {\n pointToLayer: pointToLayerFireflyForcedToolTips,\n onEachFeature: onEachFeatureFireflyForcedToolTips,\n filter: filterArea,\n }\n ); // .addTo(this.map);\n\n // ********************************************************************************\n //\n // Setup and draw the Tags\n //\n // These are drawn on a separate layer\n //\n // ********************************************************************************\n\n // add popup information\n //\n // #REVIEW - not required ATM. Left in place for later review???\n //\n const onEachFeatureTags = (feature, layer) => {\n const { properties } = feature;\n const { location, position, id } = properties;\n\n if (feature.properties && feature.properties.id) {\n const TooltipClass = {\n className: \"class-tooltip\",\n };\n\n layer.bindTooltip(\n `${location}:${position}`,\n {\n direction: \"bottom\",\n permanent: true,\n offset: [0, 20],\n //className: \"transparent-tooltip\",\n ...TooltipClass,\n },\n TooltipClass\n );\n }\n };\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayerTags = (feature, latlng) => {\n // #REVIEW - could integrate tag marker into this function\n // const { svgIcon, svgStyle } = markerDefinition(feature);\n const svgIcon = \"WorkerMarker\";\n const svgStyle = { stroke: \"fuchsia\", fill: \"sienna\" };\n const currentZoom = this.map.getZoom();\n\n return L.marker(latlng, {\n renderer: myRenderer,\n clickable: false,\n icon: makeIcon(svgIcon, svgStyle, currentZoom),\n });\n };\n\n // add firefly tag markers to the map\n this.geoJSONGroupLayerTags = L.geoJSON(geoJSONMarkersData, {\n pointToLayer: pointToLayerTags,\n //onEachFeature: onEachFeatureTags,\n filter: filterArea,\n }); // .addTo(this.map);\n\n // ********************************************************************************\n //\n // Setup and draw the marker points - map scaling points and origin/centre/max markers\n //\n // ********************************************************************************\n\n // setup scaling coord reference point markers\n const onEachFeatureMarker = (feature, layer) => {\n layer.bindPopup(\n \"ref pt:\" +\n JSON.stringify(feature.properties.index) +\n \" => \" +\n JSON.stringify(feature.geometry.coordinates)\n );\n layer.on(\"dragend\", function (e) {\n const marker = e.target;\n const position = marker.getLatLng();\n //console.log(\"xxx dragend refPt position\", position);\n marker\n .setLatLng(position, { draggable: \"true\" })\n .bindPopup(\"\" + position) // #REVIEW \"\" is hack as bindPopup will not accept just numbers\n .update();\n });\n layer.on(\"click\", (e) => {\n //transform from pixels to points\n // const transform = this.Transform(\n // this.standardPtsUtmX(),\n // this.localPtsX()\n // );\n\n const transformPixelsToUtm = this.props.mineLevel.transformPixelsToUtm;\n\n const marker = e.target;\n const position = marker.getLatLng();\n //console.log(\"xxx dragend refPt position\", JSON.stringify(position));\n\n const objLatLng = transformPixelsToUtm.transform({\n //transform\n lat: position.lat,\n lng: position.lng,\n });\n\n // console.log(\n // \"xxx feature.properties\",\n // JSON.stringify(feature.properties)\n // );\n\n const id = `ID:${feature.properties.id}`;\n\n // original geoJson coordinates\n const geoJsonPt = `E:${feature.properties.easting}, N:${feature.properties.northing}`;\n // image coordinates\n const imagePt = Object.values(position).reverse(); // map is y, x referenced. Reverse to display as x,y.\n // transformed image -> physical\n const coordPt = Object.values(objLatLng).reverse();\n\n marker\n .setLatLng(position, { draggable: \"true\" })\n .bindPopup(\n `
${id}
\n
GeoJ: ${geoJsonPt}
\n
Image: X: ${round(imagePt[0], 2)}, Y: ${round(\n imagePt[1],\n 2\n )}
\n
Coord: E: ${round(coordPt[0], 2)}, N: ${round(\n coordPt[1],\n 2\n )}
`\n )\n .update();\n\n console.log(`xxx clicked - Ref Pt marker - UTM Coords:[${coordPt}]`);\n });\n };\n\n // ******************************************************************\n //\n // Add general purpose markers to map\n //\n // ******************************************************************\n this.markerGroupLayer = L.geoJSON(\n this.localPtsGeoJson(this.markerPts({ width, height })),\n {\n pointToLayer: function (feature, latlng) {\n return L.marker(latlng, {\n //icon: greenIcon, // <--- #TODO FIX THIS!\n draggable: true,\n });\n },\n onEachFeature: onEachFeatureMarker,\n }\n ); //.addTo(this.map);\n\n // #Note - adding to the map before adding to layer will set [x] default\n\n // ******************************************************************\n //\n // Add coord reference point markers to map\n //\n // ******************************************************************\n this.refPtGroupLayer = L.geoJSON(this.localPtsGeoJson(localPtsX), {\n pointToLayer: function (feature, latlng) {\n return L.marker(latlng, {\n //icon: greenIcon, // <--- #TODO FIX THIS!\n draggable: true,\n });\n },\n onEachFeature: onEachFeatureMarker,\n }); //.addTo(this.map);\n // #Note - adding to the map before adding to layer will set [x] default .addTo(this.map);\n\n // ********************************************************************************\n //\n // Setup and draw the controller markers\n //\n // ********************************************************************************\n\n // list of controller layers\n this.layerlistControllers = {};\n\n // add popup information\n const onEachFeatureController = (feature, layer) => {\n const { properties } = feature;\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_number,\n utm_zone_letter,\n z,\n color,\n timestamp,\n user_relay,\n } = properties;\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n if (feature.properties && feature.properties.id) {\n if (false) {\n layer.bindPopup(\n `
Controller: ${id}
\n
\n
${this.testExternalStr} ${area}
\n
Geom: E:${round(easting, 2)} N:${round(\n northing,\n 2\n )} Z${Math.trunc(z)} ${utm_zone_number} ${utm_zone_letter}
\n
Image: X:${X} Y:${Y}
\n
Color: ${color}
\n
Last Report: ${lastStatusReport}
`\n );\n } else {\n //\n const controllerMarkerPopup = renderToString(\n \n );\n layer.bindPopup(controllerMarkerPopup, {\n maxWidth: \"250\", // auto // #REVIEW - FIXED SIZE OF POPUP #DEFAULT_\n });\n\n layer.on(\"popupclose\", (event) => {\n this.setState({ isPopupOpen: false });\n });\n layer.on(\"popupopen\", (event) => {\n // #WIP - disable popup open re-rendering?\n if (false) {\n this.setState({ isPopupOpen: true });\n }\n var marker = event.popup._source.feature.properties.id;\n var popUp = event.target.getPopup();\n\n // added eventListener to controller marker content\n // see - src/components/Map/ControllerMarkerPopup.js\n\n this.props.role.allowAdmin &&\n popUp\n .getElement()\n .querySelector(\".popupControllerMarkerLink\")\n .addEventListener(\"click\", (e) => {\n console.log(\n \"clicked edit on marker: \",\n e,\n \"target: \",\n e.target,\n \"dataid \",\n e.target.getAttribute(\"dataid\")\n );\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n this.props.goto(`/admin/controller/${id}`);\n } else {\n this.props.goto(`/admin/controller/`);\n }\n });\n\n // *************************\n });\n }\n\n this.layerlistControllers[feature.properties.id] = layer;\n }\n\n // #REVIEW - can't do this as-is b/c location is an array of positions.\n // Is this a duplication from FF which has never worked?\n // if (feature.properties && feature.properties.location) {\n // // adds a separate layer specifically for location\n // this[`${feature.properties.location}`].addLayer(layer);\n // }\n\n //----------------------------------------------------\n //\n // MAP MARKER MOVE CONTROLLER POSITIONS - DRAG EVENTS\n //\n //----------------------------------------------------\n\n layer.on(\"dragstart\", (e) => {\n //\n });\n\n // markerPositionChanges\n\n layer.on(\"dragend\", (e) => {\n const marker = e.target;\n const position = marker.getLatLng();\n const markerProperties = marker.feature.properties;\n const { id } = markerProperties;\n\n let newMarkerPositionChanges = this.state.markerPositionChanges;\n newMarkerPositionChanges[id] = {\n id: id,\n type: \"controller\",\n properties: markerProperties,\n position: position,\n };\n this.setState({ markerPositionChanges: newMarkerPositionChanges });\n });\n };\n\n // This is very important! Use a canvas otherwise the chart is too heavy for the browser when\n // the number of points is too high, as in this case where we have around 300K points to plot\n // var myRenderer = L.canvas({\n // padding: 0.5,\n // });\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayerController = (feature, latlng) => {\n // #KEEP THIS...\n const iconColor = { stroke: \"blue\", fill: \"blue\" };\n const currentZoom = this.map.getZoom();\n\n return L.marker(latlng, {\n renderer: myRenderer,\n icon: makeIcon(\"SquareMarker\", iconColor, currentZoom), // default to 'cross' on first write of coordinate message\n draggable: false,\n });\n };\n\n // set style of controller markers\n const controllerStyle = (feature) => {\n let setFillColor = \"green\";\n if (feature.properties.color) {\n const color = feature.properties.color;\n switch (color.status) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"orange\";\n break;\n case \"white\":\n setFillColor = \"white\";\n break;\n\n case \"red\":\n setFillColor = \"red\";\n break;\n\n default:\n setFillColor = \"green\";\n break;\n }\n }\n\n return {\n radius: 6,\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n };\n\n // add controller markers to the map\n // Note - Only Controllers and Fireflies are add to map by default (.addTo(this.map))\n this.geoJSONControllerGroupLayer = L.geoJSON(geoJSONControllers, {\n pointToLayer: pointToLayerController,\n onEachFeature: onEachFeatureController,\n style: controllerStyle,\n //coordsToLatLng: coordsToLatLng, // <<--- #REVIEW I still don't underestand what this does\n filter: filterArea,\n }).addTo(this.map);\n\n // display the layer when the map is loaded\n // if (!isMapLoading) {\n // this.geoJSONControllerGroupLayer.addTo(this.map);\n // }\n\n // ********************************************************************************\n //\n // Setup and draw the named area polygons\n //\n // ********************************************************************************\n\n // list of named area polygons\n this.layerlistNamedAreas = {};\n this.parentsUnionGroupLayers = {};\n\n const onEachFeatureNamedAreas = (feature, layer) => {\n if (feature.properties && feature.properties.id) {\n this.layerlistNamedAreas[feature.properties.id] = layer;\n }\n layer.on(\"click\", (e) => {\n const id = feature.properties.id.split(\":\")[1]; // eg. from \"DMLZ_Extraction:182736182736\" -> \"182736182736\"\n const namedAreaPolygon = e.target;\n namedAreaPolygon.bindPopup(`
Polygon: ${id}
`);\n });\n };\n\n // add named area polygons to the map\n this.geoJSONNamedAreaGroupLayer = L.geoJSON(geoJSONNamedAreas, {\n style: this.geojsonPolygonStyle,\n onEachFeature: onEachFeatureNamedAreas,\n coordsToLatLng: function (coords) {\n // swaps the coordinate references around so when polygons are created the pixel refer are [x,y] , not [y,x]\n // latitude , longitude, altitude\n return new L.LatLng(coords[1], coords[0], coords[2]); // <--------- Normal behavior\n //return new L.LatLng(coords[0], coords[1], coords[2]);\n },\n }); // #Note - adding to the map before adding to layer will set [x] default .addTo(this.map);\n\n // update leaflet id to properties (used to delete.edit shapes in local state)\n this.geoJSONNamedAreaGroupLayer.eachLayer(function (layer) {\n layer.feature.properties._leaflet_id = layer._leaflet_id; //#TODO - change to L.Stamp()\n });\n\n //#TODO - change to L.Stamp()\n // Also note that .getLayers() works for LayerGroup (and FeatureGroup and GeoJson), but not for L.Map.\n // Usage of \"private\" properties and methods like _layers or _leaflet_id or _latlng is discouraged.\n\n // add layers to the local maps state\n const geoJsonPixels = this.geoJSONNamedAreaGroupLayer.toGeoJSON();\n\n //const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n\n //console.log(\"qqq add layers to the local maps state geoJson\", geoJsonUtm);\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // push layer to back layer.bringToFront()\n this.geoJSONNamedAreaGroupLayer.bringToBack();\n\n // ********************************************************************************\n //\n // Setup and draw the named area parent multipolygons\n //\n // ********************************************************************************\n\n // create separate layer references for named area parents\n // determine unique properties array from geoJson\n //\n\n const geoJSONNamedAreaParentsThisArea =\n geoJSONNamedAreaParents.features.filter(\n (feature) => feature.properties.area === mineLevel.id\n );\n let uniqueNamedAreaParentProperties =\n geoJSONNamedAreaParentsThisArea.reduce((acc, { properties }) => {\n Object.entries(properties).forEach(([key, val]) => {\n acc[key] = acc[key] || new Set();\n acc[key].add(val);\n });\n\n return acc;\n }, {});\n let regions = [];\n this.regionGroupLayers = {};\n if (uniqueNamedAreaParentProperties[\"name\"]) {\n regions = [...uniqueNamedAreaParentProperties[\"name\"]].sort(sortAlphaNum);\n regions.forEach((value, idx) => {\n // -> this makes region group a separate layer\n // disabled for now so does not crowd the layer control\n this[value] = L.featureGroup(); //.addTo(this.map);\n this.regionGroupLayers[value] = this[value];\n });\n }\n\n // list of named area polygons\n this.layerlistNamedAreaParents = {};\n\n const onEachFeatureNamedAreaParents = (feature, layer) => {\n if (feature.properties && feature.properties.id) {\n this.layerlistNamedAreaParents[feature.properties.id] = layer;\n }\n layer.on(\"click\", (e) => {\n const id = feature.properties.id.split(\":\")[1]; // eg. from \"DMLZ_Extraction:Area_A\" -> \"Area_A\"\n const namedAreaParentPolygon = e.target;\n namedAreaParentPolygon.bindPopup(`
Named Area ID: ${id}
`);\n });\n\n if (feature.properties && feature.properties.name) {\n // adds a separate layer specifically for `name`\n\n // #NOTE - stops `geoJSONNamedAreaParentGroupLayer` adding layers on startup.\n // `geoJSONNamedAreaParentGroupLayer` is superceded in favour of\n // `parentsUnionGroupLayers`\n if (false) {\n this[`${feature.properties.name}`].addLayer(layer);\n }\n }\n };\n\n // add named area polygons to the map\n this.geoJSONNamedAreaParentGroupLayer = L.geoJSON(geoJSONNamedAreaParents, {\n style: this.geojsonPolygonStyle,\n onEachFeature: onEachFeatureNamedAreaParents,\n coordsToLatLng: function (coords) {\n // swaps the coordinate references around so when polygons are created the pixel refer are [x,y] , not [y,x]\n // latitude , longitude, altitude\n return new L.LatLng(coords[1], coords[0], coords[2]); // <--------- Normal behavior\n //return new L.LatLng(coords[0], coords[1], coords[2]);\n },\n filter: filterArea,\n }); // .addTo(this.map);\n\n // #Note - adding to the map before adding to layer will set [x] default\n // update leaflet id to properties (used to delete.edit shapes in local state)\n // this.geoJSONNamedAreaParentGroupLayer.eachLayer(function (layer) {\n // layer.feature.properties._leaflet_id = layer._leaflet_id; //#TODO - change to L.Stamp()\n // });\n\n // push layer to back layer.bringToFront()\n this.geoJSONNamedAreaParentGroupLayer.bringToBack();\n\n // ********************************************************************************\n //\n // Setup the map layers into control groups and display controls\n //\n // ********************************************************************************\n\n // #NOTE - no longer used, instead see groupedOverlays below\n\n // setup layer groups\n let baseLayers = { MineMap: base };\n\n // setup layer groups overlayers (see also https://leafletjs.com/reference-1.6.0.html#control-layers-addoverlay)\n let overLayers = {\n // \" Firefly\": this\n // .geoJSONGroupLayer,\n FireFlys: this.geoJSONGroupLayer,\n Simple: this.geoJSONGroupLayerFireflySimple,\n \"FireFly ID\": this.geoJSONGroupLayerFireflyTooltips,\n Forced: this.geoJSONGroupLayerFireflyForcedTooltips,\n //Tags: this.geoJSONGroupLayerTags,\n Controllers: this.geoJSONControllerGroupLayer,\n // Regions: this.geoJSONNamedAreaGroupLayer,\n Polygons: this.geoJSONNamedAreaParentGroupLayer,\n Marker: this.markerGroupLayer,\n RefPt: this.refPtGroupLayer,\n //Cable: this.polylineGroupLayers,\n //Editable: this.editableLayers,\n };\n\n // // spread the objects to join the location layers to the overlay\n // if (true) {\n // overLayers = {\n // ...overLayers,\n // //...this.locationGroupLayers,\n // ...this.regionGroupLayers,\n // };\n // }\n // var layerControl = L.control.layers(null, overLayers, {\n // // null -> baseLayers\n // collapsed: true, //\n // });\n\n // // add it to the map\n // layerControl.addTo(this.map);\n\n // console.log(\n // `this.parentsUnionGroupLayers`,\n // this.parentsUnionGroupLayers\n // );\n\n // sort the named areas to display ordered\n const orderedParentsUnionGroupLayers = Object.keys(\n this.parentsUnionGroupLayers\n )\n .sort()\n .reduce((obj, key) => {\n obj[key] = this.parentsUnionGroupLayers[key];\n return obj;\n }, {});\n\n // APP_TERMINOLOGY\n const strNamedAreas = \"Polygons\";\n\n //\n // Use the custom grouped layer control, not \"L.control.layers\"\n // https://github.com/ismyrnow/leaflet-groupedlayercontrol\n // see also - https://stackoverflow.com/questions/34384905/leaflet-how-to-toggle-all-layers-either-off-or-on-at-once/34392545#34392545\n let groupedOverlays = {\n Markers: {\n FireFlys: this.geoJSONGroupLayer,\n Simple: this.geoJSONGroupLayerFireflySimple,\n \"FireFly ID\": this.geoJSONGroupLayerFireflyTooltips,\n Forced: this.geoJSONGroupLayerFireflyForcedTooltips,\n Controllers: this.geoJSONControllerGroupLayer,\n //\"All Named Areas\": this.geoJSONNamedAreaParentGroupLayer,\n Tags: this.geoJSONGroupLayerTags,\n //Editable: this.editableLayers,\n },\n\n // #NOTE - these are commented out to disable the group listing for now.\n // #TODO - add displaying this as a setup config option\n //\"Named Area\": { ...this.regionGroupLayers }, // multipolygons\n Polygons: { ...orderedParentsUnionGroupLayers }, //this.parentsUnionGroupLayers\n };\n\n if (DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER) {\n groupedOverlays = {\n ...groupedOverlays,\n Locations: this.locationGroupLayers,\n\n //Regions: this.regionGroupLayers,\n };\n }\n\n const options = {\n collapsed: true,\n //exclusiveGroups: [\"Named Areas\"],\n groupsCollapsable: true, // see - https://github.com/ismyrnow/leaflet-groupedlayercontrol/pull/46\n // Show a checkbox next to non-exclusive group labels for toggling all\n groupCheckboxes: true,\n };\n\n // Use the custom grouped layer control, not \"L.control.layers\"\n // https://github.com/ismyrnow/leaflet-groupedlayercontrol\n // see also - https://stackoverflow.com/questions/34384905/leaflet-how-to-toggle-all-layers-either-off-or-on-at-once/34392545#34392545\n this.controller = L.control\n .groupedLayers(null, groupedOverlays, options)\n .addTo(this.map);\n\n // if (!isMapLoading) {\n // this.controller.addTo(this.map);\n // }\n\n // ********************************************************************************\n //\n // Set polylines joining the Fireflies\n //\n //\n // #NOTE: this has to be done after the locationGroupLayers has been rendered, and the group control\n // is defined as it uses addOverlay() to add the polylines to the existing control\n //\n // ********************************************************************************\n\n if (DEFAULT_SHOW_FIREFLY_POLYLINE_GROUP_LAYER) {\n this.polylineGroupLayers = {};\n\n // step through the list of locationGroupLayers\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n // create an object with the posObject[position] = latlng coordinates\n let posObject = {};\n\n // loop each layer - #REVIEW - this could be labourious - perhaps only do if selected to display?\n // eslint-disable-next-line no-loop-func\n value.eachLayer(function (layer) {\n posObject[layer.feature.properties.position] = layer.getLatLng();\n });\n\n // sort the posObject by position order (i.e. object key) so line draws from position 1 -> n\n\n // see - https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key\n const ordered = {};\n Object.keys(posObject)\n .sort()\n .forEach(function (key) {\n ordered[key] = posObject[key];\n });\n\n // plot a polyline using ordered array of values\n // create name object from layer name (i.e. key is the POSITION)\n const layerName = \"poly_\" + key;\n this[layerName] = L.polyline(Object.values(ordered)).addTo(this.map); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n\n // add this layer to layer group to add to control layer later\n this.polylineGroupLayers[layerName] = this[layerName];\n }\n\n // #NOTE\n // ..this will need to be updated for the groupedLayer control\n //\n //\n // add group to overlays by iterating over the object\n // https://stackoverflow.com/questions/55471295/adding-multiple-overlays-to-leaflets-layers-control\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n this.controller.addOverlay(value, key, \"Cables\"); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n }\n }\n\n //----------------------------------------------------\n //\n // MAP MOVEMENT - DRAG ZOOM ETC\n //\n // see - https://gis.stackexchange.com/questions/54454/disable-leaflet-interaction-temporary\n //----------------------------------------------------\n\n const disableMapMovement = (map) => {\n map.dragging.disable();\n map.touchZoom.disable();\n map.doubleClickZoom.disable();\n //map.scrollWheelZoom.disable();\n map.smoothWheelZoom.disable();\n map.boxZoom.disable();\n map.keyboard.disable();\n if (map.tap) map.tap.disable();\n };\n\n const enableMapMovement = (map) => {\n map.dragging.enable();\n map.touchZoom.enable();\n map.doubleClickZoom.enable();\n //map.scrollWheelZoom.enable();\n map.smoothWheelZoom.enable();\n map.boxZoom.enable();\n map.keyboard.enable();\n if (map.tap) map.tap.enable();\n };\n\n // on startup disable map movement by user\n disableMapMovement(this.map);\n\n //----------------------------------------------------\n //\n // MAP MARKER ZOOM - CONTROLS\n //\n //\n // Custom zoom controls\n //\n //----------------------------------------------------\n\n // listeners for disabling buttons\n this.map.on(\"zoomend\", (e) => {\n const map = e.target,\n max = map.getMaxZoom(),\n min = map.getMinZoom(),\n current = map.getZoom(),\n isMapView = this.state.isMapView;\n\n if (current < max) {\n if (isMapView) {\n zoomInButton.enable();\n }\n }\n if (current >= max) {\n if (isMapView) {\n zoomInButton.disable();\n }\n }\n if (current > min) {\n if (isMapView) {\n zoomOutButton.enable();\n }\n }\n if (current <= min) {\n if (isMapView) {\n zoomOutButton.disable();\n }\n }\n });\n\n const moveMapViewZoomIn = ``;\n const moveMapViewZoomOut = ``;\n\n const zoomInButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-in-move-map-view\",\n icon: moveMapViewZoomIn,\n title: \"Zoom In\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() + 1);\n },\n },\n ],\n });\n\n const zoomOutButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-out-move-map-view\",\n icon: moveMapViewZoomOut,\n title: \"Zoom Out\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() - 1);\n },\n },\n ],\n });\n //const zoomBar = L.easyBar([zoomInButton, zoomOutButton]);\n //zoomBar.addTo(this.map);\n\n //----------------------------------------------------\n //\n // MAP VIEW MOVE - CONTROLS\n //\n //----------------------------------------------------\n\n const moveMapViewShow = ``;\n const moveMapViewHide = ``;\n\n const disableActiveLayer = (layer, layerName, activeLayersList) => {\n let newActiveLayersList = [activeLayersList];\n if (this.map.hasLayer(layer)) {\n if (!newActiveLayersList.includes(layerName)) {\n newActiveLayersList.push(layerName);\n\n this.map.removeLayer(layer);\n }\n }\n\n return newActiveLayersList;\n };\n\n const enableActiveLayer = (layer, layerName, activeLayersList) => {\n let newActiveLayersList = activeLayersList;\n if (!this.map.hasLayer(layer)) {\n if (newActiveLayersList.includes(layerName)) {\n newActiveLayersList.filter((layer) => layer !== layerName);\n\n layer.addTo(this.map);\n }\n }\n\n return newActiveLayersList;\n };\n\n // remove all layers\n\n const disableAllActiveLayers = (activeLayersList) => {\n let newActiveLayerList = [...activeLayersList];\n\n // remove all layers\n newActiveLayerList = disableActiveLayer(\n this.geoJSONGroupLayer,\n \"geoJSONGroupLayer\",\n newActiveLayerList\n );\n newActiveLayerList = disableActiveLayer(\n this.geoJSONGroupLayerFireflyTooltips,\n \"geoJSONGroupLayerFireflyTooltips\",\n newActiveLayerList\n );\n newActiveLayerList = disableActiveLayer(\n this.geoJSONGroupLayerFireflyForcedTooltips,\n \"geoJSONGroupLayerFireflyForcedTooltips\",\n newActiveLayerList\n );\n newActiveLayerList = disableActiveLayer(\n this.geoJSONControllerGroupLayer,\n \"geoJSONControllerGroupLayer\",\n newActiveLayerList\n );\n newActiveLayerList = disableActiveLayer(\n this.geoJSONGroupLayerTags,\n \"geoJSONGroupLayerTags\",\n newActiveLayerList\n );\n\n return newActiveLayerList;\n };\n\n const enableAllActiveLayers = (activeLayersList) => {\n let newActiveLayerList = [...activeLayersList];\n\n // add all layers\n this.geoJSONGroupLayer.addTo(this.map);\n\n // add layers which were displayed\n newActiveLayerList = enableActiveLayer(\n this.geoJSONGroupLayer,\n \"geoJSONGroupLayer\",\n newActiveLayerList\n );\n newActiveLayerList = enableActiveLayer(\n this.geoJSONGroupLayerFireflyTooltips,\n \"geoJSONGroupLayerFireflyTooltips\",\n newActiveLayerList\n );\n newActiveLayerList = enableActiveLayer(\n this.geoJSONGroupLayerFireflyForcedTooltips,\n \"geoJSONGroupLayerFireflyForcedTooltips\",\n newActiveLayerList\n );\n newActiveLayerList = enableActiveLayer(\n this.geoJSONControllerGroupLayer,\n \"geoJSONControllerGroupLayer\",\n newActiveLayerList\n );\n newActiveLayerList = enableActiveLayer(\n this.geoJSONGroupLayerTags,\n \"geoJSONGroupLayerTags\",\n newActiveLayerList\n );\n\n // FireFlys: this.geoJSONGroupLayer,\n // \"FireFly ID\": this.geoJSONGroupLayerFireflyTooltips,\n // Forced: this.geoJSONGroupLayerFireflyForcedTooltips,\n // Controllers: this.geoJSONControllerGroupLayer,\n // //\"All Named Areas\": this.geoJSONNamedAreaParentGroupLayer,\n // Tags: this.geoJSONGroupLayerTags,\n // //Editable: this.editableLayers,\n\n return newActiveLayerList;\n };\n\n //\n\n const toggleMapLayers = (control, map, moveMap) => {\n const { isPokeTheWorker, TurnOnOffPokeTheWorker, SetMapMarkerDragging } =\n this.props;\n\n let newActiveLayerList = [...this.state.activeLayersList];\n\n switch (moveMap) {\n case true:\n // turn off data collection\n SetMapMarkerDragging(true);\n this.setState({ isMarkerDragging: true });\n\n // remove all the active layers\n newActiveLayerList = disableAllActiveLayers(newActiveLayerList);\n\n // add simple marker layer\n this.geoJSONGroupLayerFireflySimple.addTo(this.map);\n\n // turn off data collection\n // #NOTE - this is setup as condition for DEBUGing layers\n if (false) {\n if (isPokeTheWorker) {\n TurnOnOffPokeTheWorker(false);\n }\n\n this.setState({ isPokeTheWorkerLocal: false });\n }\n\n break;\n case false:\n // remove simple layer\n this.map.removeLayer(this.geoJSONGroupLayerFireflySimple);\n\n // add all the active layers\n newActiveLayerList = enableAllActiveLayers(newActiveLayerList);\n\n // restore/refresh the layer control\n // .....#WIP?????????????\n\n SetMapMarkerDragging(false);\n this.setState({ isMarkerDragging: false });\n\n // turn off data collection\n // #NOTE - this is setup as condition for DEBUGing layers\n if (false) {\n // turn on data collection\n this.setState({ isPokeTheWorkerLocal: true });\n\n if (!isPokeTheWorker) {\n TurnOnOffPokeTheWorker(true);\n }\n }\n\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefresh: true });\n\n break;\n\n default:\n break;\n }\n\n this.setState({ activeLayerList: newActiveLayerList });\n };\n\n const moveMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"show-move-map-view\",\n icon: moveMapViewShow,\n title: \"Pan and Zoom\",\n onClick: (control, map) => {\n // show the zoom controls\n moveMapViewButton.disable();\n zoomOutButton.enable();\n zoomInButton.enable();\n cancelMapViewButton.enable();\n moveMarkerPositionsButton.disable();\n\n // enable map movement\n enableMapMovement(this.map);\n\n // map has started moving so disable data collection\n mapStartMoving();\n\n toggleMapLayers(control, map, true);\n this.setState({ isMapView: true });\n },\n },\n {\n stateName: \"hide-move-map-view\",\n icon: moveMapViewHide,\n title: \"Disable move view\",\n },\n ],\n });\n\n const cancelMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"cancel-move-map-view\",\n icon: \"fa fa-times\",\n title: \"Disable Pan and Zoom\",\n onClick: (control, map) => {\n map.closePopup();\n\n // show the zoom controls\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n moveMarkerPositionsButton.enable();\n\n // disable map movement\n disableMapMovement(this.map);\n\n // map has stopped moving so enable data collection\n mapStopMoving();\n\n toggleMapLayers(control, map, false);\n this.setState({ isMapView: false });\n },\n },\n ],\n });\n\n let moveMapViewBar = L.easyBar([\n moveMapViewButton,\n zoomInButton,\n zoomOutButton,\n cancelMapViewButton,\n ]);\n moveMapViewBar.addTo(this.map);\n\n // startup hide - zoom buttons\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER MOVE POSITIONS - CONTROLS\n //\n //----------------------------------------------------\n\n // Alternate methods to display icons:\n // \n // ''\n //\n // see - https://github.com/CliffCloud/Leaflet.EasyButton/issues/82\n // see - http://danielmontague.com/projects/easyButton.js/v1/examples/#fancier-disable\n // see custom.css 'easyButton' section for styling\n\n const enableFeatureGroupDraggable = (featureGroup, action) => {\n featureGroup.eachLayer(function (layer) {\n if (layer instanceof L.Marker) {\n //console.log(`123 layer`, action, layer);\n if (action) {\n // if (layer.feature.id === \"GBC_Extraction:P26E:1\") {\n // console.log(`123 layer`, layer);\n // }\n layer.dragging.enable();\n } else if (!action) {\n layer.dragging.disable();\n }\n }\n });\n };\n\n const changeMarkerStyle = (featureGroup, markerName) => {\n const currentZoom = this.map.getZoom();\n featureGroup.eachLayer(function (layer) {\n if (layer instanceof L.Marker) {\n const position = layer?.feature?.properties?.position || 0;\n const color =\n layer?.feature?.properties?.light?.color?.status || \"grey\";\n\n const newColor = { stroke: color, fill: color, text: position };\n\n // console.log(\n // `gggg layer?.feature?.properties?.`,\n // color,\n // newColor,\n // layer?.feature?.properties\n // );\n switch (markerName) {\n case \"typicalNumberedMapMarker\":\n layer.setIcon(\n makeIcon(\n \"TypicalNumberedMapMarker\",\n newColor, // hack position into color object for numbered markers\n currentZoom\n )\n );\n break;\n\n default:\n break;\n }\n }\n });\n };\n\n const moveMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"move-marker-positions\",\n icon: \"fas fa-edit\",\n title: \"Edit FireFly and Controller positions\",\n onClick: (control, map) => {\n moveMarkerPositionsButton.disable();\n saveMarkerPositionsButton.enable();\n cancelMarkerPositionsButton.enable();\n\n // disable move\n moveMapViewButton.disable();\n\n let newActiveLayerList = [...this.state.activeLayersList];\n // remove all the active layers\n newActiveLayerList = disableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n // make sure FFs and Controller layers are enabled\n this.geoJSONGroupLayer.addTo(this.map);\n this.geoJSONControllerGroupLayer.addTo(this.map);\n\n // enable dragging of markers\n enableFeatureGroupDraggable(this.geoJSONGroupLayer, true);\n enableFeatureGroupDraggable(this.geoJSONControllerGroupLayer, true);\n\n // change the markers to look 'editable'\n // fireflys\n changeMarkerStyle(\n this.geoJSONGroupLayer,\n \"typicalNumberedMapMarker\"\n );\n // controllers\n changeMarkerStyle(\n this.geoJSONControllerGroupLayer,\n \"typicalNumberedMapMarker\"\n );\n\n // turn off data collection\n const {\n isPokeTheWorker,\n TurnOnOffPokeTheWorker,\n SetMapMarkerDragging,\n } = this.props;\n\n SetMapMarkerDragging(true);\n this.setState({ isMarkerDragging: true });\n\n if (isPokeTheWorker) {\n TurnOnOffPokeTheWorker(false);\n }\n this.setState({ isPokeTheWorkerLocal: false });\n },\n },\n ],\n });\n\n const saveMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"save-marker-positions\",\n icon: \"fas fa-save\",\n title: \"Save position changes\",\n onClick: (e) => {\n const markerPositionChanges = this.state.markerPositionChanges;\n\n // console.log(\n // ` markerPositionChanges markerPositionChanges`,\n // markerPositionChanges\n // );\n\n if (!_isEmpty(markerPositionChanges)) {\n const {\n saveFirefly,\n saveUPS,\n transformPixelsToUtm,\n mineLevelId,\n } = this.props;\n\n let promiseArray = [];\n\n for (const change in markerPositionChanges) {\n const {\n id,\n type,\n properties,\n position: changedPosition,\n } = markerPositionChanges[change];\n\n const objLatLng = transformPixelsToUtm.transform({\n lat: changedPosition.lat,\n lng: changedPosition.lng,\n });\n\n // transform position to UTM\n const newPosition = {\n mineLevelId: mineLevelId,\n lat: objLatLng.lat,\n lng: objLatLng.lng,\n };\n\n // console.log(\n // ` markerPositionChanges id, type, properties, newPosition`,\n // id,\n // type,\n // properties,\n // changedPosition,\n // newPosition\n // );\n\n switch (type) {\n case \"firefly\":\n const {\n id: fireflyId,\n position: fireflyPosition,\n location: fireflyLocation,\n mac: fireflyMac,\n note: fireflyNote,\n } = properties;\n\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveFirefly({\n values: {\n id: fireflyId,\n position: newPosition,\n fireflyLocation,\n fireflyPosition,\n fireflyMac,\n fireflyNote,\n },\n resolve,\n reject,\n });\n })\n );\n break;\n case \"controller\":\n const { id: upsId } = properties;\n\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveUPS({\n values: {\n id: upsId,\n position: newPosition,\n name: null,\n }, // #NOTE #REVIEW - name is no longer used\n resolve,\n reject,\n });\n })\n );\n break;\n default:\n break;\n }\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"UPDATING CONTROLLER/FIREFLY POSITIONS\", results);\n })\n .then(\n () => {\n let newActiveLayerList = [...this.state.activeLayersList];\n // enable all the active layers\n newActiveLayerList =\n enableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n //\n closeMarkerPositionButtons();\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n }\n closeMarkerPositionButtons();\n },\n },\n ],\n });\n\n const closeMarkerPositionButtons = () => {\n // clear all position changes\n this.setState({ markerPositionChanges: {} });\n // disable marker drag\n enableFeatureGroupDraggable(this.geoJSONGroupLayer, false);\n enableFeatureGroupDraggable(this.geoJSONControllerGroupLayer, false);\n\n let newActiveLayerList = [...this.state.activeLayersList];\n // enable all the active layers\n newActiveLayerList = enableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n // close buttons\n moveMarkerPositionsButton.enable();\n saveMarkerPositionsButton.disable();\n cancelMarkerPositionsButton.disable();\n\n // enable move\n moveMapViewButton.enable();\n\n // turn on data collection\n this.setState({ isPokeTheWorkerLocal: true });\n const { isPokeTheWorker, TurnOnOffPokeTheWorker, SetMapMarkerDragging } =\n this.props;\n\n SetMapMarkerDragging(false);\n this.setState({ isMarkerDragging: false });\n\n if (!isPokeTheWorker) {\n TurnOnOffPokeTheWorker(true);\n }\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefresh: true });\n };\n\n const cancelMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"cancel-marker-positions\",\n icon: \"fa fa-times\",\n title: \"Cancel position changes\",\n onClick: (e) => {\n // clear all position changes\n this.setState({ markerPositionChanges: {} });\n // disable dragging of markers\n enableFeatureGroupDraggable(this.geoJSONGroupLayer, false);\n enableFeatureGroupDraggable(\n this.geoJSONControllerGroupLayer,\n false\n );\n\n let newActiveLayerList = [...this.state.activeLayersList];\n // enable all the active layers\n newActiveLayerList = enableAllActiveLayers(newActiveLayerList);\n this.setState({ activeLayerList: newActiveLayerList });\n\n // close buttons\n moveMarkerPositionsButton.enable();\n saveMarkerPositionsButton.disable();\n cancelMarkerPositionsButton.disable();\n\n // enable move\n moveMapViewButton.enable();\n\n // turn on data collection\n this.setState({ isPokeTheWorkerLocal: true });\n const { isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n TurnOnOffPokeTheWorker(true);\n }\n\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefresh: true });\n },\n },\n ],\n });\n\n let editBar = L.easyBar([\n moveMarkerPositionsButton,\n saveMarkerPositionsButton,\n cancelMarkerPositionsButton,\n ]);\n\n if (this.props.role.allowAdmin) {\n editBar.addTo(this.map);\n }\n\n // startup hide - save and cancel buttons\n moveMarkerPositionsButton.enable();\n saveMarkerPositionsButton.disable();\n cancelMarkerPositionsButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER REFRESH - CONTROLS\n //\n //----------------------------------------------------\n\n const refreshMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"reset-marker-positions\",\n icon: \"fa fa-redo\",\n title: \"Refresh Map\",\n onClick: (e) => {\n // force a map refresh to restore marker positions & disable drag\n this.setState({ forceMapRefresh: true });\n this.map.fitBounds(bounds);\n },\n },\n ],\n });\n\n let refreshMapBar = L.easyBar([refreshMarkerPositionsButton]);\n refreshMapBar.addTo(this.map);\n\n //----------------------------------------------------\n //\n // MAP EVENTS\n //\n //----------------------------------------------------\n\n const mapLayerChangingOnInputToggle = (e) => {\n if (this.controller._handlingClick) {\n // Executes only on input toggle, not on\n // map.addLayer(marker) or map.removeLayer(marker)\n this.updateLayerControlState();\n }\n };\n\n this.map.on(\n \"overlayadd overlayremove layeradd layerremove\",\n mapLayerChangingOnInputToggle\n );\n\n const mapLayerChanging = () => {\n // console.log(`layeradd updateLayerControlState`);\n\n this.updateLayerControlState();\n };\n\n // executes when adding layers via previewList\n this.map.on(\"layeradd layerremove\", mapLayerChanging);\n\n // map manipulation and moving events\n\n // Detects click on Zoom in and Zoom out buttons\n // Works but not sure it is necessary we already use 'zoomstart' etc\n // #WIP - this works\n if (false) {\n var elementLControlZoomIn = document.querySelector(\n \"a.leaflet-control-zoom-in\"\n );\n\n L.DomEvent.addListener(elementLControlZoomIn, \"click\", (e) => {\n console.log(\n `COLLECTING DATA ... elementLControlZoomIn `,\n new Date().getTime().toString()\n );\n\n this.props.SetMapMoving(true);\n\n this.setState({ isPokeTheWorkerLocal: false });\n\n const { isPokeTheWorker } = this.props;\n if (isPokeTheWorker) {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n });\n\n var elementLControlZoomOut = document.querySelector(\n \"a.leaflet-control-zoom-out\"\n );\n\n L.DomEvent.addListener(elementLControlZoomOut, \"click\", (e) => {\n console.log(`COLLECTING DATA ... elementLControlZoomOut `);\n\n this.props.SetMapMoving(false);\n\n this.setState({ isPokeTheWorkerLocal: false });\n\n const { isPokeTheWorker } = this.props;\n if (isPokeTheWorker) {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n });\n }\n\n const mapStartMoving = () => {\n this.props.SetMapMoving(true);\n this.setState({ isMoving: true });\n\n if (!this.state.isMarkerDragging) {\n this.setState({ isPokeTheWorkerLocal: false });\n\n const { isPokeTheWorker } = this.props;\n if (isPokeTheWorker) {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n }\n };\n\n const mapStopMoving = () => {\n this.props.SetMapMoving(false);\n this.setState({ isMoving: false });\n\n if (!this.state.isMarkerDragging) {\n this.setState({ isPokeTheWorkerLocal: true });\n const { isPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n }\n };\n\n //disable_simple\n // if implement 'pan' tool then no longer need this to start/stop\n if (false) {\n // fires when map starts moving: dragging map, zooming etc.\n this.map.on(\"movestart zoomstart \", mapStartMoving); // mousedown?\n\n // fires when map is moving\n this.map.on(\"move\", (e) => {\n //console.log(`COLLECTING DATA ... move `);\n\n this.props.SetMapMoving(true);\n\n const { isPokeTheWorker } = this.props;\n // reinforce turning off data collection!\n // this should never happen....but....\n if (isPokeTheWorker) {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n this.setState({ isPokeTheWorkerLocal: false });\n });\n }\n\n // fires when map stops moving: dragging map, zooming etc.\n this.map.on(\"moveend zoomend \", mapStopMoving); // mouseup?\n\n // ###################################################################################\n // See other definition for polylines.\n // these should be defined after the fireflies are defined\n //\n // ###################################################################################\n //\n //\n //\n\n // ********************************************************************************\n //\n // Set polylines joining the Fireflies\n //\n //\n // ***** NOTE: this has to be done after the locationGroupLayers has been rendered\n // ...probably more likely need layer control defined before start adding groups ****\n //\n // #REVEW <--- reorder the code\n // ********************************************************************************\n\n // if (DEFAULT_SHOW_FIREFLY_POLYLINE_GROUP_LAYER) {\n // this.polylineGroupLayers = {};\n\n // // step through the list of locationGroupLayers\n // for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n // // create an object with the posObject[position] = latlng coordinates\n // let posObject = {};\n\n // // loop each layer - #REVIEW - this could be labourious - perhaps only do if selected to display?\n // // eslint-disable-next-line no-loop-func\n // value.eachLayer(function (layer) {\n // posObject[layer.feature.properties.position] = layer.getLatLng();\n // });\n\n // // sort the posObject by position order (i.e. object key) so line draws from position 1 -> n\n\n // // see - https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key\n // const ordered = {};\n // Object.keys(posObject)\n // .sort()\n // .forEach(function (key) {\n // ordered[key] = posObject[key];\n // });\n\n // // plot a polyline using ordered array of values\n // // create name object from layer name (i.e. key is the POSITION)\n // const layerName = \"poly_\" + key;\n // this[layerName] = L.polyline(Object.values(ordered)).addTo(this.map); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n\n // // add this layer to layer group to add to control layer later\n // this.polylineGroupLayers[layerName] = this[layerName];\n // }\n\n // // #NOTE\n // // ..this will need to be updated for the groupedLayer control\n // //\n // //\n // // add group to overlays by iterating over the object\n // // https://stackoverflow.com/questions/55471295/adding-multiple-overlays-to-leaflets-layers-control\n // for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n // // #WIP - layerControl below commented out while testing groupLayer control\n // //\n // //layerControl.addOverlay(value, key); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n // }\n // }\n\n // *****************************************************************************************\n // #REVIEW - setup ordering layers for all levels with toggle\n // setup layer control events\n // https://stackoverflow.com/questions/14103489/leaflet-layer-control-events\n this.map.on(\"overlayadd\", onOverlayAdd);\n\n function onOverlayAdd(e) {\n // https://gis.stackexchange.com/questions/137061/how-to-change-layer-order-in-leaflet-js\n // push layer to back layer.bringToFront()\n\n if (e.name === \"Polygon\") {\n e.layer.bringToBack();\n }\n //console.log(\"onOverlayAdd e\", e);\n }\n\n //----------------------------------------------------\n //\n // MAP EVENTS (more :-)\n //\n //----------------------------------------------------\n\n // bind 'this' to get access to map\n const zoomend = () => {\n const currentZoom = this.map.getZoom();\n console.log(\"zoomend currentZoom\", currentZoom);\n\n let newMapViewState = this.state.mapViewState;\n newMapViewState.zoom = currentZoom;\n this.setState({ mapViewState: newMapViewState });\n\n // Tracking whether zooming in or out\n // only update icon if size has changed\n let diffZoom = this.previousZoom - currentZoom;\n\n // diffZoom > 0 - console.log(\"zoomend zoomed out\");\n // iffZoom < 0 - console.log(\"zoomend zoomed in\");\n if (diffZoom !== 0) {\n const firefliesIdInLayer = Object.keys(this.layerlistFireflies);\n firefliesIdInLayer.forEach((fireflyId, idx) => {\n const iconOptions =\n this.layerlistFireflies[fireflyId].getIcon().options;\n const { iconName, iconSize, iconColor } = iconOptions;\n\n // only update icon if size has changed\n\n this.layerlistFireflies[fireflyId].setIcon(\n makeIcon(iconName, iconColor, currentZoom)\n );\n });\n }\n\n // #WIP - tool tip implementation integrated with the main FF marker\n // see also - tooltip in main marker definition\n //\n // Started implementing show/hide of tooltip based on\n // see - https://stackoverflow.com/questions/42364619/hide-tooltip-in-leaflet-for-a-zoom-range\n //\n // const lastZoom = this.previousZoom;\n // const tooltipThreshold = -1;\n // if (\n // currentZoom < tooltipThreshold &&\n // (!lastZoom || lastZoom >= tooltipThreshold)\n // ) {\n // this.map.eachLayer(function (l) {\n // if (l.getTooltip()) {\n // var tooltip = l.getTooltip();\n // l.unbindTooltip().bindTooltip(tooltip, {\n // permanent: false,\n // });\n // }\n // });\n // } else if (\n // zoom >= tooltipThreshold &&\n // (!lastZoom || lastZoom < tooltipThreshold)\n // ) {\n // this.map.eachLayer(function (l) {\n // if (l.getTooltip()) {\n // var tooltip = l.getTooltip();\n // l.unbindTooltip().bindTooltip(tooltip, {\n // permanent: true,\n // });\n // }\n // });\n // }\n\n this.previousZoom = currentZoom;\n };\n\n this.map.on(\"zoomend\", zoomend);\n\n const moveend = () => {\n const currentCenter = this.map.getCenter();\n\n let newMapViewState = this.state.mapViewState;\n newMapViewState.center = currentCenter;\n this.setState({ mapViewState: newMapViewState });\n };\n\n this.map.on(\"moveend\", moveend);\n\n // ********************************************************************************\n //\n // Setup polygons drawn on the map\n //\n //\n // NOTE: uses leaflet.draw leaflet-draw\n //\n // ********************************************************************************\n\n // Truncate value based on number of decimals\n var _round = function (num, len) {\n return Math.round(num * Math.pow(10, len)) / Math.pow(10, len);\n };\n // Helper method to format LatLng object (x.xxxxxx, y.yyyyyy)\n var strLatLng = function (latlng) {\n return \"(\" + _round(latlng.lat, 6) + \", \" + _round(latlng.lng, 6) + \")\";\n };\n\n // Generate popup content based on layer type\n // - Returns HTML string, or null if unknown object\n var getPopupContent = function (layer) {\n // Marker - add lat/long\n if (layer instanceof L.Marker || layer instanceof L.CircleMarker) {\n return strLatLng(layer.getLatLng());\n // Circle - lat/long, radius\n } else if (layer instanceof L.Circle) {\n var center = layer.getLatLng(),\n radius = layer.getRadius();\n return (\n \"Center: \" +\n strLatLng(center) +\n \"
\" +\n \"Radius: \" +\n _round(radius, 2) +\n \" m\"\n );\n // Rectangle/Polygon - area\n } else if (layer instanceof L.Polygon) {\n var latlngs = layer._defaultShape\n ? layer._defaultShape()\n : layer.getLatLngs();\n\n // get the pixel coordinates of the shape\n var coords = latlngs.map(function (point) {\n return [point.lng, point.lat]; // #REVIEW - reverse display lat, long = YX\n });\n\n return (\n \"Coords: \" +\n JSON.stringify(coords) +\n \"
_leaflet_id: \" +\n L.stamp(layer)\n );\n // Polyline - distance\n } else if (layer instanceof L.Polyline) {\n var latlngs = layer._defaultShape\n ? layer._defaultShape()\n : layer.getLatLngs(),\n distance = 0;\n if (latlngs.length < 2) {\n return \"Distance: N/A\";\n } else {\n for (var i = 0; i < latlngs.length - 1; i++) {\n distance += latlngs[i].distanceTo(latlngs[i + 1]);\n }\n return \"Distance: \" + _round(distance, 2) + \" m\";\n }\n }\n return null;\n };\n\n // create the editable layers to draw on\n this.editableLayers = L.featureGroup(); // .addTo(this.map);\n //#REVIEW - this stops edirtable layers displaying\n //\n // #Note - adding to the map before adding to layer will set [x] default\n\n // https://stackoverflow.com/questions/40088421/returning-clicked-layer-leaflet\n // see - https://jsfiddle.net/3v7hd2vx/108/\n // attached to this.editableLayers group\n\n // DISABLE THIS ONCLICK ACTION - but leave in code for debugging\n if (DEBUG_ENABLED_FALSE) {\n this.editableLayers.on(\"click\", (event) => {\n const { layer } = event;\n\n // console.log(\"xxx this.editableLayers click \" + L.stamp(layer));\n // console.log(\"xxx this.editableLayers - _leaflet_id \" + layer._leaflet_id);\n\n // Note 'layer.edited' only true after handles moved\n //&& layer.edited\n if (layer instanceof L.Polygon || layer instanceof L.Rectangle) {\n // rectangle, polygon, circle\n const colors = [\"green\", \"orange\", \"blue\", \"red\"];\n const currentColor = layer.options.fillColor;\n const index = colors.findIndex((x) => x === currentColor);\n let newColor;\n index + 1 > colors.length - 1\n ? (newColor = colors[0])\n : (newColor = colors[index + 1]);\n\n layer.setStyle({ color: newColor, fillColor: newColor });\n layer.feature.properties.color.status = layer.options.fillColor; // set fillColor as active color in geoJSON\n }\n });\n }\n\n // #WIP - more editable layers use from control screen\n // check what layers are drawn.......\n //console.log(\"this.editableLayers layer before 1\", this.editableLayers);\n //this.editableLayers.eachLayer(function (layer) {\n //console.log(\"this.editableLayers layer before\", layer);\n // Pass this information through Redux to outside\n //});\n\n // add existing layer to editable layer so can edit existing/loaded polygons\n //let that=this; // pass editable layer into function\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n console.log(\n \"Adding mqtt Named Area to this.editableLayers -> \",\n layer._leaflet_id\n ); // KEEP AS PERMANENT INDICATOR THAT MAP GROUPS ARE UPDATING\n\n // #WIP - this is failing when going from another page back to control screen\n // \"TypeError: Cannot read property 'style' of undefined\"\n if (layer.getElement() !== undefined) {\n layer.getElement().style.display = \"block\"; // this resets any hidden layer actions\n }\n\n this.editableLayers.addLayer(layer);\n });\n\n // --- LAYER INFORMATION TO OUTSIDE MAP\n\n // #WIP - more editable layers use from control screen\n // check what layers are drawn.......\n //this.editableLayers.eachLayer(function (layer) {\n //console.log(\"this.editableLayers layer after\", layer);\n // Pass this information through Redux to outside\n //});\n\n // #TESTING ICON STYLING AND ANIMATION\n\n // https://piratefsh.github.io/how-to/2015/10/16/animating-leaflet-markers.html\n\n // https://leafletjs.com/reference-1.7.1.html\n // https://stackoverflow.com/questions/41884070/how-to-make-markers-in-leaflet-blinking\n // https://stackoverflow.com/questions/31961549/pulsating-leaflet-marker-using-css3-animations\n // With the class added, the marker will blink:\n // L.DomUtil.addClass(marker._icon, \"blinking\");\n // Without the class, it won't:\n // L.DomUtil.removeClass(marker._icon, \"blinking\");\n\n // +++++++++++++++++++++++++++++++++++++++++++++++++++++\n //\n // Finally! map drawn!!!!!!!!\n //\n // ++++++++++++++++++++++++++++++++++++++++++++++\n };\n\n convertGeoJsonPixelsToUtm = (geoJsonPixels, mineLevel) => {\n // Output coordinates of shape in UTM\n // returns geoJSON\n\n // convert pixel coordinates in geoJson Pixels to utm\n // deep clone - to stop geometry being converted on raw *utm data\n geoJsonPixels = JSON.parse(JSON.stringify(geoJsonPixels));\n const geoJsonUtm = transformGeoJsonPixelsToUtm(geoJsonPixels, mineLevel);\n\n // #TODO - NOTE: 'drawnItemsToJSON' below strips out the properties!\n // - needs to be updated to preserve PROPERTIES\n // - do not use until fixed\n\n // preserve styling of polygon in geoJson\n //\n //geoJson = this.drawnItemsToJSON(this.editableLayers);\n return geoJsonUtm;\n };\n\n // find a random point in the holding pen\n randomPointInPoly = function (polygon) {\n var bounds = polygon.getBounds();\n var x_min = bounds.getEast();\n var x_max = bounds.getWest();\n var y_min = bounds.getSouth();\n var y_max = bounds.getNorth();\n\n var lat = y_min + Math.random() * (y_max - y_min);\n var lng = x_min + Math.random() * (x_max - x_min);\n\n var point = turf.point([lng, lat]);\n var poly = polygon.toGeoJSON();\n var inside = turf.inside(point, poly);\n\n if (inside) {\n return point;\n } else {\n return this.randomPointInPoly(polygon);\n }\n };\n\n updateLayerControlState = () => {\n // update state of controls\n let layerControlState = {};\n for (const [key, value] of Object.entries(this.parentsUnionGroupLayers)) {\n layerControlState[key] = this.map.hasLayer(value);\n }\n this.setState({ layerControlState: layerControlState });\n };\n\n shouldComponentUpdate(nextProps, nextState) {\n const { mineLevel, isPokeTheWorker } = nextProps;\n const { isPokeTheWorkerLocal } = nextState;\n\n // console.log(`nextState.isMapLoaded`, nextState.isMapLoaded);\n // console.log(`nextState.isMaping`, nextState.isMaping);\n\n // console.log(`this.state.isMapLoaded`, this.state.isMapLoaded);\n // console.log(`this.state.isMaping`, this.state.isMaping);\n\n // // if map is not loaded\n // if (!nextState.isMapLoaded){\n // if (!_isEqual(this.state.isMapLoading, nextState.isMapLoading))\n\n // }\n\n //console.log(`nextState.isPokeTheWorkerLocal`, isPokeTheWorkerLocal);\n\n if (mineLevel === undefined || !isPokeTheWorkerLocal) {\n return false;\n } else {\n return true;\n }\n }\n\n componentDidMount() {\n const { mineLevel, isPokeTheWorker } = this.props;\n\n if (!_isEmpty(mineLevel)) {\n this.setState({ map: { area: mineLevel?.id } });\n\n // set local version of isPokeTheWorker\n //this.setState({ isPokeTheWorkerLocal: isPokeTheWorker });\n\n this.setState({ isMapComponentDidMount: true });\n\n //console.log(\"mapViewState componentDidMount\", mineLevel?.id);\n\n const newMapViewState = this.props.componentstate.get(\n \"mapViewState\",\n mineLevel?.id\n );\n // console.log(\n // \"newMapViewState componentDidMount\",\n // mineLevel?.id,\n // newMapViewState\n // );\n if (!_isEmpty(newMapViewState)) {\n // console.log(\n // \"newMapViewState componentDidMount setState newMapViewState\",\n // mineLevel?.id,\n // newMapViewState\n // );\n // wait for state change before mounting the map\n this.setState({ mapViewState: newMapViewState }, () => {\n //console.log(\"newMapViewState updated\");\n this.mapMount();\n });\n } else {\n this.mapMount();\n }\n } else {\n // #NOTE - this should never happen, but on rapid reload of the page\n // I experienced mineLevel undefined.\n\n console.log(`LOAD ERROR: AREA IS EMPTY `, mineLevel);\n }\n }\n\n componentWillUnmount() {\n const { mineLevel } = this.props;\n\n //console.log(\"newMapViewState\", mineLevel?.id, this.state.mapViewState);\n\n const {\n mapViewState: { center, zoom },\n } = this.state;\n\n const newMapViewState = {\n center: center !== undefined ? center : this.previousCenter,\n zoom: zoom !== undefined ? zoom : this.previousZoom,\n };\n\n //console.log(`newMapViewState componentWillUnmount`, newMapViewState);\n\n const settings = {\n section: \"mapViewState\",\n key: mineLevel?.id,\n data: { ...newMapViewState },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n\n // this.props.componentstate.set(\n // \"mapViewState\",\n // mineLevel?.id,\n // newMapViewState\n // );\n\n // clear out map\n if (this.map && this.map.remove) {\n this.map.off();\n this.map.remove();\n }\n }\n\n // standardPtsUtmX = () => {\n // const { mineLevel } = this.props;\n // const { ref_coord } = mineLevel;\n\n // let result = [];\n\n // ref_coord.forEach((coord) => {\n // result.push({ lat: coord.utm[0], lng: coord.utm[1] });\n // });\n // return result;\n // };\n\n standardPtsUtmX = () => {\n const { mineLevel } = this.props;\n const { ref_coord } = mineLevel;\n\n let result = {};\n ref_coord.forEach((coord) => {\n const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n const index = indexArray[1];\n\n result[index] = { lat: coord.utm[0], lng: coord.utm[1] };\n });\n\n // sort object by key\n Object.keys(result)\n .sort()\n .forEach(function (v, i) {\n //console.log(v, result[v]);\n });\n\n // return the values\n return Object.values(result);\n };\n\n // localPtsX = () => {\n // const { mineLevel } = this.props;\n // const { ref_coord } = mineLevel;\n\n // let result = [];\n // ref_coord.forEach((coord) => {\n // result.push({\n // id: coord.id,\n // lat: coord.image_xy[0],\n // lng: coord.image_xy[1],\n\n // easting: coord.utm[0],\n // northing: coord.utm[1],\n // zoneNum: coord.utm_zone_number,\n // zoneLetter: coord.utm_zone_letter,\n // });\n // });\n // return result;\n // };\n\n localPtsX = () => {\n const { mineLevel } = this.props;\n const { ref_coord } = mineLevel;\n\n let result = {};\n ref_coord.forEach((coord) => {\n const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n const index = indexArray[1];\n\n result[index] = {\n // used for transformation\n lat: coord.image_xy[0],\n lng: coord.image_xy[1],\n // used for display on marker popups\n id: coord.id,\n easting: coord.utm[0],\n northing: coord.utm[1],\n zoneNum: coord.utm_zone_number,\n zoneLetter: coord.utm_zone_letter,\n };\n });\n\n // sort object by key\n Object.keys(result)\n .sort()\n .forEach(function (v, i) {\n //console.log(v, result[v]);\n });\n\n // return the values\n return Object.values(result);\n };\n\n mapMount = () => {\n const { render } = this.props;\n\n const mapId = \"map-\" + render;\n\n const { mineLevel } = this.props;\n\n //console.log(\"hhh mapMount mineLevel\", mineLevel);\n\n const {\n geoJSONMarkersDataUtm,\n geoJSONMarkersDataUtmForced,\n geoJSONNamedAreasUtm,\n geoJSONNamedAreaParentsUtm,\n geoJSONControllersUtm,\n } = this.props;\n\n let geoJSONMarkersData;\n let geoJSONMarkersDataForced;\n let geoJSONControllers;\n //\n // #REVIEW - issue here is that the component mounts before the mqtt messages have populated the objecet -> redux -> component etc.\n // need to ensure .features exists to transform...\n\n // ***************************************************************\n //\n // Update fireflies geoJson\n //\n // ***************************************************************\n\n if (\n typeof geoJSONMarkersDataUtm.features !== \"undefined\" &&\n geoJSONMarkersDataUtm.features.length\n ) {\n // #REVIEW - this now happens in WebWorker reducer for fireflies\n // deep clone - to stop geometry being converted on raw *utm data\n //geoJSONMarkersData = JSON.parse(JSON.stringify(geoJSONMarkersDataUtm));\n //geoJSONMarkersData = this.transformGeoJsonUtmToPixels(geoJSONMarkersData);\n\n geoJSONMarkersData = geoJSONMarkersDataUtm;\n } else {\n // add an empty geoJson featurecollection\n geoJSONMarkersData = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // ***************************************************************\n //\n // Update fireflies Forced geoJson\n //\n // ***************************************************************\n\n if (\n typeof geoJSONMarkersDataUtmForced.features !== \"undefined\" &&\n geoJSONMarkersDataUtmForced.features.length\n ) {\n geoJSONMarkersDataForced = geoJSONMarkersDataUtmForced;\n } else {\n // add an empty geoJson featurecollection\n geoJSONMarkersDataForced = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // ***************************************************************\n //\n // Update Controllers geoJson\n //\n // ***************************************************************\n\n if (\n typeof geoJSONControllersUtm.features !== \"undefined\" &&\n geoJSONControllersUtm.features.length\n ) {\n geoJSONControllers = geoJSONControllersUtm;\n } else {\n // add an empty geoJson featurecollection\n geoJSONControllers = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // ***************************************************************\n //\n // Update named area geoJson\n //\n // ***************************************************************\n\n let geoJSONNamedAreas;\n\n if (\n typeof geoJSONNamedAreasUtm.features !== \"undefined\" &&\n geoJSONNamedAreasUtm.features.length\n ) {\n // deep clone - to stop geometry being converted on raw *utm data\n geoJSONNamedAreas = JSON.parse(JSON.stringify(geoJSONNamedAreasUtm));\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n geoJSONNamedAreas = transformGeoJsonUtmToPixels(\n geoJSONNamedAreas,\n mineLevelObj,\n 1,\n false\n );\n } else {\n // add an empty geoJson featurecollection\n geoJSONNamedAreas = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // ***************************************************************\n //\n // Update named area parent geoJson\n //\n // ***************************************************************\n\n let geoJSONNamedAreaParents;\n\n if (\n typeof geoJSONNamedAreaParentsUtm.features !== \"undefined\" &&\n geoJSONNamedAreaParentsUtm.features.length\n ) {\n // deep clone - to stop geometry being converted on raw *utm data\n geoJSONNamedAreaParents = JSON.parse(\n JSON.stringify(geoJSONNamedAreaParentsUtm)\n );\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n geoJSONNamedAreaParents = transformGeoJsonUtmToPixels(\n geoJSONNamedAreaParents,\n mineLevelObj,\n 1,\n false\n );\n } else {\n // add an empty geoJson featurecollection\n geoJSONNamedAreaParents = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n const { mapViewState } = this.state;\n\n //console.log(\"mapViewState < draw\", this.state);\n\n // ***************************************************************\n //\n // draw the map\n //\n // ***************************************************************\n\n this.drawTheMap(\n mapId,\n mineLevel,\n geoJSONMarkersData,\n geoJSONMarkersDataForced,\n geoJSONNamedAreas,\n geoJSONNamedAreaParents,\n geoJSONControllers,\n //\n mapViewState\n );\n };\n\n componentDidUpdate(prevProps, prevState) {\n // check if map is now visible\n if (prevProps.showMap !== this.props.showMap && this.props.showMap) {\n // reinitialise map\n // see - https://gis.stackexchange.com/questions/289975/toggling-leaflet-map-on-click\n this.map.invalidateSize();\n }\n\n // #DEBUG - messages to show the count # of markers in each layer when component updates\n //\n if (DEBUG_SHOW_COUNT_OF_MARKERS_EACH_LAYER) {\n // #WIP #DEBUG - how many markers\n // Construct an empty list to fill with onscreen markers.\n var inBounds = [],\n // Get the map bounds - the top-left and bottom-right locations.\n bounds = this.map.getBounds();\n\n // For each marker, consider whether it is currently visible by comparing\n // with the current map bounds.\n this.geoJSONGroupLayer.eachLayer(function (marker) {\n if (bounds.contains(marker.getLatLng())) {\n inBounds.push(marker.options.id);\n }\n });\n\n console.log(\n \"geoJSONGroupLayer - time \",\n new Date().getTime() / 1000,\n \"marker # \",\n inBounds.length\n );\n\n inBounds = [];\n\n this.markerGroupLayer.eachLayer(function (marker) {\n if (bounds.contains(marker.getLatLng())) {\n inBounds.push(marker.options.id);\n }\n });\n\n console.log(\n \"markerGroupLayer - time \",\n new Date().getTime() / 1000,\n \"marker # \",\n inBounds.length\n );\n\n inBounds = [];\n\n this.refPtGroupLayer.eachLayer(function (marker) {\n if (bounds.contains(marker.getLatLng())) {\n inBounds.push(marker.options.id);\n }\n });\n\n console.log(\n \"refPtGroupLayer - time \",\n new Date().getTime() / 1000,\n \"marker # \",\n inBounds.length\n );\n\n inBounds = [];\n\n this.geoJSONNamedAreaGroupLayer.eachLayer(function (layer) {\n // console.log(\"layer\", layer);\n if (bounds.contains(layer.getLatLngs())) {\n inBounds.push(layer.options.id);\n }\n });\n\n console.log(\n \"geoJSONNamedAreaGroupLayer - time \",\n new Date().getTime() / 1000,\n \"marker # \",\n inBounds.length\n );\n\n console.log(\n \"locationGroupLayers - time \",\n new Date().getTime() / 1000,\n \"marker # \",\n this.locationGroupLayers !== undefined\n ? this.locationGroupLayers.length\n : undefined\n );\n\n console.log(\n \"polylineGroupLayers - time \",\n new Date().getTime() / 1000,\n \"marker # \",\n this.polylineGroupLayers !== undefined\n ? this.polylineGroupLayers.length\n : undefined\n );\n\n // ***********\n }\n\n const { mineLevel } = this.props;\n\n // if the area (mine level) has changed, remove the map and remount it all again\n if (\n prevProps.mineLevelId !== this.props.mineLevelId &&\n !_isEmpty(mineLevel)\n ) {\n if (this.map && this.map.remove) {\n this.map.off();\n this.map.remove();\n }\n\n // console.log(\"hhh mineLevel\", mineLevel);\n\n this.setState({ map: { area: mineLevel.id } });\n // reset map load state pending reload of area background image\n\n // console.log(\"loaded isMapLoading\", true);\n this.setState({ isMapLoading: true });\n\n const newMapViewState = this.props.componentstate.get(\n \"mapViewState\",\n mineLevel?.id\n );\n if (!_isEmpty(newMapViewState)) {\n //console.log(\"newMapViewState\", newMapViewState);\n this.setState({ mapViewState: newMapViewState });\n }\n this.mapMount();\n }\n\n // delay update until background map image has loaded\n if (this.state.isMapLoading) {\n console.log(\n `WARNING.....Map is loading...updates are not rendering!!!!!!!!!`\n );\n return;\n }\n\n // ***************************************\n //\n // Load map control\n //\n // The map control lists the named area polygons.\n // These may update via props.\n // If the count changes the control needs to be completely redrawn.\n //\n // ***************************************\n const regionGroupLayersCount = Object.keys(this.regionGroupLayers).length;\n const parentsUnionGroupLayersCount = Object.keys(\n this.parentsUnionGroupLayers\n ).length;\n\n if (\n regionGroupLayersCount !== undefined &&\n parentsUnionGroupLayersCount !== undefined\n ) {\n if (\n regionGroupLayersCount !== this.state.regionGroupLayersCount ||\n parentsUnionGroupLayersCount !== this.state.parentsUnionGroupLayersCount\n ) {\n // remove previous control and reload it\n this.controller.remove();\n\n if (!this.map.hasLayer(this.geoJSONGroupLayer)) {\n this.geoJSONGroupLayer.addTo(this.map);\n }\n if (!this.map.hasLayer(this.geoJSONControllerGroupLayer)) {\n this.geoJSONControllerGroupLayer.addTo(this.map);\n }\n\n // #WIP #TODO\n // Make a common function!!!!\n // #######################################################################\n\n // console.log(\n // `this.parentsUnionGroupLayers`,\n // this.parentsUnionGroupLayers\n // );\n\n // sort the named areas to display ordered\n\n const orderedParentsUnionGroupLayers = Object.keys(\n this.parentsUnionGroupLayers\n )\n .sort()\n .reduce((obj, key) => {\n obj[key] = this.parentsUnionGroupLayers[key];\n return obj;\n }, {});\n\n //\n // Use the custom grouped layer control, not \"L.control.layers\"\n // https://github.com/ismyrnow/leaflet-groupedlayercontrol\n // see also - https://stackoverflow.com/questions/34384905/leaflet-how-to-toggle-all-layers-either-off-or-on-at-once/34392545#34392545\n\n let groupedOverlays = {\n Markers: {\n FireFlys: this.geoJSONGroupLayer,\n Simple: this.geoJSONGroupLayerFireflySimple,\n \"FireFly ID\": this.geoJSONGroupLayerFireflyTooltips,\n Forced: this.geoJSONGroupLayerFireflyForcedTooltips,\n Controllers: this.geoJSONControllerGroupLayer,\n //\"All Named Areas\": this.geoJSONNamedAreaParentGroupLayer,\n Tags: this.geoJSONGroupLayerTags,\n //Editable: this.editableLayers,\n },\n\n // #NOTE - these are commented out to disable the group listing for now.\n // #TODO - add displaying this as a setup config option\n\n //\"Named Area Regions:\": { ...this.regionGroupLayers }, // multipolygons\n Polygons: { ...orderedParentsUnionGroupLayers }, //this.parentsUnionGroupLayers\n };\n\n // spread the objects to join the location layers to the overlay\n if (DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER) {\n groupedOverlays = {\n ...groupedOverlays,\n Locations: this.locationGroupLayers,\n //Regions: {...this.regionGroupLayers},\n };\n }\n\n // adds control group which is later updated by updateFireflyMarkersGeoJSON()\n if (DEFAULT_SHOW_FIREFLY_POLYLINE_GROUP_LAYER) {\n groupedOverlays = {\n ...groupedOverlays,\n Cables: this.polylineGroupLayers,\n //Regions: {...this.regionGroupLayers},\n };\n }\n\n const options = {\n collapsed: true,\n //exclusiveGroups: [\"Named Areas\"],\n groupsCollapsable: true, // see - https://github.com/ismyrnow/leaflet-groupedlayercontrol/pull/46\n // Show a checkbox next to non-exclusive group labels for toggling all\n groupCheckboxes: true,\n };\n\n // console.log(\n // \"loaded isMapLoading @ componentDidUpdate groupedLayer this.controller.addTo(this.map) ++++++++\"\n // );\n\n this.controller = L.control\n .groupedLayers(null, groupedOverlays, options)\n .addTo(this.map);\n\n this.setState({ regionGroupLayersCount: regionGroupLayersCount });\n this.setState({\n parentsUnionGroupLayersCount: parentsUnionGroupLayersCount,\n });\n }\n }\n\n // // respond to checkbox settings\n // // toggle display of marker group\n // if (this.markerGroupLayer) {\n // if (true) {\n // //this.props.parentState.isCheckboxMarker\n // this.map.addLayer(this.markerGroupLayer);\n // } else {\n // //this.map.addLayer(this.markerGroupLayer);\n // this.map.removeLayer(this.markerGroupLayer);\n // }\n // }\n\n // // toggle display of Fireflies group\n // if (this.refPtGroupLayer) {\n // if (true) {\n // //this.props.parentState.isCheckboxRefMarker\n // this.map.addLayer(this.refPtGroupLayer);\n // } else {\n // //this.map.addLayer(this.refPtGroupLayer);\n // this.map.removeLayer(this.refPtGroupLayer);\n // }\n // }\n\n // ****************************************************************************************\n //\n // Enable / disabled control layers, named areas etc.\n //\n // ****************************************************************************************\n\n // // use this to control layers, named areas etc.\n // if (\n // this.locationGroupLayers &&\n // this.polylineGroupLayers &&\n // this.geoJSONNamedAreaGroupLayer &&\n // this.regionGroupLayers\n // ) {\n // if (false) {\n // for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n // //console.log(\"key\", key);\n // this.map.addLayer(value);\n // }\n // } else {\n // for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n // this.map.removeLayer(value);\n // }\n // }\n\n // if (false) {\n // for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n // //console.log(\"key\", key);\n // this.map.addLayer(value);\n // }\n // } else {\n // for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n // this.map.removeLayer(value);\n // }\n // }\n\n // if (false) {\n // for (const [key, value] of Object.entries(\n // this.geoJSONNamedAreaGroupLayer\n // )) {\n // //console.log(\"key\", key);\n // this.map.addLayer(value);\n // }\n // } else {\n // for (const [key, value] of Object.entries(\n // this.geoJSONNamedAreaGroupLayer\n // )) {\n // this.map.removeLayer(value);\n // }\n // }\n\n // if (false) {\n // for (const [key, value] of Object.entries(this.regionGroupLayers)) {\n // console.log(\"regionGroupLayers key\", key);\n // this.map.addLayer(value);\n // }\n // } else {\n // for (const [key, value] of Object.entries(this.regionGroupLayers)) {\n // this.map.removeLayer(value);\n // }\n // }\n // }\n\n // // keep track of state of named area polygon display (i.e. as triggered by layer control)\n // for (const [key, value] of Object.entries(\n // this.parentsUnionGroupLayers\n // )){\n // }\n\n // console.log(\n // `this.state.isMapComponentDidMount`,\n // this.state.isMapComponentDidMount\n // );\n\n // !_isEmpty(this.props.regionPreview)\n\n // update display of named areas by mouse over on buttons\n\n // if regionPreview is defined\n if (this.props.regionPreview !== undefined) {\n // if the parentGroupLayers exist, and there are some!\n if (!_isEmpty(this.parentsUnionGroupLayers)) {\n // if the regionPreview has changed _OR_ this is the first time (or back)\n if (\n JSON.stringify(prevProps.regionPreview) !==\n JSON.stringify(this.props.regionPreview) ||\n this.state.isMapComponentDidMount\n ) {\n // refresh polygon display if component is a new mount\n if (this.state.isMapComponentDidMount) {\n this.setState({ isMapComponentDidMount: false });\n }\n\n // console.log(`prevProps.regionPreview`, prevProps.regionPreview);\n // console.log(\"this.props.regionPreview\", this.props.regionPreview);\n // console.log(\n // `this.parentsUnionGroupLayers`,\n // this.parentsUnionGroupLayers\n // );\n\n const regionPreviewList = this.props?.regionPreview;\n\n if (regionPreviewList) {\n // check every layer\n for (const [key, value] of Object.entries(\n this.parentsUnionGroupLayers\n )) {\n // flag for layer in previewList\n const isShow = regionPreviewList.some(\n (item) => item.namedArea === key\n );\n\n // if layer is displayed\n if (this.state.layerControlState[key] === true) {\n // ..but *not* in the preview list\n if (!isShow) {\n // remove it\n this.map.removeLayer(value);\n }\n // if layer is not displayed\n } else {\n //... but is in the preview list\n if (isShow) {\n // ... display it\n this.map.addLayer(value);\n }\n }\n }\n\n // regionPreviewList.forEach((region, idx) => {\n // const {\n // id: areaId,\n // spec,\n // type,\n // name,\n // namedArea: parentName,\n // } = region;\n\n // //console.log(`regionPreview region`, region);\n\n // if (spec !== undefined) {\n // if (type === \"Polygon\") {\n // // Polygon = *not* level or area wide, also not `undefined`\n // if (areaId === this.props.mineLevelId) {\n // // if layer in previewList and not displayed ...\n // if (!this.state.layerControlState[parentName]) {\n // const layer = this.parentsUnionGroupLayers[parentName];\n // if (layer !== undefined) {\n // //...show it\n // this.map.addLayer(layer);\n // }\n // }\n // }\n // }\n // }\n // });\n } else {\n for (const [key, value] of Object.entries(\n this.parentsUnionGroupLayers\n )) {\n this.state.layerControlState[key] === true\n ? this.map.addLayer(value)\n : this.map.removeLayer(value);\n }\n }\n\n // #NOTE - support for regionPreview as one object, not list of objects\n if (DEBUG_ENABLED_FALSE) {\n const {\n spec,\n type,\n name,\n namedArea: parentName,\n } = this.props.regionPreview;\n if (name !== undefined) {\n if (type === \"Polygon\") {\n // Polygon = *not* level or area wide, also not `undefined`\n const nameArray = spec.split(\":\");\n const area = nameArray[0];\n // const parentName = nameArray[1];\n if (area === this.props.mineLevelId) {\n if (!this.state.layerControlState[parentName]) {\n //console.log(\"add layer\", parentName);\n const layer = this.parentsUnionGroupLayers[parentName];\n if (layer !== undefined) {\n this.map.addLayer(layer);\n }\n }\n }\n }\n } else {\n // restore layer control state\n // console.log(\n // \"this.state.layerControlState\",\n // this.state.layerControlState\n // );\n\n for (const [key, value] of Object.entries(\n this.parentsUnionGroupLayers\n )) {\n this.state.layerControlState[key] === true\n ? this.map.addLayer(value)\n : this.map.removeLayer(value);\n }\n }\n }\n }\n }\n\n // ****************************************************************************************\n //\n // ###REVIEW ##PENDING DELETE\n // old code used in named area editing map\n // ****************************************************************************************\n\n const parentId = \"parentNamedArea\";\n\n // #REVIEW / TODO - move this filter to a common area\n const isParentDirty =\n this.props?.isDirty?.namedArea.filter(\n (namedArea) => namedArea === parentId\n ).length > 0;\n\n // ---------------------------------------------------------------\n // remove layers queued for deletion (via named areas UI)\n\n const namedAreaDeleteSelections = this.props.namedAreaDeleteSelections;\n\n let namedAreaDeleted = false; // flag to make the map update quicker after something deleted\n namedAreaDeleteSelections.forEach((selection, idx) => {\n // find the selection by id, by checking every layer in editableLayers\n\n this.editableLayers.eachLayer((layer) => {\n if (layer.feature.properties.id === selection.id) {\n console.log(\"----> namedAreaDeleteSelections remove\", selection.id);\n\n // delete from editableLayers, when named areas area updated below the 'UpdateLocalMap' will remove this item\n // and consequently from the named area list (as this populates via redux)\n this.editableLayers.removeLayer(layer); // <----------- this is the most important bit\n\n // delete from\n this.props.namedAreaClearDeleteSelections(selection);\n namedAreaDeleted = true;\n }\n });\n });\n\n // ****************************************************************************************\n //\n // Update Firefly markers\n //\n // ****************************************************************************************\n //\n\n if (\n !_isEmpty(this.props.geoJSONMarkersDataUtm) && //#WIP - disabled to test rendering update for lightingplan changes\n this.props.geoJSONMarkersDataUtm.features && // features propertie exists but does not have to have any FFs\n // #NOTE - ATM this state is not used (i.e. not set). Leave in place for #REVIEW\n !this.state.isPopupOpen && // don't update if a marker popup is open, because redraw clobber eventListener is open dlg\n (this.props.fireflyIdsUpdateList.length > 0 ||\n this.state.forceMapRefresh)\n ) {\n if (this.state.forceMapRefresh)\n console.log(`------------> FORCED REFRESH`);\n\n // keep a copy of the previous state\n // #REVIEW #TODO - is this necesary since we have already compared at the reducer?\n let prevGeoJSONMarkersData = {};\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONMarkersData = JSON.parse(\n JSON.stringify(this.props.geoJSONMarkersDataUtm)\n );\n\n if (DEBUG_ENABLED_FALSE) {\n // #REVIEW/TODO #WIP\n // check for [0,0] or out of rage points and move them to the pen\n // const transform = this.Transform(this.localPts(), this.standardPtsUtm());\n // const geoJsonTransform = [];\n\n // #WIP - test for out of range too!\n geoJSONMarkersData.features.map((value, idx) => {\n const arrayLatLng = value.geometry.coordinates.slice();\n // check if rx an un positioned marker i.e. [0,0]\n const isAllZero = arrayLatLng.every((item) => item === 0);\n if (isAllZero) {\n // console.log(\n // \"Found FF isAllZero value.properties.id -> \",\n // value.properties.id\n // );\n\n // update FF value.properties.id with new coordinate in the pen\n let randomHoldingPenCoordinate;\n if (this.holdingPen !== undefined) {\n const hasHoldingPen = this.map.hasLayer(this.holdingPen);\n if (isAllZero && hasHoldingPen) {\n randomHoldingPenCoordinate = this.randomPointInPoly(\n this.holdingPen\n );\n // console.log(\n // \"isAllZero randomHoldingPenCoordinate\",\n // randomHoldingPenCoordinate\n // );\n\n // change the value properties coordinates with new holding pen point\n //console.log(\"isAllZero value\", JSON.stringify(value));\n let newValue = JSON.parse(JSON.stringify(value));\n newValue.geometry = randomHoldingPenCoordinate.geometry;\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n // convert to Utm values\n const newPointUtm = this.convertGeoJsonPixelsToUtm(\n {\n type: \"FeatureCollection\",\n features: [newValue],\n },\n mineLevelObj\n ).features[0].geometry.coordinates.slice();\n // #REVIEW/TODo #FIX!!!!!!!!!!!! - should filter to find the id, ATM just grab first one (and only) one which comes back\n\n //console.log(\"isAllZero newPointUTtm\", newPointUTtm);\n\n // send via mqtt for change\n // #WIP....send FF update within map\n\n const changeTopic = `firefly/${newValue.properties.id}/change`;\n\n const changeMsg = {\n id: newValue.properties.id,\n mac: newValue.properties.mac,\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [newPointUtm[0], newPointUtm[1]],\n token: messageToken(),\n };\n\n //console.log(\"isAllZero changeFF\", changeMsg);\n\n // #WIP - the issue here is this sends out lots of messages until the changes is made...flooding the system.\n // need to log the send, wait for an ack, clear it.\n // disabled pending implement ack management\n if (false) {\n this.props.mqttPublish({\n topic: changeTopic,\n qos: 0,\n message: changeMsg,\n retained: false,\n });\n }\n }\n }\n }\n });\n }\n\n //\n // update the fireflies.\n\n // make a local copy\n let newFireflyIdsUpdateList = this.props.fireflyIdsUpdateList;\n\n // check for deleted FFs\n if (\n !_isEmpty(this.props.fireflyIdsUpdateList) &&\n !_isEmpty(this.props.fireflyIdsDeleteList)\n ) {\n // check if there are any FFs for deletion and if so delete it from\n // the firefly layers - this.layerlistFireflies[id]\n if (this.props.fireflyIdsDeleteList.length > 0) {\n let newLayerListFireflies = {};\n let updatedFireflyIds = [];\n for (const [key, value] of Object.entries(\n this.layerlistFireflies\n )) {\n if (this.props.fireflyIdsDeleteList.includes(key)) {\n this.map.removeLayer(value);\n // if we delete the ID don't update it\n newFireflyIdsUpdateList = newFireflyIdsUpdateList.filter(\n (ff) => ff === key\n );\n // remove FF Id from fireflyIdsUpdateList after it's been processed\n //\n updatedFireflyIds.push(key);\n } else {\n newLayerListFireflies[key] = value;\n }\n }\n // remove FF Id from fireflyIdsUpdateList\n this.props.fireflyIdsUpdateListDeleteId(updatedFireflyIds);\n this.layerlistFireflies = newLayerListFireflies;\n }\n }\n\n // now manage the FF updates - this.geoJSONMarkersData / this.geoJSONGroupLayerFireflySimple\n if (\n !_isEmpty(this.props.fireflyIdsUpdateList) ||\n this.state.forceMapRefresh\n ) {\n // update markers for geoJSON\n this.updateFireflyMarkersGeoJSON(\n this.map,\n geoJSONMarkersData,\n prevGeoJSONMarkersData,\n this.props.mineLevelId,\n newFireflyIdsUpdateList,\n this.state.forceMapRefresh\n );\n }\n\n // if doing forced map refresh reset flag\n if (this.state.forceMapRefresh) {\n this.setState({ forceMapRefresh: false });\n }\n }\n\n // ****************************************************************************************\n //\n // Update Firefly Forced markers\n //\n // ****************************************************************************************\n //\n\n if (\n !_isEmpty(this.props.geoJSONMarkersDataUtmForced) &&\n !_isEmpty(this.props.geoJSONMarkersDataUtmForced?.features)\n ) {\n // keep a copy of the previous state\n let prevGeoJSONMarkersDataForced = {};\n if (prevProps.geoJSONMarkersDataForced !== undefined) {\n prevGeoJSONMarkersDataForced = JSON.parse(\n JSON.stringify(prevProps.geoJSONMarkersDataForced)\n );\n }\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONMarkersDataForced = JSON.parse(\n JSON.stringify(this.props.geoJSONMarkersDataUtmForced)\n );\n\n if (!_isEmpty(this.props.fireflyIdsUpdateList)) {\n // update markers for geoJSON\n this.updateFireflyForcedMarkersGeoJSON(\n this.map,\n geoJSONMarkersDataForced,\n prevGeoJSONMarkersDataForced,\n this.props.mineLevelId,\n this.props.fireflyIdsUpdateList\n );\n }\n }\n\n // ****************************************************************************************\n //\n // Update controller markers\n //\n // ****************************************************************************************\n\n // const prevGeoJSONControllersUtm = JSON.stringify(\n // prevProps.geoJSONControllersUtm\n // );\n // const newGeoJSONControllersUtm = JSON.stringify(\n // this.props.geoJSONControllersUtm\n // );\n\n // // if each object has content\n // if (\n // !_isEmpty(prevGeoJSONControllersUtm) &&\n // !_isEmpty(newGeoJSONControllersUtm)\n // ) {\n // }\n\n if (\n (!_isEmpty(this.props.geoJSONControllersUtm) &&\n !_isEmpty(this.props.geoJSONControllersUtm?.features) &&\n this.props.geoJSONControllersUtm !==\n prevProps.geoJSONControllersUtm &&\n // #WIP?????????????????????????\n // is this really why???????//\n !this.state.isPopupOpen) || // don't update if a marker popup is open, because redraw clobber eventListener is open dlg\n this.state.forceMapRefresh\n ) {\n // keep a copy of the previous state\n let prevGeoJSONControllers = {};\n if (prevProps.geoJSONControllersUtm !== undefined) {\n prevGeoJSONControllers = JSON.parse(\n JSON.stringify(prevProps.geoJSONControllersUtm)\n );\n }\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONControllers = JSON.parse(\n JSON.stringify(this.props.geoJSONControllersUtm)\n );\n\n // update markers for geoJSON\n this.updateControllerMarkersGeoJSON(\n this.map,\n geoJSONControllers,\n prevGeoJSONControllers,\n this.props.mineLevelId,\n this.state.forceMapRefresh\n );\n }\n\n // ****************************************************************************************\n //\n // update named area polygons\n //\n // ****************************************************************************************\n\n // update from source data if\n // * not empty\n // * props have changed\n // _or_\n // * named areas have been locally deleted\n\n // WIP HERE - previously allowed update if (OR) namedAreaDeleted = true even if no changes to data to stop redraw of namedAreas <------\n // || namedAreaDeleted\n // ...working though?\n\n // #REVIEW/TODO - make a function out of this\n\n // incoming objects (current and prevProps) are different even though JSON content is the same.\n // compare the strings to stop unnecessary updates\n const prevGeoJSONNamedAreasUtm = JSON.stringify(\n prevProps.geoJSONNamedAreasUtm\n );\n const newGeoJSONNamedAreasUtm = JSON.stringify(\n this.props.geoJSONNamedAreasUtm\n );\n\n let isChangedgeoJSONNamedAreasUtm = false;\n\n // if each object has content\n if (\n !_isEmpty(prevGeoJSONNamedAreasUtm) &&\n !_isEmpty(newGeoJSONNamedAreasUtm)\n ) {\n // are they changed?\n isChangedgeoJSONNamedAreasUtm =\n prevGeoJSONNamedAreasUtm !== newGeoJSONNamedAreasUtm ? true : false;\n }\n\n if (\n // isChangedgeoJSONNamedAreasUtm ||\n // namedAreaDeleted\n (!_isEmpty(this.props.geoJSONNamedAreasUtm) &&\n !_isEmpty(this.props.geoJSONNamedAreasUtm?.features) &&\n this.props.geoJSONNamedAreasUtm !== prevProps.geoJSONNamedAreasUtm) ||\n namedAreaDeleted\n // || heartBeatChanged\n ) {\n // console.log(\"componentDidUpdate namedAreaHiddenSelections - updating!\");\n\n // #WIP - check if localMapState and incoming data differ\n // with view to filtering localMapState data for delete and hidden namedAreas\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONNamedAreas = JSON.parse(\n JSON.stringify(this.props.geoJSONNamedAreasUtm)\n );\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n // transform the coordinates to pixel image references\n geoJSONNamedAreas = transformGeoJsonUtmToPixels(\n geoJSONNamedAreas,\n mineLevelObj,\n 1,\n false\n );\n\n //#WIP - merge geoJSONNamedAreas and localMapState, giving priority to geoJSONNamedAreas if propertie.id is same\n //i.e. get geoJSONNamedAreas and import all\n\n const local = this.props.localMapState?.features;\n const mqtt = geoJSONNamedAreas?.features;\n\n let localIds = [];\n let mqttIds = [];\n\n if (local) {\n local.forEach((item, idx) => {\n localIds[item.properties.id] = idx;\n });\n }\n // console.log(\"componentDidUpdate local\", local);\n if (mqtt) {\n mqtt.forEach((item, idx) => {\n mqttIds[item.properties.id] = idx;\n });\n }\n\n if (!isParentDirty) {\n // update markers for geoJSON\n this.updateNamedAreasGeoJSON(\n this.map,\n geoJSONNamedAreas,\n this.props.mineLevelId\n );\n }\n\n // update localMapState with all objects in the editable layer\n if (this.map.hasLayer(this.editableLayers)) {\n // add geoJSONNamedAreaGroupLayer layer to editable layer so can edit existing/loaded polygons\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n // console.log(\n // \"Adding mqtt Named Area to this.editableLayers -> \",\n // layer._leaflet_id\n // ); // KEEP AS PERMANENT INDICATOR THAT MAP GROUPS ARE UPDATING\n this.editableLayers.addLayer(layer);\n });\n\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n\n //#REVEW/TODO - this should only happen if the shape has changed otherwise use the coordinates in the features.properties.coordinatesUtm\n // ----->\n //const transform = this.props.mineLevel.transform;\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n // <-----\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // console.log(\n // \"map componentDidUpdate this.props.localMapState - after update\",\n // JSON.stringify(geoJsonUtm)\n // );\n\n const geo = geoJsonUtm?.features;\n let geoIds = [];\n if (geo) {\n geo.forEach((item, idx) => {\n geoIds[item.properties.id] = idx;\n });\n }\n // console.log(\"componentDidUpdate geoIds\", geoIds);\n\n //#WIP - testing hide and show layers\n\n // #REVIEW/TODO\n // THIS NEEDS TO BE RE_WRITTEN TO RUN OVER ALL EDITABLE LAYERS\n //\n this.editableLayers.eachLayer((layer) => {\n // #WIP - this is failing when going from another page back to control screen\n // \"TypeError: Cannot read property 'style' of undefined\"\n if (layer.getElement() !== undefined) {\n layer.getElement().style.display = \"block\"; // this resets any hidden layer actions\n }\n });\n\n //#REVIEW/TODO - namedAreaHiddenSelections and namedAreaDeleteSelections are 'same' make function or restructure message/object\n\n const namedAreaHiddenSelections = this.props.namedAreaHideSelections;\n //#REVIEW/TODO - filter by parentId - currently ignore id\n const namedAreasHidden = namedAreaHiddenSelections.map((na) => na.id);\n // console.log(\"namedAreasHidden\", namedAreasHidden);\n\n // const namedAreaDeleteSelections = this.props.namedAreaDeleteSelections;\n // //#REVIEW/TODO - filter by parentId - currently ignore id\n // const namedAreasDeleted = namedAreaDeleteSelections.map((na) => na.id);\n // // console.log(\"namedAreasDeleted\", namedAreasDeleted);\n\n this.editableLayers.eachLayer((layer) => {\n const includesNamedAreaHidden = namedAreasHidden.includes(\n layer.feature.properties.id\n );\n // const includesNamedAreaDeleted = namedAreasDeleted.includes(\n // layer.feature.properties.id\n // );\n\n if (!includesNamedAreaHidden) {\n //\n return;\n }\n layer.getElement().style.display = \"none\";\n });\n\n this.editableLayers.bringToBack();\n this.geoJSONNamedAreaGroupLayer.bringToBack();\n }\n }\n\n //#############################################\n\n // ****************************************************************************************\n //\n // update named area parent multipolygons\n //\n // ****************************************************************************************\n\n // incoming objects (current and prevProps) are different even though JSON content is the same.\n // compare the strings to stop unnecessary updates\n // if each object has content\n\n if (\n !_isEmpty(this.props.geoJSONNamedAreaParentsUtm) &&\n !_isEmpty(this.props.geoJSONNamedAreaParentsUtm?.features) &&\n this.props.geoJSONNamedAreaParentsUtm !==\n prevProps.geoJSONNamedAreaParentsUtm\n ) {\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONNamedAreaParents = JSON.parse(\n JSON.stringify(this.props.geoJSONNamedAreaParentsUtm)\n );\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n // transform the coordinates to pixel image references\n geoJSONNamedAreaParents = transformGeoJsonUtmToPixels(\n geoJSONNamedAreaParents,\n mineLevelObj,\n 1,\n false\n );\n\n // update markers for geoJSON\n this.updateNamedAreaParentsGeoJSON(\n this.map,\n geoJSONNamedAreaParents,\n this.props.mineLevelId\n );\n }\n\n //#############################################\n }\n }\n\n updateFireflyMarkersGeoJSON(\n map,\n geoJSONMarkersData,\n prevGeoJSONMarkersData,\n mineLevelId,\n fireflyIdsUpdateList,\n forceUpdate\n ) {\n const blueMarker = {\n radius: 6,\n fillColor: \"blue\",\n };\n\n const redMarker = {\n radius: 6,\n fillColor: \"red\",\n };\n\n const orangeMarker = {\n radius: 6,\n fillColor: \"orange\",\n };\n\n const greenMarker = {\n radius: 6,\n fillColor: \"green\",\n };\n\n if (false) {\n // convert previous marker data to keyed object\n let prevMarkerData = {};\n if (prevGeoJSONMarkersData?.features !== undefined) {\n prevGeoJSONMarkersData.features.map((feature, idx) => {\n const {\n properties: { id },\n } = feature;\n prevMarkerData[id] = feature;\n });\n }\n\n //console.log(\"FF_marker before calc\", prevMarkerData);\n\n // update....\n geoJSONMarkersData.features.map((feature, idx) => {\n const { properties } = feature;\n\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n z,\n utm_zone_number,\n utm_zone_letter,\n fireflyNote,\n //color,\n light,\n controllerMode,\n deviceStatus,\n timestamp,\n ups_id,\n mac,\n } = properties;\n\n // const isChanged = !_isEqual(prevMarkerData[id], feature);\n\n const isChanged =\n JSON.stringify(prevMarkerData[id]) !== JSON.stringify(feature);\n\n // console.log(\n // \"FF_Marker JSON.stringify(prevMarkerData[id])\",\n // JSON.stringify(prevMarkerData[id])\n // );\n\n // console.log(\"FF_Marker JSON.stringify(feature)\", JSON.stringify(feature));\n\n // console.log(\"FF_Marker isChanged\", isChanged);\n\n // #DEBUG\n // if (id === \"DMLZ_Extraction:P17:1\") {\n // console.log(\"xxx P17:1 isChanged\", isChanged);\n // }\n // if (id === \"DMLZ_Extraction:P16:2\") {\n // console.log(\"xxx P16:2 isChanged\", isChanged);\n // }\n // if (id === \"DMLZ_Extraction:P18:2\") {\n // console.log(\"xxx P18:2 isChanged\", isChanged);\n // }\n\n // console.log(\"isChanged\", prevMarkerData[id]);\n // console.log(\"isChanged\", feature);\n // console.log(\n // `isChanged ${id} : ${isChanged} : old: ${prevMarkerData[id]?.properties?.timestamp}`\n // );\n // console.log(\n // `isChanged ${id} : ${isChanged} : new: ${feature?.properties?.timestamp}`\n // );\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n const {\n brightness,\n color,\n marker,\n led_state,\n off_time,\n on_time,\n train,\n } = light;\n\n // Make sure there is a layergroup for new markers.\n // layer groups are defined by LOCATION.\n // If a new LOCATION is added, check and add if necessary.\n //\n // Note: @28Oct20 - layergroups are not used ATM. This is development work\n // which has not been released.\n //\n if (this.map.hasLayer(this[location])) {\n } else {\n this[location] = L.featureGroup().addTo(this.map);\n this.locationGroupLayers[location] = this[location];\n }\n\n if (this.layerlistFireflies[id]) {\n // DEBUG ??????????????????????\n // if (id === \"DMLZ_Extraction:P17:1\") {\n // console.log(\n // \"xxx P17:1 this.layerlistFireflies[id]\",\n // this.layerlistFireflies[id]?.feature.geometry?.coordinates,\n // new Date().getTime()\n // );\n // }\n if (isChanged) {\n // if (id === \"DMLZ_Extraction:P17:1\") {\n // console.log(\n // \"xxx P17:1 this.layerlistFireflies[id] isChanged\",\n // new Date().getTime()\n // );\n // }\n\n //\n //\n const { svgIcon, svgStyle } = markerDefinition(feature);\n const currentZoom = this.map.getZoom();\n\n this.layerlistFireflies[id].setIcon(\n makeIcon(svgIcon, svgStyle, currentZoom)\n );\n\n // update popup content\n if (false) {\n this.layerlistFireflies[id].getPopup().setContent(\n `
Firefly: ${id}
\n
Controller: ${ups_id}
\n\n
\n
${this.testExternalStr} ${area}:${location}:${position}
\n
Geom: E:${round(easting, 2)} N:${round(\n northing,\n 2\n )} Z${Math.trunc(\n z\n )} ${utm_zone_number} ${utm_zone_letter}
\n
Image: X:${X} Y:${Y}
\n
Color: Requested ${color.plan}, Reported ${\n color.status\n }
\n
Last Report: ${lastStatusReport}
`\n );\n } else if (false) {\n const popupInfo = `${id}
${id}

`;\n this.layerlistFireflies[id].getPopup().setContent(popupInfo);\n } else {\n //console.log(\"FF_marker popup update\");\n\n // #WIP\n // collect events for this ff.\n // This is used to indicate which light is toggled in the popup and to\n // know which priority event to fire in the attached eventListener.\n const fireflyNamedAreaId = createFireflyNamedAreaId(id);\n\n const namedAreaEventForFirefly = this.props.namedAreaEvents?.find(\n (event) => event.id.includes(fireflyNamedAreaId)\n );\n\n const fireflyMarkerPopup = renderToString(\n \n );\n\n // after sending forcedClickList to the popup, clear it\n // acknowledge click while processing\n let newForcedClickList = [...this.state.forcedClickList];\n if (newForcedClickList.includes(id)) {\n newForcedClickList = newForcedClickList.filter(\n (item) => item !== id\n );\n this.setState({ forcedClickList: newForcedClickList });\n }\n\n // update popup content\n this.layerlistFireflies[id]\n .getPopup()\n .setContent(fireflyMarkerPopup);\n\n // if (id === \"DMLZ_Extraction:P17:1\") {\n // console.log(`P17:1 update content ${id}`);\n // }\n // re-attached the event listener\n // this.layerlistFireflies[id].on(\"popupopen\", (event) => {\n // var marker = event.popup._source.feature.properties.id;\n // console.log(\"popup update marker\", marker);\n\n // console.log(\"popup update event.target\", event.target);\n // var popUp = event.target.getPopup();\n // console.log(\"popup update popup\", popUp);\n // console.log(\"popup update getElement\", popUp.getElement());\n // console.log(\n // \"popup update getElement.querySelector\",\n // popUp.getElement().querySelector(\".popupFireflyMarkerLink\")\n // );\n\n // popUp\n // .getElement()\n // .querySelector(\".popupFireflyMarkerLink\")\n // .addEventListener(\"click\", (e) => {\n // console.log(\n // \"update clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"dataId \",\n // e.target.getAttribute(\"dataId\")\n // );\n\n // const id = e.target.getAttribute(\"dataId\");\n // if (!_isEmpty(id)) {\n // this.props.goto(`/admin/firefly/${id}`);\n // }\n // });\n // });\n }\n }\n //??????????????????????\n } else if (feature.properties.area === mineLevelId) {\n // if it's not in the layer list, and is in the area i.e. `mineLevelId` add it..........\n //\n // Note - pointToLayer and onEachFeature are defined in ComponentDidMount() and\n // .addData() runs `onEachFeatureFirefly` which adds the feature to layerlistFireflies[]\n\n this.geoJSONGroupLayer.addData(geoJSONMarkersData.features[idx]);\n }\n });\n } else {\n // #WIP - updated version\n\n // tracks fireflies which have been updated. These should be deleted from the list.\n let updatedFireflyIds = [];\n\n // update....\n geoJSONMarkersData.features.map((feature, idx) => {\n const { properties } = feature;\n\n const { id, location } = properties;\n\n // Make sure there is a layergroup for new markers.\n // layer groups are defined by LOCATION.\n // If a new LOCATION is added, check and add if necessary.\n\n if (DEFAULT_SHOW_FIREFLY_LOCATION_GROUP_LAYER) {\n if (this.map.hasLayer(this[location])) {\n } else {\n this[location] = L.featureGroup().addTo(this.map);\n this.locationGroupLayers[location] = this[location];\n }\n }\n\n if (this.layerlistFireflies[id]) {\n if (fireflyIdsUpdateList.includes(id) || forceUpdate) {\n // remove FF Id from fireflyIdsUpdateList - it is being processed\n //\n updatedFireflyIds.push(id);\n\n const {\n area,\n position,\n easting,\n northing,\n z,\n utm_zone_number,\n utm_zone_letter,\n fireflyNote,\n //color,\n light,\n controllerMode,\n timestamp,\n ups_id,\n mac,\n deviceStatus,\n } = properties;\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n const {\n brightness,\n color,\n marker,\n led_state,\n off_time,\n on_time,\n train,\n } = light;\n\n // #WIP - check if moved?\n // #NOTE - for 1st\n // see #fireflyIdsUpdateList - src/components/WebWorker/reducer.js\n //\n\n // console.log(\n // `FIREFLY UPDATED!!! id`,\n // id,\n // fireflyIdsUpdateList,\n // forceUpdate\n // );\n\n if (true) {\n var newLatLng = new L.LatLng(Y, X);\n this.layerlistFireflies[id].setLatLng(newLatLng);\n }\n\n //\n const { svgIcon, svgStyle } = markerDefinition(feature);\n const currentZoom = this.map.getZoom();\n\n this.layerlistFireflies[id].setIcon(\n makeIcon(svgIcon, svgStyle, currentZoom)\n );\n\n //console.log(`FIREFLY MARKER_REDRAW ID `, id);\n\n // #WIP\n // collect events for this ff.\n // This is used to indicate which light is toggled in the popup and to\n // know which priority event to fire in the attached eventListener.\n // const forcedLightEventInfo = {\n // active: true,\n // light: {\n // color: \"yellow\",\n // state: \"ON\",\n // brightness: 70,\n // on_time: 10,\n // off_time: 10,\n // train: 10,\n // },\n // };\n\n const fireflyNamedAreaId = createFireflyNamedAreaId(id);\n\n const namedAreaEventForFirefly = this.props.namedAreaEvents?.find(\n (event) => event.id.includes(fireflyNamedAreaId)\n );\n\n // console.log(\n // `fireflyMarkerPopup TWO fireflyNamedAreaId`,\n // fireflyNamedAreaId,\n // namedAreaEventForFirefly,\n // this.props.namedAreaEvents,\n // properties,\n // this.layerlistFireflies[id]\n // );\n\n // update popup content\n const fireflyMarkerPopup = renderToString(\n \n );\n\n // after sending forcedClickList to the popup, clear it\n // acknowledge click while processing\n let newForcedClickList = [...this.state.forcedClickList];\n if (newForcedClickList.includes(id)) {\n newForcedClickList = newForcedClickList.filter(\n (item) => item !== id\n );\n this.setState({ forcedClickList: newForcedClickList });\n }\n\n // Update popup content\n // If it is open close it and reopen with updated content\n //\n const isPopupOpen = this.layerlistFireflies[id].isPopupOpen();\n if (isPopupOpen) {\n this.layerlistFireflies[id].closePopup();\n this.layerlistFireflies[id]\n .getPopup()\n // https://leafletjs.com/reference-1.7.1.html#popup-setcontent\n .setContent(fireflyMarkerPopup);\n this.layerlistFireflies[id].openPopup();\n } else {\n this.layerlistFireflies[id]\n .getPopup()\n // https://leafletjs.com/reference-1.7.1.html#popup-setcontent\n .setContent(fireflyMarkerPopup);\n }\n }\n //??????????????????????\n } else if (feature.properties.area === mineLevelId) {\n //console.log(\"FF_UPDATE -> ADD TO LAYER LIST ...\", id);\n // if it's not in the layer list, and is in the area i.e. `mineLevelId` add it..........\n //\n // Note - pointToLayer and onEachFeature are defined in ComponentDidMount() and\n // .addData() runs `onEachFeatureFirefly` which adds the feature to layerlistFireflies[]\n\n this.geoJSONGroupLayer.addData(geoJSONMarkersData.features[idx]);\n }\n });\n\n // after processing the list send a delete processed items from the update list\n this.props.fireflyIdsUpdateListDeleteId(updatedFireflyIds);\n\n if (DEFAULT_SHOW_FIREFLY_POLYLINE_GROUP_LAYER) {\n // After update firefly, recalculate all polylines.\n // Delete the control layer, delete the layers from the map.\n // Re-build both map and control layers.\n //\n // #REVIEW\n // - could make this more efficient by tracking which FFs have changed\n\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n this.controller.removeLayer(value);\n this.map.removeLayer(value);\n }\n\n this.polylineGroupLayers = {};\n\n // step through the list of locationGroupLayers\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n // create an object with the posObject[position] = latlng coordinates\n let posObject = {};\n\n // loop each layer - #REVIEW - this could be labourious - perhaps only do if selected to display?\n // eslint-disable-next-line no-loop-func\n value.eachLayer(function (layer) {\n posObject[layer.feature.properties.position] = layer.getLatLng();\n });\n\n // sort the posObject by position order (i.e. object key) so line draws from position 1 -> n\n\n // see - https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key\n const ordered = {};\n Object.keys(posObject)\n .sort()\n .forEach(function (key) {\n ordered[key] = posObject[key];\n });\n\n // plot a polyline using ordered array of values\n // create name object from layer name (i.e. key is the POSITION)\n const layerName = \"poly_\" + key;\n this[layerName] = L.polyline(Object.values(ordered)).addTo(this.map); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n\n // add this layer to layer group to add to control layer later\n this.polylineGroupLayers[layerName] = this[layerName];\n }\n\n // #NOTE\n // ..this will need to be updated for the groupedLayer control\n //\n //\n // add group to overlays by iterating over the object\n // https://stackoverflow.com/questions/55471295/adding-multiple-overlays-to-leaflets-layers-control\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n this.controller.addOverlay(value, key, \"Cables\"); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n }\n }\n\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n }\n }\n\n updateFireflyForcedMarkersGeoJSON(\n map,\n geoJSONMarkersDataForced,\n prevGeoJSONMarkersDataForced,\n mineLevelId,\n fireflyIdsUpdateList\n ) {\n // FORCED light data is different to Firefly data. We display _ALL_ of the geoJSONMarkersDataForced\n // with a tooltip. There is not need to e.g. `this.layerlistFirefliesForced[id].unbindTooltip();`\n // unbind the tooltip - we just remove the layer completely.\n //\n\n if (geoJSONMarkersDataForced.features.length < 1) {\n // if no data, reinitialise layer list\n this.layerlistFirefliesForced = {};\n // remove all layers\n if (this.geoJSONGroupLayerFireflyForcedTooltips) {\n this.geoJSONGroupLayerFireflyForcedTooltips.eachLayer((layer) => {\n this.geoJSONGroupLayerFireflyForcedTooltips.removeLayer(layer);\n });\n }\n }\n // if there is data in `geoJSONMarkersDataForced`\n else {\n // create a new the force lights layer list\n let newLayerlist = {};\n\n // compare the keys in the layer list with the new data\n const prevLayerlistFirefliesForcedIds = Object.keys(\n this.layerlistFirefliesForced\n );\n const geoJSONMarkersDataForcedIds = geoJSONMarkersDataForced.features.map(\n (feature) => feature.id\n );\n // check previous layers\n prevLayerlistFirefliesForcedIds.forEach((id) => {\n // to see if this is still valid data\n if (geoJSONMarkersDataForcedIds.includes(id)) {\n // if so, keep it\n newLayerlist[id] = this.layerlistFirefliesForced[id];\n }\n // if not, delete it from current layer group\n else {\n this.geoJSONGroupLayerFireflyForcedTooltips.removeLayer(\n this.layerlistFirefliesForced[id]\n );\n }\n });\n // now, update the layer list. We have removed old data.\n this.layerlistFirefliesForced = newLayerlist;\n\n // At this point we have `this.layerlistFirefliesForced` containing\n // all current Force markers.\n // This leaves the task to add those which are new....\n //\n // step through `geoJSONMarkersDataForced` to update ....\n geoJSONMarkersDataForced.features.map((feature, idx) => {\n const { properties } = feature;\n const { id, location, position, forced } = properties;\n\n // if `this.layerlistFirefliesForced[id]` does not exist for this Force,\n // and area is correct -> addData()\n if (\n !this.layerlistFirefliesForced[id] &&\n feature.properties.area === mineLevelId\n ) {\n // if it's not in the layer list, and is in the area i.e. `mineLevelId` add it..........\n //\n // Note - pointToLayer and onEachFeature are defined in ComponentDidMount() and\n // .addData() runs `onEachFeatureFireflyForcedToolTips` which adds the feature to layerlistFirefliesForced[]\n\n this.geoJSONGroupLayerFireflyForcedTooltips.addData(\n geoJSONMarkersDataForced.features[idx]\n );\n }\n });\n }\n }\n\n // WIP\n updateControllerMarkersGeoJSON(\n map,\n geoJSONControllers,\n prevJSONControllers,\n mineLevelId,\n forceUpdate\n ) {\n // map the geoJSONControllers and delete all the markers who have changed propertie\n // and accumulate these markers and\n // add them all at the end\n\n // convert previous marker data to keyed object\n let prevMarkerData = {};\n if (prevJSONControllers?.features !== undefined) {\n prevJSONControllers.features.map((feature, idx) => {\n const {\n properties: { id },\n } = feature;\n prevMarkerData[id] = feature;\n });\n }\n\n // find the fireflies which have changed in geojsonMarkerOptions object\n geoJSONControllers.features.map((feature, idx) => {\n const { properties } = feature;\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_number,\n utm_zone_letter,\n z,\n color,\n timestamp,\n mode,\n master,\n //\n deviceStatus,\n user_relay,\n } = properties;\n\n //console.log(\"xxx deviceStatus\", deviceStatus);\n\n let isChanged = !_isEqual(\n omitDeep(prevMarkerData[id], [\"timestamp\"]),\n omitDeep(feature, [\"timestamp\"])\n );\n\n // console.log(`MARKER_REDRAW isChanged`, isChanged);\n // if (isChanged) {\n // console.log(`MARKER_REDRAW prevMarkerData[id]`, prevMarkerData[id]);\n // console.log(`MARKER_REDRAW feature`, feature);\n // }\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n // status checks\n let status = \"OK\"; // lets assume everything is OK. Ever the optimist eh?!\n\n if (deviceStatus.includes(StatusEnum.API_FETCH)) {\n status = \"API_FETCH\";\n }\n\n if (\n deviceStatus.includes(StatusEnum.NO_STATUS_REPORT) ||\n deviceStatus.includes(StatusEnum.TIMEOUT)\n ) {\n status = \"INACTIVE_CONTROLLER\";\n }\n\n let isUpsBatteryOnFault = false;\n if (deviceStatus.includes(StatusEnum.CONTROLLER_ON_BATTERY)) {\n isUpsBatteryOnFault = true;\n }\n\n let isUpsNetworkFault = false;\n if (deviceStatus.includes(StatusEnum.CONTROLLER_NETWORK_FAULT)) {\n isUpsNetworkFault = true;\n }\n\n const isSirenActive = isKthBitSet(user_relay, 1);\n if (isSirenActive) {\n status = \"RELAY_SIREN\";\n }\n\n // _#DEMO_MODE - force regular updates irrespective of real changes\n if (\n !isSirenActive &&\n (this.props.userSettings?.feature?.includes(\"showDemoMode\") ||\n isDemoMode())\n ) {\n status = \"OK\";\n }\n\n // console.log(`MARKER_REDRAW isChanged`, isChanged);\n // console.log(`MARKER_REDRAW status !== \"OK\"`, status !== \"OK\");\n // console.log(`MARKER_REDRAW forceUpdate`, forceUpdate);\n\n // controller color is set but whether there are faults and mode settings\n //let upsFaultmsg = this.props.faults;\n\n //console.log(\"xxx Controller MARKER_REDRAW upsFaultmsg\", upsFaultmsg);\n // const isUpsNetworkFault = upsFaultmsg.some(\n // (fault) =>\n // fault.type === \"network\" &&\n // fault.active &&\n // fault.id === id &&\n // fault.area === area\n // );\n\n // if (isUpsNetworkFault) {\n // status = \"NETWORK_FAULT\";\n // }\n\n // // #Note - this is probably overkill to detect battery ON for controller\n // // but making sure!\n // const isUpsBatteryOnFault = upsFaultmsg.some(\n // (fault) =>\n // fault.type === \"battery\" &&\n // fault.active &&\n // fault.subtype === \"charge\" &&\n // fault.description.includes(\"ON\") &&\n // fault.id === id &&\n // fault.area === area\n // );\n\n if (this.layerlistControllers[id]) {\n if (isChanged || status !== \"OK\" || forceUpdate) {\n // ####SVG Marker###\n // default\n let svgIcon = \"SquareMarker\";\n let svgStyle = { stroke: \"grey\", fill: \"grey\" };\n\n // CONTROLLER UPS MODE SETTINGS\n // * isInCommission\n // * isMaster\n const isInCommission = mode.toLowerCase() === \"commission\";\n const isMaster = master ? true : false;\n\n // isInCommission - change icon\n isInCommission\n ? (svgIcon = \"StarMarker\")\n : (svgIcon = \"SquareMarker\");\n\n // isMaster - change color\n switch (isMaster) {\n case true:\n default:\n svgStyle = { stroke: \"blue\", fill: \"blue\" };\n break;\n case false:\n svgStyle = { stroke: \"brown\", fill: \"brown\" };\n break;\n }\n\n // CONTROLLER UPS FAULT SETTINGS\n // * isUpsNetworkFault\n // * isUpsBatteryOnFault i.e. status === \"CONTROLLER_ON_BATTERY\"\n // override color if network fault &/or battery fault\n // ups icon normal = blue/blue\n // network fault = outline red, fill blue, SquareMarker\n // battery fault = outline red, fill orange, DiamondMarker\n\n if (isUpsNetworkFault) {\n if (isUpsBatteryOnFault) {\n svgIcon = \"DiamondMarker\";\n svgStyle = { stroke: \"red\", fill: \"orange\" };\n } else {\n svgIcon = \"SquareMarker\";\n svgStyle = { stroke: \"blue\", fill: \"red\" };\n }\n } else {\n if (isUpsBatteryOnFault) {\n svgIcon = \"DiamondMarker\";\n svgStyle = { stroke: \"blue\", fill: \"orange\" };\n }\n }\n\n // #NOTE\n // #WIP\n // Status switch is used for firefly. The checks above should be moved\n // into the case below.\n\n switch (status) {\n case \"RELAY_SIREN\":\n svgIcon = \"RelaySirenMarker\";\n break;\n case \"API_FETCH\":\n svgIcon = \"TriangleMarker\";\n break;\n\n case \"INACTIVE_CONTROLLER\": // aka UPS_TIMEOUT\n svgStyle = { stroke: \"fuchsia\", fill: \"black\" };\n svgIcon = \"HourGlassMarker\";\n break;\n default:\n break;\n }\n\n const currentZoom = this.map.getZoom();\n\n this.layerlistControllers[id].setIcon(\n makeIcon(svgIcon, svgStyle, currentZoom)\n );\n\n //console.log(`CONTROLLER MARKER_REDRAW ID `, id);\n\n // update popup content\n if (false) {\n this.layerlistControllers[id].getPopup().setContent(\n `
Controller: ${id}
\n
\n
${this.testExternalStr} ${area}
\n
Geom: E:${round(easting, 2)} N:${round(\n northing,\n 2\n )} Z${Math.trunc(z)} ${utm_zone_number} ${utm_zone_letter}
\n
Image: X:${X} Y:${Y}
\n
Color: ${color}
\n
Last Report: ${lastStatusReport}
`\n );\n } else {\n const controllerMarkerPopup = renderToString(\n \n );\n\n // Update popup content\n // If it is open close it and reopen with updated content\n //\n const isPopupOpen = this.layerlistControllers[id].isPopupOpen();\n if (isPopupOpen) {\n this.layerlistControllers[id].closePopup();\n this.layerlistControllers[id]\n .getPopup()\n // https://leafletjs.com/reference-1.7.1.html#popup-setcontent\n .setContent(controllerMarkerPopup);\n this.layerlistControllers[id].openPopup();\n } else {\n this.layerlistControllers[id]\n .getPopup()\n .setContent(controllerMarkerPopup);\n }\n }\n }\n } else if (properties.area === mineLevelId) {\n // if it's not in the layer list, and is in the area i.e. `mineLevelId` add it..........\n //\n // Note - pointToLayer and onEachFeature are defined in ComponentDidMount() and\n // .addData() runs `onEachFeatureController` which adds the feature to layerlistControllers[]\n this.geoJSONControllerGroupLayer.addData(\n geoJSONControllers.features[idx]\n );\n }\n });\n }\n\n updateNamedAreasGeoJSON(map, geoJSONPolygonData, mineLevelId) {\n // #TODO - !\n // map the geoJSONPolygonData and delete all the shapes who have changed propertie\n // and accumulate these shapes\n // add them all at the end\n\n // check if a named area has been removed\n // get list of IDs for current named area (i.e. layers)\n const layersIds = Object.keys(this.layerlistNamedAreas);\n\n // get the Ids for the incoming update of named area data\n let namedAreaIds = [];\n for (const namedArea in geoJSONPolygonData.features) {\n namedAreaIds.push(geoJSONPolygonData.features[namedArea].properties.id);\n }\n\n // check for a difference\n // filter each item and return it if it is *not* in the namedAreas\n const inLayerNotInNamedArea = layersIds.filter(\n (i) => !namedAreaIds.includes(i)\n );\n\n inLayerNotInNamedArea.forEach((layer, idx) => {\n // delete any layers which are in layersIds but *not* in namedAreaIds\n // remove the layer from layer groups\n this.editableLayers.removeLayer(this.layerlistNamedAreas[layer]);\n this.geoJSONNamedAreaGroupLayer.removeLayer(\n this.layerlistNamedAreas[layer]\n );\n // to be really sure remove it from the map completely\n this.map.removeLayer(this.layerlistNamedAreas[layer]);\n // delete the layer from the list\n delete this.layerlistNamedAreas[layer];\n // update localMapstate\n });\n\n // find the named areas which have changed in geoJSONPolygonData object\n geoJSONPolygonData.features.map(({ properties }, idx) => {\n const {\n id,\n area,\n parent,\n type,\n name,\n parent_name,\n sub_type = \"region\",\n } = properties;\n\n //console.log(\"geoJSONPolygonData properties\", properties);\n\n // if the shape is not in the layer list\n if (!this.layerlistNamedAreas[id]) {\n // add it\n // note pointToLayer and onEachFeature are defined in ComponentDidMount() <--- #REVIEW - is it? i.e. for namedArea?\n\n this.geoJSONNamedAreaGroupLayer.addData(\n geoJSONPolygonData.features[idx]\n );\n } else {\n // if the shape exists but has changed, update it\n\n // #WIP - should also review updates to shape coordinates\n\n // AFAIK the only way to update is to go through every layer until finding the match!\n // thankfully there are not many layers for namedAreas\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n if (layer === this.layerlistNamedAreas[id]) {\n layer.feature.properties = properties;\n }\n });\n }\n\n // create/update a union of named area polygon shapes\n if (\n type !== \"LEVEL_WIDE\" &&\n type !== \"ALL_AREAS\" &&\n area === mineLevelId\n ) {\n // console.log(\"union ----------------------\");\n // console.log(\"union parent, type\", parent, type, area);\n\n const parentsUnionGroupLayersCount = Object.keys(\n this.parentsUnionGroupLayers\n ).length;\n\n const parentName =\n parent_name.length > 0 ? parent_name : parent.replace(`${area}:`, \"\");\n\n // #NOTE - VERY USEFUL DEBUG. DO NOT DELETE\n if (DEBUG_ENABLED_FALSE) {\n console.log(\n \"union parentName, parentsUnionGroupLayersCount, layerlistNamedAreas\",\n parentName,\n parentsUnionGroupLayersCount,\n this.layerlistNamedAreas\n );\n }\n\n // if the shape is not in the parentsUnionGroupLayers layer list or the layerlist count has changed\n if (\n !this.parentsUnionGroupLayers[parentName] ||\n parentsUnionGroupLayersCount !==\n this.state.parentsUnionGroupLayersCount\n ) {\n // add it\n for (const [key, value] of Object.entries(this.layerlistNamedAreas)) {\n // console.log(\"union key \", key);\n\n const {\n feature: {\n properties: { type, area, name, sub_type },\n },\n } = value;\n\n if (DEBUG_ENABLED_FALSE) {\n console.log(\n \"union this.layerlistNamedAreas -> area, name, type, sub_type\",\n area,\n name,\n type,\n sub_type\n );\n }\n\n if (\n type !== \"LEVEL_WIDE\" &&\n type !== \"ALL_AREAS\" &&\n area === mineLevelId &&\n key.includes(parent)\n ) {\n // make a layer group per parent\n if (this[parent] === undefined) {\n this[parent] = new L.LayerGroup();\n }\n\n value.addTo(this[parent]);\n }\n }\n\n // #NOTE - VERY USEFUL DEBUG. DO NOT DELETE\n if (DEBUG_ENABLED_FALSE) {\n console.log(\n \"union unify paret -> this[parent].getLayers\",\n parent,\n this[parent].getLayers()\n );\n }\n\n let layer = unify(this[parent].getLayers());\n const namedAreaPolygonPopup = renderToString(\n \n );\n layer.bindPopup(namedAreaPolygonPopup);\n layer.on(\"popupclose\", (event) => {\n this.setState({ isPopupOpen: false });\n });\n layer.on(\"popupopen\", (event) => {\n // #WIP - disable popup open re-rendering?\n if (false) {\n this.setState({ isPopupOpen: true });\n }\n\n //console.log(`namedAreaPolygonPopup event`, event);\n\n var namedAreaParent = event.popup._source.feature.properties.parent;\n var popUp = event.target.getPopup();\n\n // added eventListener to controller marker content\n // see - src/components/Map/NamedAreaPolygonPopup.js\n popUp\n .getElement()\n .querySelector(\".popupNamedAreaPolygon\")\n .addEventListener(\"click\", (e) => {\n console.log(\n \"clicked edit on polygon: \",\n e,\n \"target: \",\n e.target,\n \"dataid \",\n e.target.getAttribute(\"dataid\")\n );\n\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n this.props.goto(`/admin/named-area/${id}`);\n } else {\n this.props.goto(`/admin/named-area/`);\n }\n });\n\n // *************************\n });\n // #NOTE - VERY USEFUL DEBUG. DO NOT DELETE\n if (DEBUG_ENABLED_FALSE) {\n console.log(\"union unify layer\", layer);\n }\n this.parentsUnionGroupLayers[parentName] = layer;\n } else {\n // update?\n }\n }\n });\n\n // update leaflet id to properties (used to delete.edit shapes in local state) <--- #REVIEW - is it? may not be necessary now\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n layer.feature.properties._leaflet_id = layer._leaflet_id;\n layer.bindPopup(`
geoJSONNamedAreaGroupLayer
`);\n //console.log(`geoJSONNamedAreaGroupLayer`, layer);\n });\n }\n\n updateNamedAreaParentsGeoJSON(map, geoJSONPolygonData, mineLevelId) {\n // find the named areas which have changed in geoJSONPolygonData object\n geoJSONPolygonData.features.map((feature, idx) => {\n const { properties } = feature;\n const { id, area, name } = properties;\n\n if (this.map.hasLayer(this[name])) {\n } else if (properties.area === mineLevelId) {\n this[name] = L.featureGroup(); //.addTo(this.map);\n this.regionGroupLayers[name] = this[name];\n }\n\n // if the shape is not in the layer list\n if (this.layerlistNamedAreaParents[id]) {\n // #WIP update it .............\n //\n // Leave this space for potential updates - what?\n //\n //\n //\n } else if (properties.area === mineLevelId) {\n // AFAIK the only way to update is to go through every layer until finding the match!\n // thankfully there are not many layers for namedAreas\n // this.geoJSONNamedAreaParentGroupLayer.eachLayer((layer) => {\n // if (layer === this.layerlistNamedAreaParents[id]) {\n // layer.feature.properties = properties;\n // }\n // });\n this.geoJSONNamedAreaParentGroupLayer.addData(\n geoJSONPolygonData.features[idx]\n );\n }\n });\n\n // // update leaflet id to properties (used to delete.edit shapes in local state) <--- #REVIEW - is it? may not be necessary now\n // this.geoJSONNamedAreaParentGroupLayer.eachLayer((layer) => {\n // layer.feature.properties._leaflet_id = layer._leaflet_id;\n // });\n }\n\n // heartBeat = () => {\n // const heartBeat = this.state.heartBeat;\n // //console.log(\"heartBeat\", heartBeat);\n // this.setState({ heartBeat: !heartBeat });\n // };\n\n render() {\n const { render, showMap, mineLevel = {} } = this.props;\n const { isMapLoading } = this.state;\n\n const mapId = \"map-\" + render;\n\n const { legend: isShowLegend } = this.props.namedAreaDisplaySettings;\n\n const visibility =\n showMap !== true ? { display: \"none\" } : { display: \"block\" };\n\n const showLegend = isShowLegend\n ? undefined\n : { minHeight: \"calc(95vh - 320px)\" };\n\n const {\n image_info: { backgroundColor },\n } = mineLevel;\n\n const bgColor = backgroundColor\n ? `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`\n : \"green\";\n\n return (\n <>\n \n
\n \n {/*
*/}\n
\n \n\n {/* testing loading image by having image in a separte part of the dom */}\n {/* {\n console.log(`loaded image `, this.state.mapSrc);\n this.setState({ isMapLoaded: true });\n }}\n /> */}\n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const mineLevel = getAreaById(state, props.mineLevelId);\n\n const transformPixelsToUtm = mineLevel?.transformPixelsToUtm;\n\n const markersData = getMapState(state);\n\n // Firefly coordinates\n let geoJSONMarkersDataUtm = getFireflyCoordinatesByAreaId(\n state,\n props.mineLevelId\n );\n\n // #DEBUG - setup empty layer\n //geoJSONMarkersDataUtm = [];\n\n // Forced Firefly coordinates\n let geoJSONMarkersDataUtmForced = getFireflyCoordinatesForcedByAreaId(\n state,\n props.mineLevelId\n );\n\n // #DEBUG - setup empty layer\n geoJSONMarkersDataUtmForced = [];\n\n // Firefly update changes\n const fireflyIdsUpdateList = getFireflyIdsUpdateListByArea(\n state,\n props.mineLevelId\n );\n\n // Firefly deletetions\n const fireflyIdsDeleteList = getFireflyIdsDeleteListByArea(\n state,\n props.mineLevelId\n );\n\n // Controller coordinates\n const geoJSONControllersUtm = getControllerCoordinatesByAreaId(\n state,\n props.mineLevelId\n );\n\n // Named Area polygons\n let geoJSONNamedAreasUtm = getNamedAreaInfos(state);\n\n // #DEBUG - setup empty layer\n //geoJSONNamedAreasUtm = [];\n\n let geoJSONNamedAreaParentsUtm = getNamedAreaParentInfos(state);\n\n // #DEBUG - setup empty layer\n //geoJSONNamedAreaParentsUtm = [];\n\n const namedAreaDeleteSelections = getNamedAreaDeleteSelections(state);\n const namedAreaHideSelections = getNamedAreaHideSelections(state);\n const namedAreaDisplaySettings = getNamedAreaDisplaySettings(state);\n\n const localMapState = GetLocalMap(state);\n const isDirty = getIsDirty(state);\n\n const faults = getFaults(state) || [];\n\n const regionPreview = getRegionPreviewListByAreaId(state, props.mineLevelId); // { spec, type, name, namedArea };\n\n // check for image files\n const folderFilesList = getFolderFileNamesListById(state, \"areas\");\n\n // message banner support\n const { messageBanners } = state.alarmButton;\n\n // deviceTimestamps for checking timeout\n\n const timedOutDevices = getTimedOutDevices(state);\n\n const isPokeTheWorker = isOnOffPokeTheWorker(state);\n\n const namedAreaEvents = getNamedAreaEventsByAreaId(state, props.mineLevelId);\n\n // user roles\n\n const userSuper = isUserSuper(state);\n const userAdmin = isUserAdmin(state);\n const userUser = isUserUser(state);\n const userGuest = isUserGuest(state);\n\n // map image from state\n // this has previously been loaded and saved to the Settings reducer state\n const mapImageFromState = getMapImageById(state, props.mineLevelId);\n\n return {\n mineLevel,\n markersData,\n geoJSONMarkersDataUtm,\n geoJSONMarkersDataUtmForced,\n localMapState,\n geoJSONNamedAreasUtm,\n namedAreaDeleteSelections,\n namedAreaHideSelections,\n isDirty,\n namedAreaDisplaySettings,\n geoJSONControllersUtm,\n //\n faults,\n geoJSONNamedAreaParentsUtm,\n regionPreview,\n //\n fireflyIdsUpdateList,\n fireflyIdsDeleteList,\n folderFilesList,\n //\n messageBanners,\n //\n timedOutDevices,\n //\n isPokeTheWorker,\n //\n namedAreaEvents,\n //\n transformPixelsToUtm,\n // user roles\n role: {\n allowGuest: userGuest,\n allowOperator: userSuper || userAdmin || userUser,\n allowAdmin: userSuper || userAdmin,\n allowSuper: userSuper,\n },\n //\n // map image from state\n mapImageFromState,\n //\n //\n userSettings: getUserSettings(state) || {},\n };\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n UpdateLocalMap: (mapState) => {\n dispatch(UpdateLocalMap(mapState));\n },\n namedAreaClearDeleteSelections: (parentId) => {\n dispatch(namedAreaClearDeleteSelections(parentId));\n },\n namedAreasSetIsDirty: (id) => {\n dispatch(namedAreasSetIsDirty(id));\n },\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n goto: (path) => dispatch(push(path)),\n fireflyIdsUpdateListDeleteId: (id) =>\n dispatch(fireflyIdsUpdateListDeleteId(id)),\n // flash message support\n clearFlashMessages: () => {\n dispatch(clearFlashMessages());\n },\n removeFlashMessage: (id) => {\n dispatch(removeFlashMessage(id));\n },\n addWarningFlashMessageIdColor: (id, color, header, message) => {\n dispatch(addWarningFlashMessageIdColor(id, color, header, message));\n },\n SetMessageBanner: (messageState) => {\n dispatch(SetMessageBanner(messageState));\n },\n TurnOnOffPokeTheWorker: (action) => {\n dispatch(TurnOnOffPokeTheWorker(action));\n },\n SetMapMoving: (bool) => dispatch(SetMapMoving(bool)),\n SetMapMarkerDragging: (bool) => dispatch(SetMapMarkerDragging(bool)),\n\n //\n saveNewNamedArea: (data) => dispatch(saveNewNamedArea(data)),\n deleteNamedArea: (id) => {\n dispatch(deleteNamedArea(id));\n },\n //\n // see - src/pages/ControlRoomPage/PrecannedOperations.js\n activate: (operation) => dispatch(activateNamedAreaEventSingle(operation)),\n cancel: (operation) => dispatch(cancelNamedAreaEvent(operation)),\n waitEventTimeOut: (action) => dispatch(waitEventTimeOut(action)),\n saveFirefly: (data) => dispatch(saveFirefly(data)),\n saveUPS: (data) => dispatch(saveUPS(data)),\n //\n // region preview\n addAreaPreview: (area) => dispatch(addAreaPreview(area)),\n removeAreaPreview: (area) => dispatch(removeAreaPreview(area)),\n\n saveUserSettingsComponentState: (data) =>\n dispatch(saveUserSettingsComponentState(data)),\n});\n\nexport default withComponentStateCache(\n connect(mapStateToProps, mapDispatchToProps)(Map)\n);\n","import Immutable from \"seamless-immutable\";\nimport { getMineLevelById } from \"MineLevels/reducer\";\n// test\nimport { createSelectorCreator, defaultMemoize } from \"reselect\";\nimport isEqual from \"lodash/isEqual\";\n\nconst initialState = Immutable({\n byId: {},\n order: [],\n isLoading: false,\n error: null,\n});\n\nexport default function reduce(state = initialState, action = {}) {\n switch (action.type) {\n case \"NAMED_AREAS_FETCH_REQUESTED\":\n return state.merge({ isLoading: true });\n case \"NAMED_AREAS_FETCH_SUCCEEDED\":\n return state.merge([\n Immutable(action.payload),\n { isLoading: false, error: null },\n ]);\n case \"NAMED_AREAS_FETCH_FAILED\":\n return state.merge({ isLoading: false, error: action.payload });\n default:\n return state;\n }\n}\n\nexport const getAllNamedAreas = (state) => {\n return Immutable(\n state.namedAreas.order.map((id) => {\n const obj = state.namedAreas.getIn([\"byId\", id]);\n const mineLevel = getMineLevelById(state, obj.mineLevelId);\n const mineLevelName = mineLevel ? mineLevel.name : \"No mine level??\";\n return obj.set(\"mineLevelName\", mineLevelName);\n })\n );\n};\n\nexport const getNamedAreaById = (state, id) => {\n return getAllNamedAreas(state).find((area) => area.id === id);\n};\n\n// create a \"selector creator\" that uses lodash.isEqual instead of ===\nconst createDeepEqualSelector = createSelectorCreator(defaultMemoize, isEqual);\n\nexport const makeGetNamedAreasForLevel = createDeepEqualSelector(\n (state, props) => props.mineLevelId,\n (state) => state.namedAreas.order.map((id) => state.namedAreas.byId[id]),\n (mineLevelId, namedAreas) => {\n return namedAreas\n .filter((area) => area.mineLevelId === mineLevelId)\n .asMutable();\n }\n);\n","import React from \"react\";\nimport Icon from \"semantic-ui-react/dist/commonjs/elements/Icon\";\n// import customicons from './custom.svg' // this should be used after upgrading to CRA 2.0\nimport \"./index.css\";\nimport ReactSVG from \"react-svg\";\n// SVG & CSS produced with this: https://icomoon.io/\n// Following broadly the process here: https://medium.com/douglas-matoso-english/build-an-svg-icon-component-with-react-de9db211ebd6\n\nexport default function ({ name, ...props }) {\n // if (name.indexOf('custom-') === -1) {\n // return (\n // \n // )\n // }\n // name = name.slice(7)\n let path = `icons/${name}`;\n\n if (!path.endsWith(\".svg\")) path += \".svg\";\n\n // \n return (\n
\n \n
\n // \n // \n // \n );\n}\n","import React, { Component } from \"react\";\nimport { Popup, Button, Grid } from \"semantic-ui-react\";\n\nimport { connect } from \"react-redux\";\nimport Icon from \"components/Icon\";\n\nimport isEmpty from \"lodash/isEmpty\";\n\nimport { isActiveEvent } from \"OperationalChanges/reducer\";\n\nimport {\n getNamedAreaEventButtonGroupState,\n getAllAreaStatuses,\n getAllNamedAreaStatuses,\n} from \"components/WebWorker/reducer\";\n\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport {\n cancelNamedAreaEvent,\n activateNamedAreaEvent,\n updateButtonGroupState,\n waitEventTimeOut,\n} from \"OperationalChanges/actions\";\n\nimport isEqual from \"lodash/isEqual\";\n\nimport { appResponsive } from \"components/ConfigJs\";\nimport { useMediaQuery } from \"react-responsive\";\n\nclass SingleOperation extends Component {\n shouldComponentUpdate(nextProps, nextState) {\n return !isEqual(JSON.stringify(this.props), JSON.stringify(nextProps));\n }\n\n _onClick = (e, { operation, area, buttonInfo }) => {\n // console.log(\n // \"SingleOperation _onClick operation\",\n // new Date().getTime(),\n // JSON.stringify(operation)\n // );\n\n if (false) {\n // debug .................\n console.log(\n \"SingleOperation _onClick operation\",\n JSON.stringify(operation)\n );\n console.log(\"SingleOperation _onClick area\", JSON.stringify(area));\n console.log(\"SingleOperation _onClick area.spec\", area.spec);\n console.log(\n \"SingleOperation _onClick area.groupsArray\",\n area.groupsArray\n );\n\n console.log(\"SingleOperation _onClick operation.type\", operation.type);\n console.log(\n \"SingleOperation _onClick operation.priority\",\n operation.priority\n );\n console.log(\"SingleOperation _onClick operation.group\", operation.group);\n console.log(\n \"SingleOperation _onClick area.groupsArray[operation.group]\",\n area.groupsArray[operation.group]\n );\n console.log(\n \"SingleOperation _onClick area.groupsArray[operation.group].length\",\n area.groupsArray[operation.group].length\n );\n\n console.log(\"SingleOperation _onClick buttonInfo\", buttonInfo);\n\n // debug .................\n }\n\n // Note:\n //\n // Two cases:\n // 1 - whole mine event\n // In this case we simulate the whole mine by triggering a level wide event\n // for all areas\n // 2 - separate named areas\n // Separate named areas includes level wide events.\n\n // 1 - for ALL_AREAS\n if (area.spec === \"ALL_AREAS\") {\n // console.log(\"ALL_AREAS click operation\", operation);\n // console.log(\"ALL_AREAS click area\", area);\n // console.log(\"ALL_AREAS click buttonInfo\", buttonInfo);\n\n // Note - this process sends an operation per mine level for whole mine events\n // ... however should instead use `ups/mine_wide_emergency` message\n if (false) {\n // find all named areas for the mine,\n // there is a level wide named area named after\n // each area name. i.e. area id = named area id\n const allAreas = this.props.allAreas;\n if (allAreas !== undefined || !isEmpty(allAreas)) {\n const namedAreas = allAreas.map((area) => area.id);\n namedAreas.forEach((namedArea) => {\n // change the operation, area and buttonInfo to simulate a level wide named event\n //\n let newOperation = operation;\n newOperation.id = namedArea;\n newOperation.named_area = namedArea;\n\n let newArea = area;\n newArea.id = namedArea;\n newArea.name = namedArea;\n newArea.spec = namedArea;\n\n // ...this is unchanged (for now)\n let newButtonInfo = buttonInfo;\n\n this.processClick(newOperation, newArea, newButtonInfo);\n });\n }\n }\n if (true) {\n // Send mine_wide_emergency for Mine Wide buttons\n // `ups/mine_wide_emergency`\n // Sets all the firefly's to the same color and state for all devices mine wide\n // {\n // \"color\": \"RED,GREEN,AMBER,WHITE,BLUE,ZONE\"\n // \"state\": \"The Led flash state ON,OFF,STROBE,FORWARD,BACKWARD\",\n // \"level\": 1,2,3,4\n // \"clear\": true / false\n // }\n\n this.processClick(operation, area, buttonInfo);\n }\n } else {\n // 2 - process a named event single operation\n this.processClick(operation, area, buttonInfo);\n }\n\n //\n };\n\n processClick = (operation, area, buttonInfo) => {\n // #NOTE - here there are two possible states for the button\n //\n // 1 - button is shown as active in the UI\n // 2 - button is show as inactive in the UI\n //\n // If only 1 button is shown as ACTIVE in a row (i.e. the buttonGroup) then this has an active event associated with it.\n // If >1 button is shown as ACTIVE in a row, then the highest priority button will have the current active event.\n // Buttons in a row are in order of priority. Left is lowest, right is highest.\n //\n // Buttons are drawn in button groups.\n //\n // Consider a named area button group with three separate groups.\n // Three buttons in the 1st, one in 2nd, 2 in 3rd.\n //\n // Group 0 - 1 - 2\n //\n // [0][1][2]-[0]-[0][1]\n //\n // Group:Button 0:2 may be selected, but if 1:0 or say 2:1 is selected then the event is associated with the most recent\n // button press (2:1) but buttons 0:2, 1:0 and 2:1 will all be shown as active in the UI (i.e. a solid icon).\n //\n // isActiveEvent - indicates if the event is active on that button\n // isActiveButton - indicates if the button is shown as active in the UI\n\n const namedAreaParent = area.spec;\n const namedAreaPriority = operation.priority;\n const selectedNamedAreaButtonGroups = area.groupsArray;\n\n // update buttons group state from the click (on a button!)\n const buttons = this.props.buttonGroupState;\n let newButtons = JSON.parse(JSON.stringify(buttons));\n\n // #DEBUG messages\n if (false) {\n console.log(\"processClick operation\", operation);\n console.log(\"processClick area\", area);\n console.log(\"processClick buttonInfo\", buttonInfo);\n console.log(\n \"processClick newButtons - updated named area event group state\",\n newButtons\n );\n console.log(\"processClick namedAreaParent\", namedAreaParent);\n console.log(\n \"processClick newButtons[namedAreaParent]\",\n newButtons[namedAreaParent]\n );\n }\n\n if (!newButtons.hasOwnProperty(namedAreaParent)) {\n // catch error if no button group state for button\n //\n // set default button group\n newButtons[namedAreaParent] = { 0: -1 };\n }\n\n const isActiveButton =\n newButtons[namedAreaParent][buttonInfo.group] === buttonInfo.index;\n\n const isActiveEvent = this.props.isActive;\n\n // All_Area (i.e. Mine Wide) buttons are special - they do not toggle off.\n // i.e. b/c emergency event messages do not have active=true/false, rather they exist or do not exist.\n const isAllAreasButton = area?.type === \"ALL_AREAS\";\n const isToggleButton = !isAllAreasButton;\n\n if (false) {\n console.log(\"processClick isActiveEvent\", isActiveEvent);\n console.log(\"processClick isActiveButton\", isActiveButton);\n }\n // Gets the next highest buttons\n // step through all the button event states and see if any others are active (from highest to lowest priority)\n // return the highest button (if any)\n //\n // e.g. nextPriorityEventOperation = getNextPriorityEventOperation(newButtons[namedAreaParent], selectedNamedAreaButtonGroups)\n const getNextPriorityEventOperation = (buttons, selectedButtonGroups) => {\n let nextPriorityEventOperation = {};\n let group = Object.keys(buttons).length;\n while (group--) {\n // go backward from highest to lowest priority\n const groupButtonSet = buttons[group];\n if (groupButtonSet !== -1) {\n nextPriorityEventOperation =\n selectedButtonGroups[group][groupButtonSet];\n break;\n }\n }\n return nextPriorityEventOperation;\n };\n\n // Sets redux event to pause collection of updated events from mqtt\n // This allows the button click to change locally for the wait period,\n // and for the event send to update the broker state and\n // confirm the action\n const waitEventTimeOut = (seconds) => {\n this.props.waitEventTimeOut(\"start\");\n setTimeout(() => {\n this.props.waitEventTimeOut(\"stop\");\n }, seconds); // WAIT_EVENT_TIMEOUT\n };\n\n // ********************************\n //\n // MAIN\n //\n // ********************************\n //\n // only if button group is defined (may be undefined on startup)\n //\n if (\n newButtons[namedAreaParent] !== undefined ||\n !isEmpty(newButtons[namedAreaParent])\n ) {\n // initialise button group records data is inconsistent\n if (\n Object.keys(newButtons[namedAreaParent])?.length !==\n selectedNamedAreaButtonGroups?.length\n ) {\n newButtons[namedAreaParent] = {};\n for (let i = 0; i < selectedNamedAreaButtonGroups.length; i++) {\n newButtons[namedAreaParent][i] = -1;\n }\n }\n\n if (isActiveButton && isToggleButton) {\n //\n // Clicked button is active.\n // Could be active because it is an active event &/or is an active button selection\n //\n // if it's an activeEvent and activeButton, then toggle the event off, then check if there is another\n // event which should be sent by checking what the next priority event is.\n //\n // if it's *not* an activeEvent and activeButton, then update the button state, and *resend* current event.\n // Resending the current event sends the updated button group state to all clients.\n // Also (perhaps) reinforces the event _BUT_ perhaps sends unnecessary event traffic.\n //\n //\n // #REVIEW -\n // As per above point about unnecessary event traffic, could consider:\n // ? - send a separate mqtt message which contains the button group information\n // ? - send the button group information via the sever/db. This process is similar to what happens in v2\n //\n //\n //\n\n // isActiveButton so toggle it off. i.e. set button group as -1 denotes no button set\n newButtons[namedAreaParent][buttonInfo.group] = -1;\n\n // console.log(\"kkk newButtons\", newButtons);\n this.props.updatebuttons(newButtons);\n\n if (isActiveEvent) {\n // isActiveButton and isActiveEvent so cancel the event....\n waitEventTimeOut(1000);\n this.props.cancel(operation);\n\n // ok, we cancelled an event, so check if should there be\n // another event to activate?\n let nextPriorityEventOperation = getNextPriorityEventOperation(\n newButtons[namedAreaParent],\n selectedNamedAreaButtonGroups\n );\n\n // if there is a next highest event (i.e. an active button) activate it\n if (!isEmpty(nextPriorityEventOperation)) {\n waitEventTimeOut(1000);\n this.props.activate(nextPriorityEventOperation);\n }\n } else {\n // !isActiveEvent\n //\n // This button has *no* active event, so find any current event and resend it.\n //\n // If there is a next highest event (i.e. an active button) *resend* (i.e. re-activate) it.\n //\n // #NOTE\n // * - didn't bother checking if the event is active since if the button is active, and it's a higher priority then\n // it should be activated anyway.\n //\n let nextPriorityEventOperation = getNextPriorityEventOperation(\n newButtons[namedAreaParent],\n selectedNamedAreaButtonGroups\n );\n\n if (!isEmpty(nextPriorityEventOperation)) {\n waitEventTimeOut(1000);\n this.props.activate(nextPriorityEventOperation);\n }\n }\n }\n // !isActiveButton\n // Note - toggleButtons and !toggleButtons can both select inactive buttons\n else {\n //\n // not an active button so update the button state in the button group, making it active\n //\n newButtons[namedAreaParent][buttonInfo.group] = buttonInfo.index;\n this.props.updatebuttons(newButtons);\n\n // ok, so we've clicked the button, but is there already an existing event ongoing at a higher priority?\n // if so then we don't need to trigger this event.\n let nextPriorityEventOperation = getNextPriorityEventOperation(\n newButtons[namedAreaParent],\n selectedNamedAreaButtonGroups\n );\n // if the next highest event is this event operation then fire away!\n if (namedAreaPriority >= nextPriorityEventOperation.priority) {\n waitEventTimeOut(1000);\n this.props.activate(operation);\n } else {\n // resend the highest priority event.\n // This is primarily to send around the button group state changes for\n // other buttons but also to reinforce the event.\n waitEventTimeOut(1000);\n this.props.activate(nextPriorityEventOperation);\n }\n }\n }\n };\n\n render() {\n const {\n area,\n operation,\n isActive,\n key,\n buttonInfo,\n buttonGroupState,\n displaySettings,\n size,\n buttonStyle,\n } = this.props;\n\n //console.log(\"SingleOperation re-render \", new Date().getTime());\n\n const namedAreaParent = area.spec;\n let buttonActive = false;\n let buttonEnabled = true; // #WIP - should default to false\n\n // #DEBUG messages\n if (false) {\n console.log(\"SingleOperation -----------------------\");\n console.log(\n \"SingleOperation buttonGroupState\",\n JSON.stringify(buttonGroupState)\n );\n console.log(\"SingleOperation area\", area);\n console.log(\"SingleOperation operation\", operation);\n console.log(\"SingleOperation buttonInfo\", buttonInfo);\n }\n\n if (!isEmpty(buttonGroupState)) {\n if (\n buttonGroupState[namedAreaParent] !== undefined &&\n !isEmpty(buttonGroupState[namedAreaParent])\n ) {\n // DEBUG msgs\n if (false) {\n console.log(\"buttonActive namedAreaParent\", namedAreaParent);\n\n console.log(\"buttonActive buttonGroupState\", buttonGroupState);\n console.log(\n \"buttonActive buttonGroupState[namedAreaParent]\",\n buttonGroupState[namedAreaParent]\n );\n console.log(\"buttonActive buttonInfo.group\", buttonInfo.group);\n console.log(\n \"buttonActive buttonGroupState[namedAreaParent][buttonInfo.group]\",\n buttonGroupState[namedAreaParent][buttonInfo.group]\n );\n console.log(\"buttonActive buttonInfo.index\", buttonInfo.index);\n console.log(\"buttonActive ----------\");\n }\n // button is active (i.e. enabled) in named area setup\n // assume active if set active or state is undefined\n buttonEnabled = buttonInfo.enable || buttonInfo.enable === undefined;\n\n // consider button active to send events if\n // 1 - the index is value\n // 2 - the button is enabled in setup of named area buttons\n\n buttonActive =\n buttonGroupState[namedAreaParent][buttonInfo.group] ===\n buttonInfo.index && buttonInfo.index !== -1;\n //&& buttonEnabled;\n\n // #DEBUG msgs\n if (false && namedAreaParent === \"DMLZ_Extraction:1234\") {\n console.log(\n \"buttonActive Single --------------------------------------------------------\"\n );\n console.log(\n \"buttonActive Single --------\",\n JSON.stringify(buttonInfo),\n \"---\",\n JSON.stringify(buttonGroupState[namedAreaParent]),\n \" ----------\"\n );\n console.log(\n \"buttonActive Single --------------------------------------------------------\"\n );\n console.log(\"buttonActive Single buttonEnabled\", buttonEnabled);\n console.log(\"buttonActive Single buttonActive\", buttonActive);\n console.log(\"buttonActive Single buttonInfo\", buttonInfo);\n console.log(\"buttonActive Single buttonInfo.index\", buttonInfo.index);\n console.log(\"buttonActive Single namedAreaParent \", namedAreaParent);\n console.log(\"buttonActive Single buttonInfo.group\", buttonInfo.group);\n console.log(\"buttonActive Single buttonGroupState\", buttonGroupState);\n console.log(\n \"buttonActive Single buttonGroupState[namedAreaParent]\",\n buttonGroupState[namedAreaParent]\n );\n console.log(\n \"buttonActive Single buttonGroupState[namedAreaParent][buttonInfo.group]\",\n buttonGroupState[namedAreaParent][buttonInfo.group]\n );\n }\n }\n }\n\n const buttonColor = (color) => {\n switch (color) {\n case \"red\":\n return \"red\";\n case \"orange\":\n case \"amber\":\n return \"orange\";\n case \"white\":\n return \"white\";\n case \"blue\":\n return \"blue\";\n case \"no_change\":\n return \"grey\";\n case \"off\":\n return \"black\";\n default:\n // not \"GREEN\" as used by the FF controller but \"green\" used by the semantic ui CSS\n return color.toLowerCase(); // #REVIEW - this shouldn't be necessary as I thought I'd caught these previously but THIS MAKES SURE!\n }\n };\n\n const color = buttonColor(operation.color) || \"red\";\n\n // const iconColor = isActive && buttonActive ? \"white\" : color;\n const iconColor = buttonActive ? \"grey\" : color; // was \"white\"\n\n const iconName = operation.icon;\n const iconOpacity = buttonEnabled ? \"1\" : \"0.2\";\n const style = { ...buttonStyle, opacity: iconOpacity };\n\n const { hint: isShowHint } = displaySettings;\n\n return (\n \n \n \n }\n content={`${area.name} - ${operation.hint}`}\n position=\"top right\" // bottom center\n basic\n disabled={!isShowHint}\n />\n );\n }\n}\n\nSingleOperation = connect(\n () => {\n return (state, props) => {\n const isActive = isActiveEvent(state, props);\n const buttonGroupState = getNamedAreaEventButtonGroupState(state);\n const allAreas = getAllAreaStatuses(state);\n // const namedAreaDisplaySettings = getNamedAreaDisplaySettings(state);\n\n return {\n isActive,\n buttonGroupState,\n allAreas,\n //namedAreaDisplaySettings,\n };\n };\n },\n (dispatch, props) => {\n // const { area, operation } = props;\n // const activate = buildActivateChange(area, operation);\n return {\n activate: (operation) => dispatch(activateNamedAreaEvent(operation)),\n cancel: (operation) => dispatch(cancelNamedAreaEvent(operation)),\n updatebuttons: (buttons) => dispatch(updateButtonGroupState(buttons)),\n waitEventTimeOut: (action) => dispatch(waitEventTimeOut(action)),\n };\n }\n)(SingleOperation);\n\n// function areEqual(prevProps, nextProps) {\n// /*\n// return true if passing nextProps to render would return\n// the same result as passing prevProps to render,\n// otherwise return false\n// */\n// console.log(\"nextProps\", nextProps);\n// //console.log(\"areEqual\", isEqual(nextProps, prevProps));\n\n// const {\n// area: prevArea,\n// displayAllOnMineLevel: prevDisplayAllOnMineLevel,\n// displaySettings: prevDisplaySettings,\n// } = prevProps;\n// const {\n// area: nextArea,\n// displayAllOnMineLevel: nextDisplayAllOnMineLevel,\n// displaySettings: nextDisplaySettings,\n// } = nextProps;\n\n// //return isEqual(nextProps, prevProps);\n\n// return true; //isEqual(nextArea, prevArea);\n// }\n\n//export const PrecannedOperations = React.memo(_PrecannedOperations, areEqual);\nfunction PrecannedOperations({\n area,\n //options, // #TODO - return BUTTON GROUP for all named areas .........\n floated,\n displayAllOnMineLevel = false,\n //size = \"medium\",\n displaySettings,\n ...props\n}) {\n const { mobile, tablet, laptop, desktop } = appResponsive();\n\n // 125 difference was determined empirically\n const isDesktopOrLaptop = useMediaQuery({\n query: `(min-width: ${desktop - 125}px)`,\n }); // 1225x\n const isTabletOrMobileDevice = useMediaQuery({\n query: `(max-width: ${mobile - 125}px)`,\n }); // 1224px\n\n const { view } = displaySettings;\n let size = \"medium\";\n switch (view) {\n case \"compressed\":\n size = \"mini\";\n break;\n case \"normal\":\n size = \"medium\";\n break;\n case \"expanded\":\n size = \"huge\";\n break;\n default:\n size = \"medium\";\n break;\n }\n // override size for top header icons\n if (area.id === \"ALL_AREAS\") {\n size = \"massive\";\n }\n\n // if LEVEL_WIDE make one size bigger than selected\n if (area.type === \"LEVEL_WIDE\") {\n const sizes = [\n \"mini\",\n \"tiny\",\n \"small\",\n \"medium\",\n \"large\",\n \"big\",\n \"huge\",\n \"massive\",\n ];\n size = sizes[sizes.indexOf(size) + 1];\n }\n\n return area.groupsArray.map((group) => {\n if (isTabletOrMobileDevice)\n return createGroupMinimal({\n area,\n floated,\n size,\n group,\n displaySettings,\n });\n if (isDesktopOrLaptop)\n return createGroup({ area, floated, size, group, displaySettings });\n // default\n return createGroup({ area, floated, size, group, displaySettings });\n });\n}\n\nconst createGroup = ({ area, floated, size, group, displaySettings }) => {\n return (\n \n {group.map((option, idx) => {\n return (\n \n );\n })}\n \n );\n};\n\nconst createGroupMinimal = ({\n area,\n floated,\n size,\n group,\n displaySettings,\n}) => {\n return (\n \n \n \n {group.map((option, idx) => {\n return (\n \n );\n })}\n \n \n \n );\n};\n\nconst mapStateToProps = (state, props) => {\n return {\n displaySettings: getNamedAreaDisplaySettings(state),\n };\n};\n\nexport default connect(mapStateToProps)(PrecannedOperations);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport \"react-virtualized/styles.css\";\nimport { Column, Table as VTable, AutoSizer } from \"react-virtualized\";\n\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\nimport {\n showAreaPreview,\n stopAreaPreview,\n} from \"components/RegionPreview/actions\";\nimport { makeGetNamedAreasForLevel } from \"NamedAreas/reducer\";\n\nimport {\n getNamedAreaParentStatusesByAreaId,\n getNamedAreaStatusesById,\n} from \"components/WebWorker/reducer\";\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport PrecannedOperations from \"pages/ControlRoomPage/PrecannedOperations\";\n\nimport isEqual from \"lodash/isEqual\";\n\nclass MineLevelPrecannedOperationsList extends Component {\n constructor(props) {\n super(props);\n this.state = {\n viewables: this._prepViewables(this.props),\n };\n }\n\n _prepViewables = (props) => {\n const { mineLevelId, namedAreasParents, levelWideNamedArea } = props;\n\n return [\n // #REVIEW - disable `fixed` level wide display in preference to real named area events\n // {\n // key: \"level\",\n // area: {\n // id: levelWideNamedArea.area, // mineLevelId,\n // spec: levelWideNamedArea.id, //mineLevelId,\n // name: \"LEVEL WIDE\",\n // //type: \"MINE_LEVEL\",\n // groupsArray: levelWideNamedArea.button,\n // },\n // },\n ...namedAreasParents.map((namedArea) => ({\n key: `named-area-${namedArea.id}`,\n area: {\n id: namedArea.area,\n spec: namedArea.id,\n name:\n namedArea.type !== \"LEVEL_WIDE\"\n ? namedArea.namedArea\n : \"LEVEL WIDE\",\n type: namedArea.type,\n groupsArray: namedArea.button,\n namedArea: namedArea.namedArea, // #NOTE - repeated here, as needed for SOP version\n },\n })),\n ];\n };\n\n componentWillReceiveProps(nextProps) {\n if (this.props !== nextProps) {\n this.setState({ viewables: this._prepViewables(nextProps) });\n }\n }\n\n _getDatum(list, index) {\n return list[index];\n }\n render() {\n const { showAreaPreview, stopAreaPreview, displaySettings, userSettings } =\n this.props;\n const { viewables } = this.state;\n const rowGetter = ({ index }) => this._getDatum(viewables, index);\n\n // #NOTE #REVIEW #TODO - make common function\n //\n const { view } = displaySettings;\n // default row height\n let rowHeight;\n let fontSize;\n switch (view) {\n case \"compressed\":\n rowHeight = 30;\n fontSize = 0.6; // 30/50\n break;\n case \"normal\":\n rowHeight = 50;\n fontSize = 1; // 50/50\n break;\n case \"expanded\":\n rowHeight = 80;\n fontSize = 1.6; // 80/50\n break;\n default:\n rowHeight = 50;\n fontSize = 1;\n break;\n }\n\n //console.log(\"SOP viewables\", viewables);\n\n return (\n \n {({ width, height }) => {\n return (\n {\n showAreaPreview && showAreaPreview(area);\n }}\n onRowMouseOut={({ rowData: { area } }) => {\n stopAreaPreview && stopAreaPreview(area);\n }}\n >\n {\n return rowData.area.name;\n }}\n />\n {\n return (\n \n );\n }}\n />\n \n );\n }}\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const { mineLevelId } = props;\n const namedAreasParents = getNamedAreaParentStatusesByAreaId(\n state,\n mineLevelId\n );\n\n const levelWideNamedArea = getNamedAreaStatusesById(state, mineLevelId);\n\n // id -> id\n // mineLevelId -> area\n // areaName -> namedArea\n\n const displaySettings = getNamedAreaDisplaySettings(state);\n\n return {\n namedAreasParents,\n levelWideNamedArea,\n //namedAreas: tempData_min, // makeGetNamedAreasForLevel(state, props), // tempData // #REVIEW - delete, old implementation left in for testing\n displaySettings,\n };\n};\n\nexport default connect(mapStateToProps, {\n //fetchNamedAreas,\n showAreaPreview,\n stopAreaPreview,\n})(MineLevelPrecannedOperationsList);\n","import React, { Component } from \"react\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Popup,\n Button,\n Menu,\n Ref,\n Header,\n Segment,\n Icon as SemIcon,\n Checkbox,\n} from \"semantic-ui-react\";\n\nimport { connect } from \"react-redux\";\nimport Icon from \"components/Icon\";\n\nimport isEmpty from \"lodash/isEmpty\";\n\nimport { isActiveEvent } from \"OperationalChanges/reducer\";\n\nimport {\n showAreaPreview,\n stopAreaPreview,\n addAreaPreview,\n removeAreaPreview,\n clearAreaPreview,\n addAllAreaPreview,\n} from \"components/RegionPreview/actions\";\n\nimport { getRegionPreviewList } from \"components/RegionPreview/reducer\";\n\nimport {\n getNamedAreaEventButtonGroupState,\n getAllAreaStatuses,\n getAllNamedAreaStatuses,\n} from \"components/WebWorker/reducer\";\n\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport {\n cancelNamedAreaEvent,\n activateNamedAreaEvent,\n updateButtonGroupState,\n waitEventTimeOut,\n removeRemoteButtonClick,\n} from \"OperationalChanges/actions\";\n\nimport { getRemoteButtonClick } from \"OperationalChanges/reducer\";\n\nimport _isEqual from \"lodash/isEqual\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport {\n appResponsive,\n isUserRelay as _isUserRelay,\n isPolygonShowHide,\n} from \"components/ConfigJs\";\nimport MediaQuery from \"react-responsive\";\nimport { updateRemoteButtonClick } from \"OperationalChanges/actions\";\nimport { isKthBitSet } from \"utils/bit-operations\";\n\nconst ICON_DEFINITIONS = {\n isSirenIcon: \"bullhorn\",\n isExtTriggerIcon: \"chain\",\n isScheduledIcon: \"clock outline\",\n};\n\nexport class SingleOperation extends Component {\n constructor(props) {\n super(props);\n this.contextRef = React.createRef();\n this[`${props.buttonRef}`] = React.createRef();\n this.state = {\n open: false,\n isRemoteButtonClick: false,\n appResponsive: appResponsive(),\n isUserRelay: false,\n isPolygonShowHide: isPolygonShowHide(),\n };\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n return (\n !_isEqual(JSON.stringify(this.props), JSON.stringify(nextProps)) ||\n this.state.open !== nextState.open ||\n this.props.remoteButtonClick?.length > 0\n );\n }\n\n componentDidUpdate(prevProps, prevState) {\n // check if button is in 'remoteButtonClick'.\n // ATM this indicated to trigger the siren.\n //\n const remoteButtonClick = this.props?.remoteButtonClick;\n const prevRemoteButtonClick = prevProps?.remoteButtonClick;\n\n const isRemoteButtonClick =\n remoteButtonClick?.includes(this.props?.buttonRef) || false;\n // with update, if button is in 'remoteButtonClick' array then fire the click handler.\n //\n\n if (remoteButtonClick !== prevRemoteButtonClick && isRemoteButtonClick) {\n // set the local state to inform the button of isRemoteButtonClick (Siren)\n this.setState({ isRemoteButtonClick: isRemoteButtonClick }, () => {\n // https://stackoverflow.com/questions/40091000/simulate-click-event-on-react-element\n\n this[`${this.props.buttonRef}`].current.handleClick();\n this.props.removeRemoteButtonClick(this.props.buttonRef);\n });\n }\n }\n\n _onClick = (e, data) => {\n const { operation, area, buttonInfo } = data;\n\n if (false) {\n // debug .................\n\n console.log(\n \"SingleOperation _onClick operation\",\n new Date().getTime(),\n JSON.stringify(operation)\n );\n console.log(\"SingleOperation _onClick operation\", operation);\n\n console.log(\n \"SingleOperation _onClick this.state.isRemoteButtonClick\",\n this.state.isRemoteButtonClick\n );\n\n console.log(\"SingleOperation _onClick area\", area);\n console.log(\"SingleOperation _onClick area.spec\", area.spec);\n console.log(\n \"SingleOperation _onClick area.groupsArray\",\n area.groupsArray\n );\n\n console.log(\"SingleOperation _onClick operation.type\", operation.type);\n console.log(\n \"SingleOperation _onClick operation.priority\",\n operation.priority\n );\n console.log(\"SingleOperation _onClick operation.group\", operation.group);\n console.log(\n \"SingleOperation _onClick area.groupsArray[operation.group]\",\n area.groupsArray[operation.group]\n );\n console.log(\n \"SingleOperation _onClick area.groupsArray[operation.group].length\",\n area.groupsArray[operation.group].length\n );\n\n console.log(\"SingleOperation _onClick buttonInfo\", buttonInfo);\n\n // debug .................\n }\n\n // Note:\n //\n // Two cases:\n // 1 - whole mine event\n // In this case we simulate the whole mine by triggering a level wide event\n // for all areas\n // 2 - separate named areas\n // Separate named areas includes level wide events.\n\n // 1 - for ALL_AREAS\n if (area.spec === \"ALL_AREAS\") {\n // console.log(\"ALL_AREAS click operation\", operation);\n // console.log(\"ALL_AREAS click area\", area);\n // console.log(\"ALL_AREAS click buttonInfo\", buttonInfo);\n\n // Note - this process sends an operation per mine level for whole mine events\n // ... however should instead use `ups/mine_wide_emergency` message\n if (false) {\n // find all named areas for the mine,\n // there is a level wide named area named after\n // each area name. i.e. area id = named area id\n const allAreas = this.props.allAreas;\n if (allAreas !== undefined || !isEmpty(allAreas)) {\n const namedAreas = allAreas.map((area) => area.id);\n namedAreas.forEach((namedArea) => {\n // change the operation, area and buttonInfo to simulate a level wide named event\n //\n let newOperation = operation;\n newOperation.id = namedArea;\n newOperation.named_area = namedArea;\n\n let newArea = area;\n newArea.id = namedArea;\n newArea.name = namedArea;\n newArea.spec = namedArea;\n\n // ...this is unchanged (for now)\n let newButtonInfo = buttonInfo;\n\n this.processClick({\n operation: newOperation,\n area: newArea,\n buttonInfo: newButtonInfo,\n });\n });\n }\n }\n if (true) {\n // Send mine_wide_emergency for Mine Wide buttons\n // `ups/mine_wide_emergency`\n // Sets all the firefly's to the same color and state for all devices mine wide\n // {\n // \"color\": \"RED,GREEN,AMBER,WHITE,BLUE,ZONE\"\n // \"state\": \"The Led flash state ON,OFF,STROBE,FORWARD,BACKWARD\",\n // \"level\": 1,2,3,4\n // \"clear\": true / false\n // }\n\n this.processClick({\n operation: operation,\n area: area,\n buttonInfo: buttonInfo,\n });\n }\n } else {\n // 2 - process a named event single operation\n\n this.processClick({\n operation: operation,\n area: area,\n buttonInfo: buttonInfo,\n });\n }\n\n //\n };\n\n processClick = ({ operation: rxOperation, area, buttonInfo }) => {\n // clone operation as need to update properties later based on state (see 'relay_active')\n let operation = { ...rxOperation };\n\n // #NOTE - here there are two possible states for the button\n //\n // 1 - button is shown as active in the UI\n // 2 - button is show as inactive in the UI\n //\n // If only 1 button is shown as ACTIVE in a row (i.e. the buttonGroup) then this has an active event associated with it.\n // If >1 button is shown as ACTIVE in a row, then the highest priority button will have the current active event.\n // Buttons in a row are in order of priority. Left is lowest, right is highest.\n //\n // Buttons are drawn in button groups.\n //\n // Consider a named area button group with three separate groups.\n // Three buttons in the 1st, one in 2nd, 2 in 3rd.\n //\n // Group 0 - 1 - 2\n //\n // [0][1][2]-[0]-[0][1]\n //\n // Group:Button 0:2 may be selected, but if 1:0 or say 2:1 is selected then the event is associated with the most recent\n // button press (2:1) but buttons 0:2, 1:0 and 2:1 will all be shown as active in the UI (i.e. a solid icon).\n //\n // isActiveEvent - indicates if the event is active on that button\n // isActiveButton - indicates if the button is shown as active in the UI\n\n const namedAreaParent = area.spec;\n const namedAreaPriority = operation.priority;\n const selectedNamedAreaButtonGroups = area.groupsArray;\n\n // update buttons group state from the click (on a button!)\n const buttons = this.props.buttonGroupState;\n let newButtons = JSON.parse(JSON.stringify(buttons));\n\n // #DEBUG messages\n if (false) {\n console.log(\"processClick operation\", operation);\n console.log(\"processClick area\", area);\n console.log(\"processClick buttonInfo\", buttonInfo);\n console.log(\n \"processClick newButtons - updated named area event group state\",\n newButtons\n );\n console.log(\"processClick namedAreaParent\", namedAreaParent);\n console.log(\n \"processClick newButtons[namedAreaParent]\",\n newButtons[namedAreaParent]\n );\n }\n\n if (!newButtons.hasOwnProperty(namedAreaParent)) {\n // catch error if no button group state for button\n //\n // set default button group\n newButtons[namedAreaParent] = { 0: -1 };\n }\n\n const isActiveButton =\n newButtons[namedAreaParent][buttonInfo.group] === buttonInfo.index;\n\n const isActiveEvent = this.props.isActive;\n\n let prevRelayActive = operation.relay_active;\n\n const isRemoteButtonClick = this.state.isRemoteButtonClick;\n // console.log(\n // \"processClick isResendEvent prevRelayActive\",\n // `${prevRelayActive}`\n // );\n\n // see - 'relay-active'\n if (isRemoteButtonClick) {\n // #WIP - isRemoteClick needs to be expanded to passing relay_active object\n operation.relay_active = 1; // #NOTE = changes to bit operation\n // remote click is 'acknowledged' so clear flag\n this.setState({ isRemoteButtonClick: false });\n } else {\n // #WIP - isRemoteClick needs to be expanded to passing relay_active object\n operation.relay_active = 0; // #NOTE = changes to bit operation\n }\n\n if (false) {\n console.log(\n \"processClick isResendEvent isRemoteButtonClick \",\n isRemoteButtonClick\n );\n\n console.log(\"processClick isResendEvent isActiveEvent\", isActiveEvent);\n console.log(\"processClick isResendEvent isActiveButton\", isActiveButton);\n console.log(\n \"processClick isResendEvent prevRelayActive\",\n prevRelayActive\n );\n console.log(\n \"processClick isResendEvent operation.relay_active\",\n operation.relay_active\n );\n }\n\n // check for remote control/resend event trigger\n let isResendEvent = false;\n if (\n isActiveEvent &&\n isActiveButton &&\n prevRelayActive !== operation.relay_active &&\n isRemoteButtonClick\n ) {\n isResendEvent = true;\n\n console.log(\n `isResendEvent - processClick resend event with operation.relay_active = '${\n operation.relay_active\n }' (don't toggle button from '${isActiveButton}' -> '${!isActiveButton}'. resendEvent = ${isResendEvent} )`\n );\n }\n\n // Gets the next highest buttons\n // step through all the button event states and see if any others are active (from highest to lowest priority)\n // return the highest button (if any)\n //\n // e.g. nextPriorityEventOperation = getNextPriorityEventOperation(newButtons[namedAreaParent], selectedNamedAreaButtonGroups)\n const getNextPriorityEventOperation = (buttons, selectedButtonGroups) => {\n let nextPriorityEventOperation = {};\n let group = Object.keys(buttons).length;\n while (group--) {\n // go backward from highest to lowest priority\n const groupButtonSet = buttons[group];\n if (groupButtonSet !== -1) {\n nextPriorityEventOperation =\n selectedButtonGroups[group][groupButtonSet];\n break;\n }\n }\n return nextPriorityEventOperation;\n };\n\n // Sets redux event to pause collection of updated events from mqtt\n // This allows the button click to change locally for the wait period,\n // and for the event send to update the broker state and\n // confirm the action\n const waitEventTimeOut = (seconds) => {\n this.props.waitEventTimeOut(\"start\");\n setTimeout(() => {\n this.props.waitEventTimeOut(\"stop\");\n }, seconds); // WAIT_EVENT_TIMEOUT\n };\n\n // ********************************\n //\n // MAIN processing\n //\n // ********************************\n //\n // only if button group is defined (may be undefined on startup)\n //\n if (\n newButtons[namedAreaParent] !== undefined ||\n !isEmpty(newButtons[namedAreaParent])\n ) {\n // initialise button group records data is inconsistent\n if (\n Object.keys(newButtons[namedAreaParent])?.length !==\n selectedNamedAreaButtonGroups?.length\n ) {\n newButtons[namedAreaParent] = {};\n for (let i = 0; i < selectedNamedAreaButtonGroups.length; i++) {\n newButtons[namedAreaParent][i] = -1;\n }\n }\n\n if (isActiveButton) {\n //\n // Clicked button is active.\n // Could be active because it is an active event &/or is an active button selection\n //\n // if it's an activeEvent and activeButton, then toggle the event off, then check if there is another\n // event which should be sent by checking what the next priority event is.\n //\n // if it's *not* an activeEvent and activeButton, then update the button state, and *resend* current event.\n // Resending the current event sends the updated button group state to all clients.\n // Also (perhaps) reinforces the event _BUT_ perhaps sends unnecessary event traffic.\n //\n //\n // #REVIEW -\n // As per above point about unnecessary event traffic, could consider:\n // ? - send a separate mqtt message which contains the button group information\n // ? - send the button group information via the sever/db. This process is similar to what happens in v2\n //\n //\n //\n\n //console.log(\"processClick isResendEvent\", isResendEvent);\n\n // isActiveButton and not a resendEvent then update the button group, otherwise everything stays the same\n if (!isResendEvent) {\n //console.log(\"processClick isResendEvent - updatebuttons\");\n\n // isActiveButton so toggle it off. i.e. set button group as -1 denotes no button set\n newButtons[namedAreaParent][buttonInfo.group] = -1;\n\n //console.log(\"kkk updatebuttons newButtons\", newButtons);\n this.props.updatebuttons(newButtons);\n }\n\n if (isActiveEvent) {\n if (isResendEvent) {\n // isActiveButton and isActiveEvent but operation has changed so don't cancel (i.e. toggle) the event, just resend it\n // Don't look for next highest event, just resend the current state with a new operation.\n // rather, just resend the event with updated operation\n\n // console.log(\n // \"processClick isResendEvent activate - operation\",\n // operation\n // );\n\n waitEventTimeOut(1000);\n this.props.activate(operation);\n } else {\n // isActiveButton and isActiveEvent so cancel the active event....\n\n // console.log(\n // \"processClick isResendEvent cancel - operation\",\n // operation\n // );\n\n waitEventTimeOut(1000);\n this.props.cancel(operation);\n\n // ok, we cancelled an event, so check if should there be\n // another event to activate?\n let nextPriorityEventOperation = getNextPriorityEventOperation(\n newButtons[namedAreaParent],\n selectedNamedAreaButtonGroups\n );\n\n // console.log(\n // \"processClick isResendEvent activate - operation\",\n // nextPriorityEventOperation\n // );\n\n // if there is a next highest event (i.e. an active button) activate it\n if (!isEmpty(nextPriorityEventOperation)) {\n waitEventTimeOut(1000);\n this.props.activate(nextPriorityEventOperation);\n }\n }\n } else {\n // !isActiveEvent\n //\n // This button has *no* active event, so find any current event and resend it.\n //\n // If there is a next highest event (i.e. an active button) *resend* (i.e. re-activate) it.\n //\n // #NOTE\n // * - didn't bother checking if the event is active since if the button is active, and it's a higher priority then\n // it should be activated anyway.\n //\n let nextPriorityEventOperation = getNextPriorityEventOperation(\n newButtons[namedAreaParent],\n selectedNamedAreaButtonGroups\n );\n\n // console.log(\n // \"processClick isResendEvent activate - operation\",\n // nextPriorityEventOperation\n // );\n\n if (!isEmpty(nextPriorityEventOperation)) {\n waitEventTimeOut(1000);\n this.props.activate(nextPriorityEventOperation);\n }\n }\n } else {\n // !isActiveButton\n //\n // not an active button so update the button state in the button group, making it active\n //\n newButtons[namedAreaParent][buttonInfo.group] = buttonInfo.index;\n //console.log(\"kkk updatebuttons newButtons\", newButtons);\n this.props.updatebuttons(newButtons);\n\n // ok, so we've clicked the button, but is there already an existing event ongoing at a higher priority?\n // if so then we don't need to trigger this event.\n let nextPriorityEventOperation = getNextPriorityEventOperation(\n newButtons[namedAreaParent],\n selectedNamedAreaButtonGroups\n );\n // if the next highest event is this event operation then fire away!\n if (namedAreaPriority >= nextPriorityEventOperation.priority) {\n // console.log(\n // \"processClick isResendEvent activate - operation\",\n // nextPriorityEventOperation\n // );\n\n waitEventTimeOut(1000);\n this.props.activate(operation);\n } else {\n // resend the highest priority event.\n // This is primarily to send around the button group state changes for\n // other buttons but also to reinforce the event.\n\n // console.log(\n // \"processClick isResendEvent activate - operation\",\n // nextPriorityEventOperation\n // );\n\n waitEventTimeOut(1000);\n this.props.activate(nextPriorityEventOperation);\n }\n }\n }\n };\n\n render() {\n const {\n area,\n operation,\n isActive,\n key,\n buttonInfo,\n buttonGroupState,\n displaySettings,\n title,\n maxLabelLength,\n regionPreviewList,\n disabled,\n userSettings,\n } = this.props;\n\n const { appResponsive, isPolygonShowHide } = this.state;\n\n const isUserRelay =\n userSettings?.feature?.includes(\"showUserRelay\") || _isUserRelay();\n\n //console.log(\"SingleOperation re-render \", new Date().getTime());\n\n const namedAreaParent = area.spec;\n let buttonActive = false;\n let buttonEnabled = true; // #WIP - should default to false\n\n // #DEBUG messages\n if (false) {\n console.log(\n \"SingleOperation buttonGroupState\",\n JSON.stringify(buttonGroupState)\n );\n console.log(\"SingleOperation area\", area);\n console.log(\"SingleOperation operation\", operation);\n console.log(\"SingleOperation buttonInfo\", buttonInfo);\n }\n\n if (!isEmpty(buttonGroupState)) {\n if (\n buttonGroupState[namedAreaParent] !== undefined &&\n !isEmpty(buttonGroupState[namedAreaParent])\n ) {\n // DEBUG msgs\n if (false) {\n console.log(\"buttonActive namedAreaParent\", namedAreaParent);\n\n console.log(\"buttonActive buttonGroupState\", buttonGroupState);\n console.log(\n \"buttonActive buttonGroupState[namedAreaParent]\",\n buttonGroupState[namedAreaParent]\n );\n console.log(\"buttonActive buttonInfo.group\", buttonInfo.group);\n console.log(\n \"buttonActive buttonGroupState[namedAreaParent][buttonInfo.group]\",\n buttonGroupState[namedAreaParent][buttonInfo.group]\n );\n console.log(\"buttonActive buttonInfo.index\", buttonInfo.index);\n console.log(\"buttonActive ----------\");\n }\n // button is active (i.e. enabled) in named area setup\n // assume active if set active or state is undefined\n buttonEnabled = buttonInfo.enable || buttonInfo.enable === undefined;\n\n // consider button active to send events if\n // 1 - the index is value\n // 2 - the button is enabled in setup of named area buttons\n\n buttonActive =\n buttonGroupState[namedAreaParent][buttonInfo.group] ===\n buttonInfo.index && buttonInfo.index !== -1;\n //&& buttonEnabled;\n\n // #DEBUG msgs\n if (false) {\n console.log(\n \"buttonActive Single --------------------------------------------------------\"\n );\n console.log(\n \"buttonActive Single --------\",\n JSON.stringify(buttonInfo),\n \"---\",\n JSON.stringify(buttonGroupState[namedAreaParent]),\n \" ----------\"\n );\n console.log(\n \"buttonActive Single --------------------------------------------------------\"\n );\n console.log(\"buttonActive Single buttonEnabled\", buttonEnabled);\n console.log(\"buttonActive Single buttonActive\", buttonActive);\n console.log(\"buttonActive Single buttonInfo\", buttonInfo);\n console.log(\"buttonActive Single buttonInfo.index\", buttonInfo.index);\n console.log(\"buttonActive Single namedAreaParent \", namedAreaParent);\n console.log(\"buttonActive Single buttonInfo.group\", buttonInfo.group);\n console.log(\"buttonActive Single buttonGroupState\", buttonGroupState);\n console.log(\n \"buttonActive Single buttonGroupState[namedAreaParent]\",\n buttonGroupState[namedAreaParent]\n );\n console.log(\n \"buttonActive Single buttonGroupState[namedAreaParent][buttonInfo.group]\",\n buttonGroupState[namedAreaParent][buttonInfo.group]\n );\n }\n }\n }\n\n const buttonColor = (color) => {\n switch (color) {\n case \"red\":\n return \"red\";\n case \"orange\":\n case \"amber\":\n return \"orange\";\n case \"white\":\n return \"white\";\n case \"blue\":\n return \"blue\";\n case \"no_change\":\n return \"grey\";\n case \"off\":\n return \"black\";\n default:\n // not \"GREEN\" as used by the FF controller but \"green\" used by the semantic ui CSS\n return color.toLowerCase(); // #REVIEW - this shouldn't be necessary as I thought I'd caught these previously but THIS MAKES SURE!\n }\n };\n\n const color = buttonColor(operation.color) || \"red\";\n\n // console.log(\"color\", operation, color);\n\n // const iconColor = isActive && buttonActive ? \"white\" : color;\n\n const iconColor = buttonActive ? \"grey\" : color; // was \"white\"\n const iconName = operation.icon;\n const iconOpacity = buttonEnabled ? \"1\" : \"0.2\";\n const buttonStyle = { padding: \"0.5em\", opacity: iconOpacity };\n\n const { hint: isShowHint, view } = displaySettings;\n\n let size = \"medium\";\n switch (view) {\n case \"compressed\":\n size = \"mini\";\n break;\n case \"normal\":\n size = \"medium\";\n break;\n case \"expanded\":\n size = \"huge\";\n break;\n default:\n size = \"medium\";\n break;\n }\n\n // override size for top header icons\n if (area.type === \"WHOLE_MINE\") {\n size = \"massive\";\n }\n\n // if LEVEL_WIDE make one size bigger than selected\n if (area.type === \"MINE_LEVEL\") {\n const sizes = [\n \"mini\",\n \"tiny\",\n \"small\",\n \"medium\",\n \"large\",\n \"big\",\n \"huge\",\n \"massive\",\n ];\n size = sizes[sizes.indexOf(size) + 1];\n }\n\n const createContextFromEvent = (e) => {\n const left = e.clientX;\n const top = e.clientY;\n const right = left + 1;\n const bottom = top + 1;\n return {\n getBoundingClientRect: () => ({\n left,\n top,\n right,\n bottom,\n\n height: 0,\n width: 0,\n }),\n };\n };\n\n const handleRelayUserCheck = (e, data) => {\n const { label, checked, stringnamedareaparentpriority } = data;\n\n //console.log(`handleRelayUserCheck label, checked`, label, checked);\n //console.log(`handleRelayUserCheck data`, data);\n\n this.props.updateRemoteButtonClick([stringnamedareaparentpriority]);\n\n // if (checked) {\n // setSelection([...selection, label]);\n // } else {\n // setSelection(selection.filter((el) => el !== label));\n // }\n };\n\n const handleItemClick = (event, data) => {\n const { name: item, area } = data;\n const { id, name, namedArea, spec, type } = area;\n const {\n showAreaPreview,\n addAreaPreview,\n removeAreaPreview,\n clearAreaPreview,\n addAllAreaPreview,\n regionPreviewList,\n allAreas,\n } = this.props;\n\n // create array of all named areas polygons\n const currentArea = allAreas.find((area) => area.id === id);\n let allNamedAreaPolygons = [];\n\n if (!_isEmpty(currentArea?.namedAreaGroup)) {\n currentArea.namedAreaGroup.forEach((row, index) => {\n const { subItems } = row;\n subItems.map(({ label, subItems }, index) => {\n subItems.map(({ label, settings, namedArea }) => {\n const area = {\n spec: namedArea.id,\n type: \"Polygon\",\n id: id,\n namedArea: label,\n };\n allNamedAreaPolygons.push(area);\n });\n });\n });\n }\n\n const previewState = { id, name, namedArea, spec, type };\n\n // console.log(` handleItemClick data`, data);\n // console.log(` handleItemClick previewState`, previewState);\n // console.log(` handleItemClick regionPreviewList`, regionPreviewList);\n // console.log(\n // ` handleItemClick allNamedAreaPolygons`,\n // allNamedAreaPolygons\n // );\n\n const isPreview = regionPreviewList.find(\n (preview) => preview.spec === spec\n );\n\n switch (item) {\n case \"show\":\n showAreaPreview(previewState);\n break;\n case \"add\":\n if (!isPreview) {\n addAreaPreview(previewState);\n }\n break;\n case \"remove\":\n if (isPreview) {\n removeAreaPreview(previewState);\n }\n break;\n case \"showAll\":\n addAllAreaPreview(allNamedAreaPolygons);\n break;\n case \"clear\":\n clearAreaPreview();\n break;\n case \"list\":\n //console.log(` handleItemClick regionPreviewList`, regionPreviewList);\n break;\n default:\n break;\n }\n\n this.setState({ open: false });\n };\n\n const isPreview = regionPreviewList.find(\n (preview) => preview.spec === area.spec\n );\n\n const isAnyPreview = !_isEmpty(regionPreviewList);\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n\n const { mobile, tablet, laptop, desktop } = appResponsive;\n const isDesktopOrLaptop = tablet; // (min-width: 1351px)\n const isTabletOrMobileDevice = tablet; // 1350 (max-width: 1350px)\n\n // Setup display of icons\n //\n // There are current three icons which append to buttons to indicate the active state of:\n // * siren - isSirenIcon\n // * external trigger - isExtTriggerIcon\n // * scheduled event - isScheduledIcon\n\n let displayIcons = [];\n\n // isSirenIcon - determined from review of current event\n // siren is active if there is a namedAreaParent with relay_event_active = 1 in the level\n // See - src/pages/ControlRoomPage/MineLevelCustomSOPList.js\n // Search \"// Show siren icon active?\"\n\n const isSirenIcon = isKthBitSet(operation.relay_active, 1) || false;\n if (isSirenIcon) {\n displayIcons.push(\"isSirenIcon\");\n }\n\n const isExtTriggerIcon =\n operation?.origin?.includes(\"ext_trigger_event\") === true;\n\n if (isExtTriggerIcon) {\n displayIcons.push(\"isExtTriggerIcon\");\n }\n\n const isScheduledEventIcon =\n operation?.origin?.includes(\"scheduled_event\") === true;\n\n if (isScheduledEventIcon) {\n displayIcons.push(\"isScheduledIcon\");\n }\n\n const isButtonIcons = displayIcons.length;\n\n // button length changes to accommodate additional icons\n const buttonWidth = isButtonIcons\n ? maxLabelLength + displayIcons.length * 3 + 3\n : maxLabelLength + 3; // add a 'bit' more to compensate for non-monospace fonts\n\n //console.log(\"xxx displayIcons, operation\", displayIcons, operation);\n\n return (\n <>\n \n \n {title}\n
\n {displayIcons.map((displayIcon, idx) => (\n \n ))}\n
\n \n
\n \n <>\n \n {\n e.preventDefault();\n this.contextRef.current = createContextFromEvent(e);\n this.setState({ open: true });\n }}\n size={size}\n key={key}\n color={color}\n icon={isButtonIcons}\n operation={operation}\n area={area}\n buttonInfo={buttonInfo}\n onClick={this._onClick}\n basic={!buttonActive}\n style={{\n padding: \"0.5em\",\n marginBottom: \"5px\",\n width: `${buttonWidth}ch`,\n height: \"2em\",\n\n // #NOTE #BUTTON_STYLE - styling to display button wrapped on level\n display: \"flex\",\n }}\n disabled={disabled}\n >\n {title}\n
\n {displayIcons.map((displayIcon, idx) => (\n \n ))}\n
\n \n
\n this.setState({ open: false })}\n open={this.state.open}\n position={\"top left\"}\n >\n {area.namedArea !== title && (\n {`${title} (${area.namedArea})`}
\n )}\n {area.namedArea === title && (\n
{title}
\n )}\n\n \n \n Polygon\n\n \n \n \n Edit {strNamedArea}\n \n {isPolygonShowHide && !isPreview && (\n \n \n Show {strNamedArea}\n \n )}\n {isPolygonShowHide && isPreview && (\n \n \n Hide {strNamedArea}\n \n )}\n {isPolygonShowHide && (\n <>\n \n \n Show All {strNamedAreas}\n \n \n \n Hide All {strNamedAreas}\n \n \n )}\n {/* \n \n List Regions to Console\n */}\n \n \n {isUserRelay && (\n \n User Relay\n \n \n \n \n {/* \n \n \n \n \n */}\n \n \n )}\n \n {false && isShowHint && (\n \n External Trigger MQTT Message {operation.named_area}:\n {operation.priority}\n \n )}\n \n \n \n \n );\n }\n}\n\nSingleOperation = connect(\n () => {\n return (state, props) => {\n const isActive = isActiveEvent(state, props);\n const buttonGroupState = getNamedAreaEventButtonGroupState(state);\n const allAreas = getAllAreaStatuses(state);\n // const namedAreaDisplaySettings = getNamedAreaDisplaySettings(state);\n\n const regionPreviewList = getRegionPreviewList(state);\n\n return {\n isActive,\n buttonGroupState,\n allAreas,\n //namedAreaDisplaySettings,\n regionPreviewList,\n remoteButtonClick: getRemoteButtonClick(state),\n };\n };\n },\n (dispatch, props) => {\n // const { area, operation } = props;\n // const activate = buildActivateChange(area, operation);\n return {\n activate: (operation) => dispatch(activateNamedAreaEvent(operation)),\n cancel: (operation) => dispatch(cancelNamedAreaEvent(operation)),\n updatebuttons: (buttons) => dispatch(updateButtonGroupState(buttons)),\n waitEventTimeOut: (action) => dispatch(waitEventTimeOut(action)),\n showAreaPreview: (area) => dispatch(showAreaPreview(area)),\n stopAreaPreview: (area) => dispatch(stopAreaPreview(area)),\n addAreaPreview: (area) => dispatch(addAreaPreview(area)),\n removeAreaPreview: (area) => dispatch(removeAreaPreview(area)),\n clearAreaPreview: () => dispatch(clearAreaPreview()),\n addAllAreaPreview: (allPolygonsArray) =>\n dispatch(addAllAreaPreview(allPolygonsArray)),\n removeRemoteButtonClick: (id) => dispatch(removeRemoteButtonClick(id)),\n updateRemoteButtonClick: (clickList) =>\n dispatch(updateRemoteButtonClick(clickList)),\n };\n }\n)(SingleOperation);\n\n// function areEqual(prevProps, nextProps) {\n// /*\n// return true if passing nextProps to render would return\n// the same result as passing prevProps to render,\n// otherwise return false\n// */\n// console.log(\"nextProps\", nextProps);\n// //console.log(\"areEqual\", _isEqual(nextProps, prevProps));\n\n// const {\n// area: prevArea,\n// displayAllOnMineLevel: prevDisplayAllOnMineLevel,\n// displaySettings: prevDisplaySettings,\n// } = prevProps;\n// const {\n// area: nextArea,\n// displayAllOnMineLevel: nextDisplayAllOnMineLevel,\n// displaySettings: nextDisplaySettings,\n// } = nextProps;\n\n// //return _isEqual(nextProps, prevProps);\n\n// return true; //_isEqual(nextArea, prevArea);\n// }\n\n//export const PrecannedOperations = React.memo(_PrecannedOperations, areEqual);\nfunction PrecannedOperations({\n area,\n //options, // #TODO - return BUTTON GROUP for all named areas .........\n floated,\n displayAllOnMineLevel = false,\n //size = \"medium\",\n displaySettings,\n userSettings,\n ...props\n}) {\n const { view } = displaySettings;\n let size = \"medium\";\n switch (view) {\n case \"compressed\":\n size = \"mini\";\n break;\n case \"normal\":\n size = \"medium\";\n break;\n case \"expanded\":\n size = \"huge\";\n break;\n default:\n size = \"medium\";\n break;\n }\n // override size for top header icons\n if (area.id === \"ALL_AREAS\") {\n size = \"massive\";\n }\n\n // if LEVEL_WIDE make one size bigger than selected\n if (area.type === \"LEVEL_WIDE\") {\n const sizes = [\n \"mini\",\n \"tiny\",\n \"small\",\n \"medium\",\n \"large\",\n \"big\",\n \"huge\",\n \"massive\",\n ];\n size = sizes[sizes.indexOf(size) + 1];\n }\n\n return area.groupsArray.map((group) => {\n return createGroup({\n area,\n floated,\n size,\n group,\n displaySettings,\n userSettings,\n });\n });\n}\n\nconst createGroup = ({\n area,\n floated,\n size,\n group,\n displaySettings,\n userSettings,\n}) => {\n return (\n \n {group.map((option, idx) => {\n return (\n \n );\n })}\n \n );\n};\n\nconst mapStateToProps = (state, props) => {\n return {\n displaySettings: getNamedAreaDisplaySettings(state),\n };\n};\n\nexport default connect(mapStateToProps)(PrecannedOperations);\n","////////////////////////////////////////////////////////\n//\n// This components is copy of react-heartbeat\n//\nimport React, { Component, Fragment } from 'react';\nimport PropTypes from 'prop-types';\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar Heartbeat = function (_Component) {\n _inherits(Heartbeat, _Component);\n\n function Heartbeat(props) {\n _classCallCheck(this, Heartbeat);\n\n var _this = _possibleConstructorReturn(this, _Component.call(this, props));\n\n _this.beat = function () {\n // Register when the timer started\n let nextBeat = new Date().getTime() + _this.props.heartbeatInterval\n\n // Callback\n _this.props.heartbeatFunction();\n \n // Do not allow to call the timer too often.\n // Allow for small margin, but if crossed force full interval.\n let diff_time = nextBeat - new Date().getTime() \n if (diff_time < (_this.props.heartbeatInterval - 250)) {\n diff_time = _this.props.heartbeatInterval\n }\n var nextTimeout = setTimeout(_this.beat, diff_time);\n _this.setState({\n nextBeat: new Date().getTime() + diff_time,\n timeout: nextTimeout\n });\n };\n\n _this.state = {\n timeout: null\n };\n return _this;\n }\n\n Heartbeat.prototype.componentDidMount = function componentDidMount() {\n this.setState({\n timeout: setTimeout(this.beat, this.props.heartbeatInterval)\n });\n };\n\n Heartbeat.prototype.componentWillUnmount = function componentWillUnmount() {\n clearTimeout(this.state.timeout);\n };\n\n Heartbeat.prototype.render = function render() {\n return React.createElement(Fragment, null);\n };\n\n return Heartbeat;\n}(Component);\n\nHeartbeat.propTypes = process.env.NODE_ENV !== \"production\" ? {\n heartbeatInterval: PropTypes.number,\n heartbeatFunction: PropTypes.func.isRequired\n } : {};\n\nHeartbeat.defaultProps = {\n heartbeatInterval: 1000\n };\n\nexport { Heartbeat as default };","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n showAreaPreview,\n stopAreaPreview,\n} from \"components/RegionPreview/actions\";\n\nimport { makeGetNamedAreasForLevel } from \"NamedAreas/reducer\";\n\nimport { getNamedAreaEventsByAreaId } from \"components/WebWorker/reducer\";\n\nimport {\n getNamedAreaParentStatusesByAreaId,\n getNamedAreaStatusesById,\n getAreaStatusesById,\n} from \"components/WebWorker/reducer\";\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\nimport PrecannedOperations from \"pages/ControlRoomPage/PrecannedOperations\";\nimport \"react-virtualized/styles.css\";\nimport { Column, Table as VTable, AutoSizer } from \"react-virtualized\";\nimport {\n Grid,\n Segment,\n Message,\n Header,\n Button,\n Icon,\n Popup,\n Checkbox,\n Container,\n} from \"semantic-ui-react\";\nimport { SingleOperation } from \"pages/ControlRoomPage/PreCannedOperationsCustomSOP\";\nimport {\n isConfigJs,\n isShowEventButtons,\n controlScreenSOPdata,\n} from \"components/ConfigJs\";\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport { isBoomgateCrane, isShowLightControlSim } from \"components/ConfigJs\";\nimport { updateRemoteButtonClick } from \"OperationalChanges/actions\";\n//import { isKthBitSet } from \"utils/bit-operations\";\nimport _isEqual from \"lodash/isEqual\";\n\nimport { getObjectDiff } from \"utils/getObjectDiff\";\nimport { Slider } from \"react-semantic-ui-range\";\nimport Heartbeat from \"utils/Heartbeat\";\n\nimport { getUserSessionIp, messageToken } from \"utils/messageToken\";\nimport { getUserSettings } from \"auth/reducer\";\n\n// based on `MineLevelPrecannedOperationsList`\nclass MineLevelCustomSOPList extends Component {\n constructor(props) {\n super(props);\n this.state = {\n viewables: this._prepViewables(this.props),\n sirenState: [],\n sirenIconClickTimeout: [],\n //sirenIconClickTimeout: [],\n //\n isShowLightControlSim: false,\n lightControlSimData: [],\n isLightControlSim: false,\n lightControlSimRate: 5000,\n };\n }\n\n getSimData = (namedAreaGroup) => {\n //console.log(`sim namedAreaGroup`, namedAreaGroup);\n\n let simData = [];\n if (namedAreaGroup !== null) {\n //groups\n namedAreaGroup.map((group) => {\n // levels\n group.subItems.map((level) => {\n // buttons\n level.subItems.map((na) => {\n simData.push(\n `${na?.namedArea?.button?.named_area}:${na?.namedArea?.button?.priority}`\n );\n });\n });\n });\n }\n return simData;\n };\n\n componentDidMount() {\n if (isShowLightControlSim()) {\n this.setState({ isShowLightControlSim: true });\n let simData = [];\n if (this.props.namedAreaGroup) {\n simData = this?.getSimData([...this.props.namedAreaGroup]) || [];\n }\n this.setState({ isShowLightControlSim: simData });\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (isShowLightControlSim() !== this.state.isShowLightControlSim) {\n this.setState({ isShowLightControlSim: isShowLightControlSim() });\n }\n\n if (!_isEqual(this.props.namedAreaGroup, prevProps.namedAreaGroup)) {\n let simData = [];\n if (this.props.namedAreaGroup) {\n simData = this?.getSimData([...this.props.namedAreaGroup]) || [];\n }\n\n this.setState({ isShowLightControlSim: simData });\n }\n }\n\n _prepViewables = (props) => {\n const { mineLevelId, namedAreasParents, levelWideNamedArea } = props;\n\n // console.log(\"levelWideNamedArea\", levelWideNamedArea);\n return [\n // #REVIEW - disable `fixed` level wide display in preference to real named area events\n // {\n // key: \"level\",\n // area: {\n // id: levelWideNamedArea.area, // mineLevelId,\n // spec: levelWideNamedArea.id, //mineLevelId,\n // name: \"LEVEL WIDE\",\n // //type: \"MINE_LEVEL\",\n // groupsArray: levelWideNamedArea.button,\n // },\n // },\n ...namedAreasParents.map((namedArea) => ({\n key: `named-area-${namedArea.id}`,\n area: {\n id: namedArea.area,\n spec: namedArea.id,\n name:\n namedArea.type !== \"LEVEL_WIDE\"\n ? namedArea.namedArea\n : \"LEVEL WIDE\",\n type: namedArea.type,\n groupsArray: namedArea.button,\n },\n })),\n ];\n };\n\n // shouldComponentUpdate(nextProps, nextState) {\n // return !_isEqual(JSON.stringify(this.props), JSON.stringify(nextProps));\n // }\n\n //#DEBUG_SOLUTION - reviewing render states\n\n // shouldComponentUpdate(nextProps, nextState) {\n // const thisState = JSON.parse(JSON.stringify(this.state));\n // const newState = JSON.parse(JSON.stringify(nextState));\n\n // const thisProps = JSON.parse(JSON.stringify(this.props));\n // const newProps = JSON.parse(JSON.stringify(nextProps));\n\n // const diffProps = getObjectDiff(thisProps, newProps);\n // const diffState = getObjectDiff(thisState, newState);\n\n // const checkProps = !_isEqual(thisProps, newProps);\n // const checkState = !_isEqual(thisState, newState);\n\n // const check = checkProps || checkState;\n\n // if (true && check) {\n // console.log(`xxx check diff`, check, diffProps, diffState);\n // console.log(`xxx check thisProps`, thisProps);\n // console.log(`xxx check newProps`, newProps);\n // console.log(`xxx check thisState`, thisState);\n // console.log(`xxx check newState`, newState);\n // }\n\n // return check;\n // }\n\n componentWillReceiveProps(nextProps) {\n if (\n !_isEqual(this.props, nextProps) &&\n nextProps.mineLevelId === this.props.mineLevelId\n ) {\n // console.log(`xx8xx this.props`, this.props);\n // console.log(`xx8xx nextProps`, nextProps);\n\n this.setState({ viewables: this._prepViewables(nextProps) });\n }\n }\n\n _getDatum(list, index) {\n return list[index];\n }\n\n handleTimeoutSirenIconClick = (id) => {\n let newSirenIconClickTimeout = [...this.state.sirenIconClickTimeout];\n\n // after timeout remote the id from the state\n newSirenIconClickTimeout = newSirenIconClickTimeout.filter(\n (item) => item !== id\n );\n this.setState({ sirenIconClickTimeout: newSirenIconClickTimeout });\n };\n\n timerSirenIconClick = (id) => {\n let newSirenIconClickTimeout = [...this.state.sirenIconClickTimeout];\n\n //if id does not already exist add it to the state\n if (!newSirenIconClickTimeout?.some((ids) => ids?.includes(id))) {\n newSirenIconClickTimeout.push(id);\n }\n this.setState({ sirenIconClickTimeout: newSirenIconClickTimeout });\n setTimeout(this.handleTimeoutSirenIconClick, 2000, id);\n };\n\n handleSirenIconClick = (data) => {\n const {\n id,\n namedAreaParentsPriorityByLevel,\n uniqueParentsNamedAreaEventsSirenActive,\n isSirenIconActive,\n } = data?.buttonInfo;\n\n // if 'isSirenIconActive' then on -> off toggle\n // toggleIdState - id, and indicates whether toggling 'on' (true) or 'off' (false)\n // e.g. \"['9a27a19d-d6ac-4f8b-a9cb-ce4da4934741:true']\"\n const toggleIdState = `${id}:${!isSirenIconActive}`;\n\n // set timeout for icon to be active for 2*1000 milli-seconds\n this.timerSirenIconClick(toggleIdState);\n // for user feedback we want the sirenIcon to stay on until updated when the click action event is applied to the polygons.\n // i.e. click to change polygon state, wait for response, in meantime simulate the state.\n // If the click action is not applied the icon will eventually time out.\n // timerSirenIconClick() - adds the clicked event id to the state 'sirenIconClickTimeout' and sets the timeout\n // after the timeout, handleTimeout() removed the completed event id from the state 'sirenIconClickTimeout'\n\n // Note:\n // this.state.sirenState - shows which levels have siren flag active\n // namedAreaParentsPriorityByLevel - all named areas on a level\n // uniqueParentsNamedAreaEventsSirenActive - named areas which have active siren\n\n // convert {id:priority} to array strings to make comparison easier\n const stringAllOnLevel = namedAreaParentsPriorityByLevel?.map(\n (item) => `${item.id}:${item.priority}`\n );\n\n const stringActiveSiren = uniqueParentsNamedAreaEventsSirenActive?.map(\n (item) => `${item.id}:${item.priority}`\n );\n\n // handleSirenIconClick is toggle action\n const isSirenActive = this.state.sirenState?.includes(id);\n\n let clickList = [];\n\n if (isSirenActive) {\n // toggle off so 'click' on all the buttons which are active\n // i.e. uniqueParentsNamedAreaEventsSirenActive\n\n clickList = stringAllOnLevel.filter((item) =>\n stringActiveSiren.includes(item)\n );\n } else {\n // toggle on so 'click' on all the buttons which are inactive\n // i.e. in namedAreaParentsPriorityByLevel but not uniqueParentsNamedAreaEventsSirenActive\n\n clickList = stringAllOnLevel.filter(\n (item) => !stringActiveSiren.includes(item)\n );\n }\n\n //\n // Clicking siren button, passes the array with [{\"id:property\"},...] to\n // remoteButtonClick reducer state.\n // This updates the 'SingleOperation' (see - src/pages/ControlRoomPage/PreCannedOperationsCustomSOP.js)\n // and fires the handleSirenIconClick() for the React.createRef() defined.\n // After firing the click the button is removed from the remoteButtonClick array state.\n //\n //\n\n // debug siren icon handler\n if (false) {\n console.log(`handleSirenIconClick id`, id);\n console.log(`handleSirenIconClick stringAllOnLevel`, stringAllOnLevel);\n console.log(`handleSirenIconClick stringActiveSiren`, stringActiveSiren);\n console.log(\n `handleSirenIconClick this.state.sirenState`,\n this.state.sirenState\n );\n console.log(`handleSirenIconClick isSirenActive`, isSirenActive);\n console.log(`handleSirenIconClick clickList`, clickList);\n console.log(\n `handleSirenIconClick -----------------------------------------------------`\n );\n }\n\n this.props.updateRemoteButtonClick(clickList);\n };\n\n handleTimeoutLightControlSim = (timerProps) => {\n const sampleRandomButton = _.sample(this.state.lightControlSimData);\n this.props.updateRemoteButtonClick([sampleRandomButton]);\n };\n\n onChangeLightControlSimCheckbox = (evt, data) => {\n let checked = data.checked;\n\n this.setState({\n isLightControlSim: checked,\n });\n };\n\n render() {\n const {\n showAreaPreview,\n stopAreaPreview,\n displaySettings,\n styleInfo,\n namedAreasParents,\n mineLevelId,\n namedAreaGroup,\n strings,\n userSettings,\n } = this.props;\n\n // ===========isLightControlSim==================\n\n const { isLightControlSim, lightControlSimRate } = this.state;\n\n const settingsLightControlSim = {\n start: (10 * 1000) / 1000,\n min: 1,\n max: 60,\n step: 1,\n onChange: (value) => {\n this.setState({\n lightControlSimRate: value * 1000,\n });\n },\n };\n\n const simpleClickSimulator = () => {\n return (\n <>\n \n \n \n \n
Light Control Simulator
\n \n this.onChangeLightControlSimCheckbox(evt, data)\n }\n />\n }\n />\n
\n {`Button click rate ${\n this.state.lightControlSimRate / 1000\n } seconds`}\n
\n \n
\n
\n
\n {isLightControlSim && (\n \n )}\n \n \n );\n };\n\n const getStringUniqueParentsNamedAreaEvents_Source_EventActive = (\n namedAreasEvents_Source_Active\n ) => {\n // get the unique named area parents objects where the _SOURCE_ is active.\n // e.g. source could be the siren, external trigger event, scheduled event job\n //\n // e.g. [{id: 'IOT_Office:a0836b4b-7d06-45b5-9c62-e4bb182f04ad:1633993784425', area: 'IOT_Office', parent: 'IOT_Office:a0836b4b-7d06-45b5-9c62-e4bb182f04ad', priority: 12, active: true, …}, ...]\n // after .map()\n // e.g. [{id: 'IOT_Office:a0836b4b-7d06-45b5-9c62-e4bb182f04ad', priority: 12},...]\n // Note - we are comparing parents here\n const uniqueParentnamedAreasEvents_Source_ActiveArray = new Set();\n // _Source_\n const uniqueParentsNamedAreaEvents_Source_Active =\n namedAreasEvents_Source_Active\n .filter((event) => {\n if (\n uniqueParentnamedAreasEvents_Source_ActiveArray.has(event.parent)\n ) {\n return false;\n }\n uniqueParentnamedAreasEvents_Source_ActiveArray.add(event.parent);\n return true;\n })\n .map((result) => {\n return {\n id: result?.parent,\n priority: result?.priority,\n };\n });\n\n const stringUniqueParentsNamedAreaEvents_Source_Active =\n uniqueParentsNamedAreaEvents_Source_Active.map((item) => {\n return `${item.id}:${item.priority}`;\n });\n\n return {\n stringUniqueParentsNamedAreaEvents_Source_Active,\n uniqueParentsNamedAreaEvents_Source_Active,\n };\n };\n\n // =============================\n\n const { viewables, isShowLightControlSim } = this.state;\n\n // railway_application\n const boomgateCrane = isBoomgateCrane() || false;\n\n const rowGetter = ({ index }) => this._getDatum(viewables, index);\n\n // #NOTE #REVIEW #TODO - make common function\n //\n\n const { view } = displaySettings;\n const { fontSize, paddingBottom } = styleInfo;\n\n // default row height\n let rowHeight = 50;\n switch (view) {\n case \"compressed\":\n rowHeight = 30;\n break;\n case \"normal\":\n rowHeight = 50;\n break;\n case \"expanded\":\n rowHeight = 80;\n\n break;\n default:\n rowHeight = 50;\n break;\n }\n\n // #NOTE - style does not work on Message.header so pass different classes\n // to set the font size.\n // Not pretty, but it works.\n //\n // default header font size\n let headerFontSize = \"10\"; // i.e. 1.0em\n switch (fontSize) {\n case 0.6:\n headerFontSize = \"08\";\n break;\n case 1:\n headerFontSize = \"12\";\n break;\n case 1.6:\n headerFontSize = \"20\";\n break;\n default:\n headerFontSize = \"10\";\n break;\n }\n\n const showEventButtons = isShowEventButtons() === true;\n\n let sopRows = [];\n if (namedAreaGroup !== undefined) {\n sopRows = namedAreaGroup;\n // #WIP - FIX THIS! re-loads SOP list continuously\n // console.log(\n // \"loading namedAreaGroup ....\",\n // JSON.stringify(namedAreaGroup)\n // );\n } else if (isConfigJs() && controlScreenSOPdata()) {\n sopRows = controlScreenSOPdata();\n if (showEventButtons) {\n console.log(\"SOP sopRows\", sopRows);\n }\n if (!_isEmpty(sopRows)) {\n sopRows = sopRows.find((item) => item.area === mineLevelId)?.data;\n }\n }\n\n const sopRowStyle = {\n fontSize: `${fontSize} rem`,\n marginRight: \"3px\",\n paddingBottom: `0.1em`,\n };\n\n let content = [];\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n\n const inactiveSirenPopupLabel =\n \"Click to activate all polygons on this level, and the sirens on Controllers connected to FireFlys in these polygons. \";\n const activeSirenPopupLabel =\n \"Click to deactivate all polygons (and controller sirens) on this level\";\n\n if (!_isEmpty(sopRows)) {\n if (!_isEmpty(namedAreasParents)) {\n sopRows.forEach((row, index) => {\n // Review Access Privileges for the user\n //\n // console.log(`xxx row`, row);\n const userAccessThisGroup = userSettings?.namedAreaGroup?.find(\n (nag) => nag.id === row.id\n )?.access || [\"r\", \"w\", \"x\"];\n\n // console.log(\"xxx userAccessThisGroup\", userAccessThisGroup);\n\n let disabled = true; // \"x\"\n let hide = true; // \"r\"\n\n if (userAccessThisGroup.includes(\"r\")) hide = false;\n if (userAccessThisGroup.includes(\"x\")) disabled = false;\n\n const { label, subItems } = row;\n !hide &&\n content.push(\n \n \n {label}\n \n \n \n {_isEmpty(subItems) ? (\n \n \n {\n strings?.[\n \"There are no levels defined for this group.\"\n ]\n }\n \n \n ) : (\n subItems.map(\n ({ id, label, settings, subItems }, index) => {\n //console.log(`xxx label, subItems`, label, subItems);\n\n // #NOTE - sets the width of the buttons to be same for each level.\n // Uses the length of the custom label (settings.title) if it exists,\n // else uses default label (i.e. named area parent name)\n\n let maxLabelLength = Math.max(\n ...subItems.map((items) => {\n return items?.settings?.title?.length > 0\n ? items?.settings?.title?.length\n : items?.label?.length;\n })\n ); // minimum label lengths\n\n // get the named area parents and their priority for the level\n // e.g. [{id: 'IOT_Office:a0836b4b-7d06-45b5-9c62-e4bb182f04ad', priority: 12}, ...]\n\n // This is needed ........................\n const namedAreaParentsPriorityByLevel = subItems\n ?.filter((subItem) => subItem.parent === id)\n ?.map((subItem) => {\n return {\n id: subItem?.namedArea?.id,\n priority: subItem?.namedArea?.button?.priority,\n };\n });\n\n // #NOTE - this returns namedAreaParentsPriorityByLevel as a string array.\n // Not used ATM but may be useful later\n const namedAreaParentsPriorityByLevelString = subItems\n ?.filter((subItem) => subItem.parent === id)\n ?.map(\n (subItem) =>\n `${subItem?.namedArea?.id}:${subItem?.namedArea?.button?.priority}`\n );\n\n // ****************************************************************************************************\n //\n // Show siren icon active?\n // siren is active if there is a namedAreaParent with relay_event_active = 1 in the level\n //\n // ****************************************************************************************************\n\n // #NOTE #WIP #TODO\n // CHECK THIS 1ST BIT IS SET, RATHER THAN FOR \"1\" BELOW\n // \\/\\/\\/\\/\\/\\/\\/\\/\n //\n\n // check if there are any namedAreaEvents active with relay_event_active = 1\n const namedAreasEventsSirenActive =\n this.props.namedAreaEvents.filter(\n (event) =>\n event.active && event?.relay_event_active === 1\n );\n\n const {\n stringUniqueParentsNamedAreaEvents_Source_Active:\n stringUniqueParentsNamedAreaEventsSirenActive,\n uniqueParentsNamedAreaEvents_Source_Active:\n uniqueParentsNamedAreaEventsSirenActive,\n } = getStringUniqueParentsNamedAreaEvents_Source_EventActive(\n namedAreasEventsSirenActive\n );\n\n // #NOTE _ MAKE THIS INTO A FUNCTION!!!!!!!!!!!\n\n // get the unique named area parents objects where siren is active\n // e.g. [{id: 'IOT_Office:a0836b4b-7d06-45b5-9c62-e4bb182f04ad:1633993784425', area: 'IOT_Office', parent: 'IOT_Office:a0836b4b-7d06-45b5-9c62-e4bb182f04ad', priority: 12, active: true, …}, ...]\n // after .map()\n // e.g. [{id: 'IOT_Office:a0836b4b-7d06-45b5-9c62-e4bb182f04ad', priority: 12},...]\n // Note - we are comparing parents here\n // const uniqueParentnamedAreasEventsSirenActiveArray =\n // new Set();\n // const uniqueParentsNamedAreaEventsSirenActive =\n // namedAreasEventsSirenActive\n // .filter((event) => {\n // if (\n // uniqueParentnamedAreasEventsSirenActiveArray.has(\n // event.parent\n // )\n // ) {\n // return false;\n // }\n // uniqueParentnamedAreasEventsSirenActiveArray.add(\n // event.parent\n // );\n // return true;\n // })\n // .map((result) => {\n // return {\n // id: result?.parent,\n // priority: result?.priority,\n // };\n // });\n\n // const stringUniqueParentsNamedAreaEventsSirenActive =\n // uniqueParentsNamedAreaEventsSirenActive.map((item) => {\n // return `${item.id}:${item.priority}`;\n // });\n\n // So in summary:\n // per level .....\n //\n // this.state.sirenState - shows which levels have siren flag active\n //\n // namedAreaParentsPriorityByLevel - all named areas on a level\n // uniqueParentsNamedAreaEventsSirenActive - named areas which have active siren\n //\n\n // test - are namedAreas in 'namedAreaParentsPriorityByLevel' active events in 'uniqueParentsNamedAreaEventsSirenActive'\n //const isSirenActive = this.state.sirenState?.includes(id);\n\n // isActiveSiren - indicates if this button has an active siren event\n let isSirenActive = false;\n\n isSirenActive = namedAreaParentsPriorityByLevel\n ?.map((item) => {\n return uniqueParentsNamedAreaEventsSirenActive\n .map((it) => {\n return (\n it.id === item.id &&\n it.priority === item.priority\n );\n })\n .includes(true);\n })\n .includes(true);\n\n // update local state siren buttons\n // e.g. [\"\",... ]\n let newSirenState = [...this.state.sirenState];\n if (newSirenState?.includes(id) && !isSirenActive) {\n newSirenState = newSirenState.filter(\n (siren) => siren !== id\n );\n this.setState({ sirenState: newSirenState });\n } else if (\n isSirenActive &&\n !newSirenState?.includes(id)\n ) {\n newSirenState.push(id);\n this.setState({ sirenState: newSirenState });\n }\n\n // isShowSiren is a flag from the config for the level indicating whether to allow display of\n // the siren icon - from config for level\n const isShowSiren = settings?.siren_state == \"on\";\n\n // check toggleIdState\n // toggle button -> ON e.g. \"['9a27a19d-d6ac-4f8b-a9cb-ce4da4934741:true']\"\n // toggle button -> OFF e.g. \"['9a27a19d-d6ac-4f8b-a9cb-ce4da4934741:false']\"\n\n let isSirenIconActive = false;\n\n const toggleIdStateON =\n this.state.sirenIconClickTimeout?.includes(\n `${id}:true`\n );\n\n const toggleIdStateOFF =\n this.state.sirenIconClickTimeout?.includes(\n `${id}:false`\n );\n\n // Whether or not to show the siren icon active (i.e. flag isSirenIconActive),\n // depends on\n // #1 - if there is an active siren event in the row (isShowSiren)\n // #2 - if the icon button has been click to change the state. (toggleIdStateON or toggleIdStateOFF)\n //\n // If clicked, then force a timeout to an OFF state or an ON state.\n //\n // if the siren icon is active\n if (isSirenActive) {\n // and there is no entry in `sirenIconClickTimeout` to change state of the icon\n if (!toggleIdStateOFF && !toggleIdStateON) {\n // icon is active\n isSirenIconActive = true;\n } // but if the icon has been toggled OFF\n else if (toggleIdStateOFF && !toggleIdStateON) {\n // set the icon as inactive\n isSirenIconActive = false;\n }\n // !isSirenActive\n } else {\n if (!toggleIdStateOFF && !toggleIdStateON) {\n isSirenIconActive = false;\n } else if (!toggleIdStateOFF && toggleIdStateON) {\n isSirenIconActive = true;\n }\n }\n\n // ****************************************************************************************************\n //\n // Show external_trigger_event icon active?\n // external_trigger_event is active if there is a namedAreaParent with origin = \"external_trigger_event\" in the level\n //\n // ****************************************************************************************************\n\n // check if there are any namedAreaEvents active with relay_event_active = 1\n const namedAreasEventsExternalTriggerEventActive =\n this.props.namedAreaEvents.filter(\n (event) =>\n event.active &&\n [\"ext_trigger_event\"]?.includes(event?.origin)\n );\n\n const {\n stringUniqueParentsNamedAreaEvents_Source_Active:\n stringUniqueParentsNamedAreaEventsExternalTriggerEventActive,\n uniqueParentsNamedAreaEvents_Source_Active:\n uniqueParentsNamedAreaEventsExternalTriggerEventActive, // Not used for external trigger events\n } = getStringUniqueParentsNamedAreaEvents_Source_EventActive(\n namedAreasEventsExternalTriggerEventActive\n );\n\n // ****************************************************************************************************\n //\n // Show scheduled_event icon active?\n // external_trigger_event is active if there is a namedAreaParent with origin = \"external_trigger_event\" in the level\n //\n // ****************************************************************************************************\n\n // check if there are any namedAreaEvents active with relay_event_active = 1\n const namedAreasEventsScheduledEventActive =\n this.props.namedAreaEvents.filter(\n (event) =>\n event.active &&\n [\"scheduled_event\"]?.includes(event?.origin)\n );\n\n const {\n stringUniqueParentsNamedAreaEvents_Source_Active:\n stringUniqueParentsNamedAreaEventsScheduledEventActive,\n uniqueParentsNamedAreaEvents_Source_Active:\n uniqueParentsNamedAreaEventsScheduledEventActive, // Not used for scheduled events\n } = getStringUniqueParentsNamedAreaEvents_Source_EventActive(\n namedAreasEventsScheduledEventActive\n );\n\n // *************************************************************************************\n\n return (\n \n \n \n \n \n {/* see - src/pages/ControlRoomPage/PreCannedOperationsCustomSOP.js \"\" */}\n {isShowSiren && (\n \n this.handleSirenIconClick(data)\n }\n disabled={disabled}\n />\n }\n />\n // }\n // />\n )}\n \n \n \n {label}\n \n \n \n \n \n \n {_isEmpty(subItems) ? (\n \n \n There are no {strNamedAreas} defined for\n this level.\n \n \n ) : (\n subItems.map(\n ({ label, settings, namedArea }) => {\n let operation = [];\n // #WIP - testing setup button in namedAreaGroups\n //\n // ...current process working process\n if (false) {\n operation = namedAreasParents.find(\n (na) => na.id === namedArea.id\n )?.button; // #REVIEW #TODO ##FIXTHIS - buttons returns [[]] as elsewhere buttons.map() works. Why is this necessary?\n }\n\n // if mqtt messages are not available on startup, or slow to load, then\n // `operation` may not be defined\n if (operation === undefined) {\n return null;\n } else {\n // console.log(\n // \"operation kkk namedAreasParents\",\n // namedAreasParents\n // );\n // console.log(\n // \"operation kkk namedArea\",\n // namedArea\n // );\n // console.log(\n // \"operation kkk operation\",\n // JSON.stringify(operation)\n // );\n\n // compose content to pass\n // this is same as in PrecannedOperations.js\n //\n\n //#WIP - hack out a groupsArray\n let newGroupsArray = [];\n const priority =\n namedArea?.button?.priority;\n const button = namedArea?.button;\n if (priority !== undefined) {\n for (\n let index = 0;\n index <= priority;\n index++\n ) {\n newGroupsArray[index] = {\n ...button,\n };\n newGroupsArray[index].priority =\n index;\n }\n }\n\n // console.log(\"newGroupsArray\", newGroupsArray);\n // console.log(\n // \"newGroupsArray old operation\",\n // operation\n // );\n\n // use settings.title if it is defined\n const buttonLabel = settings?.title\n ? settings.title\n : label;\n\n if (\n buttonLabel?.length > maxLabelLength\n )\n maxLabelLength = buttonLabel.length;\n\n const area = {\n groupsArray: [newGroupsArray], // operation, // [newGroupsArray], // #WIP - ????????????////\n name: buttonLabel,\n spec: namedArea.id,\n type: \"Polygon\",\n id: mineLevelId,\n namedArea: label,\n };\n\n let option = {};\n\n // #WIP - testing setup button in namedAreaGroups\n //\n // ...current process working process\n if (false) {\n option =\n operation[0][namedArea.priority]; // // #REVIEW #TODO ##FIXTHIS - buttons returns [[]] as elsewhere buttons.map() works. Why is this necessary?\n } else {\n option = { ...namedArea?.button }; // #WIP - ????????????////\n }\n\n // 'option' comes from the button definition that is created when the namedAreaGroup is defined.\n // The button definition does not know the event state of relay_active.\n // So from event checks set the option.relay_active property.\n\n // #WIP #TODO - this needs to be expanded to other relay parameters\n // pass bits for relay registers\n // isSirenActive - level only\n if (\n stringUniqueParentsNamedAreaEventsSirenActive.includes(\n `${namedArea.id}:${option.priority}`\n )\n ) {\n option.relay_active = 1; // bit 1 = siren\n } else {\n option.relay_active = 0;\n }\n\n // see - `sendNamedAreaEventParent`\n\n // #DOGS_BREAKFAST!!!!!!!!!!!!!!!!\n // The origin and operator is unknown to the button so this is an attempt to match\n // the reocrds. This should be reviewed in detail.\n\n //\n // #WIP #TODO ---\n // Find the matching event and get the current origin and operator to update the record.\n // Similar to the siren icon.\n // Generalise??????????\n //\n\n if (\n stringUniqueParentsNamedAreaEventsExternalTriggerEventActive.includes(\n `${namedArea.id}:${option.priority}`\n )\n ) {\n // Similarly, the button definition does not know the current Origin and Operator.\n // Overwrite the default settings for active user information.\n //\n option.origin = \"ext_trigger_event\";\n option.operator = \"ext_trigger_event\";\n } else if (\n stringUniqueParentsNamedAreaEventsScheduledEventActive.includes(\n `${namedArea.id}:${option.priority}`\n )\n ) {\n // Similarly, the button definition does not know the current Origin and Operator.\n // Overwrite the default settings for active user information.\n //\n option.origin = \"scheduled_event\";\n option.operator = \"scheduled_event\";\n } else {\n // Similarly, the button definition does not know the current Origin and Operator.\n // Overwrite the default settings for active user information.\n //\n option.origin = \"CLIENT\"; // #TODO #REVIEW -\n option.operator =\n this.props.userSessionIp; // #TODO #REVIEW - from the user session information\n }\n\n // title of the button\n const title = buttonLabel;\n\n if (option?.type === undefined)\n return null; // #WIP - ????????????////\n\n // ****************\n return (\n \n );\n }\n }\n )\n )}\n \n \n );\n }\n )\n )}\n \n \n \n );\n });\n }\n } else {\n content.push(\n \n );\n }\n return (\n <>\n {content}\n {isShowLightControlSim && simpleClickSimulator()}\n {showEventButtons && (\n \n {({ width, height }) => {\n return (\n {\n showAreaPreview && showAreaPreview(area);\n }}\n onRowMouseOut={({ rowData: { area } }) => {\n stopAreaPreview && stopAreaPreview(area);\n }}\n >\n {\n return rowData.area.name;\n }}\n />\n {\n return (\n \n );\n }}\n />\n \n );\n }}\n \n )}\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const { mineLevelId } = props;\n\n const area = getAreaStatusesById(state, mineLevelId) || {};\n const { namedAreaGroup } = area;\n\n //console.log(\"namedAreaGroup\", namedAreaGroup);\n\n const namedAreasParents = getNamedAreaParentStatusesByAreaId(\n state,\n mineLevelId\n );\n\n const levelWideNamedArea = getNamedAreaStatusesById(state, mineLevelId);\n\n // id -> id\n // mineLevelId -> area\n // areaName -> namedArea\n\n const displaySettings = getNamedAreaDisplaySettings(state);\n\n // support for sirens\n const namedAreaEvents = getNamedAreaEventsByAreaId(state, mineLevelId);\n\n const userSessionIp = getUserSessionIp();\n const userSettings = getUserSettings(state);\n\n return {\n namedAreasParents,\n levelWideNamedArea,\n //namedAreas: tempData_min, // makeGetNamedAreasForLevel(state, props), // tempData // #REVIEW - delete, old implementation left in for testing\n displaySettings,\n namedAreaGroup,\n namedAreaEvents,\n userSessionIp,\n userSettings,\n };\n};\n\nexport default connect(mapStateToProps, {\n showAreaPreview,\n stopAreaPreview,\n updateRemoteButtonClick,\n})(MineLevelCustomSOPList);\n","export const imageCheck = (folderFilesList, image_filename, imageInfo) => {\n // check file exists on server\n let url;\n if (folderFilesList?.includes(image_filename)) {\n url = process.env.PUBLIC_URL + \"/areas/\" + image_filename;\n } else {\n console.log(`IMAGE> IMAGECHECK`, image_filename, \"not in folderFilesList\");\n\n // setup a dummy image and load the map image in the background\n // create a replacement image using known dimensions\n let canvas = document.createElement(\"canvas\");\n // set desired size of transparent image\n canvas.width = imageInfo?.width || 10000; //#TODO - get default image load\n canvas.height = imageInfo?.height || 8000; //#TODO - get default image load\n // extract as new image (data-uri)\n url = canvas.toDataURL();\n\n // #NOTE #WIP #TODO\n // SET A MESSAGE IF THE MAP FILE IS NOT AVAILABLE\n }\n\n return url;\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Grid, Segment, Dimmer, Loader, Icon } from \"semantic-ui-react\";\n\n//import NamedAreaOperationsList from \"./NamedAreaOperationsList\";\n\nimport NamedAreaDisplaySettings from \"pages/ControlRoomPage/NamedAreaDisplaySettings\";\n\nimport MapSimple from \"components/Map/MineLevelMapLeafletSimple\";\nimport Map from \"components/Map/MineLevelMapLeaflet\";\n\nimport MineLevelPrecannedOperationsList from \"pages/ControlRoomPage/MineLevelPrecannedOperationsList\";\nimport MineLevelCustomSOPList from \"pages/ControlRoomPage/MineLevelCustomSOPList\";\n\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport {\n isConfigJs,\n faultMessageBannerDisplay,\n faultMessageBannerText,\n isBoomgateCrane as _isBoomgateCrane,\n isLightingControl as _isLightingControl,\n isAreaMapSimple,\n isAreaImageToState,\n} from \"components/ConfigJs\";\n\nimport { isUserGuest } from \"auth/reducer\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\nimport { imageCheck } from \"utils/imageCheck\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport _isEqual from \"lodash/isEqual\";\n\n// >>>>> flash message support\nimport {\n addWarningFlashMessageIdColor,\n removeFlashMessage,\n clearFlashMessages,\n SetMessageBanner,\n} from \"FlashMessages/actions\";\n\nimport cuid from \"cuid\";\n// <<<<< flash message support\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport { isMapMoving } from \"components/Map/reducer\";\nimport { isDraggingMarker } from \"components/Map/reducer\";\nimport { getObjectDiff } from \"utils/getObjectDiff\";\n\nimport { SetMapImage } from \"components/Settings/actions\";\nimport { getMapImages } from \"components/Settings/reducer\";\n\nclass MineLevelOpsControl extends Component {\n constructor(props) {\n super(props);\n this.state = {\n columnWidth: 6,\n isMapLoaded: [],\n isBoomgateCrane: false,\n isLightingControl: false,\n //\n isAreaMapSimple: false,\n isAreaImageToState: false,\n };\n }\n\n //#DEBUG_SOLUTION - reviewing render states\n //\n // shouldComponentUpdate(nextProps, nextState) {\n // const thisState = JSON.parse(JSON.stringify(this.state));\n // const newState = JSON.parse(JSON.stringify(nextState));\n\n // const thisProps = JSON.parse(JSON.stringify(this.props));\n // const newProps = JSON.parse(JSON.stringify(nextProps));\n\n // const diffProps = getObjectDiff(thisProps, newProps);\n // const diffState = getObjectDiff(thisState, newState);\n\n // const checkProps = !_isEqual(thisProps, newProps);\n // const checkState = !_isEqual(thisState, newState);\n\n // const check = checkProps || checkState;\n\n // if (check) {\n // console.log(`xxx check diff`, check, diffProps, diffState);\n // console.log(`xxx check thisProps`, thisProps);\n // console.log(`xxx check newProps`, newProps);\n // console.log(`xxx check thisState`, thisState);\n // console.log(`xxx check newState`, newState);\n // }\n\n // return check;\n // }\n\n componentDidMount() {\n const { userSettings } = this.props;\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n // configjs settings\n const areaMapSimple = isAreaMapSimple() || false;\n this.setState({ isAreaMapSimple: areaMapSimple });\n //\n const areaImageToState = isAreaImageToState() || false;\n this.setState({ isAreaImageToState: areaImageToState });\n //\n const isBoomgateCrane = _isBoomgateCrane() || false;\n this.setState({ isBoomgateCrane: isBoomgateCrane });\n\n const isLightingControl =\n userSettings?.application?.includes(\"smartLighting\") ||\n _isLightingControl() ||\n _isLightingControl();\n this.setState({ isLightingControl: isLightingControl });\n\n const { areaIds, areaImageFileNames, folderFilesList } = this.props;\n\n //console.log(`xxxxx componentDidMount areaIds `, areaIds);\n\n // AreaImage preloading\n //\n areaIds.forEach((areaId) => {\n const img = new Image();\n const imageFilename = areaImageFileNames.find?.(\n (item) => item.id === areaId\n )?.src;\n\n const imageSrc = process.env.PUBLIC_URL + \"/areas/\" + imageFilename;\n img.src = imageSrc;\n // see - https://stackoverflow.com/questions/42615556/how-to-preload-images-in-react-js\n // #REVIEW\n // Consider this comment about preloading with hooks\n // - https://stackoverflow.com/questions/42615556/how-to-preload-images-in-react-js/67924817#67924817\n //\n window[imageSrc] = img;\n img.onload = () => {\n if (false) {\n console.log(\n `check ok to collect data? IMAGE LOADED: Loaded `,\n areaId,\n ` image ${imageSrc}`\n );\n }\n let mapsLoaded = this.state.isMapLoaded;\n mapsLoaded.push(areaId);\n this.setState({\n isMapLoaded: mapsLoaded,\n });\n };\n });\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n componentDidUpdate(prevProps, prevState) {\n const {\n areaIds,\n isPokeTheWorker,\n isMoving,\n isDragging,\n mapImagesFromState,\n } = this.props;\n\n // #Note - mapImagesFromState is dependent on 'isAreaImageToState' = true\n const mapImageIds = [...mapImagesFromState.map((img) => img.id)];\n const isMapLoaded = [...this.state.isMapLoaded];\n\n const shouldTurnOnPokeTheWorker =\n (_isEqual(isMapLoaded.sort(), areaIds.sort()) ||\n _isEqual(mapImageIds.sort(), areaIds.sort())) && // all areas are loaded\n !isPokeTheWorker && // worker is already off\n (isMapLoaded.length > 0 || mapImageIds.length > 0) && // there are actually areas loaded through the fetch (i.e. not 0 state initial load situation where areaIds is empty )\n !isMoving && // the map isn't moving or popup is not displaying.\n !isDragging; // the map markers are not being dragged/repositioned\n\n if (false) {\n console.log(`check ok to collect data? - level`, this.props?.level?.id);\n\n console.log(\n `check ok to collect data? - _isEqual(isMapLoaded.sort(), areaIds)`,\n _isEqual(isMapLoaded.sort(), areaIds)\n );\n console.log(\n `check ok to collect data? - _isEqual(mapImageIds.sort(), areaIds)`,\n _isEqual(mapImageIds.sort(), areaIds)\n );\n console.log(\n `check ok to collect data? - isMapLoaded `,\n isMapLoaded,\n `areaIds`,\n areaIds\n );\n\n console.log(\n `check ok to collect data? - !isPokeTheWorker`,\n !isPokeTheWorker\n );\n console.log(\n `check ok to collect data? - isMapLoaded.length`,\n isMapLoaded.length\n );\n console.log(\n `check ok to collect data? - isMapLoaded.length`,\n mapImageIds.length\n );\n console.log(`check ok to collect data? - !isMoving)`, !isMoving);\n console.log(`check ok to collect data? - !isDragging)`, !isDragging);\n\n console.log(`check ok to collect data? - ----------------)`);\n console.log(\n `check ok to collect data? - shouldTurnOnPokeTheWorker)`,\n shouldTurnOnPokeTheWorker\n );\n console.log(`check ok to collect data? - ----------------)`);\n }\n\n // if loaded all areas turn on data again\n //\n // turn on data collecting again if ...\n if (shouldTurnOnPokeTheWorker) {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n }\n\n // #WIP - #TODO - MAKE COMMON\n // see - src/components/Map/MineLevelMapLeaflet.js\n // message banner support\n //\n //\n faultMessageBannerId = (faultType) => {\n // check if a message of this type exists\n\n // get the id for the flash message\n const messageBanners = this.props.messageBanners; // from redux state\n\n //console.log(`messageBanners`, messageBanners);\n return messageBanners[faultType].id;\n };\n\n clearFaultMessageBanner = (faultType) => {\n // get the id for the flash message\n const bannerId = this.faultMessageBannerId(faultType);\n\n //console.log(`message bannerId`, bannerId);\n if (bannerId) {\n this.props.removeFlashMessage(bannerId);\n //#REVIEW - make this a function..........\n // delete this banner message from state\n let tmpObj = {};\n tmpObj.faultType = faultType;\n tmpObj.display = false;\n tmpObj.id = \"\";\n\n this.props.SetMessageBanner(tmpObj);\n }\n };\n\n areaImageNotFoundMessage = (areaImageNotFound, imageFilename) => {\n const messageBanners = this.props?.messageBanners;\n\n if (messageBanners === undefined) return;\n\n // #NOTE - old comment, but still applies. Need to centralise function.\n //#REVIEW - force to one type for now - this needs to be merged with AlarmButtons and other messaging\n\n const bannerDisplayed = messageBanners[\"areaImageNotFound\"]?.display;\n let bannerInfo = messageBanners[\"areaImageNotFound\"]?.info || [];\n const isBannerDisplayedForThisImageFilename =\n bannerInfo?.includes(imageFilename);\n\n // console.log(`messageBanners`, messageBanners);\n // console.log(`messageBanners imageFilename`, imageFilename);\n // console.log(`messageBanners bannerInfo`, bannerInfo);\n // console.log(\n // `messageBanners isBannerDisplayedForThisImageFilename`,\n // isBannerDisplayedForThisImageFilename\n // );\n // console.log(`messageBanners ---------------------`);\n\n //\n if (isConfigJs() && faultMessageBannerDisplay()) {\n const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n // if this fault type allows message banner display (in config)\n // and there hasn't been a message banner displayed previously\n\n if (isMessageBannerForFaultType[\"areaImageNotFound\"]) {\n if (areaImageNotFound) {\n // set\n if (bannerDisplayed) {\n // banner already exists\n if (!isBannerDisplayedForThisImageFilename) {\n // update banner\n // clear current banner\n this.clearFaultMessageBanner(\"areaImageNotFound\");\n // set a new banner\n this.setFaultMessageBanner([...bannerInfo, imageFilename]);\n }\n } else {\n // no current banner\n // set a new banner\n this.setFaultMessageBanner([...bannerInfo, imageFilename]);\n }\n } else {\n // clear banner\n if (bannerDisplayed) {\n if (isBannerDisplayedForThisImageFilename) {\n // clear just this banner\n // clear current banner\n this.clearFaultMessageBanner(\"areaImageNotFound\");\n // set a new banner\n this.setFaultMessageBanner(\n bannerInfo.filter((file) => file !== \"B\")\n );\n }\n //\n }\n }\n }\n }\n };\n\n setFaultMessageBanner = (bannerInfo) => {\n console.log(`message bannerInfo`, bannerInfo);\n // set a new banner\n // create a unique ID for the banner\n const id = cuid();\n // display a new banner\n this.displayErrors(id, \"areaImageNotFound\", bannerInfo);\n\n // record the update state of banner including the id (needed to delete this particular banner)\n let tmpObj = {};\n tmpObj.faultType = \"areaImageNotFound\"; // #REVIEW - force to one status check type for now\n tmpObj.display = true;\n tmpObj.id = id;\n // multiple files : same\n tmpObj.info = bannerInfo;\n\n this.props.SetMessageBanner(tmpObj);\n };\n\n // get the text for the fault message banner from config.js or set default\n getFaultMessageBannerText = (faultType) => {\n let header;\n let message;\n let color;\n\n if (isConfigJs() && faultMessageBannerText()) {\n const messageBannerText = faultMessageBannerText(); // from config.js file\n header = messageBannerText[faultType].header;\n message = messageBannerText[faultType].message;\n color = messageBannerText[faultType].color;\n } else {\n // default messages if config.js object is stuffed\n switch (faultType) {\n case \"areaImageNotFound\":\n header = \"Area Image Can Not Be Found\";\n message =\n \"An area image can not be found on the server, or the server connection has failed. Check the server operation then log out/in.\";\n color = \"red\";\n break;\n default:\n break;\n }\n }\n\n return { header, message, color };\n };\n\n // loads header and message to display on control screen page\n // depending on significance of the error\n // All cases go to the Browser Logger page\n //\n displayErrors(id, faultType, info) {\n const { header, message, color } =\n this.getFaultMessageBannerText(faultType);\n\n // set color from highest fault_level for the faultType\n // const color = this.setColorMessageBanner(faultType);\n\n this.props.addWarningFlashMessageIdColor(\n id,\n color,\n header,\n message + \" \" + info.join(\", \") || \"Unknown problem\"\n );\n //console.log(\"message displayErrors - \" + header + \"-\" + message);\n }\n\n render() {\n const {\n level,\n displaySettings,\n isUserGuest,\n areaIds,\n areaImageFileNames,\n folderFilesList,\n strings,\n } = this.props;\n\n const {\n isBoomgateCrane,\n isLightingControl,\n isAreaMapSimple,\n isAreaImageToState,\n } = this.state;\n\n // custom SOP interface\n let sopInterface = displaySettings?.sopInterface;\n\n if (sopInterface === undefined) {\n sopInterface = true;\n }\n\n // CSS for Component\n // const styleMineLevelOpsControl = {\n // height: \"100%\",\n // };\n\n // const styleMineLevelMap = {\n // height: \"100vH\", // \"700px\",\n // width: \"100%\",\n // position: \"relative\",\n // zIndex: 0,\n // };\n\n // #NOTE #REVIEW #TODO - make common function\n //\n const { view } = displaySettings;\n let fontSize;\n let paddingBottom;\n switch (view) {\n case \"compressed\":\n fontSize = 0.6; // 30/50\n paddingBottom = 0.8;\n break;\n case \"normal\":\n fontSize = 1; // 50/50\n paddingBottom = 1;\n break;\n case \"expanded\":\n fontSize = 1.6; // 80/50\n paddingBottom = 1.2;\n break;\n default:\n fontSize = 1;\n paddingBottom = 1;\n break;\n }\n\n const styleInfo = { fontSize, paddingBottom };\n\n const { columnWidth } = displaySettings;\n let controlsWidth = columnWidth;\n let imageWidth = 16 - controlsWidth;\n\n let hideLeftColumn = false;\n if (controlsWidth === 0) {\n hideLeftColumn = true;\n }\n\n let hideRightColumn = false;\n if (controlsWidth === 16) {\n hideRightColumn = true;\n }\n\n // override if user is Guest or lighting control is not enabled\n if (isUserGuest || !isLightingControl) {\n controlsWidth = 0;\n imageWidth = 16;\n hideLeftColumn = true;\n }\n\n // console.log(\n // `this.state.isMapLoaded`,\n // JSON.stringify(areaIds),\n // JSON.stringify(this.state.isMapLoaded)\n // );\n\n // https://stackoverflow.com/questions/19183180/how-to-save-an-image-to-localstorage-and-display-it-on-the-next-page\n\n // You don't need the getBase64Image function.\n // Data urls are already base 64 so when you call reader.readAsDataURL\n // the e.target.result sent to the reader.onload handler will be all you need.\n\n function getBase64Image(img) {\n var canvas = document.createElement(\"canvas\");\n canvas.width = img.width;\n canvas.height = img.height;\n\n var ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n\n var dataURL = canvas.toDataURL(\"image/png\");\n\n return dataURL.replace(/^data:image\\/(png|jpg);base64,/, \"\");\n }\n\n return (\n
\n \n \n {!hideLeftColumn && (\n \n \n \n \n \n {level.name}\n
\n \n \n \n {!sopInterface && (\n \n )}\n {sopInterface && (\n // #REVIEW #TODO - a div of any size allows overflow to work - why???\n //
\n \n //
\n )}\n \n )}\n {hideRightColumn &&
}\n {!hideRightColumn && (\n \n {areaIds.map((areaId) => {\n //#NOTE - #WIP - ONLY RENDER ONE IMAGE\n //\n\n if (areaId === level.id) {\n // if (this.state.isMapLoaded.includes?.(areaId)) {\n // return (\n // // \n // \n // );\n // }\n\n const imageFilename = areaImageFileNames.find?.(\n (item) => item.id === areaId\n )?.src;\n\n const imageSrc =\n process.env.PUBLIC_URL + \"/areas/\" + imageFilename;\n\n let loadingMessage = ``;\n\n // is image already loaded and saved to State\n const isMapImageFromState =\n this.props.mapImagesFromState.find(\n (img) => img.id === areaId\n );\n\n const isMapLoaded =\n this.state.isMapLoaded.includes?.(areaId) ||\n isMapImageFromState;\n\n // #NOTE\n // #WIP\n // work out a solution for presenting the message banner without needing\n // to check file lists every render.\n // File image checks should be moved to startup/config process.\n //\n\n if (\n !folderFilesList?.includes(imageFilename) ||\n _isEmpty(imageFilename)\n ) {\n // set message banner\n //this.areaImageNotFoundMessage(true, imageFilename);\n loadingMessage = `Map image file ${imageSrc} can not be found please check Area settings.`;\n } else {\n // clear message banner\n //this.areaImageNotFoundMessage(false, imageFilename);\n loadingMessage = `.... loading map image file ${imageSrc}`;\n }\n\n // #NOTE\n // #REVIEW - the code below is duplicated in 'src/components/AreaImages/index.js'\n // is called in 'src/components/App/index.js'\n // to pre-load all images to memory.\n // The code below pre-dates , and should be removed after review of the\n // mapload process.\n //\n\n return (\n <>\n \n {loadingMessage}\n \n\n {/* #WIP - This is has been disabled to preference the image preload in componentDidMount */}\n {false && !isMapLoaded && (\n \n )}\n \n {/* \n {areaIds.map((areaId) => {\n // console.log(`areaImageFileNames`, areaId, areaImageFileNames);\n\n const imageSrc = `/areas/${\n areaImageFileNames.find?.((item) => item.id === areaId)?.src\n }`;\n\n // const ImageSrc={`/areas/extraction_7May21-2021-May-12-11-52-30.png`}\n\n return (\n <>\n \n Loading\n \n */}\n
\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const displaySettings = getNamedAreaDisplaySettings(state);\n\n const areas = getAllAreaStatuses(state) || [];\n const areaIds = areas.map((area) => area?.id);\n const areaImageFileNames = areas.map((area) => {\n return { id: area.id, src: area.image_filename };\n });\n\n // check for image files\n const folderFilesList = getFolderFileNamesListById(state, \"areas\");\n\n // message banner support\n const { messageBanners } = state.alarmButton;\n\n return {\n displaySettings,\n isUserGuest: isUserGuest(state),\n areaIds,\n areaImageFileNames,\n //\n folderFilesList,\n //\n messageBanners,\n //\n isPokeTheWorker: isOnOffPokeTheWorker(state),\n //\n isMoving: isMapMoving(state),\n isDragging: isDraggingMarker(state),\n //\n mapImagesFromState: getMapImages(state),\n };\n};\n\nconst mapDispatchToProps = (dispatch) => ({\n // flash message support\n clearFlashMessages: () => {\n dispatch(clearFlashMessages());\n },\n removeFlashMessage: (id) => {\n dispatch(removeFlashMessage(id));\n },\n addWarningFlashMessageIdColor: (id, color, header, message) => {\n dispatch(addWarningFlashMessageIdColor(id, color, header, message));\n },\n SetMessageBanner: (messageState) => {\n dispatch(SetMessageBanner(messageState));\n },\n TurnOnOffPokeTheWorker: (action) => {\n dispatch(TurnOnOffPokeTheWorker(action));\n },\n //\n SetMapImage: (action) => {\n dispatch(SetMapImage(action));\n },\n});\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(MineLevelOpsControl);\n","import React from \"react\";\nimport { Message } from \"semantic-ui-react\";\nimport { isDebugPagePropsMessages } from \"components/ConfigJs\";\n\n// isDebugPagePropsMessages() && (\n\nexport const DebugPagePropsMessages = ({ that }) => {\n const show = isDebugPagePropsMessages();\n return (\n show && (\n \n Page data:\n
Props {JSON.stringify(that.props, null, 2)}
\n
State {JSON.stringify(that.state, null, 2)}
\n
\n )\n );\n};\n","import React from \"react\";\nimport {\n Container,\n Segment,\n Grid,\n GridRow,\n GridColumn,\n} from \"semantic-ui-react\";\n\n// #REVIEW\n// ? style box with rounded corner box with separate padding\n// ? could change tooltips to semantic-ui for consistency, but would be a lot bigger\nconst LegendIcon = ({ icon, index }) => {\n return (\n
\n \"\"\n
\n {icon.text}\n \n {icon.tooltip}\n \n
\n
\n );\n};\n\nconst Legend = ({ icons }) => (\n \n \n \n \n {icons.map((value, index) => {\n return (\n \n \n \n );\n })}\n \n \n \n \n);\n\nexport default Legend;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Header,\n Divider,\n Tab,\n Grid,\n Container,\n Message,\n} from \"semantic-ui-react\";\n\nimport ActiveOperationChangesList from \"pages/ControlRoomPage/ActiveOperationalChangesList\";\nimport { MineLevelContext } from \"ApplicationContexts\";\nimport { getAllMineLevels } from \"MineLevels/reducer\";\nimport { fetchMineLevels } from \"MineLevels/actions\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { LayersControl } from \"react-leaflet\";\nimport MineLevelMap from \"components/MineLevelMap\";\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroup\";\nimport CurrentSeismicFeatureGroup from \"containers/CurrentSeismicFeatureGroup\";\n\nimport MineLevelOpsControl from \"pages/ControlRoomPage/MineLevelOpsControl\";\n\nimport {\n getAllAreaStatuses,\n getMqttDataLoading,\n} from \"components/WebWorker/reducer\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { isConfigJs, TemplateDefaultArea } from \"components/ConfigJs\";\n\nimport Legend from \"components/Legend\";\nimport { legend } from \"components/ConfigJs\";\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport { strings } from \"components/App/localisation\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport { getUserData } from \"auth/reducer\";\n\nclass GeneralHomePage extends Component {\n render() {\n const { levels, isDataLoading, namedAreaDisplaySettings, userSettings } =\n this.props;\n\n const { legend: isShowLegend, sopInterface: isSopInterface } =\n namedAreaDisplaySettings;\n\n const configJs = isConfigJs();\n // check if the default area is loading correctly from config.js\n // if this load fails the webworker may never return a valid areaStatuses\n // resulting in an endless 'data loading' sequence.\n\n const startupProblem = !configJs || _isEmpty(levels);\n const templateDefaultArea = TemplateDefaultArea();\n\n if (startupProblem) {\n console.log(\"LOADING ERROR: NO AREAS TO DISPLAY.\");\n console.log(\"CHECK IF CONFIG.JS IS LOADED OK.....? - \", configJs);\n console.log(\n \"DEFAULT AREA TEMPLATE LOADED - \",\n JSON.stringify(templateDefaultArea)\n );\n }\n\n return (\n <>\n {startupProblem && (\n
\n \n \n \n \n \n \n \n {/* dummy row for spacing consistency */}\n \n ({\n menuItem: strings?.[\"Loading ...\"],\n render: () => (\n \n \n \n ),\n }))}\n />\n \n \n
\n )}\n {!startupProblem && (\n
\n \n \n \n \n {/*
Light Status
*/}\n
\n \n \n \n
\n
\n ({\n menuItem: level.name,\n render: () => (\n \n \n \n ),\n }))}\n />\n {isShowLegend && }\n \n
\n
\n )}\n \n );\n }\n}\n\nfunction mapStateToProps(state) {\n const thisUser = getUserData(state);\n\n return {\n levels: getAllAreaStatuses(state),\n isDataLoading: getMqttDataLoading(state),\n namedAreaDisplaySettings: getNamedAreaDisplaySettings(state),\n userSettings: thisUser?.settings || {},\n };\n}\n\nexport default connect(mapStateToProps, { fetchMineLevels })(GeneralHomePage);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Grid, Segment } from \"semantic-ui-react\";\n\n//import NamedAreaOperationsList from \"./NamedAreaOperationsList\";\n\nimport NamedAreaDisplaySettings from \"pages/ControlRoomPage/NamedAreaDisplaySettings\";\n\nimport Map from \"components/Map/MineLevelMapLeaflet\";\nimport MineLevelPrecannedOperationsList from \"pages/ControlRoomPage/MineLevelPrecannedOperationsList\";\nimport MineLevelCustomSOPList from \"pages/ControlRoomPage/MineLevelCustomSOPList\";\n\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\n// railway_application\nimport { isBoomgateCrane } from \"components/ConfigJs\";\n\nimport { isUserGuest } from \"auth/reducer\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nclass MineLevelOpsControl extends Component {\n constructor(props) {\n super(props);\n this.state = {\n columnWidth: 6,\n };\n }\n render() {\n const {\n level,\n displaySettings,\n isUserGuest,\n areaIds,\n strings,\n userSettings,\n } = this.props;\n\n // railway_application\n const boomgateCrane = isBoomgateCrane() || false;\n\n // custom SOP interface\n let sopInterface = displaySettings?.sopInterface;\n\n if (sopInterface === undefined) {\n sopInterface = true;\n }\n\n // CSS for Component\n // const styleMineLevelOpsControl = {\n // height: \"100%\",\n // };\n\n // const styleMineLevelMap = {\n // height: \"100vH\", // \"700px\",\n // width: \"100%\",\n // position: \"relative\",\n // zIndex: 0,\n // };\n\n // #NOTE #REVIEW #TODO - make common function\n //\n const { view } = displaySettings;\n let fontSize;\n let paddingBottom;\n switch (view) {\n case \"compressed\":\n fontSize = 0.6; // 30/50\n paddingBottom = 0.8;\n break;\n case \"normal\":\n fontSize = 1; // 50/50\n paddingBottom = 1;\n break;\n case \"expanded\":\n fontSize = 1.6; // 80/50\n paddingBottom = 1.2;\n break;\n default:\n fontSize = 1;\n paddingBottom = 1;\n break;\n }\n\n const styleInfo = { fontSize, paddingBottom };\n\n // override if user is Guest\n if (isUserGuest) {\n // #WIP - what to do for guest?\n }\n\n return (\n
\n \n \n \n {!sopInterface && (\n \n )}\n {sopInterface && (\n // #REVIEW #TODO - a div of any size allows overflow to work - why???\n //
\n \n //
\n )}\n \n
\n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const displaySettings = getNamedAreaDisplaySettings(state);\n\n const areas = getAllAreaStatuses(state) || [];\n const areaIds = areas.map((area) => area.id);\n\n return {\n displaySettings,\n isUserGuest: isUserGuest(state),\n areaIds,\n };\n};\n\nexport default connect(mapStateToProps, null)(MineLevelOpsControl);\n","import React, { Component, useState } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport L from \"leaflet\";\nimport \"leaflet-draw\";\nimport \"leaflet-contextmenu\";\nimport { greenIcon } from \"assets/leaflet/leaflet-color-markers\";\nimport { LeastSquaresApproximationFourPointsSixParametersTransformation } from \"projection\";\nimport {\n getMapState,\n getFireflyCoordinates,\n getNamedAreaInfos,\n getNamedAreaDeleteSelections,\n getNamedAreaHideSelections,\n getIsDirty,\n} from \"components/WebWorker/reducer\";\n\nimport {\n namedAreaClearDeleteSelections,\n namedAreasSetIsDirty,\n mqttPublish,\n} from \"components/WebWorker/actions\";\n\nimport { GetLocalMap } from \"components/Map/reducer\";\nimport { UpdateLocalMap } from \"components/Map/actions\";\n\nimport { round } from \"utils/number-utils.js\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport * as turf from \"@turf/turf\";\n\nimport { makeIcon } from \"components/Map/MakeIcon\";\n\n// import plugin's css (if present)\n// note, that this is only one of possible ways to load css\nimport \"leaflet-contextmenu/dist/leaflet.contextmenu.css\";\nimport { messageToken } from \"utils/messageToken\";\n\n// #REVIEW - move this.locationGroupLayers etc. to state rather than forced via \"this.\"\n// use setState to update once groups are defined\n\nclass Map extends React.Component {\n constructor(props) {\n super(props);\n\n this.state = {\n refPts: {},\n thislocalMapState: {},\n map: { area: \"DMLZ_Extraction\" },\n heartBeat: true,\n };\n }\n\n // styling for polygons\n geojsonPolygonStyle = (feature) => {\n let setFillColor;\n if (feature.properties.active_color) {\n const color = feature.properties.active_color;\n switch (color.toLowerCase) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"yellow\";\n break;\n case \"red\":\n setFillColor = \"red\";\n break;\n\n default:\n setFillColor = \"green\";\n break;\n }\n }\n\n return {\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.5,\n };\n };\n\n localPts = () => {\n // measured from pixel positions\n const localRef1 = {\n id: \"localRef1\",\n lat: 4764,\n lng: 4202,\n easting: 736959.54,\n northing: 9549076.153,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef2 = {\n id: \"localRef2\",\n lat: 3236,\n lng: 7815,\n easting: 737526.058,\n northing: 9549315.041,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef3 = {\n id: \"localRef3\",\n lat: 5978,\n lng: 10090,\n easting: 737883.021,\n northing: 9548885.911,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef4 = {\n id: \"localRef4\",\n lat: 7611,\n lng: 8061,\n easting: 737564.472,\n northing: 9548630.213,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n return [localRef1, localRef2, localRef3, localRef4];\n };\n\n markerPts = (img) => {\n const { width, height } = img;\n\n // image pixel positions = lat,lng\n // geometric refernece coord = easting, northing, zoneNum, zoneLetter,\n // {lat, lng, easting, northing, zoneNum, zoneLetter}\n\n const markerOrigin = {\n lat: 0,\n lng: 0,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n const markerMiddle = {\n lat: height / 2,\n lng: width / 2,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n const markerMax = {\n lat: height,\n lng: width,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n\n return [markerOrigin, markerMiddle, markerMax];\n };\n\n // creates a geoJson object for the map reference points\n // pass in map pixel ref lat,lng and the coord reference easting, northing\n // geometry coordinats are in pixels\n //\n // e.g. localPtsGeoJson([{ lat: 0, lng: 0, easting: 0, northing: 0, zoneNum: 53, zoneLetter: \"M\", z: 0 },...[...]);\n //\n // still using lat and lng because leaflet uses these references.\n //\n localPtsGeoJson = (points) => {\n let localPtsGeoJson = [];\n points.map(\n ({ id, lat, lng, easting, northing, zoneNum, zoneLetter }, idx) => {\n const objLatLng = { lat: lng, lng: lat }; // #REVIEW - have swapped around lat and long **ADRESS THIS**\n const point = Object.values(objLatLng);\n\n // structure geoJSON object\n\n const geojsonFeature = {\n id,\n type: \"Feature\",\n properties: {\n index: idx,\n id: id,\n area: \"refArea\",\n location: \"refPt\",\n position: idx,\n easting: easting,\n northing: northing,\n utm_zone_number: zoneNum,\n utm_zone_letter: zoneLetter,\n z: 0,\n color: \"toBeDone\",\n },\n geometry: {\n type: \"Point\",\n coordinates: point,\n },\n };\n localPtsGeoJson.push(geojsonFeature);\n }\n );\n return {\n type: \"FeatureCollection\",\n features: localPtsGeoJson,\n };\n };\n\n standardPtsUtm = () => {\n // #TODO - this is duplicated in localPts()\n const ref1utm = {\n northing: 9549076.153,\n easting: 736959.54,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref2utm = {\n northing: 9549315.041,\n easting: 737526.058,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref3utm = {\n northing: 9548885.911,\n easting: 737883.021,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref4utm = {\n northing: 9548630.213,\n easting: 737564.472,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n\n // rest UTM values\n const standardRef1 = { lat: ref1utm.easting, lng: ref1utm.northing };\n const standardRef2 = { lat: ref2utm.easting, lng: ref2utm.northing };\n const standardRef3 = { lat: ref3utm.easting, lng: ref3utm.northing };\n const standardRef4 = { lat: ref4utm.easting, lng: ref4utm.northing };\n\n const standardAll = [\n standardRef1,\n standardRef2,\n standardRef3,\n standardRef4,\n ];\n\n return standardAll;\n };\n\n // the geometric coordinate to map pixel transformation\n Transform = (localPts, standardPts) => {\n const LeastSq4Pt =\n LeastSquaresApproximationFourPointsSixParametersTransformation.fromPoints(\n localPts,\n standardPts\n );\n return LeastSq4Pt;\n };\n\n // create geojson markerData\n markerToGeoJSON = (markersData, transform) => {\n const geoJSONMarkersData = [];\n\n markersData.map(\n ({ id, lat, lng, name, color, position, location }, idx) => {\n // transform the point from latlng to pixels\n const objLatLng = { lat: lat, lng: lng };\n const point = Object.values(transform.transform(objLatLng));\n\n // structure geoJSON object\n const geojsonFeature = {\n type: \"Feature\",\n properties: {\n id: id,\n name: name,\n color: color,\n position: position,\n location: location,\n },\n geometry: {\n type: \"Point\",\n coordinates: point,\n },\n };\n geoJSONMarkersData.push(geojsonFeature);\n }\n );\n return {\n type: \"FeatureCollection\",\n features: geoJSONMarkersData,\n };\n };\n\n // support for map leaflet.contextmenu\n showCoordinates = (e) => {\n alert(e.latlng);\n };\n\n centerMap = (e) => {\n this.map.panTo(e.latlng);\n };\n\n fitMap = (e, bounds) => {\n this.map.fitBounds(bounds);\n };\n\n zoomIn = (e) => {\n this.map.zoomIn();\n };\n\n zoomOut = (e) => {\n this.map.zoomOut();\n };\n\n // draw\n drawTheMap = (mapId, url, geoJSONMarkersData, geoJSONNamedAreas) => {\n ////////////////////////////////////////////////////////////////////////////\n // Conversion from (x, y) raster image coordinates to equivalent of latLng\n // Taken from Leaflet tutorial \"Non-geographical maps\"\n // http://leafletjs.com/examples/crs-simple/crs-simple.html\n ////////////////////////////////////////////////////////////////////////////\n var yx = L.latLng;\n var xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n };\n\n var minZoom = 2; // no need for zoom out completely\n var maxZoom = 6; // ...as defined by tile generation\n const width = 12571;\n const height = 9571;\n\n const img = [\n width, // original width of image `level.jpg` - undercut 800 conversion example => x / ~longitude (0 is left, width, 13234 is right)\n height, // original height of image => y / ~ reverse of latitude (0 is top, height, 9356 is bottom)\n ];\n\n // const { markersData, geoJSONMarkersDataUtm } = this.props;\n\n // // let geoJSONMarkersData = this.markerToGeoJSON(\n // // markersData,\n // // this.Transform(this.localPts(), this.standardPts())\n // // );\n\n // let geoJSONMarkersData = geoJSONMarkersDataUtm;\n // //console.log(\"geoJSONMarkersData TEST\", geoJSONMarkersDataUtm);\n // console.log(\"geoJSONMarkersData markerToGeoJSON\", geoJSONMarkersData);\n\n //break into subgroups for testing - only \"P23\"\n let subGroupData = [];\n\n geoJSONMarkersData.features.map(({ properties }, idx) => {\n const { location } = properties;\n\n if (location === \"P23\") {\n subGroupData.push(geoJSONMarkersData.features[idx]);\n }\n });\n\n subGroupData = {\n type: \"FeatureCollection\",\n features: subGroupData,\n };\n\n //all the resting - but not \"P23\"\n\n let tempGroupData = [];\n\n geoJSONMarkersData.features.map(({ properties }, idx) => {\n const { location } = properties;\n\n if (location !== \"P23\") {\n tempGroupData.push(geoJSONMarkersData.features[idx]);\n }\n });\n\n tempGroupData = {\n type: \"FeatureCollection\",\n features: tempGroupData,\n };\n\n // reassign main group to not have P23\n // geoJSONMarkersData = tempGroupData;\n\n //console.log(\"geoJSONMarkersData\", geoJSONMarkersData);\n\n /**\n *\n * Tile 0/0/0 is 256 x 256 px, and so are all other tiles.\n * gda2tile-leaflet sets tiles with reference to top left.\n *\n * In tile 0/0/0 width, height coordinate is 206, 146,\n * requiring a 1/64 scaling. i.e. e.g. 206/13234 = 64.\n * There is no offset. i.e. image is in top left\n * a = 1/64\n * b = 0\n * c = 1/64\n * d = 0\n *\n */\n\n L.CRS.MySimple = L.extend({}, L.CRS.Simple, {\n // coefficients: a b c d\n transformation: new L.Transformation(1 / 64, 0, 1 / 64, 0),\n });\n\n // center calculation based on original pixel dimensions\n //\n const center = [img[0] / 2, img[1] / 2];\n\n var bounds = L.latLngBounds([xy(0, 0), xy(img)]);\n\n let base = L.tileLayer(url, {\n bounds: bounds, // http://leafletjs.com/reference-1.0.3.html#gridlayer-bounds\n noWrap: true,\n });\n\n this.map = L.map(mapId, {\n crs: L.CRS.MySimple, // http://leafletjs.com/reference-1.0.3.html#map-crs\n maxBounds: bounds.pad(0.5), // http://leafletjs.com/reference-1.0.3.html#map-maxbounds\n minZoom: minZoom,\n maxZoom: maxZoom,\n attributionControl: false,\n contextmenu: false, // context menu plugin `npm i leaflet-contextmenu`\n contextmenuWidth: 140,\n contextmenuItems: [\n {\n text: \"Show coordinates\",\n callback: this.showCoordinates,\n },\n {\n text: \"Center map here\",\n callback: this.centerMap,\n },\n {\n text: \"Show all\",\n callback: (e) => this.fitMap(e, bounds),\n },\n \"-\",\n {\n text: \"Zoom in\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-in.png\",\n callback: this.zoomIn,\n },\n {\n text: \"Zoom out\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-out.png\",\n callback: this.zoomOut,\n },\n ],\n }).setView(xy(center), 2); // move view to center pixel position\n\n // setup a dummy image and load the map image in the background\n // create a replacement image using known dimensions\n let canvas = document.createElement(\"canvas\");\n // set desired size of transparent image\n canvas.width = width;\n canvas.height = height;\n // extract as new image (data-uri)\n let overlayUrl = canvas.toDataURL();\n\n // #WIP - setup switch to move between blank background and area\n overlayUrl = url;\n\n // set single image background\n const image = L.imageOverlay(overlayUrl, bounds);\n image.addTo(this.map);\n\n // setup layer for geoJSON data\n\n var geojsonMarkerOptions = {\n radius: 6,\n fillColor: \"#ff7800\",\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n contextmenu: true, // contextmenu items for each geoJson marker\n contextmenuItems: [\n {\n text: \"Additional entry for this marker...\",\n },\n ],\n };\n\n // setup a pen for waylaid fireflies\n\n // #WIP - pen\n // #REVIEW\n // - https://www.npmjs.com/package/@turf/boolean-point-in-polygon\n // - http://turfjs.org/\n\n // holding pen is top corner starting from 75% in and ending 25% down\n\n this.holdingPen = L.polygon([\n [0, width * 0.75],\n [0, width],\n [height * 0.25, width],\n [height * 0.25, width * 0.75],\n ]).addTo(this.map);\n // -> see randomPointInPoly function\n\n // setup layer for geoJSON data\n // this.geoJSONGroupLayer = L.geoJSON(geoJSONMarkersData, {\n // pointToLayer: function(feature, latlng) {\n // return L.circleMarker(latlng, geojsonMarkerOptions);\n // },\n // }).addTo(this.map);\n\n this.layerlistFireflies = {};\n\n // #REVIEW - https://stackoverflow.com/questions/46580213/pass-a-parameter-to-oneachfeature-leaflet\n // should pass layerlistFireflies and stuff through instead of using scope to access\n // ....?\n function onEachFeatureClosure(stuff) {\n return function onEachFeature(feature, layer) {\n // does this feature have a property named popupContent?\n if (feature.properties && feature.properties.id) {\n layer.bindPopup(JSON.stringify(feature)); //feature.properties.name\n this.layerlistFireflies[feature.properties.id] = layer;\n }\n\n // Attempt to split data to different layers\n // if (feature.properties.location == \"P23\") {\n // // see - https://stackoverflow.com/questions/10953303/javascript-interpret-string-as-object-reference\n // let tempStr = \"p23GroupLayer\";\n // this[tempStr].addLayer(layer);\n // // this.p23GroupLayer.addLayer(layer);\n // }\n\n if (\n feature.properties &&\n feature.properties.location\n // &&\n // feature.properties.location === \"P23\"\n ) {\n //let tempStr = \"P23\";\n //let tempStr = `${feature.properties.location}`;\n this[`${feature.properties.location}`].addLayer(layer);\n }\n };\n }\n\n // #REVIEW\n // change coordinate order\n // https://gis.stackexchange.com/questions/246102/leaflet-reads-geojson-x-y-as-y-x-how-can-i-correct-this\n // L.geoJSON(geoJsonData, {\n // coordsToLatLng: function (coords) {\n // // latitude , longitude, altitude\n // //return new L.LatLng(coords[1], coords[0], coords[2]); //Normal behavior\n // return new L.LatLng(coords[0], coords[1], coords[2]);\n // },\n // });\n\n this.testExternalStr = \"Point:\"; // test passing variable outside into ....\n\n // add popup information\n const onEachFeatureFirefly = (feature, layer) => {\n // #REVIEW - does this feature have a property named popupContent?\n\n const { properties } = feature;\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_number,\n utm_zone_letter,\n z,\n color,\n } = properties;\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n if (feature.properties && feature.properties.id) {\n layer.bindPopup(\n `
${id}
\n
${this.testExternalStr} ${area}:${location}:${position}
\n
Geom: E:${round(easting, 2)} N:${round(\n northing,\n 2\n )} Z${Math.trunc(z)} ${utm_zone_number} ${utm_zone_letter}
\n
Image: X:${X} Y:${Y}
\n
Color: ${color}
`\n );\n\n this.layerlistFireflies[feature.properties.id] = layer;\n }\n\n // Attempt to split data to different layers\n // if (feature.properties.location == \"P23\") {\n // // see - https://stackoverflow.com/questions/10953303/javascript-interpret-string-as-object-reference\n // let tempStr = \"p23GroupLayer\";\n // this[tempStr].addLayer(layer);\n // // this.p23GroupLayer.addLayer(layer);\n // }\n\n if (\n feature.properties &&\n feature.properties.location\n // &&\n // feature.properties.location === \"P23\"\n ) {\n //let tempStr = \"P23\";\n //let tempStr = `${feature.properties.location}`;\n\n // adds a separate layer specifically for location\n this[`${feature.properties.location}`].addLayer(layer);\n\n // this.map.addLayer(this[`${feature.properties.location}`]);\n }\n\n // shift/transform the coordinate\n // https://gis.stackexchange.com/questions/85358/adding-offset-to-geojson-layer-in-leaflet\n // var coords = feature.geometry.coordinates;\n // //var lengthOfCoords = feature.geometry.coordinates.length;\n\n // // #REVIEW - need to change this for polyLine\n // coords[0] = coords[0] + 100;\n // coords[1] = coords[1] + 100;\n\n // // draw the marker again at new point\n // L.circleMarker(coords, geojsonMarkerOptions);\n\n // const objLatLng = {\n // lat: feature.geometry.coordinates[0] + 100,\n // lng: feature.geometry.coordinates[1] + 100,\n // };\n // //const point = Object.values(this.transform.transform(objLatLng));\n // const point = Object.values(objLatLng);\n // feature.geometry = {\n // type: \"Point\",\n // coordinates: point,\n // };\n };\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayer = (feature, latlng) => {\n return L.circleMarker(latlng);\n };\n\n // set style of firefly markers\n const fireflyStyle = (feature) => {\n let setFillColor;\n if (feature.properties.color) {\n switch (feature.properties.color) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"yellow\";\n break;\n case \"red\":\n setFillColor = \"red\";\n break;\n\n default:\n setFillColor = \"green\";\n break;\n }\n }\n\n return {\n radius: 6,\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n };\n\n // -------------- add all locations as\n // Test draw layer by LOCATIONS\n // draw all locations to separate layers\n // filter to a specific location\n\n // map to\n // create separate arrays for each LOCATION............\n\n // determine unique properties array from geoJson\n //\n // https://stackoverflow.com/questions/56993304/extract-properties-and-unique-values-from-geojson-collection\n\n // console.log(\n // \"geoJSONMarkersData.features - uniqueProperties\",\n // geoJSONMarkersData.features\n // );\n let uniqueProperties = geoJSONMarkersData.features.reduce(\n (acc, { properties }) => {\n Object.entries(properties).forEach(([key, val]) => {\n acc[key] = acc[key] || new Set();\n acc[key].add(val);\n });\n\n return acc;\n },\n {}\n ); // uniqueProperties[key] returns a SET. Convert to array [...uniqueProperties[key]]\n\n // for (const key in uniqueProperties) {\n // console.log(\"uniqueProperties\", `${key} => ${[...uniqueProperties[key]]}`);\n // }\n\n //https://stackoverflow.com/questions/4340227/sort-mixed-alpha-numeric-array\n\n // sort the locations so they list in order on the screen\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let locations = [];\n this.locationGroupLayers = {};\n if (uniqueProperties[\"location\"]) {\n locations = [...uniqueProperties[\"location\"]].sort(sortAlphaNum);\n locations.forEach((value, idx) => {\n //console.log(\"locations[idx]\", value);\n this[value] = L.featureGroup().addTo(this.map);\n this.locationGroupLayers[value] = this[value];\n });\n }\n\n // #REVIEW - Issue is that with growing array location groups are not created on startup.\n // Need to make these with each update of the state geoJson\n\n // constrain to area\n const filterArea = (feature, layer) => {\n return feature.properties.area === this.state.map.area; // \"DMLZ_Extraction\";\n };\n\n // add firefly markers to the map\n this.geoJSONGroupLayer = L.geoJSON(geoJSONMarkersData, {\n pointToLayer: pointToLayer,\n onEachFeature: onEachFeatureFirefly,\n style: fireflyStyle,\n //coordsToLatLng: coordsToLatLng, // <<--- #REVIEW I still don't underestand what this does\n filter: filterArea,\n }).addTo(this.map);\n\n // ********************************************************************************\n //\n // Set and draw the marker points - map scaling points and origin/centre/max markers\n //\n // ********************************************************************************\n\n // setup scaling coord reference point markers\n const onEachFeatureMarker = (feature, layer) => {\n layer.bindPopup(\n \"ref pt:\" +\n JSON.stringify(feature.properties.index) +\n \" => \" +\n JSON.stringify(feature.geometry.coordinates)\n );\n layer.on(\"dragend\", function (e) {\n const marker = e.target;\n const position = marker.getLatLng();\n console.log(\"xxx dragend refPt position\", position);\n marker\n .setLatLng(position, { draggable: \"true\" })\n .bindPopup(\"\" + position) // #REVIEW \"\" is hack as bindPopup will not accept just numbers\n .update();\n });\n layer.on(\"click\", (e) => {\n // transform from pixels to points\n const transform = this.Transform(\n this.standardPtsUtm(),\n this.localPts()\n );\n const marker = e.target;\n const position = marker.getLatLng();\n console.log(\"xxx dragend refPt position\", JSON.stringify(position));\n\n const objLatLng = transform.transform({\n lat: position.lat,\n lng: position.lng,\n });\n\n console.log(\n \"xxx feature.properties\",\n JSON.stringify(feature.properties)\n );\n\n const id = `ID:${feature.properties.id}`;\n\n // original geoJson coordinates\n const geoJsonPt = `E:${feature.properties.easting}, N:${feature.properties.northing}`;\n // image coordinates\n const imagePt = Object.values(position); //.reverse(); // map is y, x referenced. Reverse to display as x,y.\n // transformed image -> physical\n const coordPt = Object.values(objLatLng); //.reverse();\n\n marker\n .setLatLng(position, { draggable: \"true\" })\n .bindPopup(\n `
${id}
\n\n
GeoJ: ${geoJsonPt}
\n
Image: ${round(imagePt[0], 2)},${round(imagePt[1], 2)}
\n
Coord: ${round(coordPt[0], 2)},${round(coordPt[1], 2)}
`\n )\n .update();\n\n console.log(`xxx clicked - Ref Pt marker - UTM Coords:[${coordPt}]`);\n });\n };\n\n // add markers to map\n this.markerGroupLayer = L.geoJSON(\n this.localPtsGeoJson(this.markerPts({ width, height })),\n {\n pointToLayer: function (feature, latlng) {\n return L.marker(latlng, {\n //icon: greenIcon, // <--- #TODO FIX THIS!\n draggable: true,\n });\n },\n onEachFeature: onEachFeatureMarker,\n }\n ).addTo(this.map);\n\n // add coord reference point markers to map\n\n this.refPtGroupLayer = L.geoJSON(this.localPtsGeoJson(this.localPts()), {\n pointToLayer: function (feature, latlng) {\n return L.marker(latlng, {\n //icon: greenIcon, // <--- #TODO FIX THIS!\n draggable: true,\n });\n },\n onEachFeature: onEachFeatureMarker,\n }).addTo(this.map);\n\n // AWESOME FONT IDEA\n // https://gis.stackexchange.com/questions/90017/change-default-leaflet-marker-color\n\n // ********************************************************************************\n //\n // Setup and draw the named area polygons\n //\n // ********************************************************************************\n\n // list of named area polygons\n this.layerlistNamedAreas = {};\n\n const onEachFeatureNamedAreas = (feature, layer) => {\n if (feature.properties && feature.properties.id) {\n this.layerlistNamedAreas[feature.properties.id] = layer;\n }\n layer.on(\"click\", (e) => {\n //console.log(\"na click feature.properties.id\", feature.properties.id);\n\n const id = feature.properties.id.split(\":\")[1]; // eg. from \"DMLZ_Extraction:182736182736\" -> \"182736182736\"\n const namedAreaPolygon = e.target;\n namedAreaPolygon.bindPopup(`
Named Area: ${id}
`);\n });\n };\n\n // check if geoJSONNamedAreas has any areas\n // if not add at least one!\n // #REVIEW/TODO - this default should come from the setting in db\n //\n const defaultNamedArea = {\n type: \"Feature\",\n properties: {\n id: \"defaultNamedArea\",\n name: \"defaultNamedArea\",\n parent: \"parentNamedArea\", // #REVIEW/TODO - pass in parent Named Area\n area: \"DMLZ_Extraction\",\n priority: 1,\n Firefly_List: \"\",\n active_color: \"AMBER\",\n active_state: \"ON\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"off\",\n color: \"amber\",\n\n // #REVIEW/TODO/WIP - yet to be implemented\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"off\",\n color: \"green\",\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 3,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"off\",\n color: \"green\",\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 4,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"green\",\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n ],\n },\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [737809.166, 9549066.886],\n [737703.561, 9549063.944],\n [737584.687, 9548925.63],\n [737646.288, 9548887.191],\n [737658.232, 9548897.419],\n [737726.042, 9548853.966],\n [737785.321, 9548838.814],\n [737837.514, 9548897.337],\n [737848.083, 9548938.28],\n [737750.6, 9549001.738],\n [737809.166, 9549066.886],\n ],\n ],\n },\n };\n\n // add feature 'default' for startup\n // disable. Used for debugging\n if (false) {\n geoJSONNamedAreas.features.push(defaultNamedArea);\n console.log(\n \"this.editableLayers geoJSONNamedAreaGroupLayer geoJSONNamedAreas\",\n JSON.stringify(geoJSONNamedAreas)\n );\n }\n\n // add named area polygons to the map\n this.geoJSONNamedAreaGroupLayer = L.geoJSON(geoJSONNamedAreas, {\n style: this.geojsonPolygonStyle,\n onEachFeature: onEachFeatureNamedAreas,\n }).addTo(this.map);\n\n // update leaflet id to properties (used to delete.edit shapes in local state)\n this.geoJSONNamedAreaGroupLayer.eachLayer(function (layer) {\n layer.feature.properties._leaflet_id = layer._leaflet_id; //#TODO - change to L.Stamp()\n });\n\n //#TODO - change to L.Stamp()\n // Also note that .getLayers() works for LayerGroup (and FeatureGroup and GeoJson), but not for L.Map.\n // Usage of \"private\" properties and methods like _layers or _leaflet_id or _latlng is discouraged.\n\n // add layers to the local maps state\n const geoJsonPixels = this.geoJSONNamedAreaGroupLayer.toGeoJSON();\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(geoJsonPixels);\n\n //console.log(\"qqq add layers to the local maps state geoJson\", geoJsonUtm);\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // push layer to back layer.bringToFront()\n this.geoJSONNamedAreaGroupLayer.bringToBack();\n\n // ********************************************************************************\n //\n // Setup the map layers into control groups and display controls\n //\n // ********************************************************************************\n\n // setup layer groups\n let baseLayers = { MineMap: base };\n // setup layer groups overlayers (see also https://leafletjs.com/reference-1.6.0.html#control-layers-addoverlay)\n let overLayers = {\n FireFly: this.geoJSONGroupLayer,\n Marker: this.markerGroupLayer,\n RefPt: this.refPtGroupLayer,\n Polygon: this.geoJSONNamedAreaGroupLayer,\n };\n\n // spread the objects to join the location layers to the overlay\n overLayers = { ...overLayers, ...this.locationGroupLayers };\n\n // define layer control\n var layerControl = L.control.layers(baseLayers, overLayers, {\n collapsed: false, //\n });\n\n // add it to the map\n layerControl.addTo(this.map);\n\n // // see - https://groups.google.com/forum/#!searchin/leaflet-js/control$20onadd/leaflet-js/rKMZX3PKFuI\n // // then remove the control container\n // layerControl._container.remove();\n\n // // append the control container to the other div\n // document\n // .getElementById(\"custom-map-controls\")\n // .appendChild(layerControl.onAdd(this.map));\n\n // ********************************************************************************\n //\n // Set polylines joining the Fireflies\n //\n //\n // NOTE: this has to be done after the locationGroupLayers has been rendered\n // ...probably more likely need layer control defined before start adding groups\n //\n // #REVEW <--- reorder the code\n // ********************************************************************************\n\n // step through the list of locationGroupLayers\n this.polylineGroupLayers = {};\n\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n // create an object with the posObject[position] = latlng coordinates\n let posObject = {};\n\n // loop each layer - #REVIEW - this could be labourious - perhaps only do if selected to display?\n // eslint-disable-next-line no-loop-func\n value.eachLayer(function (layer) {\n posObject[layer.feature.properties.position] = layer.getLatLng();\n });\n\n // sort the posObject by position order (i.e. object key) so line draws from position 1 -> n\n\n // see - https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key\n const ordered = {};\n Object.keys(posObject)\n .sort()\n .forEach(function (key) {\n ordered[key] = posObject[key];\n });\n\n // plot a polyline using ordered array of values\n // create name object from layer name (i.e. key is the POSITION)\n const layerName = \"poly_\" + key;\n this[layerName] = L.polyline(Object.values(ordered)).addTo(this.map);\n\n // add this layer to layer group to add to control layer later\n this.polylineGroupLayers[layerName] = this[layerName];\n\n // add individual layer\n // see - https://gis.stackexchange.com/questions/161940/how-to-add-layers-and-update-layer-control-dynamically-leaflet\n // layerControl.addOverlay(this[layerName], layerName);\n }\n\n // add group to overlays by iterating over the object\n // https://stackoverflow.com/questions/55471295/adding-multiple-overlays-to-leaflets-layers-control\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n layerControl.addOverlay(value, key);\n }\n\n // #REVIEW - setup ordering layers for all levels with toggle\n // setup layer control events\n // https://stackoverflow.com/questions/14103489/leaflet-layer-control-events\n this.map.on(\"overlayadd\", onOverlayAdd);\n\n function onOverlayAdd(e) {\n // https://gis.stackexchange.com/questions/137061/how-to-change-layer-order-in-leaflet-js\n // push layer to back layer.bringToFront()\n\n if (e.name === \"Polygon\") {\n e.layer.bringToBack();\n }\n //console.log(\"onOverlayAdd e\", e);\n }\n\n // ********************************************************************************\n //\n // Setup polygons drawn on the map\n //\n //\n // NOTE: uses leaflet.draw leaflet-draw\n //\n // ********************************************************************************\n\n // Truncate value based on number of decimals\n var _round = function (num, len) {\n return Math.round(num * Math.pow(10, len)) / Math.pow(10, len);\n };\n // Helper method to format LatLng object (x.xxxxxx, y.yyyyyy)\n var strLatLng = function (latlng) {\n return \"(\" + _round(latlng.lat, 6) + \", \" + _round(latlng.lng, 6) + \")\";\n };\n\n // Generate popup content based on layer type\n // - Returns HTML string, or null if unknown object\n var getPopupContent = function (layer) {\n // Marker - add lat/long\n if (layer instanceof L.Marker || layer instanceof L.CircleMarker) {\n return strLatLng(layer.getLatLng());\n // Circle - lat/long, radius\n } else if (layer instanceof L.Circle) {\n var center = layer.getLatLng(),\n radius = layer.getRadius();\n return (\n \"Center: \" +\n strLatLng(center) +\n \"
\" +\n \"Radius: \" +\n _round(radius, 2) +\n \" m\"\n );\n // Rectangle/Polygon - area\n } else if (layer instanceof L.Polygon) {\n var latlngs = layer._defaultShape\n ? layer._defaultShape()\n : layer.getLatLngs();\n\n // get the pixel coordinates of the shape\n var coords = latlngs.map(function (point) {\n return [point.lng, point.lat]; // #REVIEW - reverse display lat, long = YX\n });\n\n return (\n \"Coords: \" +\n JSON.stringify(coords) +\n \"
_leaflet_id: \" +\n L.stamp(layer)\n );\n // Polyline - distance\n } else if (layer instanceof L.Polyline) {\n var latlngs = layer._defaultShape\n ? layer._defaultShape()\n : layer.getLatLngs(),\n distance = 0;\n if (latlngs.length < 2) {\n return \"Distance: N/A\";\n } else {\n for (var i = 0; i < latlngs.length - 1; i++) {\n distance += latlngs[i].distanceTo(latlngs[i + 1]);\n }\n return \"Distance: \" + _round(distance, 2) + \" m\";\n }\n }\n return null;\n };\n\n // create the editable layers to drawn on\n\n // #REVIEW - the use of VAR here is an issue.\n // this.editableLayers is only accessible to componentDidMount, not componentDidUpdate\n // needs to go to STATE\n //\n this.editableLayers = L.featureGroup().addTo(this.map);\n // this.map.addLayer(this.editableLayers);\n\n // console.log(\n // \"hasLayer this.map.hasLayer(this.editableLayers)\",\n // this.map.hasLayer(this.editableLayers)\n // );\n\n const drawPluginOptions = {\n position: \"topleft\",\n draw: {\n polygon: {\n title: \"Draw a named area polygon\",\n allowIntersection: false, // Restricts shapes to simple polygons\n drawError: {\n color: \"#e1e100\", // Color the shape will turn when intersects\n message: \"Oh snap! you can't draw that!\", // Message that will show when intersect\n },\n shapeOptions: {\n color: \"green\",\n fillColor: \"green\",\n fillOpacity: 0.7,\n opacity: 1,\n },\n },\n polyline: false, // disable toolbar item by setting it to false\n circle: false, // removet the circle marker\n rectangle: {\n title: \"Draw a named area rectangle\",\n shapeOptions: {\n color: \"green\",\n fillColor: \"green\",\n fillOpacity: 0.7,\n opacity: 1,\n },\n },\n marker: false, // removes the marker point\n circlemarker: false, // removed the circlemarker\n },\n edit: {\n featureGroup: this.editableLayers, //REQUIRED!!\n edit: {\n // https://github.com/Leaflet/Leaflet.draw/issues/295\n // changes colour when in edit mode\n // this property shouldn't be needed\n selectedPathOptions: {\n // this property should be one level up\n color: \"#000\",\n fillColor: \"#000\",\n },\n },\n remove: false, // disables the trash can remove function\n },\n };\n\n // Initialise the draw control and pass it the FeatureGroup of editable layers\n this.drawControl = new L.Control.Draw(drawPluginOptions);\n this.map.addControl(this.drawControl);\n\n // add a 2nd control - this couold be for setting colors\n // see - https://gis.stackexchange.com/questions/181092/is-it-possible-to-edit-draw-panel-in-leaflet-draw\n const drawControl2options = {\n position: \"bottomleft\",\n draw: {\n polygon: {\n title: \"Draw a sexy polygon!\",\n allowIntersection: false,\n drawError: {\n color: \"#b00b00\",\n timeout: 1000,\n },\n shapeOptions: {\n color: \"#bada55\",\n },\n showArea: true,\n },\n polyline: {\n metric: false,\n },\n circle: {\n shapeOptions: {\n color: \"#662d91\",\n },\n },\n },\n edit: {\n featureGroup: this.editableLayers, //REQUIRED!!\n remove: true,\n },\n };\n\n // disable draw control #2\n if (false) {\n this.drawControl2 = new L.Control.Draw(drawControl2options);\n this.map.addControl(this.drawControl2);\n }\n\n // position in center\n // https://stackoverflow.com/questions/23762176/leaflet-custom-control-position-center/49036235#49036235\n\n // set popup event on created object\n // view-source:http://leaflet.github.io/Leaflet.draw/docs/examples/popup.html\n\n // get and set style\n // layer.setStyle({\n // weight: 5,\n // color: '#666',\n // dashArray: '',\n // fillOpacity: 0,\n // opacity: 0.9,\n // });\n\n // layer.options\n\n // Object created - bind popup to layer, add to feature group\n // draw:created\n this.map.on(L.Draw.Event.CREATED, (event) => {\n console.log(\"xxx draw:created\");\n\n // create layer\n let layer = event.layer;\n // Setup layer for geoJSON\n // Intialize layer.feature\n let feature = (layer.feature = layer.feature || {});\n // Intialize feature.type\n feature.type = feature.type || \"Feature\";\n // Intialize feature.properties\n let props = (feature.properties = feature.properties || {});\n\n // create default geoJson object properties for named area\n\n // #TODO/REVIEW - give shape an id. Must be unique so give timecode from epoch\n const namedAreaTimestamp = new Date().getTime(); // timestamp;\n\n props.id = this.state.map.area + \":\" + namedAreaTimestamp;\n props._leaflet_id = L.stamp(layer); // leaflet id\n props.name = `${namedAreaTimestamp}`;\n props.parent = \"parentNamedArea\";\n props.area = this.state.map.area;\n props.priority = 1;\n props.Firefly_List = [];\n props.type = \"Polygon\"; // #TODO - get type from shape created? If only support Polygon restrict entry.\n props.default_state = \"off\";\n\n props.default_color = layer.options.fillColor; // set fillColor as active color in geoJSON;\n props.button = [\n // #TODO - getDefaultButtonSet() - ATM just do 4 buttons for testing\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"off\",\n color: \"green\",\n // #REVIEW/TODO/WIP - yet to be implemented\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"off\",\n color: \"green\",\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 3,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"off\",\n color: \"green\",\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 4,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"green\",\n active: \"true\", // allows enable/disable of button column\n group: 0, // grouping of columns\n column: 0, // index for position of column - as different to priority\n },\n ];\n\n // 'status' - used to track the status of the object on maps and in lists\n // options:\n // drawn - drawn on the localmap. i.e. not a named area source from the messages/db\n // mqtt - defined by the messages/db\n // [proposed] deleted - marked for deletion\n props.status = \"drawn\";\n\n // #TODO -\n // getDefaultButtonSet () => {\n // get # of buttons in named area group based on 'parent'\n // append default button set\n // }\n\n // DISABLE - only used for debugging\n if (false) {\n let content = getPopupContent(layer);\n if (content !== null) {\n layer.bindPopup(content);\n }\n }\n\n console.log(\"qqq props created\", props);\n // add to editable layes\n this.editableLayers.addLayer(layer); // Note - .style.display = 'block' for default\n\n // NO - don't do this unless the area is saved!\n // ..........\n // add to layer list\n // this.layerlistNamedAreas[props.id] = layer;\n\n // update the localMapState\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(geoJsonPixels);\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n console.log(\n \"xxx draw:created this.props.localMapState\",\n this.props.localMapState\n );\n console.log(\n \"xxx draw:created thislocalMapState\",\n this.state.thislocalMapState\n );\n });\n\n // Object(s) edited - update popups\n // draw:edited\n this.map.on(L.Draw.Event.EDITED, (event) => {\n var layers = event.layers,\n content = null;\n layers.eachLayer(function (layer) {\n console.log(\"qqq this.editableLayers edit \" + L.stamp(layer));\n\n content = getPopupContent(layer);\n if (content !== null) {\n layer.setPopupContent(content);\n }\n });\n\n // #REVIEW / TODO - pass in parentId\n // mark the form as dirty\n const parentId = \"parentNamedArea\";\n this.props.namedAreasSetIsDirty(parentId);\n\n // #REVIEW / TODO - pass in parentId\n // move this to a common 'update()' function\n\n // update the localMapState\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(geoJsonPixels);\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n });\n\n // Named Areas edited - update state\n // draw:editstop\n this.map.on(L.Draw.Event.EDITSTOP, (event) => {\n console.log(\"xxx draw:editstop \", event);\n //const { layer } = event;\n //console.log(\"xxx EDITSTOP click \" + L.stamp(layer));\n //console.log(\"xxx DRAWSEDITSTOPTOP - _leaflet_id \" + layer._leaflet_id);\n // console.log(\"xxx this.props.localMapState\", this.props.localMapState);\n // console.log(\"xxx thislocalMapState\", this.state.thislocalMapState);\n });\n\n // Named Areas edited - update state\n // draw:drawstop\n this.map.on(L.Draw.Event.DRAWSTOP, (event) => {\n console.log(\"xxx draw:drawstop \", event);\n });\n\n // Named Areas edited - update state\n // draw:deleted\n this.map.on(L.Draw.Event.DELETED, (event) => {\n console.log(\"xxx draw:deleted \", event);\n\n // return list of deleted layers...\n const editedlayers = event.layers;\n console.log(\"xxx draw:deleted layers\", editedlayers);\n\n // update the localMapState\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(geoJsonPixels);\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // const {\n // namedAreas: { features },\n // } = this.props.localMapState;\n\n // // make a new list without the deleted layers\n // let newNamedAreas = [];\n // console.log(\"xxx newNamedAreas\", newNamedAreas);\n // editedlayers.eachLayer((layer) => {\n // features.forEach((feature, index, arr) => {\n // if (feature.properties._leaflet_id !== layer._leaflet_id) {\n // newNamedAreas.push(feature);\n // }\n // });\n // });\n\n // // update state as geoJson\n // this.props.UpdateLocalMap({\n // namedAreas: {\n // type: \"FeatureCollection\",\n // features: newNamedAreas,\n // },\n // });\n // this.setState({\n // thislocalMapState: {\n // type: \"FeatureCollection\",\n // features: newNamedAreas,\n // },\n // });\n });\n\n // yet another this.editableLayers on click event to\n // output the maps state for debugging\n // this.editableLayers.on(\"click\", (event) => {\n // console.log(\"xxx this.props.localMapState\", this.props.localMapState);\n // console.log(\"xxx thislocalMapState\", this.state.thislocalMapState);\n // });\n\n // https://stackoverflow.com/questions/40088421/returning-clicked-layer-leaflet\n // see - https://jsfiddle.net/3v7hd2vx/108/\n // attached to this.editableLayers group\n\n // DISABLE THIS ONCLICK ACTION - but leave in code for debugging\n if (false) {\n this.editableLayers.on(\"click\", (event) => {\n const { layer } = event;\n\n // console.log(\"xxx this.editableLayers click \" + L.stamp(layer));\n // console.log(\"xxx this.editableLayers - _leaflet_id \" + layer._leaflet_id);\n\n // Note 'layer.edited' only true after handles moved\n //&& layer.edited\n if (layer instanceof L.Polygon || layer instanceof L.Rectangle) {\n // rectangle, polygon, circle\n const colors = [\"green\", \"yellow\", \"blue\", \"red\"];\n const currentColor = layer.options.fillColor;\n const index = colors.findIndex((x) => x === currentColor);\n let newColor;\n index + 1 > colors.length - 1\n ? (newColor = colors[0])\n : (newColor = colors[index + 1]);\n\n layer.setStyle({ color: newColor, fillColor: newColor });\n layer.feature.properties.color = layer.options.fillColor; // set fillColor as active color in geoJSON\n\n // console.log(\n // \"xxx this.editableLayers - UTM Coords:\",\n // JSON.stringify(convertPixelsToUtm(event))\n // );\n }\n });\n }\n\n const convertPixelsToUtm = (event) => {\n const latlngs = event.layer._latlngs[0]; // <----------only one lat longs array????? #REVIEW - could be more if multi-Polygo?\n // transform from pixels to points\n const transform = this.Transform(this.standardPtsUtm(), this.localPts());\n // get the pixel coordinates of the shape\n const utmPoints = latlngs.map(function (point) {\n const objUtm = transform.transform({\n lat: point.lat,\n lng: point.lng,\n });\n return [objUtm.lat, objUtm.lng];\n });\n return utmPoints;\n };\n\n // add existing layer to editable layer so can edit existing/loaded polygons\n //let that=this; // pass editable layer into function\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n console.log(\n \"Adding mqtt Named Area to this.editableLayers -> \",\n layer._leaflet_id\n ); // KEEP AS PERMANENT INDICATOR THAT MAP GROUPS ARE UPDATING\n\n layer.getElement().style.display = \"block\"; // this resets any hidden layer actions\n this.editableLayers.addLayer(layer);\n });\n\n // --- LAYER INFORMATION TO OUTSIDE MAP\n\n // check what layers are drawn.......\n this.editableLayers.eachLayer(function (layer) {\n //console.log(\"this.editableLayers layer\", layer);\n // Pass this information through Redux to outside\n });\n\n // --- LAYER CONTROL TO SEPARATE HTML\n\n // see - https://groups.google.com/forum/#!searchin/leaflet-js/control$20onadd/leaflet-js/rKMZX3PKFuI\n // then remove the control container\n layerControl._container.remove();\n\n // append the control container to the other div\n if (false) {\n // disable this for the moment\n document\n .getElementById(\"custom-map-controls\")\n .appendChild(layerControl.onAdd(this.map));\n }\n\n // map drawn!!!!!!!!\n };\n\n convertGeoJsonPixelsToUtm = (geoJsonPixels) => {\n // Output coordinates of shape in UTM\n // returns geoJSON\n\n //console.log(\"qqq geoJsonPixels\", geoJsonPixels);\n // convert pixel coordinates in geoJson Pixels to utm\n\n // deep clone - to stop geometry being converted on raw *utm data\n geoJsonPixels = JSON.parse(JSON.stringify(geoJsonPixels));\n\n const geoJsonUtm = this.transformGeoJsonPixelsToUtm(geoJsonPixels);\n\n //console.log(\"qqq geoJsonUtm transformGeoJsonPixelsToUtm\", geoJsonUtm);\n\n // #TODO - NOTE: 'drawnItemsToJSON' below strips out the properties!\n // - needs to be updated to preserve PROPERTIES\n // - do not use until fixed\n\n // preserve styling of polygon in geoJson\n //\n //geoJson = this.drawnItemsToJSON(this.editableLayers);\n return geoJsonUtm;\n };\n\n transformGeoJsonPixelsToUtm = (geoJson) => {\n const transform = this.Transform(this.standardPtsUtm(), this.localPts());\n const geoJsonTransform = [];\n\n geoJson.features.map((value, idx) => {\n let newFeature = value;\n // transform the point from pixels to pixels\n const arrayLatLng = newFeature.geometry.coordinates.slice();\n let arrayPoints = [];\n const shapeType = newFeature.geometry.type;\n switch (shapeType.toLowerCase()) {\n case \"point\":\n // convert to LatLng, transform, then convert back to array\n arrayPoints = Object.values(\n transform.transform({\n lat: arrayLatLng[1], // <-- **NOTE: lat & lng are swapped! **\n lng: arrayLatLng[0],\n })\n ).reverse();\n break;\n case \"polygon\":\n // iterate the geojons coord array\n arrayLatLng.forEach((value, i, arr) => {\n arrayPoints.push([]);\n value.forEach((value, j) => {\n // convert to LatLng, transform, then convert back to array\n let arrayPoint = Object.values(\n transform.transform({\n lat: value[1], // <-- **NOTE: lat & lng are swapped! **\n lng: value[0],\n })\n ).reverse();\n\n // accumulate results\n arrayPoints[i][j] = arrayPoint;\n });\n });\n break;\n default:\n break;\n }\n // update geometry\n newFeature.geometry.coordinates = arrayPoints;\n geoJsonTransform.push(newFeature);\n });\n\n return {\n type: \"FeatureCollection\",\n features: geoJsonTransform,\n };\n };\n\n // transformGeoJsonUtmToPixels transforms geoJson based on transform passed\n // Note:\n // * only supports points and polygons\n // * only supports single polygon shapes. i.e. not multi shapes or shapes with holes\n //\n transformGeoJsonUtmToPixels = (geoJson) => {\n const transform = this.Transform(this.localPts(), this.standardPtsUtm());\n\n const geoJsonTransform = [];\n geoJson.features.map((value, idx) => {\n let newFeature = value;\n // transform the point from latlng to pixels\n const arrayLatLng = newFeature.geometry.coordinates.slice();\n\n // check if rx an un positioned marker i.e. [0,0]\n const isAllZero = arrayLatLng.every((item) => item === 0);\n\n // if (isAllZero) {\n // console.log(\n // \"isAllZero feature\",\n // newFeature.properties.id,\n // JSON.stringify(newFeature)\n // );\n // }\n // check if map has the holding pen setup\n\n // #REVIEW/TODO #WIP\n // make sure there is a default pen point\n let randomHoldingPenCoordinate = [0, 0];\n // why is this undefined on startup? img is defined ok?!\n // if (this.holdingPen !== undefined) {\n // const hasHoldingPen = this.map.hasLayer(this.holdingPen);\n // if (isAllZero && hasHoldingPen) {\n // randomHoldingPenCoordinate = this.randomPointInPoly(this.holdingPen)\n // .geometry.coordinates;\n // console.log(\n // \"randomholdingPenCoordinate\",\n // newFeature.properties.id,\n // randomHoldingPenCoordinate\n // );\n // }\n // }\n\n // if (newFeature.properties.id === \"DMLZ_Extraction:P14:21\") {\n // console.log(\"newFeature 21\", newFeature);\n // }\n // if (newFeature.properties.id === \"DMLZ_Extraction:P14:22\") {\n // console.log(\"newFeature 22\", newFeature);\n // }\n let arrayPoints = [];\n const shapeType = newFeature.geometry.type;\n switch (shapeType.toLowerCase()) {\n case \"point\":\n // convert to LatLng, transform, then convert back to array\n if (!isAllZero) {\n arrayPoints = Object.values(\n transform.transform({\n lat: arrayLatLng[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: arrayLatLng[1],\n })\n );\n } else {\n arrayPoints = randomHoldingPenCoordinate;\n }\n\n break;\n case \"polygon\":\n // iterate the geojons coord array\n arrayLatLng.forEach((value, i, arr) => {\n arrayPoints.push([]);\n value.forEach((value, j) => {\n // convert to LatLng, transform, then convert back to array\n let arrayPoint;\n if (!isAllZero) {\n arrayPoint = Object.values(\n transform.transform({\n lat: value[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: value[1],\n })\n );\n } else {\n arrayPoint = randomHoldingPenCoordinate;\n }\n\n // accumulate results\n arrayPoints[i][j] = arrayPoint;\n });\n });\n break;\n default:\n break;\n }\n\n // update geometry\n newFeature.geometry.coordinates = arrayPoints;\n geoJsonTransform.push(newFeature);\n });\n\n return {\n type: \"FeatureCollection\",\n features: geoJsonTransform,\n };\n };\n\n // find a random point in the holding pen\n randomPointInPoly = function (polygon) {\n var bounds = polygon.getBounds();\n var x_min = bounds.getEast();\n var x_max = bounds.getWest();\n var y_min = bounds.getSouth();\n var y_max = bounds.getNorth();\n\n var lat = y_min + Math.random() * (y_max - y_min);\n var lng = x_min + Math.random() * (x_max - x_min);\n\n var point = turf.point([lng, lat]);\n var poly = polygon.toGeoJSON();\n var inside = turf.inside(point, poly);\n\n if (inside) {\n return point;\n } else {\n return this.randomPointInPoly(polygon);\n }\n };\n\n componentDidMount() {\n const { render } = this.props;\n const mapId = \"map-\" + render;\n\n // tile URL for base layer\n const url = process.env.PUBLIC_URL + \"/images/test_extraction.png\"; // #WIP - this is not used at the moment.\n\n const { geoJSONMarkersDataUtm, geoJSONNamedAreasUtm } = this.props;\n\n let geoJSONMarkersData;\n\n // #REVIEW - issue here is that the component mounts before the mqtt messages have populated the objecet -> redux -> component etc.\n // need to ensure .features exists to transform...\n\n // update fireflies\n if (\n typeof geoJSONMarkersDataUtm.features !== \"undefined\" &&\n geoJSONMarkersDataUtm.features.length\n ) {\n // #REVIEW - this now happens in WebWorker reducer for fireflies\n // deep clone - to stop geometry being converted on raw *utm data\n //geoJSONMarkersData = JSON.parse(JSON.stringify(geoJSONMarkersDataUtm));\n //geoJSONMarkersData = this.transformGeoJsonUtmToPixels(geoJSONMarkersData);\n\n geoJSONMarkersData = geoJSONMarkersDataUtm;\n } else {\n // add an empty geoJson featurecollection\n geoJSONMarkersData = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // update named area\n let geoJSONNamedAreas;\n\n if (\n typeof geoJSONNamedAreasUtm.features !== \"undefined\" &&\n geoJSONNamedAreasUtm.features.length\n ) {\n // deep clone - to stop geometry being converted on raw *utm data\n geoJSONNamedAreas = JSON.parse(JSON.stringify(geoJSONNamedAreasUtm));\n\n geoJSONNamedAreas = this.transformGeoJsonUtmToPixels(geoJSONNamedAreas);\n } else {\n // add an empty geoJson featurecollection\n geoJSONNamedAreas = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // draw the map\n this.drawTheMap(mapId, url, geoJSONMarkersData, geoJSONNamedAreas);\n\n // after document is rendered move the controls to another parent\n // see - https://gis.stackexchange.com/questions/186131/placing-controls-outside-map-container-with-leaflet\n\n // var newParent = document.getElementById(\"custom-map-controls\");\n // var oldParent = document.getElementsByClassName(\n // \"leaflet-top leaflet-right\"\n // );\n\n // while (oldParent[0].childNodes.length > 0) {\n // newParent.appendChild(oldParent[0].childNodes[0]);\n // }\n\n // _alternative tech\n //\n // 'modern way'\n // newParent.append(...oldParent.childNodes);\n // https://stackoverflow.com/questions/20910147/how-to-move-all-html-element-children-to-another-parent-using-javascript\n\n //newParent.append(...oldParent.childNodes);\n }\n\n componentDidUpdate(prevProps, prevState) {\n // console.log(\"this.state.heartBeat\", this.state.heartBeat);\n // console.log(\"prevState.heartBeat\", prevState.heartBeat);\n // console.log(\" heartBeat this.map !== undefined\", this.map !== undefined);\n\n // const heartBeatChanged =\n // this.state.heartBeat !== prevState.heartBeat && this.map !== undefined\n // ? true\n // : false;\n\n //console.log(\" heartBeatChanged heartBeat - #WIP\", heartBeatChanged);\n\n // respond to checkbox settings\n // toggle display of marker group\n if (this.markerGroupLayer) {\n if (this.props.parentState.isCheckboxMarker) {\n this.map.addLayer(this.markerGroupLayer);\n } else {\n this.map.removeLayer(this.markerGroupLayer);\n }\n }\n\n // toggle display of reference marker group\n if (this.refPtGroupLayer) {\n if (this.props.parentState.isCheckboxRefMarker) {\n this.map.addLayer(this.refPtGroupLayer);\n } else {\n this.map.removeLayer(this.refPtGroupLayer);\n }\n }\n\n // TagUnknownMarker\n // TagHardHat\n // TagTruckPickupMarker\n // TagAmbulanceMarker\n // TagLightVehicleMarker\n // TagLoaderMarker\n // TagTruckMarker\n // TagJumboMarker\n\n // toggle display of the tag personnel marker\n if (this.refPtGroupLayer) {\n console.log(\"onClickCheckbox parentState \", this.props.parentState);\n const iconSelection = this.props.parentState.iconSelection;\n if (iconSelection !== \"\") {\n this.refPtGroupLayer.eachLayer((layer) => {\n layer.setIcon(\n makeIcon(\n iconSelection,\n { stroke: \"green\", fill: \"orange\", text: \"\" },\n 1\n )\n );\n });\n this.map.addLayer(this.refPtGroupLayer);\n } else {\n this.map.removeLayer(this.refPtGroupLayer);\n }\n }\n\n // ---------------------------------------\n\n const parentId = \"parentNamedArea\";\n\n // #REVIEW / TODO - move this filter to a common area\n const isParentDirty =\n this.props?.isDirty?.namedArea.filter(\n (namedArea) => namedArea === parentId\n ).length > 0;\n\n // ---------------------------------------------------------------\n // remove layers queued for deletion (via named areas UI)\n\n // This processes any named areas which have been 'deleted' when an update to the named area is performed.\n // This ensures immediate update to the local map so user get feedback of the action.\n // Otherwise it is necessary to wait for the mqtt send/receive process to update the map, and the\n // user is left wondering whether their request has been submitted.\n\n // get array of named_areas to delete\n // e.g. [{ area: \"DMLZ_Extraction\", id: \"DMLZ_Extraction:1594276143541\" },...]\n\n //#REVIEW/TODO - merge this with namedAreaHideSelection\n // INSTEAD OF DELETING JUST HIDE THE LEVEL\n // i.e. HIDDEN = DELETED????????????\n\n const namedAreaDeleteSelections = this.props.namedAreaDeleteSelections;\n\n let namedAreaDeleted = false; // flag to make the map update quicker after something deleted\n namedAreaDeleteSelections.forEach((selection, idx) => {\n // find the selection by id, by checking every layer in editableLayers\n\n this.editableLayers.eachLayer((layer) => {\n if (layer.feature.properties.id === selection.id) {\n console.log(\"----> namedAreaDeleteSelections remove\", selection.id);\n\n // delete from editableLayers, when named areas area updated below the 'UpdateLocalMap' will remove this item\n // and consequently from the named area list (as this populates via redux)\n this.editableLayers.removeLayer(layer); // <----------- this is the most important bit\n\n // delete from\n this.props.namedAreaClearDeleteSelections(selection);\n namedAreaDeleted = true;\n }\n });\n });\n\n // ---------------------------------------------------------------\n\n // check if raw data has changed\n // update fireflies\n // if\n // * not empty\n // _and_\n // * props have changed\n\n // #REVIEW/TODO - make a function out of this ....\n // incoming objects (current and prevProps) are different even though JSON content is the same.\n // compare the strings to stop unnecessary updates\n const prevGeoJSONMarkersDataUtm = JSON.stringify(\n prevProps.geoJSONMarkersDataUtm\n );\n const newGeoJSONMarkersDataUtm = JSON.stringify(\n this.props.geoJSONMarkersDataUtm\n );\n\n let isChangedgeoJSONMarkerUtm = false;\n\n // if each object has content\n if (\n !_isEmpty(prevGeoJSONMarkersDataUtm) &&\n !_isEmpty(newGeoJSONMarkersDataUtm)\n ) {\n // are they changed?\n isChangedgeoJSONMarkerUtm =\n prevGeoJSONMarkersDataUtm !== newGeoJSONMarkersDataUtm ? true : false;\n }\n\n if (\n //#WIP - disabled to make the update happen periodically so can test hide/delete options\n // isChangedgeoJSONMarkerUtm\n\n _isEmpty(this.props.geoJSONMarkersDataUtm) !== true &&\n this.props.geoJSONMarkersDataUtm !== prevProps.geoJSONMarkersDataUtm\n ) {\n // console.log(\n // \"map componentDidUpdate this.props.geoJSONMarkersDataUtm\",\n // this.props.geoJSONMarkersDataUtm\n // );\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONMarkersData = JSON.parse(\n JSON.stringify(this.props.geoJSONMarkersDataUtm)\n );\n\n // #REVIEW/TODO #WIP\n // check for [0,0] or out of rage points and move them to the pen\n // const transform = this.Transform(this.localPts(), this.standardPtsUtm());\n // const geoJsonTransform = [];\n\n // #WIP - test for out of range too!\n geoJSONMarkersData.features.map((value, idx) => {\n const arrayLatLng = value.geometry.coordinates.slice();\n // check if rx an un positioned marker i.e. [0,0]\n const isAllZero = arrayLatLng.every((item) => item === 0);\n if (isAllZero) {\n // console.log(\n // \"Found FF isAllZero value.properties.id -> \",\n // value.properties.id\n // );\n\n // update FF value.properties.id with new coordinate in the pen\n let randomHoldingPenCoordinate;\n if (this.holdingPen !== undefined) {\n const hasHoldingPen = this.map.hasLayer(this.holdingPen);\n if (isAllZero && hasHoldingPen) {\n randomHoldingPenCoordinate = this.randomPointInPoly(\n this.holdingPen\n );\n // console.log(\n // \"isAllZero randomHoldingPenCoordinate\",\n // randomHoldingPenCoordinate\n // );\n\n // change the value properties coordinates with new holding pen point\n //console.log(\"isAllZero value\", JSON.stringify(value));\n let newValue = JSON.parse(JSON.stringify(value));\n newValue.geometry = randomHoldingPenCoordinate.geometry;\n\n // convert to Utm values\n const newPointUTtm = this.convertGeoJsonPixelsToUtm({\n type: \"FeatureCollection\",\n features: [newValue],\n }).features[0].geometry.coordinates.slice();\n // #REVIEW/TODo #FIX!!!!!!!!!!!! - should filter to find the id, ATM just grab first one (and only) one which comes back\n\n //console.log(\"isAllZero newPointUTtm\", newPointUTtm);\n\n // send via mqtt for change\n // #WIP....send FF update within map\n\n const changeTopic = `firefly/${newValue.properties.id}/change`;\n\n const changeMsg = {\n id: newValue.properties.id,\n mac: newValue.properties.mac,\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [newPointUTtm[0], newPointUTtm[1]],\n token: messageToken(),\n };\n\n //console.log(\"isAllZero changeFF\", changeMsg);\n\n // #WIP - the issue here is this sends out lots of messages until the changes is made...flooding the system.\n // need to log the send, wait for an ack, clear it.\n // disabled pending implement ack management\n if (false) {\n this.props.mqttPublish({\n topic: changeTopic,\n qos: 0,\n message: changeMsg,\n retained: false,\n });\n }\n }\n }\n }\n });\n\n // transform the coordinates to pixel image references\n\n // #REVIEW - this now happens in WebWorker reducer for fireflies\n //geoJSONMarkersData = this.transformGeoJsonUtmToPixels(geoJSONMarkersData);\n\n // update markers for geoJSON\n this.updateFireflyMarkersGeoJSON(this.map, geoJSONMarkersData);\n }\n\n // ****************************************************************************************\n //\n // update named area\n //\n // ****************************************************************************************\n\n // update from source data if\n // * not empty\n // * props have changed\n // _or_\n // * named areas have been locally deleted\n\n // WIP HERE - previously allowed update if (OR) namedAreaDeleted = true even if no changes to data to stop redraw of namedAreas <------\n // || namedAreaDeleted\n // ...working though?\n\n // #REVIEW/TODO - make a function out of this\n\n // incoming objects (current and prevProps) are different even though JSON content is the same.\n // compare the strings to stop unnecessary updates\n const prevGeoJSONNamedAreasUtm = JSON.stringify(\n prevProps.geoJSONNamedAreasUtm\n );\n const newGeoJSONNamedAreasUtm = JSON.stringify(\n this.props.geoJSONNamedAreasUtm\n );\n\n let isChangedgeoJSONNamedAreasUtm = false;\n\n // if each object has content\n if (\n !_isEmpty(prevGeoJSONNamedAreasUtm) &&\n !_isEmpty(newGeoJSONNamedAreasUtm)\n ) {\n // are they changed?\n isChangedgeoJSONNamedAreasUtm =\n prevGeoJSONNamedAreasUtm !== newGeoJSONNamedAreasUtm ? true : false;\n }\n\n if (\n // isChangedgeoJSONNamedAreasUtm ||\n // namedAreaDeleted\n (!_isEmpty(this.props.geoJSONNamedAreasUtm) &&\n this.props.geoJSONNamedAreasUtm !== prevProps.geoJSONNamedAreasUtm) ||\n namedAreaDeleted\n // || heartBeatChanged\n ) {\n // console.log(\"componentDidUpdate namedAreaHiddenSelections - updating!\");\n\n // #WIP - check if localMapState and incoming data differ\n // with view to filtering localMapState data for delete and hidden namedAreas\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONNamedAreas = JSON.parse(\n JSON.stringify(this.props.geoJSONNamedAreasUtm)\n );\n\n // transform the coordinates to pixel image references\n geoJSONNamedAreas = this.transformGeoJsonUtmToPixels(geoJSONNamedAreas);\n\n //#WIP - merge geoJSONNamedAreas and localMapState, giving priority to geoJSONNamedAreas if propertie.id is same\n //i.e. get geoJSONNamedAreas and import all\n\n const local = this.props.localMapState?.features;\n const mqtt = geoJSONNamedAreas?.features;\n\n let localIds = [];\n let mqttIds = [];\n\n if (local) {\n local.forEach((item, idx) => {\n localIds[item.properties.id] = idx;\n });\n }\n // console.log(\"componentDidUpdate local\", local);\n if (mqtt) {\n mqtt.forEach((item, idx) => {\n mqttIds[item.properties.id] = idx;\n });\n }\n // console.log(\"componentDidUpdate mqtt\", mqttIds);\n\n // console.log(\n // \"map componentDidUpdate geoJSONNamedAreas\",\n // JSON.stringify(geoJSONNamedAreas)\n // );\n\n // console.log(\n // \"map componentDidUpdate this.props.localMapState\",\n // this.props.localMapState\n // );\n\n // if the parent named area is 'dirty' i.e. being edited\n // then don't update the named areas\n // with new mqtt content\n if (!isParentDirty) {\n // update markers for geoJSON\n this.updateNamedAreasGeoJSON(this.map, geoJSONNamedAreas);\n }\n\n // update localMapState with all objects in the editable layer\n if (this.map.hasLayer(this.editableLayers)) {\n // add geoJSONNamedAreaGroupLayer layer to editable layer so can edit existing/loaded polygons\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n // console.log(\n // \"Adding mqtt Named Area to this.editableLayers -> \",\n // layer._leaflet_id\n // ); // KEEP AS PERMANENT INDICATOR THAT MAP GROUPS ARE UPDATING\n this.editableLayers.addLayer(layer);\n });\n\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n\n //#REVEW/TODO - this should only happen if the shape has changed otherwise use the coordinates in the features.properties.coordinatesUtm\n // ----->\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(geoJsonPixels);\n // <-----\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // console.log(\n // \"map componentDidUpdate this.props.localMapState - after update\",\n // JSON.stringify(geoJsonUtm)\n // );\n\n const geo = geoJsonUtm?.features;\n let geoIds = [];\n if (geo) {\n geo.forEach((item, idx) => {\n geoIds[item.properties.id] = idx;\n });\n }\n // console.log(\"componentDidUpdate geoIds\", geoIds);\n\n //#WIP - testing hide and show layers\n\n // #REVIEW/TODO\n // THIS NEEDS TO BE RE_WRITTEN TO RUN OVER ALL EDITABLE LAYERS\n //\n this.editableLayers.eachLayer((layer) => {\n layer.getElement().style.display = \"block\"; // this resets any hidden layer actions\n });\n\n //#REVIEW/TODO - namedAreaHiddenSelections and namedAreaDeleteSelections are 'same' make function or restructure message/object\n\n const namedAreaHiddenSelections = this.props.namedAreaHideSelections;\n //#REVIEW/TODO - filter by parentId - currently ignore id\n const namedAreasHidden = namedAreaHiddenSelections.map((na) => na.id);\n // console.log(\"namedAreasHidden\", namedAreasHidden);\n\n // const namedAreaDeleteSelections = this.props.namedAreaDeleteSelections;\n // //#REVIEW/TODO - filter by parentId - currently ignore id\n // const namedAreasDeleted = namedAreaDeleteSelections.map((na) => na.id);\n // // console.log(\"namedAreasDeleted\", namedAreasDeleted);\n\n this.editableLayers.eachLayer((layer) => {\n const includesNamedAreaHidden = namedAreasHidden.includes(\n layer.feature.properties.id\n );\n // const includesNamedAreaDeleted = namedAreasDeleted.includes(\n // layer.feature.properties.id\n // );\n\n if (!includesNamedAreaHidden) {\n //\n return;\n }\n layer.getElement().style.display = \"none\";\n });\n\n this.editableLayers.bringToBack();\n this.geoJSONNamedAreaGroupLayer.bringToBack();\n }\n }\n\n // use this to control layers, named areas etc.\n if (this.locationGroupLayers && this.polylineGroupLayers) {\n if (this.props.parentState.isCheckboxFireflies) {\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n //console.log(\"key\", key);\n this.map.addLayer(value);\n }\n } else {\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n this.map.removeLayer(value);\n }\n }\n\n if (this.props.parentState.isCheckboxPolyline) {\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n //console.log(\"key\", key);\n this.map.addLayer(value);\n }\n } else {\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n this.map.removeLayer(value);\n }\n }\n }\n\n // Check if isAddPolygonClicked\n if (this.props.parentState.isAddPolygonClicked) {\n // console.log(\n // \"isAddPolygonClicked\",\n // this.props.parentState.isAddPolygonClicked\n // );\n // https://github.com/Leaflet/Leaflet.draw/issues/179\n // programmatically click on toolbar\n // #REVIEW - disable until work out how to have transitional action\n // this.drawControl._toolbars.draw._modes.rectangle.handler.enable();\n }\n\n // check what layers are drawn.......\n // this.editableLayers.eachLayer(function(layer) {\n // console.log(\"this.editableLayers layer\", layer);\n // });\n }\n\n // based on\n // https://stackoverflow.com/questions/34501524/in-place-update-leaflet-geojson-feature\n // here for reference\n // these are not used yet..........\n addNewFeatureToGeoJsonLayerGroup = (myGeoJsonLayerGroup, newGeoJsonData) => {\n myGeoJsonLayerGroup.addData(newGeoJsonData);\n };\n\n updateFeature = (updatedGeoJsonData) => {\n this.deleteFeature(updatedGeoJsonData); // Remove the previously created layer.\n this.addNewFeatureToGeoJsonLayerGroup(updatedGeoJsonData); // Replace it by the new data.\n };\n\n deleteFeature = (myGeoJsonLayerGroup, myFeaturesMap, deletedGeoJsonData) => {\n var deletedFeature = myFeaturesMap[deletedGeoJsonData.properties.objectID];\n myGeoJsonLayerGroup.removeLayer(deletedFeature);\n };\n\n updateFireflyMarkersGeoJSON(map, geoJSONMarkersData) {\n const blueMarker = {\n radius: 6,\n fillColor: \"blue\",\n };\n\n const redMarker = {\n radius: 6,\n fillColor: \"red\",\n };\n\n const yellowMarker = {\n radius: 6,\n fillColor: \"yellow\",\n };\n\n const greenMarker = {\n radius: 6,\n fillColor: \"green\",\n };\n\n // map the geoJSONMarkersData and delete all the markers who have changed propertie\n // and accumulate these markers\n // add them all at the end\n\n // find the fireflies which have changed in geojsonMarkerOptions object\n geoJSONMarkersData.features.map(({ properties }, idx) => {\n const { id, color, location, position } = properties;\n\n // Make sure there is a layergroup for new markers.\n // layer groups are defined by LOCATION.\n // If a new LOCATION is added, check and add if necessary.\n //\n if (this.map.hasLayer(this[location])) {\n } else {\n this[location] = L.featureGroup().addTo(this.map);\n this.locationGroupLayers[location] = this[location];\n }\n\n // if the marker is in the layerlistFireflies\n if (this.layerlistFireflies[id]) {\n // if (id.includes(\"P17:4\")) {\n // console.log(\n // \"P17:4 current layer color = this.layerlistFireflies[id].feature.properties.color\",\n // this.layerlistFireflies[id].feature.properties.color\n // );\n // console.log(\"P17:4 new color =\", color);\n // console.log(\n // \"P17:4 this.layerlistFireflies[id].feature.properties.color !== color\",\n // this.layerlistFireflies[id].feature.properties.color !== color\n // );\n // }\n\n // if new color is not the same as the old\n if (this.layerlistFireflies[id].feature.properties.color !== color) {\n // #REVIEW - no longer remove the layer, instead just update it\n //remove the layer\n //map.removeLayer(this.layerlistFireflies[id]);\n\n // get style for new marker\n\n let newStyle;\n\n switch (color) {\n case \"red\":\n newStyle = redMarker;\n break;\n case \"blue\":\n newStyle = blueMarker;\n break;\n case \"amber\":\n newStyle = yellowMarker;\n break;\n case \"green\":\n newStyle = greenMarker;\n break;\n\n default:\n break;\n }\n\n // if (id.includes(\"P17:4\")) {\n // console.log(\"P17:4 before .setStyle\");\n // console.log(\"P17:4 color\", color);\n // console.log(\"P17:4 newStyle\", newStyle);\n // }\n\n // #REVIEW - no need to replace layer, instead just update the color\n // place a new layer with the new style\n // this.layerlistFireflies[id].addTo(map).setStyle(newStyle);\n\n this.layerlistFireflies[id].setStyle(newStyle);\n // update the color property\n this.layerlistFireflies[id].feature.properties.color = color;\n\n // if (id.includes(\"P17:4\")) {\n // console.log(\"P17:4 after .setStyle\");\n // console.log(\n // \"P17:4 this.layerlistFireflies[id].feature.properties.color\",\n // this.layerlistFireflies[id].feature.properties.color\n // );\n // console.log(\"P17:4 color\", color);\n // }\n }\n } else {\n // console.log(\n // \"hasLayer componentDidUpdate updateFireflyMarkersGeoJSON this.map.hasLayer(this.geoJSONGroupLayer)\",\n // this.map.hasLayer(this.geoJSONGroupLayer)\n // );\n\n // if it's not in the layer list add it..........\n // note pointToLayer and onEachFeature are defined in ComponentDidMount()\n this.geoJSONGroupLayer.addData(geoJSONMarkersData.features[idx]);\n }\n });\n }\n\n updateNamedAreasGeoJSON(map, geoJSONPolygonData) {\n // #TODO - !\n // map the geoJSONPolygonData and delete all the shapes who have changed propertie\n // and accumulate these shapes\n // add them all at the end\n\n // check if a named area has been removed\n // get list of IDs for current named area (i.e. layers)\n const layersIds = Object.keys(this.layerlistNamedAreas);\n\n // get the Ids for the incoming update of named area data\n let namedAreaIds = [];\n for (const namedArea in geoJSONPolygonData.features) {\n namedAreaIds.push(geoJSONPolygonData.features[namedArea].properties.id);\n }\n\n // check for a difference\n // filter each item and return it if it is *not* in the namedAreas\n const inLayerNotInNamedArea = layersIds.filter(\n (i) => !namedAreaIds.includes(i)\n );\n\n inLayerNotInNamedArea.forEach((layer, idx) => {\n // delete any layers which are in layersIds but *not* in namedAreaIds\n // remove the layer from layer groups\n this.editableLayers.removeLayer(this.layerlistNamedAreas[layer]);\n this.geoJSONNamedAreaGroupLayer.removeLayer(\n this.layerlistNamedAreas[layer]\n );\n // to be really sure remove it from the map completely\n this.map.removeLayer(this.layerlistNamedAreas[layer]);\n // delete the layer from the list\n delete this.layerlistNamedAreas[layer];\n // update localMapstate\n });\n\n // find the named areas which have changed in geoJSONPolygonData object\n geoJSONPolygonData.features.map(({ properties }, idx) => {\n const { id } = properties;\n\n // if the shape is not in the layer list\n if (!this.layerlistNamedAreas[id]) {\n // add it\n // note pointToLayer and onEachFeature are defined in ComponentDidMount() <--- #REVIEW - is it? i.e. for namedArea?\n this.geoJSONNamedAreaGroupLayer.addData(\n geoJSONPolygonData.features[idx]\n );\n } else {\n // if the shape exists but has changed, update it\n\n // #WIP - should also review updates to shape coordinates\n\n // AFAIK the only way to update is to go through every layer until finding the match!\n // thankfully there are not many layers for namedAreas\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n if (layer === this.layerlistNamedAreas[id]) {\n layer.feature.properties = properties;\n }\n });\n }\n });\n\n // update leaflet id to properties (used to delete.edit shapes in local state) <--- #REVIEW - is it? may not be necessary now\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n layer.feature.properties._leaflet_id = layer._leaflet_id;\n });\n }\n\n // heartBeat = () => {\n // const heartBeat = this.state.heartBeat;\n // //console.log(\"heartBeat\", heartBeat);\n // this.setState({ heartBeat: !heartBeat });\n // };\n\n render() {\n const { render } = this.props;\n const mapId = \"map-\" + render;\n\n return (\n <>\n
\n
\n {/*
*/}\n
\n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n // for testing force collect minelevel info for Id=1 \"DMLZ Extraction\"\n const markersData = getMapState(state);\n const geoJSONMarkersDataUtm = getFireflyCoordinates(state);\n const localMapState = GetLocalMap(state);\n const geoJSONNamedAreasUtm = getNamedAreaInfos(state);\n\n const namedAreaDeleteSelections = getNamedAreaDeleteSelections(state);\n\n const namedAreaHideSelections = getNamedAreaHideSelections(state);\n\n const isDirty = getIsDirty(state);\n\n return {\n markersData,\n geoJSONMarkersDataUtm,\n localMapState,\n geoJSONNamedAreasUtm,\n namedAreaDeleteSelections,\n namedAreaHideSelections,\n isDirty,\n };\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n UpdateLocalMap: (mapState) => {\n dispatch(UpdateLocalMap(mapState));\n },\n namedAreaClearDeleteSelections: (parentId) => {\n dispatch(namedAreaClearDeleteSelections(parentId));\n },\n namedAreasSetIsDirty: (id) => {\n dispatch(namedAreasSetIsDirty(id));\n },\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(Map);\n","import L from \"leaflet\";\n\nvar blueIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-blue.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nvar goldIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-gold.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nvar redIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-red.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nexport var greenIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-green.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nvar orangeIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-orange.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nvar yellowIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-yellow.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nvar violetIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-violet.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nvar greyIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-grey.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n\nvar blackIcon = new L.Icon({\n iconUrl: \"img/marker-icon-2x-black.png\",\n shadowUrl: \"img/marker-shadow.png\",\n iconSize: [25, 41],\n iconAnchor: [12, 41],\n popupAnchor: [1, -34],\n shadowSize: [41, 41],\n});\n","import React from \"react\";\nimport { Table } from \"semantic-ui-react/\";\n\nclass DraggableTableRow extends React.Component {\n onDragStart = (ev, i) => {\n ev.dataTransfer.setData(\"index\", i);\n };\n\n onDragOver = (ev) => {\n ev.preventDefault();\n };\n\n onDrop = (ev, a) => {\n let b = ev.dataTransfer.getData(\"index\");\n this.props.action(parseInt(a, 10), parseInt(b, 10));\n };\n\n // sets the row styling based on rowStyles which is changed when a row is selected for deletion\n rowStyle = (i) => {\n //console.log(\"qqq rowStyle\", i);\n\n const { rowStyles } = this.props;\n\n if (rowStyles[i]) {\n return { opacity: \"0.3\", backgroundColor: \"red\" };\n } else {\n return null;\n }\n };\n\n render() {\n const { i } = this.props;\n return (\n this.onDragStart(e, i)}\n onDragOver={(e) => this.onDragOver(e)}\n onDrop={(e) => {\n this.onDrop(e, i);\n }}\n >\n {this.props.children}\n \n );\n }\n}\n\nexport default DraggableTableRow;\n","import Immutable from \"seamless-immutable\";\nimport { messageToken } from \"utils/messageToken\";\nimport { microTime } from \"utils/microTime\";\n\nexport const testController = Immutable({\n id: \"11:22:33:44:55:66\",\n area: \"DMLZ Extraction\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [737750, 9549000],\n Z: 0,\n network_name: \"testController\",\n token: messageToken(),\n});\n\nexport const testFF = Immutable({\n id: \"24:0a:c4:50:c8:54\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [737750, 9549000],\n Z: 0,\n token: messageToken(),\n});\n\nexport const testLedFF = Immutable({\n id: \"24:0a:c4:50:c8:54\",\n state: \"ON\",\n color: \"RED\",\n brightness: 100,\n on_time: 0,\n off_time: 0,\n train: 0,\n token: messageToken(),\n});\n\nexport const testArea = Immutable({\n id: \"DMLZ_Apex\",\n image_filename: \"extraction.png\",\n slug: \"dmlz-extraction\",\n bounds: [\n [737074.9271303766, 9549161.164079294],\n [737074.8510577901, 9548828.072795311],\n [737654.4260753208, 9548827.910536127],\n [737074.9271303766, 9549161.164079294],\n [737074.9271303766, 9549161.164079294],\n ],\n ref_coord: [\n {\n utm_zone_letter: \"M\",\n utm: [737376.722, 9549056.885],\n z: 2969.139,\n utm_zone_number: 53,\n id: \"DMLZ_Extraction:1\",\n image_xy: [150.23, 200.45],\n },\n {\n id: \"DMLZ_Extraction:2\",\n utm: [747376.722, 9649056.885],\n z: 2969.139,\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n image_xy: [160.23, 300.45],\n },\n ],\n floor: 2345.88,\n ceiling: 2335.66,\n default_color: \"GREEN\",\n default_state: \"ON\",\n token: messageToken(),\n});\n\n// export const testArea = Immutable({\n// id: \"DMLZ_Extraction99\",\n// name: \"DMLZ_Extraction99\",\n// image_filename: \"extraction.png\",\n// slug: \"dmlz-extraction\",\n// ref_coord: [\n// {\n// Image_X: 4764,\n// Image_Y: 4202,\n// Easting: 736959.54,\n// Northing: 9549076.153,\n// Zone_Number: 53,\n// Zone_Letter: \"M\",\n// },\n// {\n// Image_X: 3236,\n// Image_Y: 7815,\n// Easting: 737526.058,\n// Northing: 9549315.041,\n// Zone_Number: 53,\n// Zone_Letter: \"M\",\n// },\n// {\n// Image_X: 5978,\n// Image_Y: 10090,\n// Easting: 737883.021,\n// Northing: 9548885.911,\n// Zone_Number: 53,\n// Zone_Letter: \"M\",\n// },\n// {\n// Image_X: 7611,\n// Image_Y: 8061,\n// Easting: 737564.472,\n// Northing: 9548630.213,\n// Zone_Number: 53,\n// Zone_Letter: \"M\",\n// },\n// ],\n// bounds: [\n// [737376.722, 9549037.197],\n// [737376.722, 9549037.197],\n// [737376.722, 9549037.197],\n// [737376.722, 9549037.197],\n// ],\n// floor: 2345,\n// ceiling: 2335,\n// status: \"OK\",\n// default_color: \"GREEN\",\n// default_state: \"ON\",\n// });\n\nexport const testNamedAreaEvent = Immutable({\n id: \"DMLZ_Extraction:AREA_46\",\n priority: 1,\n active: true,\n active_color: \"RED\",\n active_state: \"ON\",\n timestamp: microTime(),\n precanned: 0,\n token: messageToken(),\n});\n\nexport const testNamedArea = Immutable({\n id: \"DMLZ_Extraction:AREA_46\",\n name: \"AREA_46\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n origin: \"user\",\n shape: [\n [737809.166, 9549066.886],\n [737703.561, 9549063.944],\n [737584.687, 9548925.63],\n [737646.288, 9548887.191],\n [737658.232, 9548897.419],\n [737726.042, 9548853.966],\n [737785.321, 9548838.814],\n [737837.514, 9548897.337],\n [737848.083, 9548938.28],\n [737750.6, 9549001.738],\n [737809.166, 9549066.886],\n ],\n\n priority: 1,\n type: \"Polygon\",\n default_color: \"green\",\n default_state: \"on\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n on_time: 0,\n off_time: 0,\n },\n ],\n token: messageToken(),\n});\n\n// multiple named area setup\n\nexport const testNamedArea46_1 = Immutable({\n id: \"DMLZ_Extraction:AREA_46_1\",\n name: \"AREA_46_1\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n origin: \"user\",\n // shape for very 1st FF\n\n // shape: [\n // [737082.1976870192, 9549043.955279833],\n // [737082.1942551732, 9549028.928605368],\n // [737100.3934947685, 9549028.923510266],\n // [737100.3969266146, 9549043.95018473],\n // [737082.1976870192, 9549043.955279833],\n // ],\n shape: [\n [737076.1835723922, 9549038.410007201],\n [737092.1832776744, 9549024.94413115],\n [737129.8460999232, 9549065.317777187],\n [737110.3945287307, 9549077.532396676],\n [737076.1835723922, 9549038.410007201],\n ],\n priority: 1,\n type: \"Polygon\",\n default_color: \"green\",\n default_state: \"on\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"on\",\n color: \"red\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 5,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 6,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n ],\n token: messageToken(),\n});\n\nexport const testNamedArea46_2 = Immutable({\n id: \"DMLZ_Extraction:AREA_46_2\",\n name: \"AREA_46_2\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n origin: \"user\",\n shape: [\n [737104.4299204884, 9549065.324892761],\n [737118.5470888059, 9549052.485655224],\n [737157.4651025238, 9549093.172005592],\n [737134.2485288989, 9549106.952957831],\n [737104.4299204884, 9549065.324892761],\n ],\n priority: 1,\n type: \"Polygon\",\n default_color: \"green\",\n default_state: \"on\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"on\",\n color: \"red\",\n on_time: 0,\n off_time: 0,\n },\n\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 5,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 6,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n ],\n token: messageToken(),\n});\n\nexport const testNamedArea46_3 = Immutable({\n id: \"DMLZ_Extraction:AREA_46_3\",\n name: \"AREA_46_3\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n origin: \"user\",\n shape: [\n [737068.3386435859, 9549036.533869058],\n [737090.6125187926, 9549016.805121716],\n [737182.8875021795, 9549120.400737487],\n [737152.4547751799, 9549137.627323097],\n [737068.3386435859, 9549036.533869058],\n ],\n\n priority: 1,\n type: \"Polygon\",\n default_color: \"green\",\n default_state: \"on\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"on\",\n color: \"red\",\n on_time: 0,\n off_time: 0,\n },\n\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 5,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 6,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n ],\n token: messageToken(),\n});\n\nexport const testNamedArea46_4 = Immutable({\n id: \"DMLZ_Extraction:AREA_46_4\",\n name: \"AREA_46_4\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n origin: \"user\",\n shape: [\n [737322.8971520573, 9549354.439185187],\n [737322.8928622497, 9549335.655842107],\n [737342.3450344562, 9549335.65039623],\n [737342.3493242637, 9549354.43373931],\n ],\n\n priority: 1,\n type: \"Polygon\",\n default_color: \"green\",\n default_state: \"on\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"on\",\n color: \"red\",\n on_time: 0,\n off_time: 0,\n },\n\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 5,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 6,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"amber\",\n on_time: 0,\n off_time: 0,\n },\n ],\n token: messageToken(),\n});\n\nexport const testNamedAreas = [\n testNamedArea46_1,\n testNamedArea46_2,\n testNamedArea46_3,\n testNamedArea46_4,\n];\n\nexport const namedAreasGeoJson = [\n {\n type: \"Feature\",\n properties: {\n id: \"DMLZ_Extraction:AREA_46_1\",\n name: \"AREA_46_1\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n priority: 1,\n Firefly_List:\n \"DMLZ_Extraction:P17:3,DMLZ_Extraction:P17:1,DMLZ_Extraction:P17:2\",\n active_color: \"AMBER\",\n active_state: \"ON\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"on\",\n color: \"red\",\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 5,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"on\",\n color: \"amber\",\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 6,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"amber\",\n },\n ],\n },\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [737076.1835723922, 9549038.410007201],\n [737092.1832776744, 9549024.94413115],\n [737129.8460999232, 9549065.317777187],\n [737110.3945287307, 9549077.532396676],\n [737076.1835723922, 9549038.410007201],\n ],\n ],\n },\n token: messageToken(),\n },\n {\n type: \"Feature\",\n properties: {\n id: \"DMLZ_Extraction:AREA_46_2\",\n name: \"AREA_46_2\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n priority: 1,\n Firefly_List:\n \"DMLZ_Extraction:P17:4,DMLZ_Extraction:P17:5,DMLZ_Extraction:P17:3\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"on\",\n color: \"red\",\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 5,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"on\",\n color: \"amber\",\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 6,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"amber\",\n },\n ],\n },\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [737104.4299204884, 9549065.324892761],\n [737118.5470888059, 9549052.485655224],\n [737157.4651025238, 9549093.172005592],\n [737134.2485288989, 9549106.952957831],\n [737104.4299204884, 9549065.324892761],\n ],\n ],\n },\n token: messageToken(),\n },\n {\n type: \"Feature\",\n properties: {\n id: \"DMLZ_Extraction:AREA_46_3\",\n name: \"AREA_46_3\",\n parent: \"parentNamedArea\",\n area: \"DMLZ_Extraction\",\n priority: 1,\n Firefly_List:\n \"DMLZ_Extraction:P17:6,DMLZ_Extraction:P17:4,DMLZ_Extraction:P17:5,DMLZ_Extraction:P17:1,DMLZ_Extraction:P17:7,DMLZ_Extraction:P17:3,DMLZ_Extraction:P17:2\",\n button: [\n {\n clickable: true,\n icon: \"seismic_0_button.png\",\n priority: 1,\n title: \"Seismic 0\",\n alt: \"Area A - Level 0\",\n state: \"on\",\n color: \"green\",\n },\n {\n clickable: true,\n icon: \"seismic_123_button.png\",\n priority: 2,\n title: \"Seismic 123\",\n alt: \"Area A - Level 123\",\n state: \"on\",\n color: \"red\",\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 5,\n title: \"Travelway 1\",\n alt: \"Area A - Travelway 1\",\n state: \"on\",\n color: \"amber\",\n },\n {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 6,\n title: \"Travelway 2\",\n alt: \"Area A - Travelway 2\",\n state: \"on\",\n color: \"amber\",\n },\n ],\n },\n geometry: {\n type: \"Polygon\",\n coordinates: [\n [\n [737068.3386435859, 9549036.533869058],\n [737090.6125187926, 9549016.805121716],\n [737182.8875021795, 9549120.400737487],\n [737152.4547751799, 9549137.627323097],\n [737068.3386435859, 9549036.533869058],\n ],\n ],\n },\n token: messageToken(),\n },\n];\n\nexport const officeControllers = [\n {\n id: \"40:bd:32:e5:29:b3\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n },\n {\n id: \"74:e1:82:8d:c8:3c\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"04:a3:16:fd:75:63\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"0c:ae:7d:24:8c:fc\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"74:e1:82:8d:4b:86\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"c8:df:84:d3:83:b2\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"0c:ae:7d:24:8c:c6\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"0c:ae:7d:24:4b:e3\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"0c:ae:7d:24:ef:d8\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"0c:ae:7d:24:3e:1b\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"f0:45:da:83:01:44\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"40:bd:32:e6:3e:31\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Undercut\",\n token: messageToken(),\n },\n {\n id: \"74:e1:82:91:03:b9\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Extraction\",\n token: messageToken(),\n },\n {\n id: \"04:a3:16:fd:75:60\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Extraction\",\n token: messageToken(),\n },\n {\n id: \"0c:ae:7d:24:2f:75\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Extraction\",\n token: messageToken(),\n },\n {\n id: \"74:e1:82:91:60:c5\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Extraction\",\n token: messageToken(),\n },\n {\n id: \"40:bd:32:e5:93:43\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Extraction\",\n token: messageToken(),\n },\n {\n id: \"0c:ae:7d:24:d6:49\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n utm: [9548941.662, 737591.217],\n z: 0,\n area: \"DMLZ_Extraction\",\n token: messageToken(),\n },\n];\n\nexport const officeFireflies = [\n {\n id: \"DMLZ_Extraction:P17:1\",\n mac: \"b4:e6:2d:ad:09:4d\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737090.94426965, 9549037.6893732],\n network_name: \"controller 1\",\n token: messageToken(),\n },\n\n {\n id: \"DMLZ_Extraction:P17:2\",\n mac: \"b4:e6:2d:aa:54:b1\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737102.467831745, 9549052.2923983],\n network_name: \"controller 2\",\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:3\",\n mac: \"b4:e6:2d:ad:08:8d\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737113.991397232, 9549066.89542385],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:4\",\n mac: \"b4:e6:2d:ad:09:bd\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737125.514965885, 9549081.49844984],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:5\",\n mac: \"b4:e6:2d:a3:85:d9\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737137.038537933, 9549096.10147627],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:6\",\n mac: \"b4:e6:2d:ab:ca:81\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737148.562113146, 9549110.70450314],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:7\",\n mac: \"b4:e6:2d:ad:08:5d\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737160.085691747, 9549125.30753046],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:8\",\n mac: \"b4:e6:2d:ad:08:51\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737171.609273624, 9549139.91055823],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:9\",\n mac: \"b4:e6:2d:ab:ca:71\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737183.132858669, 9549154.51358644],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:10\",\n mac: \"b4:e6:2d:ad:0a:4d\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737194.656447105, 9549169.11661509],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:11\",\n mac: \"b4:e6:2d:aa:54:31\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737206.180038707, 9549183.71964419],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:12\",\n mac: \"b4:e6:2d:ab:ca:59\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737217.703633701, 9549198.32267373],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:13\",\n mac: \"b4:e6:2d:ab:ca:1d\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737229.227231967, 9549212.92570372],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:14\",\n mac: \"b4:e6:2d:ad:0b:fd\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737240.750833399, 9549227.52873416],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:15\",\n mac: \"b4:e6:2d:ad:09:c5\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737252.274438222, 9549242.13176504],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:16\",\n mac: \"b4:e6:2d:ad:08:b5\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737263.798046211, 9549256.73479636],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:17\",\n mac: \"b4:e6:2d:98:f7:95\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737275.321657588, 9549271.33782813],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:18\",\n mac: \"b4:e6:2d:a4:9b:a1\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737286.845272132, 9549285.94086035],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:19\",\n mac: \"b4:e6:2d:ab:fd:05\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737298.368890062, 9549300.54389302],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:20\",\n mac: \"b4:e6:2d:ad:0b:89\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737309.892511267, 9549315.14692612],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:21\",\n mac: \"b4:e6:2d:a4:46:09\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737321.416135637, 9549329.74995968],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:22\",\n mac: \"b4:e6:2d:ad:09:9d\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [737332.939763397, 9549344.35299368],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:23\",\n mac: \"b4:e6:2d:ab:fc:e9\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 2596.139,\n utm: [736820.393, 9549226.979],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:24\",\n mac: \"b4:e6:2d:ad:0a:29\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 2593.24,\n utm: [736959.54, 9549076.153],\n token: messageToken(),\n },\n {\n id: \"DMLZ_Extraction:P17:25\",\n mac: \"b4:e6:2d:98:f1:61\",\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 2592.711,\n utm: [737526.058, 9549315.041],\n token: messageToken(),\n },\n];\n","// TestTable-working-preComponentize-10Jun1219.js\n// https://medium.com/@subalerts/create-dynamic-table-from-json-in-react-js-1a4a7b1146ef\n// draggable row - https://codesandbox.io/s/4jw25r7l19?file=/src/index.js:1333-1353\n// hooks parent to children- https://stackoverflow.com/questions/55726886/react-hook-send-data-from-child-to-parent-component\n\nimport React, { Component, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Table, Checkbox, Icon, Button, Input } from \"semantic-ui-react\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n//import _isEqual from \"lodash/isEqual\";\nimport { getObjectDiff } from \"utils/getObjectDiff\";\n\nimport { microTime } from \"utils/microTime\";\nimport { messageToken } from \"utils/messageToken\";\n\nimport DraggableTableRow from \"./DraggableTableRow\";\n\nimport { namedAreasGeoJson } from \"./mqttMessages\";\n\nimport { mqttPublish } from \"components/WebWorker/actions\";\n\nimport {\n namedAreaSetDeleteSelections,\n namedAreaClearDeleteSelections,\n namedAreaSetShowHideSelections,\n namedAreaClearShowHideSelections,\n namedAreasSetIsDirty,\n namedAreasClearIsDirty,\n removeAcks,\n} from \"components/WebWorker/actions\";\n\nimport {\n getNamedAreaInfos,\n GetMapNamedAreasReducedProperties,\n getNamedAreaEvents,\n getAcks,\n getIsDirty,\n} from \"components/WebWorker/reducer\";\n\nimport {\n GetLocalMap,\n GetLocalMapNamedAreasReducedProperties,\n} from \"components/Map/reducer.js\";\n\nimport { GeoJsonToMqttNamedAreaChange } from \"./utils-mqttMessages\";\n\nimport { makeRandomString } from \"../../../utils/make-random\";\n\nclass TableMade extends Component {\n constructor(props) {\n super(props);\n this.state = {\n data: [],\n // rows: [],\n eventColumns: [], // which column set - true/false = active/inactive\n events: [],\n eventsSelected: [],\n deleteSelected: [], // named area ids of the rows selected to be deleted\n hideSelected: [], // named area ids of the rows selected to be hidden\n isDirty: false,\n acks: [],\n };\n }\n\n componentDidMount() {\n this.setState({ data: this.props.data });\n this.setState({ events: this.props.events });\n this.setState({ acks: this.props.acks });\n\n // set # of events states in eventColumns based on # of buttons\n // #Review/ToDO/WIP - for the moment this is fixed to 4\n\n const eventColumnsDefaults = [false, false, false, false];\n this.setState({ eventColumns: eventColumnsDefaults });\n }\n\n componentDidUpdate(prevProps, prevState) {\n // update acks\n // update new named area data\n if (prevProps.data !== this.props.data) {\n this.setState({ acks: this.props.acks });\n }\n\n // #REVIEW - possible\n // if any setting has been changed (i.e. isDirty) no longer update from mqtt state\n // _but_ update if there is a new item properties.status = \"drawn\"\n //\n // if there is an current event then after setting change this will be resent to update the event.\n const { isDirty } = this.state;\n\n // #REVIEW/ #TODO - need to support passing the parentId through here\n // set global state if dirty\n const parentId = \"parentNamedArea\";\n\n // #REVIEW / TODO\n // move this filter to a common location\n const isParentDirty =\n this.props.parentIsDirty.filter((namedArea) => namedArea === parentId)\n .length > 0;\n\n if (isParentDirty && !isDirty) {\n this.setState({ isDirty: true });\n }\n\n // this form is dirty\n if (!isParentDirty && isDirty) {\n // but the parent is not currently dirty\n this.props.namedAreasSetIsDirty(parentId); // make it dirty\n }\n\n // update new named area data\n if (prevProps.data !== this.props.data) {\n // check if any namedAreas have been drawn i.e. isDirty\n // if properties.status === \"drawn\" then set the form as dirty\n this.props.data.forEach((item, idx) => {\n if (item.properties.status === \"drawn\") {\n // set to dirty\n this.setState({ isDirty: true });\n }\n });\n\n // if Dirty we do not want to update/overwrite the current color state of the check boxes\n // when there is an updated data message\n // make a copy of the button arrays from this state\n // overwrite the incoming data giving preference to the current state\n\n // #REVIEW - this gives copies this.state unless doesn't exist at which point it collects the next sequential values from this.props\n // BUT this assumes sequential\n // need to fix to reference namedArea IDs instead\n // this.props.data is the incoming update\n // this.state.data is the current data\n let newData = this.props.data;\n\n // sort the incoming data (which is so far not reordered) by the properties.priority\n newData.sort(\n (a, b) =>\n parseFloat(a.properties.priority) - parseFloat(b.properties.priority)\n );\n\n // if the form is dirty need to retain all setting for the current data i.e. row posn, state of eye check, color box settings etc.\n // append any new data as the last row.\n\n if (isDirty) {\n let mergedData = [];\n newData.forEach((namedArea, idx) => {\n // if an existing namedArea (i.e. same propertie.id) exists overwrite the newData to keep dirty changes\n const index = this.state.data.findIndex(\n (x) => x.properties.id === namedArea.properties.id\n );\n if (index > -1) {\n mergedData[idx] = this.state.data[index];\n } else {\n mergedData[idx] = namedArea;\n }\n });\n\n // sort the merge data by existing row order\n\n // get a list of the current rows by Id\n let currentNamedRowIds = [];\n this.state.data.forEach((namedArea, idx) => {\n currentNamedRowIds.push(namedArea.properties.id);\n });\n\n // sort newData (properties.id) based on order of currentNamedRowIds\n // #REVEW - NOTE: the new namedArea will be added at the top!\n mergedData.sort(function (a, b) {\n return (\n currentNamedRowIds.indexOf(a.properties.id) -\n currentNamedRowIds.indexOf(b.properties.id)\n );\n });\n\n newData = mergedData;\n }\n\n this.setState({ data: newData });\n }\n\n // update new named area event data\n if (prevProps.events !== this.props.events) {\n // && !isDirty // <--------#WIP disable...testing. Allow update of events while dirty\n\n this.setState({ events: this.props.events });\n\n // event received.\n // check event state based on:\n // - active\n // - id (same as key)\n // - priority - for the moment this is the button column\n\n // console.log(\"qqq this.props.events rx\", this.props.events);\n // console.log(\"qqq this.state.data rx\", this.state.data);\n\n // #REVEW - FIX THIS ...ugly as!\n // update indeterminate\n const namedAreaEvents = this.props.events;\n if (namedAreaEvents !== undefined && !_isEmpty(namedAreaEvents)) {\n // #REVIEW/TODO - only supporting on 'parent' group named area, precanned i.e. button checked will be same for all\n // therefore only check the first event id i.e. id[0]\n const ids = Object.keys(namedAreaEvents);\n\n // update the state data with event button colors\n let newData = this.state.data;\n\n //console.log(\"qqq event ids\", ids);\n\n // update the color boxes from the received events\n\n // map the events.active_color = to data where events.id === namedArea.id &&\n // events.priority = button..priority\n\n newData.forEach((namedArea, idx) => {\n //console.log(\"qqq newData.namedArea\", namedArea);\n if (ids.includes(namedArea.properties.id)) {\n // find the new color from the event received\n const newColor =\n namedAreaEvents[namedArea.properties.id].active_color;\n\n // find the index of the button object which needs to be updated\n // i.e. event priority = button.priority <---- see SPECIAL NOTE below\n //\n const indexOfButtonObject = namedArea.properties.button.findIndex(\n (x) =>\n x.priority === namedAreaEvents[namedArea.properties.id].priority\n );\n // update the button object color with the new Color\n newData[idx].properties.button[indexOfButtonObject].color =\n newColor.toLowerCase(); // not \"GREEEN\" but \"green\"\n }\n });\n\n // update the state with the color from the events\n this.setState({ data: newData });\n\n // #REVIEW/TODO/WIP\n // #SPECIAL NOTE - the filtering above assumes the button row is the priority.\n // In practise the row of a button for (say) travelway might be 3 but the priority might be 6.\n //\n // the following button key have been added to allow more flexibilty but this is not yet implemented\n //\n // active: \"true\", // allows enable/disable of button column\n // group: 0, // grouping of columns\n // column: 0 // index for position of column - as different to priority\n\n // check boxes have an indeterminate state until cleared by a confirmation of the\n // event being set.\n // clear eventsSelected for indeterminate state upon receipt of state update.\n\n // get current state\n let eventsSelected = this.state.eventsSelected;\n\n // only one event state is checked\n // #REVIEW/TODO - only supporting on 'parent' group named area, precanned i.e. button checked will be same for all\n // therefore only check the first event id i.e. id[0]\n // UPDATE - since LEVEL WIDE is an event use '2'\n\n //console.log(\"eventColumns ids\", ids);\n const notMineLevels = ids.find(\n (element) =>\n element !== \"DMLZ_Extraction\" && element !== \"DMLZ_Undercut\"\n );\n //console.log(\"eventColumns notMineLevels\", notMineLevels);\n\n // #REVIEW - only support for one checkbox OR in button group\n // priority is base 1 (0 = lowest level i.e. mine level), but button ref is base 0\n\n let col = 1;\n if (\n notMineLevels !== undefined && // no mine levels\n namedAreaEvents[notMineLevels] !== undefined && // no named areas\n namedAreaEvents[notMineLevels].hasOwnProperty(\"priority\") // accommodate new situation with no events/named areas\n ) {\n col = namedAreaEvents[notMineLevels].priority - 1; //ids[2]\n }\n\n //console.log(\"eventColumns namedAreaEvents\", namedAreaEvents);\n //console.log(\"eventColumns col\", col);\n\n // remove the col set from items in eventSelected array\n eventsSelected = eventsSelected.filter((item) => item !== col);\n this.setState({ eventsSelected: eventsSelected });\n\n // keep track of which column is set\n // #REVIEW - only support for one checkbox OR in button group\n const { eventColumns } = this.state;\n\n // clear the area to all 'false'\n for (let i = 0; i < eventColumns.length; ++i) {\n eventColumns[i] = false;\n }\n // set active event to true\n // e.g. [ true, false, false, false, false]\n // is an active event in column #1\n\n eventColumns[col] = true;\n //console.log(\"eventColumns\", eventColumns);\n this.setState({ eventColumns: eventColumns });\n //this.setState({ eventColumns: [col] });\n }\n }\n }\n\n swap = (a, b) => {\n let { data } = this.state;\n\n console.log(\"qqq swap before data\", data);\n data[a] = data.splice(b, 1, data[a])[0];\n this.setState({\n ...this.state,\n data,\n });\n console.log(\"qqq swap after data\", data);\n\n // row moved i.e. draw layer order has changed so now isDirty\n this.setState({ isDirty: true });\n };\n\n onColorClick = (props) => {\n //console.log(\"qqq onColorClick \", props);\n\n // #WIP - disable dirty if color change -\n // now color change is for events in testing\n //\n if (true) {\n this.setState({ isDirty: true });\n }\n\n const { row, column } = props;\n const { data } = this.state;\n // #REVIEW - why need to deepClone here?\n\n let newData = JSON.parse(JSON.stringify(data)); /// <---deepClone\n\n const colors = [\"green\", \"amber\", \"blue\", \"red\", \"off\"];\n\n const currentColor = newData[row].properties.button[column].color;\n const index = colors.findIndex((x) => x === currentColor);\n let newColor;\n index + 1 > colors.length - 1\n ? (newColor = colors[0])\n : (newColor = colors[index + 1]);\n\n newData[row].properties.button[column].color = newColor;\n\n this.setState({ data: newData });\n };\n\n onEventClick = (col, active) => {\n const { data } = this.state;\n\n //console.log(\"qqq publishMessage click event, data\", col, active, data);\n\n let newData = JSON.parse(JSON.stringify(data)); /// <---deepClone so that reverse (see below) does not alter data object\n // NOTE: named areas are published in reverse so the 'top' in the list\n // comes out last so sets highest lighting priority\n newData.reverse().forEach((namedArea, index) => {\n //console.log(\"qqq namedArea\", namedArea);\n const eventMsg = {\n id: namedArea.properties.id,\n // this is the priority of the button. 0 is base level of lights priority, so start from 1...\n // <----#REVIEW - should get this from the button setup\n priority: col + 1, // <--- this is the button which has been checked!\n active: active,\n active_color: namedArea.properties.button[col].color,\n active_state: \"ON\",\n timestamp: microTime(), // new Date().getTime(),\n precanned: 0,\n token: messageToken(),\n };\n //console.log(\"qqq eventNamedArea row \", col, \"msg \", eventMsg);\n\n // set eventsSelected for indeterminate state\n const eventsSelected = this.state.eventsSelected.concat(col);\n this.setState({ eventsSelected: eventsSelected });\n\n this.props.onSendMqtt({\n topic: `named_area/${eventMsg.id}/event`,\n qos: 0,\n message: eventMsg,\n retained: true,\n });\n });\n };\n\n onDeleteClick = (props) => {\n // console.log(\"qqq onDeleteClick \", props);\n // console.log(\"qqq this.state.deleteSelected\", this.state.deleteSelected);\n\n const { row } = props;\n const { data } = this.state;\n\n const deleteRowId = data[row].properties.id;\n\n // deleteSelected keeps record rows which have been selected for deletion\n let { deleteSelected } = this.state;\n\n if (deleteSelected.includes(deleteRowId)) {\n // remove it\n deleteSelected.splice(deleteSelected.indexOf(deleteRowId), 1);\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n // console.log(\"namedAreaClearDeleteSelections deleteRowId\", deleteRowId);\n // this.props.namedAreaClearDeleteSelections({\n // area: \"DMLZ_Extraction\",\n // id: deleteRowId,\n // });\n // also hide it too!\n this.props.namedAreaClearShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: deleteRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n // add it\n else {\n deleteSelected.push(deleteRowId);\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n // this.props.namedAreaSetDeleteSelections({\n // area: \"DMLZ_Extraction\",\n // id: deleteRowId,\n // });\n // also hide it too!\n this.props.namedAreaSetShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: deleteRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n\n console.log(\n \"hhh namedAreaClearDeleteSelections deleteSelected\",\n deleteSelected\n );\n\n // updated state sent, so no longer dirty\n this.setState({ deleteSelected: deleteSelected });\n\n // updated state sent, so no longer dirty\n this.setState({ isDirty: true });\n };\n\n onShowHideClick = (props) => {\n // console.log(\"qqq onShowHideClick \", props);\n\n const { row } = props;\n const { data } = this.state;\n\n const hideRowId = data[row].properties.id;\n\n // hideSelected keeps record rows which have been selected for hide\n let { hideSelected } = this.state;\n\n if (hideSelected.includes(hideRowId)) {\n // remove it\n hideSelected.splice(hideSelected.indexOf(hideRowId), 1);\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n this.props.namedAreaClearShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: hideRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n // add it\n else {\n hideSelected.push(hideRowId);\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n this.props.namedAreaSetShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: hideRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n\n //console.log(\"hhh hideSelected\", hideSelected);\n\n // updated state of show and hide\n this.setState({ hideSelected: hideSelected });\n\n // show & hide do not change data so not dirty\n // this.setState({ isDirty: true });\n };\n\n getRowsData = () => {\n const { data: items, deleteSelected } = this.state;\n\n // #TODO - use the items list to determine which check box is selected\n // and change the background color\n if (items === undefined) return null;\n\n let rowStyles = [];\n items.forEach((item, idx) => {\n // filter deleteSelected and return an array in row order\n // e.g. rowStyles = [false, true, false];\n rowStyles.push(deleteSelected.includes(item?.properties?.id));\n });\n\n // items sorted by \"priority\"\n // priority may be integer or string.\n // #REVIEW - force to integer for now\n // const items = this.state.data.sort((a, b) => {\n // return a.priority.toString().localeCompare(b.priority);\n // });\n\n //const keys = this.getKeys();\n const itemsLength = items.length;\n\n return items.map((row, index) => {\n return (\n \n \n \n );\n });\n };\n\n // [SAVE CHANGES] button\n sendNamedAreaSetupMqtt = () => {\n const { data: namedAreas } = this.state;\n\n let { deleteSelected } = this.state; // let -> modified when appending drawn shapes for cleanup\n\n if (namedAreas === undefined) return null;\n\n // process namedAreas\n\n // 1 - if namedAreas marker for deletion, send these 1st and delete from namedAreas\n // 2 - then send updated namedAreas in reverse order and with priority saved\n // 3 - send updated event messages applying to 'changed' named areas\n\n // 1 - ...........\n let changedNamedAreas = [];\n\n namedAreas.forEach((namedArea, idx) => {\n const {\n properties: { id },\n } = namedArea;\n\n // if named area is selected for deletion\n if (deleteSelected.includes(id)) {\n // send a delete message\n this.props.onSendMqtt({\n topic: `named_area/${id}/delete`,\n qos: 0,\n message: {\n id: id,\n delete: true,\n token: messageToken(),\n },\n retained: false,\n });\n } else {\n changedNamedAreas.push(namedArea);\n }\n });\n\n // 2 - send changed namedAreas\n //\n // send the messages in reverse so the top namedArea in the UI (row 0) is sent last.\n // namedAreas of the same priority apply in order, so last received has highest priority.\n\n changedNamedAreas.reverse().forEach((namedArea, idx) => {\n const {\n properties: { id },\n } = namedArea;\n\n const {\n properties: { name, parent, area, origin, button },\n } = namedArea;\n\n // priority is set by the row position\n // since the messages are sent out in reverse the priority is also reversed\n // lowest priority is 1\n const priority = namedAreas.length - idx;\n\n const {\n geometry: { coordinates, type },\n } = namedArea;\n\n // #TODO\n // #REVIEW - add these to config dlg\n const default_color = \"green\";\n const default_state = \"OFF\";\n\n // send timestamp as a token\n const token = new Date().getTime().toString();\n\n // create named_area mqtt message\n const newMsg = GeoJsonToMqttNamedAreaChange(\n id,\n area,\n name,\n coordinates,\n type,\n priority,\n origin,\n parent,\n button,\n default_color,\n default_state,\n token\n );\n\n this.props.onSendMqtt({\n topic: `named_area/${id}/change`,\n qos: 0,\n message: newMsg,\n retained: false,\n });\n });\n\n // #REVIEW/TODO - this should be changed to only send for active named areas,\n // and after we have confirmation that the named areas have been deleted\n\n // 3- ........ resend any events that may be running\n // eventColumns keeps record of button columns selected and display as indeterminate\n\n // #WIP - disabled sending events when SAVE CHANGES is selected\n if (false) {\n const { eventColumns } = this.state;\n let { eventsSelected } = this.state;\n\n eventColumns.forEach((eventColumn, index) => {\n if (eventColumn) {\n this.onEventClick(index, true); // send mqtt via onEventClick\n eventsSelected.push(index);\n }\n });\n }\n\n // temp commented out as duplicated in onEventClick...\n // set eventsSelected for indeterminate state, since this event is pending confirmation\n // #REVIEW - supports only one ????\n // this.setState({ eventsSelected: eventsSelected });\n\n // after sending the update, cleanup the list and the map .........\n // Delete all the named areas from the map editlayers list,\n // if the named area has been successful saved the list will update with receipt of next mqtt named_area/+/info\n\n // let drawnNamedAreas = [];\n // namedAreas.forEach((namedArea, idx) => {\n // drawnNamedAreas.push(namedArea.properties.id);\n // });\n // deleteSelected = [...deleteSelected, ...drawnNamedAreas];\n\n // // console.log(\"ffff deleteSelected\", deleteSelected);\n // // #TODO - this is hard coded for DMLZ_Extraction <-----------##########FUX THIS!\n // let deleteSelectedtoMap = [];\n // deleteSelected.forEach((value, idx) => {\n // deleteSelectedtoMap.push({ area: \"DMLZ_Extraction\", id: value });\n // });\n // // this.props.namedAreaSetDeleteSelections(deleteSelectedtoMap);\n\n // ACK PROCESSING\n // wait for an ack to the mqtt messages before proceeding with the cleanup\n\n console.log(\"MQTT_ACKS_UPDATE this.state.acks\", this.state.acks);\n const { acks } = this.state;\n console.log(\"acks\", acks);\n // this works to remove acks - disable for the moment\n // if (acks.length > 0) {\n // this.props.removeAcks(acks[0].ts);\n // }\n\n // send all namedAreas to be deleted from the map\n // note - namdAreas includes those deleted or changed\n const parentId = \"parentNamedArea\";\n namedAreas.forEach((namedArea, idx) => {\n this.props.namedAreaSetDeleteSelections({\n area: parentId,\n id: namedArea.properties.id,\n });\n });\n\n // clear named areas deleted for selection as these have now been removed\n this.setState({ deleteSelected: [] });\n\n // updated named area state sent, so no longer dirty\n // locally\n this.setState({ isDirty: false });\n // globally\n\n this.props.namedAreasClearIsDirty(parentId);\n };\n\n resetIsDirty = () => {\n // reset changes\n\n // #REVIEW/TODO/FIX - this is a fudge until the components are modularised so can pass reset to map component etc\n console.log(\n \"FIX THIS - RESET RELOADS THE PAGE. INSTEAD RELOAD THE COMPONENT\"\n );\n window.location.reload(false);\n\n this.setState({ isDirty: false });\n };\n\n isEventSelected = (col) => {\n const eventsSelected = this.state.eventsSelected;\n if (eventsSelected.includes(col)) {\n return true;\n } else {\n return false;\n }\n };\n\n isEventSet = (col) => {\n // get select state from json object for button\n const namedAreaEvents = this.state.events;\n\n if (namedAreaEvents !== undefined && !_isEmpty(namedAreaEvents)) {\n // #REVIEW/TODO - only supporting on 'parent' group named area, precanned i.e. button checked will be same for all\n // therefore only check the first event id i.e. id[0]\n\n // could be multiple events set for a named area so loop to check\n\n const ids = Object.keys(namedAreaEvents);\n\n // #REVIEW/TODO - only supporting on 'parent' group named area, precanned i.e. button checked will be same for all\n // therefore only check the first event id i.e. id[0]\n // UPDATE - since LEVEL WIDE is an event use '2'\n\n const notMineLevels = ids.find(\n (element) =>\n element !== \"DMLZ_Extraction\" && element !== \"DMLZ_Undercut\"\n );\n\n if (\n notMineLevels !== undefined && // no mine levels\n namedAreaEvents[notMineLevels] !== undefined && // no named areas\n namedAreaEvents[notMineLevels].hasOwnProperty(\"priority\") // accommodate new situation with no events/named areas\n ) {\n if (\n col === namedAreaEvents[notMineLevels].priority - 1 &&\n namedAreaEvents[notMineLevels].active === true // ids[2]\n ) {\n // change checkbox display\n return true;\n } else {\n return false;\n }\n }\n }\n };\n\n isDeleteAllSelected = () => {};\n\n onDeleteAllClicked = () => {};\n\n render() {\n //\n //\n //\n\n // #TODO - style the row if it is selected for Deletion - deleteSelected\n //const myReference = this.rowStyle1.current; // The DOM element\n //myReference.style.backgroundColor = \"red\"; // The style you want to apply\n //this.refs.rowStyle1.style.background = \"red\";\n //\n\n const { isDirty } = this.state;\n\n const iconButtons = {\n padding: \"0.5em\",\n };\n\n // padding cell for top row\n // 4: drag, active checkbox, show/hide eye icon, named area description\n const headerCellsRowTop = (\n <>\n \n \n \n \n \n );\n\n return (\n
\n \n \n \n \n {headerCellsRowTop}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.onEventClick(0, !this.isEventSet(0))}\n />\n \n \n this.onEventClick(1, !this.isEventSet(1))}\n />\n \n \n this.onEventClick(2, !this.isEventSet(2))}\n />\n \n \n this.onEventClick(3, !this.isEventSet(3))}\n />\n \n \n this.onDeleteAllClicked()}\n />\n \n \n \n {/* \n 1\n 1\n 1\n */}\n {this.getRowsData()}\n \n \n \n \n Save Changes\n \n \n Reset Changes\n \n \n \n \n
\n
\n );\n }\n}\n\nconst RenderRow = (props) => {\n const [open, setOpen] = useState(true); // declare new state variable \"open\" with setter\n\n const color = \"black\";\n\n const isItemSelected = (e) => {\n // console.log(\"qqq isItemSelected e\", e);\n };\n\n const handleSelect = (e) => {\n // console.log(\"qqq handleSelect e\", e);\n };\n\n const handleClick = (e, key) => {\n // console.log(\"qqq key\", key);\n\n e.preventDefault();\n\n setOpen(!open);\n };\n\n const isDeleteSelected = (e) => {\n //console.log(\"qqq isDeleteSelected e\", e);\n };\n\n const handleDeleteClick = (e, key) => {\n e.preventDefault();\n\n const row = props.index;\n\n // update data!\n props.onDeleteClick({ row });\n };\n\n const handleShowHideClick = (e, key) => {\n e.preventDefault();\n\n const row = props.index;\n\n // toggle eye icon on button\n setOpen(!open);\n\n // update data!\n props.onShowHideClick({ row });\n };\n\n const eyeIcon = open ? \"eye\" : \"eye slash\";\n const gripIcon = (index, length) => {\n //console.log(\"qqq length, index\", length, index);\n switch (index) {\n case 0:\n return \"sort down\";\n case length - 1:\n return \"sort up\";\n default:\n return \"sort\";\n }\n };\n\n const iconButtons = {\n padding: \"0.5em\",\n };\n\n return (\n <>\n \n handleClick(e, props.index)}\n >\n \n \n \n \n handleSelect(e, props.index)}\n />\n \n \n handleShowHideClick(e, props.index)}\n //toggle\n //active={isShowHideSelected(props.index)}\n >\n \n \n \n \n \n \n \n \n handleDeleteClick(e, props.index)}\n />\n \n \n );\n};\n\n// priority: integer - order of items in list <-- or just sort the object?\n// active: boolean - checkbox status\n// show: boolean - show/hide on map (eye icon)\n// name: string - named area polygon shape name <-- could be generated\n// button: array of button color settings\n\nconst RenderRowColorBox = (props) => {\n // console.log(\"qqq RenderRowColorBox props\", props);\n\n const [open, setOpen] = useState(true); // declare new state variable \"open\" with setter\n\n const handleClick = (e, key) => {\n e.preventDefault();\n\n //let data = props.data;\n const row = props.index;\n const column = key;\n\n // console.log(\"qqq RenderRowColorBox index\", buttonIndex);\n // console.log(\"qqq RenderRowColorBox key\", key);\n // //console.log(\"qqq RenderRowColorBox data\", data);\n\n // console.log(\"qqq currentColor\", data.button[key].color);\n // const colors = [\"green\", \"amber\", \"blue\", \"red\"];\n // const currentColor = data.button[key].color;\n // const index = colors.findIndex((x) => x === currentColor);\n // let newColor;\n // index + 1 > colors.length - 1\n // ? (newColor = colors[0])\n // : (newColor = colors[index + 1]);\n\n // console.log(\"qqq newColor\", newColor);\n\n // update data!\n props.onColorClick({ row, column });\n\n setOpen(!open);\n };\n\n const colorBoxStyle = {\n borderRadius: 0,\n border: \"1px outset black\",\n height: \"100%\",\n margin: \".25em\",\n };\n\n const buttons = props.data.properties.button;\n\n return buttons.map((button, index) => {\n let buttonColor = \"green\";\n switch (button.color) {\n case \"amber\":\n buttonColor = \"yellow\";\n break;\n case \"no_change\":\n buttonColor = \"grey\";\n break;\n case \"off\":\n buttonColor = \"black\";\n break;\n default:\n // not \"GREEN\" as used by the FF controller but \"green\" used by the semantic ui CSS\n buttonColor = button.color.toLowerCase(); // #REVIEW - this shouldn't be necessary as I thought I'd caught these previously but THIS MAKES SURE!\n break;\n }\n\n // console.log(\n // \"qqq index, button.title, button.color, buttonColor\",\n // index,\n // button.title,\n // button.color,\n // buttonColor\n // );\n\n return (\n \n handleClick(e, index)}\n >\n \n \n \n );\n });\n};\n\nclass TestNamedAreaTable extends Component {\n constructor(props) {\n super(props);\n this.state = {\n tableData: [],\n events: [],\n acks: [],\n };\n }\n\n componentDidMount() {\n this.setState({ tableData: this.props.namedAreas }); //\n this.setState({ events: this.props.namedAreaEvents });\n this.setState({ acks: this.props.acks });\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (prevProps.namedAreas !== this.props.namedAreas) {\n this.setState({ tableData: this.props.namedAreas });\n }\n\n if (prevProps.acks !== this.props.acks) {\n this.setState({ acks: this.props.acks });\n }\n\n if (prevProps.namedAreaEvents !== this.props.namedAreaEvents) {\n // #REVIEW / TODO\n // need to support parent group\n // const parentId = \"parentNamedArea\";\n\n // #REVIEW / TODO\n // move this filter to a common location.\n // used in a few places\n // const parentIsDirty =\n // this.props.parentIsDirty.filter((namedArea) => namedArea === parentId)\n // .length > 0;\n\n // if parent group is dirty do not update event external information\n // if (parentIsDirty === false) {\n // console.log(\"dirty ....\");\n this.setState({ events: this.props.namedAreaEvents });\n // }\n }\n }\n\n render() {\n return (\n this.props.mqttPublish(mqttMsg)}\n namedAreaSetDeleteSelections={(deleteSelection) =>\n this.props.namedAreaSetDeleteSelections(deleteSelection)\n }\n namedAreaClearDeleteSelections={(deleteSelection) =>\n this.props.namedAreaClearDeleteSelections(deleteSelection)\n }\n namedAreaSetShowHideSelections={(hideSelection) =>\n this.props.namedAreaSetShowHideSelections(hideSelection)\n }\n namedAreaClearShowHideSelections={(hideSelection) =>\n this.props.namedAreaClearShowHideSelections(hideSelection)\n }\n namedAreasSetIsDirty={(id) => this.props.namedAreasSetIsDirty(id)}\n namedAreasClearIsDirty={(id) => this.props.namedAreasClearIsDirty(id)}\n parentIsDirty={this.props.parentIsDirty}\n acks={this.props.acks}\n removeAcks={(ts) => this.props.removeAcks(ts)}\n />\n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n // namedAreas direct from mqtt\n const geoJSONNamedAreasUtm = getNamedAreaInfos(state); // #REVEW - direct connection to mqtt\n const namedAreasReduced = GetMapNamedAreasReducedProperties(state);\n const namedAreasOld = geoJSONNamedAreasUtm.features;\n\n // named area events mqtt messages\n const namedAreaEvents = getNamedAreaEvents(state);\n\n // ack mqtt messages\n const acks = getAcks(state);\n\n // namedAreas from local map which includes shapes added (but not necessarily in server db)\n const localMapState = GetLocalMap(state);\n\n // #REVIEW - may not be used. Was WIP for idea. Delete?\n // a subset of local map to allow comparison of common data between mqtt and drawn\n const localNamedAreasReduced = GetLocalMapNamedAreasReducedProperties(state);\n\n const { namedArea: parentIsDirty } = getIsDirty(state);\n\n const namedAreas =\n localMapState.namedAreas !== undefined\n ? localMapState.namedAreas.features\n : [];\n return {\n namedAreasReduced,\n localNamedAreasReduced,\n geoJSONNamedAreasUtm,\n localMapState,\n namedAreas,\n namedAreaEvents,\n acks,\n parentIsDirty,\n };\n}\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n namedAreaSetDeleteSelections: (deleteSelection) => {\n dispatch(namedAreaSetDeleteSelections(deleteSelection));\n },\n namedAreaClearDeleteSelections: (deleteSelection) => {\n dispatch(namedAreaClearDeleteSelections(deleteSelection));\n },\n namedAreaSetShowHideSelections: (hideSelection) => {\n dispatch(namedAreaSetShowHideSelections(hideSelection));\n },\n namedAreaClearShowHideSelections: (hideSelection) => {\n dispatch(namedAreaClearShowHideSelections(hideSelection));\n },\n namedAreasSetIsDirty: (id) => {\n dispatch(namedAreasSetIsDirty(id));\n },\n namedAreasClearIsDirty: (id) => {\n dispatch(namedAreasClearIsDirty(id));\n },\n removeAcks: (ts) => {\n dispatch(removeAcks(ts));\n },\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(TestNamedAreaTable);\n","export function GeoJsonToMqttNamedAreaChange(\n id,\n area,\n name,\n coordinates,\n type,\n priority,\n origin,\n parent,\n button,\n default_color,\n default_state,\n style,\n token\n) {\n // duplicate first coordinate in shape to close the ring\n // e.g. coordinates\n // [\n // [\n // [737076.1835723922, 9549038.410007201],\n // [737092.1832776744, 9549024.94413115],\n // [737129.8460999232, 9549065.317777187],\n // [737110.3945287307, 9549077.532396676],\n // ],\n // ],\n\n let shape;\n // NOTE - only supports a single polygon shape, not multi-, so get the first shape in coordinates array\n shape = coordinates[0];\n // check first point and last should be the same\n if (shape[0] !== shape[shape.length - 1]) {\n // or append first to end point to close the polygon ring\n shape = [...shape, shape[0]];\n }\n\n return {\n id: id,\n area: area,\n name: name,\n shape: shape,\n type: type,\n priority: priority,\n origin: origin,\n parent: parent,\n button: button,\n default_color: default_color,\n default_state: default_state,\n style,\n token: token,\n };\n}\n","import React, { useState, useEffect } from \"react\";\nimport { connect } from \"react-redux\";\nimport { GetLocalMap } from \"components/Map/reducer\";\n\nimport { Header, Table, Button, Checkbox, Grid } from \"semantic-ui-react\";\n\nimport Map from \"./TestMqttGeoJsonMap\";\n//import Map from \"components/Map/mapBase.js\";\n//import MapMini from \"./TestMqttGeoJsonMapMini\";\n\nimport TestNamedAreaTable from \"pages/Test/TestMQTT/TestMqttNamedAreasSetup\";\n\n// based on\n// - https://embed.plnkr.co/Gvei5I0S9yEo6fCYXPuy/\n// see -> from \"./TestMapTilesMap\";\n\n// --------------------------------------\n// Marker not appearing for Simple Example\n// Fix - https://github.com/PaulLeCam/react-leaflet/issues/453\n//\nimport \"leaflet/dist/leaflet.css\";\nimport L from \"leaflet\";\n\ndelete L.Icon.Default.prototype._getIconUrl;\n\nL.Icon.Default.mergeOptions({\n iconRetinaUrl: require(\"leaflet/dist/images/marker-icon-2x.png\"),\n iconUrl: require(\"leaflet/dist/images/marker-icon.png\"),\n shadowUrl: require(\"leaflet/dist/images/marker-shadow.png\"),\n});\n// --------------------------------------\n// HACKfix: Use zIndex to stop leaflet map from being above the Semantic-UI dropdown menus!\nconst DEFAULT_MAP_STYLE = {\n height: \"800px\",\n width: \"100%\",\n position: \"relative\",\n zIndex: 0,\n};\n\nclass TestMqttGeoJson extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n isCheckboxMarker: true,\n isCheckboxRefMarker: true,\n isCheckboxFireflies: true,\n isCheckboxPolyline: false,\n isAddPolygonClicked: false,\n };\n }\n\n isAddPolygonClicked = () => {\n this.setState({\n isAddPolygonClicked: !this.state.isAddPolygonClicked,\n });\n };\n\n onClickCheckbox = (name) => {\n this.setState({\n [name]: !this.state[name],\n });\n\n // uiseful - https://hallister.github.io/semantic-react/#!/Checkbox\n\n // via REDUX map the state of the controls\n // within the Map component, catch updates and alter layers etc. based on\n // STATE messages.\n\n // _alt_\n // pass down the state to child component (as below)\n\n // see\n // https://gis.stackexchange.com/questions/186131/placing-controls-outside-map-container-with-leaflet\n };\n\n render() {\n let {\n isCheckboxMarker,\n isCheckboxRefMarker,\n isCheckboxFireflies,\n isCheckboxPolyline,\n } = this.state;\n\n const { localMapState } = this.props;\n // console.log(\n // \"localMapState namedAreas\",\n // JSON.stringify(localMapState.namedAreas)\n // );\n\n // #REVIEW - replace with object search\n // https://stackoverflow.com/questions/2631001/test-for-existence-of-nested-javascript-object-key\n function getNested(obj, ...args) {\n return args.reduce((obj, level) => obj && obj[level], obj);\n }\n\n const tempArray = getNested(localMapState, \"namedAreas\", \"features\") || [];\n // console.log(\"tempArray\", tempArray);\n\n return (\n <>\n \n
Test Named Areas for Extraction Layer
\n\n \n \n
\n {/* \n
\n */}\n \n \n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n
    \n {tempArray.map(\n (\n {\n properties: { id, Firefly_List },\n geometry: { coordinates, type },\n },\n idx\n ) => (\n
  • \n Area: \n {id}\n
    \n FireFly_List: {Firefly_List}\n
  • \n )\n )}\n
\n
\n
\n \n \n {/* */}\n \n
\n
\n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const localMapState = GetLocalMap(state);\n\n return {\n localMapState,\n };\n}\n\nexport default connect(mapStateToProps, null)(TestMqttGeoJson);\n","// railway_application\n\nimport React, { Component } from \"react\";\nimport { Popup, Button, Container, Grid } from \"semantic-ui-react\";\nimport { connect } from \"react-redux\";\nimport Icon from \"components/Icon\";\n\nimport cuid from \"cuid\";\n\nimport \"pages/ControlRoomPage/GatesAndCrane/GatesAndCrane.css\";\nimport {\n getMachineStatus,\n getAllExternalTriggerById,\n getAllButtonTriggerById,\n} from \"components/WebWorker/reducer\";\n\nclass GatesAndCrane extends Component {\n componentDidMount() {}\n\n _onClick = (operation) => () => {\n //console.log(\"_onClick\", operation);\n if (this.props.isActive) {\n //this.props.cancel(this.props.activeOpsChange.id);\n } else {\n //this.props.activate();\n }\n };\n\n render() {\n const { machines, externalTrigger, buttonTrigger, colors } = this.props; //isActive\n\n //console.log(\"render externalTrigger\", externalTrigger.active);\n //console.log(\"render buttonTrigger\", buttonTrigger.active);\n\n const isActive = true;\n\n const { gate: gateColor, crane: craneColor, alarm: alarmColor } = colors;\n\n let boomgate = [];\n for (let index = 1; index < 4; index++) {\n const machineIndex = `boomgate-${index}`;\n boomgate[index] = {\n color:\n machines[machineIndex] !== undefined\n ? machines[machineIndex].active\n ? gateColor.up\n : gateColor.down\n : \"grey\",\n icon:\n machines[machineIndex] !== undefined\n ? machines[machineIndex].active\n ? `icon-gate-${index}-open.svg`\n : `icon-gate-${index}-closed.svg`\n : `icon-gate-${index}-open.svg`,\n name: `Gate ${index}`,\n hint:\n machines[machineIndex] !== undefined\n ? machines[machineIndex].active\n ? \"OPEN\"\n : \"CLOSED\"\n : \"...waiting for status....\",\n notHint:\n machines[machineIndex] !== undefined\n ? `(${machines[machineIndex].state})`\n : \"\",\n };\n }\n\n let crane = [];\n for (let index = 1; index < 2; index++) {\n const machineIndex = `crane-${index}`;\n crane[index] = {\n color:\n machines[machineIndex] !== undefined\n ? machines[machineIndex].active\n ? craneColor.on\n : craneColor.off\n : \"grey\",\n icon: `icon-crane.svg`,\n class:\n machines[machineIndex] !== undefined\n ? machines[machineIndex].active\n ? \"flashing\"\n : \"\"\n : \"\",\n name: `Crane`,\n hint:\n machines[machineIndex] !== undefined\n ? machines[machineIndex].active\n ? \"OPERATING\"\n : \"IDLE\"\n : \"...waiting for status...\",\n };\n }\n\n return (\n \n \n \n \n \n }\n content={`${boomgate[1].name} - ${boomgate[1].hint} ${boomgate[1].notHint}`}\n position=\"bottom center\"\n basic\n />\n \n\n \n \n \n \n }\n content={`${boomgate[2].name} - ${boomgate[2].hint} ${boomgate[2].notHint}`}\n position=\"bottom center\"\n basic\n />\n \n \n \n \n \n }\n content={`${boomgate[3].name} - ${boomgate[3].hint} ${boomgate[3].notHint}`}\n position=\"bottom center\"\n basic\n />\n \n\n {/* \n \n \n \n }\n content={`${crane[1].name} - ${crane[1].hint}`}\n position=\"bottom center\"\n basic\n />\n */}\n\n \n \n \n \n }\n content={`${crane[1].name} - ${\n externalTrigger.active ? \"OPERATING\" : \"IDLE\"\n }`}\n position=\"bottom center\"\n basic\n />\n \n\n \n \n \n \n }\n content={`Button Trigger - ${\n buttonTrigger.active ? \"EMERGENCY ALARM\" : \"OFF\"\n }`}\n position=\"bottom center\"\n basic\n />\n \n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const { controllerIp } = props;\n\n const machines =\n getMachineStatus(state) !== undefined ? getMachineStatus(state) : {};\n const externalTrigger = getAllExternalTriggerById(state, controllerIp);\n const buttonTrigger = getAllButtonTriggerById(state, controllerIp);\n\n return {\n machines: machines,\n externalTrigger: externalTrigger !== undefined ? externalTrigger : {},\n buttonTrigger: buttonTrigger !== undefined ? buttonTrigger : {},\n };\n}\nexport default connect(mapStateToProps, null)(GatesAndCrane);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Header,\n Tab,\n Grid,\n Dimmer,\n Loader,\n Container,\n Message,\n} from \"semantic-ui-react\";\n\nimport MineLevelOpsControl from \"pages/ControlRoomPage/MineLevelOpsControl\";\n// mobile version\nimport MineLevelOpsControlMinimal from \"pages/ControlRoomPage/MineLevelOpsControlMinimal\";\n\nimport PrecannedOperations from \"pages/ControlRoomPage/PrecannedOperations\";\n\nimport {\n getAllAreaStatuses,\n getNamedAreaStatusesById,\n getMqttDataLoading,\n} from \"components/WebWorker/reducer\";\n\nimport { SetActiveArea } from \"components/WebWorker/actions\";\n\nimport { getNamedAreaDisplaySettings } from \"components/Settings/reducer\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport Legend from \"components/Legend\";\nimport { legend, appResponsive } from \"components/ConfigJs\";\n\nimport TestMqttGeoJson from \"pages/Test/TestMqttGeoJson\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport {\n isConfigJs,\n TemplateDefaultArea,\n controlScreenEmergencyEventButtons as _controlScreenEmergencyEventButtons,\n} from \"components/ConfigJs\";\n\n// railway_application\nimport GatesAndCrane from \"pages/ControlRoomPage/GatesAndCrane/GatesAndCrane\";\nimport {\n isBoomgateCrane as _isBoomgateCrane,\n BoomgateControllerIp,\n BoomgateColors,\n} from \"components/ConfigJs\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport MediaQuery from \"react-responsive\";\n\nimport { fetchMineLevels } from \"MineLevels/actions\";\nimport { fetchUPSs } from \"UPSPanelControllers/actions\";\nimport { fetchFireflys } from \"UPSPanelControllers/actions\";\nimport {\n fetchNamedAreas,\n fetchNamedAreaEvents,\n fetchNamedAreaTriggers,\n} from \"NamedAreas/actions\";\n\nimport { strings } from \"components/App/localisation\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\nimport { getUserData } from \"auth/reducer\";\nimport { ta } from \"date-fns/locale\";\n\nclass ControlRoomPage extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n activeIndex: 0,\n width: window.innerWidth,\n height: window.innerHeight,\n };\n }\n\n componentDidMount() {\n // track window dimension\n this.updateWindowDimensions();\n window.addEventListener(\"resize\", this.updateWindowDimensions);\n\n let tabIndex = 0;\n const currentMapTab = this.props.componentstate.get(\n \"smartLightingMapTab\",\n 1\n );\n\n //console.log(\"currentMapTab componentDidMount\", currentMapTab);\n if (Number.isInteger(currentMapTab)) {\n this.setState({ activeIndex: currentMapTab });\n tabIndex = currentMapTab;\n }\n this.props.SetActiveArea(this.props.levels?.[tabIndex]?.id || 0);\n }\n\n componentDidUpdate(prevProps, prevState) {\n const prevLevelIds = prevProps.levels?.map((level) => level.id);\n const levelIds = this.props.levels?.map((level) => level.id);\n if (\n levelIds.length > 0 &&\n JSON.stringify(prevLevelIds) !== JSON.stringify(levelIds)\n ) {\n const tabIndex = this.state.mapTab || 0;\n this.props.SetActiveArea(levelIds?.[tabIndex]);\n }\n }\n\n componentWillUnmount() {\n window.removeEventListener(\"resize\", this.updateWindowDimensions);\n\n const settings = {\n section: \"smartLightingMapTab\",\n key: 1,\n data: this.state.activeIndex,\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n //#REVIEW #TODO - is this necessary?\n //this.props.saveUserSettingsComponentState({ settings });\n\n // #WIP - debugging reset to latest tab\n //this.props.componentstate.set(\"currentMapTab\", 1, this.state.activeIndex);\n //console.log(\"currentMapTab componentWillUnmount\", this.state.activeIndex);\n\n this.props.SetActiveArea(\"\");\n }\n\n updateWindowDimensions = () => {\n this.setState({ width: window.innerWidth, height: window.innerHeight });\n };\n\n handleTabChange = (e, data) => {\n const { activeIndex, panes } = data;\n\n //console.log(\"currentMapTab handleTabChange activeIndex\", activeIndex);\n this.setState({ activeIndex });\n\n const activeArea = panes[activeIndex]?.areaId || \"\";\n this.props.SetActiveArea(activeArea);\n };\n\n render() {\n const {\n levels,\n namedAreaDisplaySettings,\n allAreasNamedArea,\n isDataLoading,\n userSettings,\n } = this.props;\n\n const { activeIndex, height, width } = this.state;\n //console.log(\"mobile width: {width} ~ height: {height}\", width, height);\n\n //console.log(\"controlRoomPage isDataLoading\", isDataLoading);\n const { legend: isShowLegend, sopInterface: isSopInterface } =\n namedAreaDisplaySettings;\n\n // #NOTE #WIP\n // This should not be necessary as defaultLevel loads through webworker\n\n const configJs = isConfigJs();\n // check if the default area is loading correctly from config.js\n // if this load fails the webworker may never return a valid areaStatuses\n // resulting in an endless 'data loading' sequence.\n\n const templateDefaultArea = TemplateDefaultArea();\n\n // DON'T DO THIS!\n //key={`div-${cuid()}`}\n\n const allAreasButtonGroup = allAreasNamedArea?.button;\n\n const isBoomgateCrane = _isBoomgateCrane() || false;\n\n const controlScreenEmergencyEventButtons =\n _controlScreenEmergencyEventButtons() || {\n show: false,\n label: \"MINE WIDE\",\n };\n\n const startupProblem = !configJs || _isEmpty(levels);\n\n if (startupProblem) {\n console.log(\"LOADING ERROR: NO AREAS TO DISPLAY.\");\n console.log(\"CHECK IF CONFIG.JS IS LOADED OK.....? - \", configJs);\n console.log(\n \"DEFAULT AREA TEMPLATE LOADED - \",\n JSON.stringify(templateDefaultArea)\n );\n }\n\n const { mobile, tablet, laptop, desktop } = appResponsive();\n\n const isDesktopOrLaptop = desktop; // (min-width: 1351px)\n const isTabletOrMobileDevice = mobile; // 1350 (max-width: 1350px)\n\n return (\n <>\n {/* See - src/components/Header/index.js for other size setups */}\n \n
\n \n \n \n \n {!isBoomgateCrane &&\n controlScreenEmergencyEventButtons.show &&\n allAreasButtonGroup !== undefined && (\n \n )}\n \n \n \n\n ({\n areaId: level.id,\n menuItem: level.name,\n render: () => (\n \n \n \n ),\n }))}\n />\n {!isDataLoading && }\n \n \n
\n
\n \n <>\n {startupProblem && (\n
\n \n \n \n \n \n \n \n \n {/* dummy row for spacing consistency */}\n \n \n ({\n menuItem: strings?.[\"Loading ...\"],\n render: () => (\n \n \n \n ),\n }))}\n />\n \n \n
\n )}\n {!startupProblem && (\n
\n \n \n \n \n
\n {allAreasButtonGroup !== undefined && (\n <>\n {!isBoomgateCrane &&\n controlScreenEmergencyEventButtons.show && (\n \n {controlScreenEmergencyEventButtons.label}\n
\n )}\n {(controlScreenEmergencyEventButtons.show ||\n !isSopInterface) && (\n \n )}\n \n )}\n \n \n \n \n \n\n {isBoomgateCrane && (\n \n \n \n )}\n \n \n {/* dummy row for spacing consistency */}\n \n \n {/* #WIP - remove dimmer to allow more feedback */}\n {/* \n Loading data\n */}\n ({\n areaId: level.id,\n menuItem: level.name,\n render: () => (\n \n \n \n ),\n }))}\n />\n {isShowLegend && }\n {/* #TODO #FIX use of `isDataLoading` {!isDataLoading && isShowLegend && } */}\n \n \n \n )}\n \n \n \n );\n\n // if (!configJs || _isEmpty(levels)) {\n // return (\n //
\n // \n // \n // \n // \n // \n // \n // \n // {/* dummy row for spacing consistency */}\n // \n // ({\n // menuItem: \"loading ...\",\n // render: () => (\n // \n // \n // \n // ),\n // }))}\n // />\n // \n // \n //
\n // );\n // } else {\n // return (\n //
\n // \n // \n // \n // \n //
\n // {allAreasButtonGroup !== undefined && (\n // <>\n // {!boomgateCrane && (\n // \n // MINE WIDE\n //
\n // )}\n // \n // \n // )}\n // \n // \n // \n // \n // \n\n // {boomgateCrane && (\n // \n // \n // \n // )}\n // \n // {/* dummy row for spacing consistency */}\n // \n // {/* #WIP - remove dimmer to allow more feedback */}\n // {/* \n // Loading data\n // */}\n // ({\n // menuItem: level.name,\n // render: () => (\n // \n // \n // \n // ),\n // }))}\n // />\n // {isShowLegend && }\n // {/* #TODO #FIX use of `isDataLoading` {!isDataLoading && isShowLegend && } */}\n // \n // \n // \n // );\n // }\n }\n}\n\nfunction mapStateToProps(state) {\n // set the display and order of levels\n\n const allAreas = getAllAreaStatuses(state);\n const thisUser = getUserData(state);\n\n return {\n allAreasNamedArea: getNamedAreaStatusesById(state, \"ALL_AREAS\"),\n namedAreaDisplaySettings: getNamedAreaDisplaySettings(state),\n levels: allAreas,\n isDataLoading: getMqttDataLoading(state),\n userSettings: thisUser?.settings || {},\n };\n}\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n fetchMineLevels,\n fetchUPSs,\n fetchFireflys,\n fetchNamedAreas,\n fetchNamedAreaEvents,\n fetchNamedAreaTriggers,\n //fetchPrecannedOperations,\n saveUserSettingsComponentState,\n SetActiveArea,\n })(ControlRoomPage)\n);\n","import React from \"react\";\nimport { Table } from \"semantic-ui-react\";\n\nexport const TrailingContent = (props) => {\n const { data, isLoading, error, columnSpan } = props;\n\n // trailing content should span two columns unless otherwise defined.\n // i.e. some forms only have one column, or first columns are small\n\n const ItemRow = ({ item, error = false, wholeRowMessage, ...props }) => {\n if (wholeRowMessage) {\n return (\n \n \n {wholeRowMessage}\n \n \n );\n }\n };\n\n if (isLoading) {\n return ;\n } else if (error) {\n return ;\n } else if (typeof data !== \"undefined\" && data.length === 0) {\n return ;\n } else {\n return null;\n }\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Modal, Header, Icon, Button } from \"semantic-ui-react\";\nimport { getServerStatus } from \"components/Settings/reducer\";\n\nexport class DeleteButton extends Component {\n state = { open: false };\n\n clicked = (e) => {\n const { onClick, id } = this.props;\n onClick(id);\n this.close();\n };\n close = () => this.setState({ open: false });\n open = () => this.setState({ open: true });\n\n render() {\n const { open } = this.state;\n const { serverStatus, strings, size = \"large\" } = this.props;\n return (\n {\n e.preventDefault(); // Stop any form validation\n this.open();\n }}\n disabled={serverStatus !== \"OK\"}\n size={size}\n >\n {strings?.[\"Delete\"] || \"Delete\"}\n \n }\n basic\n size=\"small\"\n >\n \n \n

{strings?.[\"Delete Button Message Content\"]}

\n
\n \n \n \n \n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n return {\n serverStatus: getServerStatus(state),\n };\n};\n\nDeleteButton = connect(mapStateToProps, null)(DeleteButton);\n","// see main reducer at src/reducers.js\n\nimport Immutable from \"seamless-immutable\";\n\nconst initialState = Immutable([]);\n\nexport default function reduce(state = initialState, action = {}) {\n switch (action.type) {\n case \"UPDATE_CONFLICTS\":\n //console.log(\"UPDATE_CONFLICTS\");\n return state.concat(action.payload);\n\n // #REVIEW - not used ATM\n // setup structure to for possible different fault cases or status issues\n\n case \"REMOVE_CONFLICTS\":\n //console.log(\"REMOVE_CONFLICTS\");\n return Immutable(\n state.asMutable().filter(({ id }) => !id.includes(action.payload.id))\n );\n\n case \"CLEAR_CONFLICTS\":\n console.log(\"CLEAR_CONFLICTS\");\n return initialState;\n default:\n return state;\n }\n}\n\nexport function getAllConflicts(state) {\n return state.conflicts;\n}\n","export const capitalize = s => {\n if (typeof s !== \"string\") return \"\";\n return s.charAt(0).toUpperCase() + s.slice(1);\n};\n","import React, { Component } from \"react\";\nimport { formatDate } from \"utils/format-date\";\n\nimport { Button, Popup, Icon } from \"semantic-ui-react\";\n\nimport { capitalize } from \"utils/format-text\";\n\n// XLSL 'react-export-excel' IMPLEMENTATION\n// click button to download report\n// uses https://www.npmjs.com/package/react-export-excel\n// see ex - https://github.com/rdcalle/react-export-excel/blob/HEAD/examples/with_custom_download_element.md\nimport ReactExport from \"react-export-excel\";\n\nconst ExcelFile = ReactExport.ExcelFile;\nconst ExcelSheet = ReactExport.ExcelFile.ExcelSheet;\nconst ExcelColumn = ReactExport.ExcelFile.ExcelColumn;\n\nconst exportFieldsTemplate = [\n {\n type: \"firefly\",\n fields: [\n { label: \"FireFly\", value: \"firefly\", key: \"ff_firefly\" },\n { label: \"FireFly MAC\", value: \"fireflyMac\", key: \"ff_fireflyMac\" },\n { label: \"Controller\", value: \"ups_name\", key: \"ff_ups_name\" },\n { label: \"Controller MAC\", value: \"ups_id\", key: \"ff_ups_id\" },\n { label: \"Area\", value: \"area\", key: \"ff_area\" },\n { label: \"Position\", value: \"position\", key: \"ff_position\" },\n { label: \"Location\", value: \"location\", key: \"ff_location\" },\n { label: \"Software Version\", value: \"swVersion\", key: \"ff_swVersion\" },\n { label: \"Status\", value: \"status\", key: \"ff_status\" },\n { label: \"Timestamp\", value: \"timestamp\", key: \"ff_timestamp\" },\n ],\n },\n {\n type: \"controller\",\n fields: [\n { label: \"Controller\", value: \"ups_name\", key: \"c_ups_name\" },\n { label: \"Controller MAC\", value: \"ups_id\", key: \"c_ups_id\" },\n { label: \"Controller IP\", value: \"controllerIp\", key: \"c_controllerIp\" },\n { label: \"Area\", value: \"area\", key: \"c_area\" },\n { label: \"Location\", value: \"location\", key: \"c_location\" },\n { label: \"Software Version\", value: \"version\", key: \"c_version\" },\n { label: \"Disk Used\", value: \"diskUsed\", key: \"c_diskUsed\" },\n { label: \"User Relay\", value: \"userRelay\", key: \"c_userRelay\" },\n { label: \"Status\", value: \"status\", key: \"c_status\" },\n { label: \"Timestamp\", value: \"timestamp\", key: \"c_timestamp\" },\n ],\n },\n];\n\nexport class Download extends React.Component {\n render() {\n const { data, dataType } = this.props;\n\n //console.log(\"Download data\", data);\n\n const filename = `${capitalize(dataType)}_status_report_${formatDate(\n new Date(Date.now()),\n \"dd-MMM-yy-HH-mm-ss\"\n )}`;\n\n const exportFields =\n exportFieldsTemplate?.find((field) => field?.type === dataType)?.fields ||\n [];\n\n const exportExcelColumns = exportFields?.map((field, idx) => {\n return (\n \n );\n });\n\n return (\n \n \n \n }\n />\n }\n >\n \n {exportExcelColumns}\n \n \n );\n }\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Header,\n Grid,\n Table,\n Container,\n Input,\n Pagination,\n Dropdown,\n Icon,\n Segment,\n Button,\n Checkbox,\n Radio,\n Popup,\n Message,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport { fetchUPSs, fetchFireflys } from \"UPSPanelControllers/actions\";\n\n//import { getAllFireflys } from \"UPSPanelControllers/reducer\";\nimport { getAllFireflyStatuses } from \"components/WebWorker/reducer\";\n\nimport { deleteFirefly } from \"UPSPanelControllers/actions\";\n\nimport { hasTopologyChanged } from \"UPSPanelControllers/reducer\";\n\nimport FireflyLink from \"./FireflyLink\";\nimport UPSLink from \"../ups/UPSLink\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\nimport { formatRelative, parseISO } from \"date-fns\";\nimport { formatDateRelativeNow, minutesAgo } from \"utils/format-date\";\n\n//import { timeConverter } from \"utils/format-time\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { getAllConflicts } from \"components/StatusChecks/reducer\";\n\n//import { sortAlphaNum } from \"utils/sortAlphaNum\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { StatusEnum } from \"utils/StatusEnum\";\n\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nimport { getMqttMsg } from \"components/WebWorker/reducer.js\";\n\nimport { Download } from \"components/Download/index.js\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nconst displayOptions = [\n {\n key: \"all\",\n text: \"Show All\",\n value: \"all\",\n },\n {\n key: \"ok\",\n text: \"OK\",\n value: \"ok\",\n },\n {\n key: \"commissioned\",\n text: \"New\",\n value: \"commissioned\",\n },\n // {\n // key: \"conflict\",\n // text: \"Position Conflict\",\n // value: \"conflict\",\n // },\n // {\n // key: \"moved\",\n // text: \"Position Moved\",\n // value: \"moved\",\n // },\n {\n key: \"shifted\",\n text: \"Position Shifted\",\n value: \"shifted\",\n },\n {\n key: \"timeout\",\n text: \"Timeout\",\n value: \"timeout\",\n },\n {\n key: \"old\",\n text: \"No Status Report\",\n value: \"old\",\n },\n];\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass FireflyList extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n firefly: { string: \"\", include: true },\n controller: { string: \"\", include: true },\n area: { string: \"\", include: true },\n location: { string: \"\", include: true },\n position: { string: \"\", include: true },\n note: { string: \"\", include: true },\n status: { string: \"\", include: true },\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox delete selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n // default for radio button group\n statusGroup: \"all\",\n };\n }\n\n componentDidMount() {\n const { componentstate } = this.props;\n\n const filterInput = componentstate.get(\"filterInput\", \"fireflyList\");\n\n if (!_isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n\n // reset the radio button states\n //\n const filterInputStatusString = filterInput?.status?.string;\n\n switch (filterInputStatusString) {\n case \"\":\n this.setState({ statusGroup: \"all\" });\n break;\n case \"ok\":\n this.setState({ statusGroup: \"ok\" });\n break;\n case \"Notcommissioned\":\n this.setState({ statusGroup: \"commissioned\" });\n break;\n case \"sameposition.Statusreportmissing\":\n this.setState({ statusGroup: \"conflict\" });\n break;\n case \"Reportedtopologychanged\":\n this.setState({ statusGroup: \"moved\" });\n break;\n case \"Shifted\":\n this.setState({ statusGroup: \"shifted\" });\n break;\n case \"Nostatusreport\":\n this.setState({ statusGroup: \"old\" });\n break;\n case \"Timeout\":\n this.setState({ statusGroup: \"timeout\" });\n break;\n default:\n break;\n }\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"fireflyList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n const checkItemString = item[key]?.toLowerCase()?.replace(/\\s/g, \"\"); // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n const checkMatchString = match[key]?.string?.toLowerCase();\n const checkIncludes =\n checkMatchString !== \"\" // remove item which don't match, but exclude \"\" empty case\n ? match[key].include && checkItemString.includes(checkMatchString) //'.include' = true for include, = false for exclude\n : true;\n\n checkMatch = checkMatch && checkIncludes;\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n\n return;\n }\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n // handleFilterStatusChange = ({ checked, value }) => { // <<--- for radio buttons\n handleFilterStatusChange = (e, data) => {\n this.setState({ statusGroup: data.value });\n\n let search = \"\";\n\n switch (data.value) {\n case \"ok\":\n search = \"ok\";\n break;\n case \"commissioned\":\n search = \"Not commissioned\";\n break;\n case \"conflict\":\n search = \"same position. Status report missing\";\n break;\n case \"moved\":\n search = \"Reported topology changed\";\n break;\n case \"shifted\":\n search = \"Shifted\";\n break;\n case \"old\":\n search = \"No status report\";\n break;\n case \"timeout\":\n search = \"Timeout\";\n break;\n case \"all\":\n default:\n search = \"\";\n break;\n }\n this.setFilterState({ name: \"status\", value: search }, true);\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n this.setFilterState(target, true);\n };\n\n setFilterState = ({ name, value }, include) => {\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n // update match value with most recent filter entry\n match[name].string = value.replace(/\\s/g, \"\");\n match[name].include = include;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (e, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n console.log(\"xxx fireflylist handleSelect id\", id);\n this.setState(\n (prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n }\n //() => console.log(\"xxx this.state.selections\", this.state.selections)\n );\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n if (\n item.statusValue !== StatusEnum.NOT_COMMISSIONED ||\n this.props.isDeleteFireflyNotCommissioned // && item.statusValue !== StatusEnum.OK\n ) {\n newSelections[item.id] = true;\n }\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n requestDelete = () => {\n const { selections } = this.state;\n const { deleteFirefly, push } = this.props;\n\n let promiseArray = [];\n\n for (var selection in selections) {\n //console.log(\"deleting Firefly ... \", selection);\n promiseArray.push(\n // eslint-disable-next-line no-loop-func\n new Promise((resolve, reject) => {\n deleteFirefly({ values: { id: selection }, resolve, reject });\n })\n );\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"DELETING FIREFLYS: \", results);\n })\n .then(\n () => {\n this.props.goto(\"/admin/firefly/\");\n },\n (msg) => {\n console.log(\"delete failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Total of {itemsCount} items.{\" \"}\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const fireflyFromDataById = (id) => allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let deleteButton;\n let fireflyDeleteList;\n if (selectedCount > 0) {\n let fireflyNames = [];\n //console.log(\"data\", data);\n for (var key in selections) {\n if (fireflyFromDataById(key) !== undefined) {\n let fireflyName = fireflyFromDataById(key).firefly; // returns \"name (ip_address)\"\n //fireflyName = fireflyName.substring(0, fireflyName.indexOf(\" (\")); // strip off the trailing ip\n fireflyNames.push(fireflyName);\n }\n }\n fireflyNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n fireflyNames = fireflyNames.join(\", \"); // separate by commas\n\n deleteButton = (\n \n );\n\n fireflyDeleteList = (\n \n FireFlys selected ... \n {fireflyNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{strings?.[\"FireFly Status\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n {!areAnySelected && (\n \n {viewablesPage.length} items displayed. Select items in the\n table below to apply an action.\n \n )}\n \n \n \n \n {deleteButton}\n \n
\n \n {viewablesPage.length} items displayed. {selectedCount} selected\n \n
\n \n
\n \n {fireflyDeleteList}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleFilterStatusChange(data)}\n />\n\n {/* \n \n \n this.handleFilterStatusChange(data)\n }\n />\n }\n />\n \n \n \n this.handleFilterStatusChange(data)\n }\n />\n }\n />\n \n \n \n this.handleFilterStatusChange(data)\n }\n />\n }\n />\n \n \n \n this.handleFilterStatusChange(data)\n }\n />\n }\n />\n \n \n \n this.handleFilterStatusChange(data)\n }\n />\n }\n />\n \n \n \n this.handleFilterStatusChange(data)\n }\n />\n }\n />\n \n */}\n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strings?.[\"FireFly\"]}\n \n \n {strings?.[\"Controller\"]}\n \n {/* Bulk Position */}\n \n {strings?.[\"Area\"]}\n \n \n {strings?.[\"Location\"]}\n \n \n {strings?.[\"Position\"]}\n \n \n {strings?.[\"MAC\"]}\n \n \n {strings?.[\"SW Version\"]}\n \n \n {strings?.[\"Latest Report\"]}\n \n \n {strings?.[\"Note\"]}\n \n \n {strings?.[\"Status\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n firefly,\n fireflyLink,\n controller,\n controllerLink,\n // controllerBulkPositionLink,\n area,\n position,\n location,\n lastStatusReport,\n status,\n disableDelete,\n swVersion,\n fireflyMac,\n note,\n style,\n }) => (\n \n \n this.handleSelect(id)}\n disabled={disableDelete}\n />\n \n {fireflyLink}\n {controllerLink || \"-\"}\n {/* {controllerBulkPositionLink || \"-\"} */}\n {area || \"-\"}\n {location || \"-\"}\n {position || \"-\"}\n {fireflyMac || \"-\"}\n {swVersion || \"-\"}\n {lastStatusReport}\n {note || \"-\"}\n {status || \"-\"}\n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\n// const StatusEnum = {\n// OK: 0,\n// OLD_STATUS_REPORT: 1,\n// NO_STATUS_REPORT: 2,\n// DIFFERENT_TOPOLOGY: 3,\n// NOT_COMMISSIONED: 4,\n// SAME_POSITION: 5,\n// NEW: 6,\n// properties: {\n// 1: { warning: true },\n// 2: { error: true },\n// 3: { error: true },\n// 4: { error: true },\n// 5: { error: true },\n// 6: { error: true },\n// },\n// };\n\nconst getStatus = (firefly, fireflies, conflicts, mqttMsg) => {\n const { id, timestamp, topology } = firefly;\n\n // #WIP #MOVED\n\n //console.log(`xxx mqttMsg`, mqttMsg);\n\n const faults = [\n `Firefly IOT_Office:T1:3 MAC was \"c4:4f:33:23:6f:fd\", has been changed to \"c4:4f:33:23:ad:01\"`,\n `Firefly IOT_Office:T1:2 MAC was \"c4:4f:33:23:aa:35\", has been changed to \"c4:4f:33:23:6f:fd\"`,\n `Firefly IOT_Office:T1:1 MAC was \"24:0a:c4:50:c8:58\" has been replaced to \"c4:4f:33:23:aa:35\"`,\n ];\n\n const shifted = [\n // {\n // id: \"IOT_Office:T1:3\",\n // area: \"IOT_Office\",\n // location: \"T1\",\n // position: 3,\n // oldMac: \"c4:4f:33:23:6f:fd\",\n // newMac: \"c4:4f:33:23:ad:01\",\n // },\n // {\n // id: \"IOT_Office:T1:2\",\n // area: \"IOT_Office\",\n // location: \"T1\",\n // position: 2,\n // oldMac: \"c4:4f:33:23:aa:35\",\n // newMac: \"c4:4f:33:23:6f:fd\",\n // },\n // {\n // id: \"IOT_Office:T1:1\",\n // area: \"IOT_Office\",\n // location: \"T1\",\n // position: 1,\n // oldMac: \"24:0a:c4:50:c8:58\",\n // newMac: \"c4:4f:33:23:aa:35\",\n // },\n ];\n\n // find unique Set of locations\n // for each location\n const shiftedInLocation = shifted.filter((item) => item.location === \"T1\");\n //console.log(`xxx movedInLocation`, movedInLocation);\n\n // if >1 entry for locations\n //\n let sortedShiftedInLocation = [];\n let shiftedPosition = [];\n if (shiftedInLocation.length > 1) {\n sortedShiftedInLocation = shiftedInLocation?.sort(\n (a, b) => a.position - b.position\n );\n\n // iterate to the last index\n sortedShiftedInLocation.forEach((val, idx, sortedShiftedInLocation) => {\n // test for valid object in last index\n\n if (!Object.is(sortedShiftedInLocation.length - 1, idx)) {\n const nextItem = sortedShiftedInLocation[idx + 1];\n // if consecutive positions e.g. 2 = 3 - 1\n if (val.position === nextItem?.position - 1) {\n if (val.newMac === nextItem?.oldMac) {\n shiftedPosition.push({ id: val.id, prevPosition: nextItem.id });\n }\n }\n }\n });\n }\n\n //console.log(`xxx sortedMovedInLocation`, sortedMovedInLocation);\n //console.log(`xxx movedPosition`, movedPosition);\n\n //... check for position moved (shifted)\n const isShiftedPosition = shiftedPosition.find((item) => item.id === id);\n if (isShiftedPosition) {\n return {\n value: StatusEnum.SHIFTED_POSITION,\n message: `Shifted. Was ${isShiftedPosition.prevPosition}`,\n };\n }\n\n // #WIP #TODO\n //\n // NEED TO REVIEW PROCESS FOR v3\n //\n\n // check for position conflicts\n let samePosition = [];\n //\n // conflicts.forEach((conflict, index, arr) => {\n // const { fireflyIps } = conflict;\n // if (fireflyIps !== undefined) {\n // if (fireflyIps.includes(firefly.id)) {\n // // get FFs conflicting at the samePosition (i.e. not this FF)\n // const foundThese = fireflyIps.filter(function (x) {\n // return x !== firefly.id;\n // });\n // // see if we already have foundThese\n // foundThese.forEach((conflict, index, arr) => {\n // if (!samePosition.includes(conflict)) {\n // samePosition.push(conflict);\n // }\n // });\n // }\n // }\n // });\n\n // if (samePosition.length) {\n // return {\n // value: StatusEnum.SAME_POSITION,\n // message: `Firefly (${[...samePosition]}) at the same position. ${\n // lastStatusReport ? \"Status report exists\" : \"Status report missing\"\n // }.`,\n // };\n // }\n\n // ....check for a status report?\n if (!timestamp) {\n return {\n value: StatusEnum.NO_STATUS_REPORT,\n message: \"No status report\",\n };\n }\n\n // ... has it been commissioned?\n if (\n topology &&\n topology?.deviceStatus?.includes(StatusEnum.NOT_COMMISSIONED)\n ) {\n return {\n value: StatusEnum.NOT_COMMISSIONED,\n message: \"New - Not commissioned\",\n };\n }\n\n // ... has it moved?\n // if (hasTopologyChanged(firefly, lastStatusReport)) {\n // return {\n // value: StatusEnum.DIFFERENT_TOPOLOGY,\n // message: \"Reported topology changed\",\n // };\n // }\n\n // ... has it timed out?\n if (\n topology &&\n (topology?.deviceStatus?.includes(StatusEnum.INACTIVE) ||\n topology?.deviceStatus?.includes(StatusEnum.TIMEOUT))\n ) {\n return {\n value: StatusEnum.INACTIVE,\n message: \"Timeout\",\n };\n }\n\n // ... is status report recent? i.e. in past 15 minutes?\n const minsAgo = minutesAgo(parseISO(timestamp));\n if (minsAgo > 15) {\n return {\n value: StatusEnum.OLD_STATUS_REPORT,\n message: `Last status report was ${formatRelative(\n parseISO(timestamp),\n new Date(),\n {\n includeSeconds: true,\n }\n )}`,\n };\n }\n\n // ... OK!\n return { value: StatusEnum.OK, message: \"Ok\" };\n};\n\nconst _prepData = (\n elements,\n conflicts,\n roles,\n mqttMsg,\n isDeleteFireflyNotCommissioned\n) => {\n //console.log(\"testFFs data elements\", elements);\n\n const { allowGuest, allowOperator, allowAdmin, allowSuper } = roles;\n let filteredElements = [];\n\n elements.forEach(function (element, idx) {\n const { id, topology, fireflyNote, timestamp } = element;\n const { area, position, location, ups_id, ups_name, mac } = topology;\n\n // if (id === \"DMLZ_Extraction:P17:1\") {\n // console.log(\"P17:1 testFFs data element\", element);\n // }\n\n let lastStatusReport = \"-\";\n if (timestamp !== null && timestamp !== undefined) {\n // format - previous used in tableformatters.js\n lastStatusReport = formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n });\n }\n\n let note = \"-\";\n if (fireflyNote !== undefined) {\n note = fireflyNote;\n }\n\n let swVersion = \"-\";\n // #NOTE - dead, or unresponsive FFs will not have a .device propertie\n //\n if (element?.device !== undefined) {\n const {\n device: { sw_ver },\n } = element;\n if (sw_ver !== undefined) {\n swVersion = sw_ver;\n }\n }\n\n //let upsName = \"-\";\n // #REVIEW\n // this is a hack to get the mineLevel name - should be in the UPS message?!\n //upsName = upsById[upsId].name || \"-\";\n\n // styling for rows for highlight or error states\n // report status of row\n const elementStatus = getStatus(element, elements, conflicts, mqttMsg);\n\n const { value, message } = elementStatus;\n let icon = \"check\";\n let color = \"green\";\n let style = null;\n if (value !== StatusEnum.OK) {\n icon = \"warning sign\";\n const props = StatusEnum.properties[value];\n const { warning = false, error = false } = props;\n color = (error && \"red\") || (warning && \"yellow\") || \"blue\";\n style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n }\n if (value === StatusEnum.NOT_COMMISSIONED) {\n style = { backgroundColor: \"rgb(255, 255, 0, 15%)\" };\n }\n\n const status = message;\n\n // disable delete for NOT_COMMISSIONED, and OK\n const disableDelete =\n value === StatusEnum.NOT_COMMISSIONED && !isDeleteFireflyNotCommissioned; // || value === StatusEnum.OK\n\n const fireflyLink = allowAdmin ? (\n {id}\n ) : (\n `${id || \"\"}`\n );\n\n const controllerLink = allowAdmin ? (\n {`${\n ups_id || \"\"\n } (${id})`}\n ) : (\n `${ups_id || \"\"} (${id})`\n );\n\n // compose new data set\n filteredElements[idx] = {\n id: id,\n firefly: `${id}`,\n fireflyLink: fireflyLink,\n fireflyMac: mac ? `${mac}` : \"-\",\n controller: `${ups_name} (${ups_id})`,\n controllerLink: controllerLink,\n // controllerBulkPositionLink: (\n // {ups_name}\n // ),\n area: area,\n position: `${position}`, // needs to be string for sort ordering (see localCompare)\n location: location,\n lastStatusReport: lastStatusReport,\n status: status,\n statusValue: value,\n disableDelete: disableDelete,\n swVersion: `${swVersion}`,\n note: note,\n style,\n // Raw data for download report\n ups_name,\n ups_id,\n timestamp,\n };\n });\n\n return filteredElements;\n};\n\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n deleteFirefly: (data) => dispatch(deleteFirefly(data)),\n fetchUPSs: () => dispatch(fetchUPSs()),\n fetchFireflys: (data) => dispatch(fetchFireflys(data)),\n saveUserSettingsComponentState: (data) =>\n dispatch(saveUserSettingsComponentState(data)),\n };\n};\n\nfunction mapStateToProps(state, props) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n // const { isLoading, error } = state.ups\n const isLoading = false;\n const error = false;\n\n // #REVIEW\n // this is a hack to get the UPS name - should be in the Firefly message?!\n //const { upsPanelControllers } = state;\n //const { upsById } = upsPanelControllers;\n\n const fireflyStatuses = getAllFireflyStatuses(state);\n const conflicts = getAllConflicts(state);\n\n const mqttMsg = getMqttMsg(state);\n\n // user roles\n const userSuper = isUserSuper(state);\n const userAdmin = isUserAdmin(state);\n const userUser = isUserUser(state);\n const userGuest = isUserGuest(state);\n const allowGuest = userGuest;\n\n const allowOperator = userSuper || userAdmin || userUser;\n const allowAdmin = userSuper || userAdmin;\n const allowSuper = userSuper;\n\n const { isDeleteFireflyNotCommissioned } = props;\n\n const data = _prepData(\n fireflyStatuses,\n conflicts,\n {\n allowGuest: allowGuest,\n allowOperator: allowOperator,\n allowAdmin: allowAdmin,\n allowSuper: allowSuper,\n },\n mqttMsg,\n isDeleteFireflyNotCommissioned\n );\n\n return {\n isLoading,\n error,\n data,\n conflicts,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, mapDispatchToProps)(FireflyList)\n);\n","import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { connect } from \"react-redux\";\n\nimport { withMineLevel } from \"ApplicationContexts\";\n\nimport L from \"leaflet\";\nimport { FeatureGroup, GeoJSON } from \"react-leaflet\";\n\nimport { makeIcon } from \"components/Map/MakeIcon\";\n\nimport {\n getFireflyIdsForMineLevelId,\n getFireflyCoordinatesByAreaId,\n} from \"components/WebWorker/reducer\";\n\n//import Firefly from \"containers/FireflyMapMarker\";\n\nimport hash from \"object-hash\";\nimport _isEmpty from \"lodash/isEmpty\";\n\n// #TODO #REVEW - write a geoJson parse checker\nfunction tryParseJSON(jsonObj) {\n try {\n var o = JSON.parse(JSON.stringify(jsonObj));\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,\n // but... JSON.parse(null) returns null, and typeof null === \"object\",\n // so we must check for that, too. Thankfully, null is falsey, so this suffices:\n if (o && typeof o === \"object\") {\n return true;\n }\n } catch (e) {}\n\n return false;\n}\n\nclass CurrentMineLevelFirefliesFeatureGroup extends Component {\n static propTypes = {\n children: PropTypes.node,\n className: PropTypes.string,\n dispatch: PropTypes.func.isRequired,\n };\n\n shouldComponentUpdate(nextProps, nextState) {\n const { fireflyIds: current } = this.props;\n const { fireflyIds: next } = nextProps;\n\n // console.log(\"current\", current);\n // console.log(\"next\", next);\n\n if (_isEmpty(current) || _isEmpty(next)) return false;\n\n if (current?.length === next?.length) {\n const lookup = current.reduce((acc, id) => {\n acc[id] = true;\n return acc;\n }, {});\n\n const len = next?.length;\n for (var i = 0; i < len; i++) {\n if (!lookup[next[i]]) {\n return true;\n }\n }\n return false;\n }\n return true;\n }\n\n fireflyStyle() {\n return {\n // radius: 6,\n fillColor: \"green\",\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n }\n\n render() {\n const { fireflies, PopupContent } = this.props;\n\n const onEachFeature = (feature, layer) => {\n let popupContent = ``;\n if (feature.properties && feature.properties.id) {\n popupContent += feature.properties.id;\n }\n\n layer.bindPopup(popupContent);\n };\n\n const pointToLayer = (feature, latlng) => {\n //return L.circleMarker(latlng, null); // Change marker to circle\n return L.marker(latlng, {\n icon: makeIcon(\"RoundMarker\", { stroke: \"purple\", fill: \"purple\" }, -4), // default to purple as this is not a suppported active color\n });\n };\n\n const valid = !_isEmpty(fireflies) && tryParseJSON(fireflies);\n\n return (\n valid && (\n ({\n color: \"#4a83ec\",\n weight: 0.5,\n fillColor: \"#1a1d62\",\n fillOpacity: 1,\n })}\n onEachFeature={onEachFeature}\n pointToLayer={pointToLayer}\n />\n )\n );\n // \n // {fireflies.map((id) => {\n // return (\n // \n // );\n // })}\n // \n }\n}\n\nexport function mapStateToProps(state, props) {\n const { mineLevel } = props;\n\n const fireflies = getFireflyCoordinatesByAreaId(state, mineLevel.id);\n const fireflyIds = getFireflyIdsForMineLevelId(state, mineLevel.id);\n\n return {\n fireflies,\n fireflyIds,\n };\n}\n\nexport default withMineLevel(\n connect(mapStateToProps)(CurrentMineLevelFirefliesFeatureGroup)\n);\n","import React from \"react\";\nimport { connect } from \"react-redux\";\nimport { Dropdown } from \"semantic-ui-react\";\n\n//import { getAllMineLevels } from 'MineLevels/reducer'\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nconst ChooseMineLevel = ({\n options,\n currentValue = null,\n onChange,\n disabled = false,\n}) => {\n return (\n \n );\n};\n\nfunction mapStateToProps(state) {\n return {\n options: getAllAreaStatuses(state).map((ml) => ({\n value: ml.id,\n text: ml.name,\n })),\n };\n}\n\nexport default connect(mapStateToProps)(ChooseMineLevel);\n","import React from \"react\";\nimport { Form } from \"semantic-ui-react\";\n\nimport ChooseMineLevel from \"containers/ChooseMineLevel\";\n\nconst ChooseMineLevelField = ({\n input: { value, onChange },\n label,\n disabled = false,\n type,\n meta: { touched, error },\n}) => {\n return (\n \n \n {\n onChange(value);\n }}\n />\n \n );\n};\n\nexport default ChooseMineLevelField;\n","import React from \"react\";\nimport DeviceName from \"components/DeviceName\";\n\nimport { connect } from \"react-redux\";\nimport { getUPSById } from \"UPSPanelControllers/reducer\";\nimport UPSLink from \"admin/ups/UPSLink\";\n\nconst Component = ({ ...props }) => {\n return (\n \n \n \n );\n};\n\nconst mapStateToProps = (state, props) => {\n const { id } = props;\n const ups = getUPSById(state, id);\n if (ups) {\n return { id, name: ups.name };\n }\n return { id, error: \"no UPS for id\" };\n};\n\nexport default connect(mapStateToProps)(Component);\n","import React from \"react\";\n\nimport { Children } from \"react\";\n\n// Flattens all child elements into a single list\nconst flatten = (children, flat = []) => {\n flat = [...flat, ...React.Children.toArray(children)];\n\n if (children.props && children.props.children) {\n return flatten(children.props.children, flat);\n }\n\n return flat;\n};\n\n// Strips all circular references and internal fields\nexport const simplify = (children) => {\n const flat = flatten(children);\n\n return flat.map(({ key, ref, type, props: { children, ...props } }) => ({\n key,\n ref,\n type,\n props,\n }));\n};\n\n// returns a flat array of react children\n// https://gist.github.com/gazdagergo/7833156e096683b49a21133858d521ca\n// from\n// https://github.com/facebook/react/issues/6889\n\nconst getChildrenType = (node) => {\n if (node === null) return \"null\";\n if (Array.isArray(node)) return \"array\";\n if (typeof node === \"object\") return \"object\";\n return \"string\";\n};\n\nconst getElemType = (elem) => {\n if (typeof elem === \"string\") return \"string\";\n if (elem.props.children === undefined) return \"void\";\n return \"normal\";\n};\n\nexport const reactChildrenToFlatArray = (children) => {\n const result = Children.toArray(children).map((child) => {\n switch (\n getElemType(child) // Check node type\n ) {\n case \"void\": // e.g.
\n case \"string\": // normal text\n return child;\n case \"normal\": // any other html tag or component\n switch (\n getChildrenType(child.props.children) // Check node content\n ) {\n case \"null\": // e.g. null\n case \"string\": // e.g foo\n case \"object\": // e.g. \n return child;\n case \"array\": // multiple children\n reactChildrenToFlatArray(child.props.children);\n break;\n default:\n return child;\n }\n break;\n default:\n return child;\n }\n return child;\n });\n return result;\n};\n\n//export default reactChildrenToFlatArray;\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { Map, ImageOverlay } from \"react-leaflet\";\n\nimport { simplify } from \"utils/propsChildren\";\n\nimport L from \"leaflet\";\nimport \"leaflet/dist/leaflet.css\";\nimport \"leaflet-contextmenu\";\nimport \"leaflet-contextmenu/dist/leaflet.contextmenu.css\";\nimport \"leaflet.smoothwheelzoom\";\n\n// easy button for pan tool\n// see - https://www.npmjs.com/package/leaflet-easybutton\n// easybutton & leaflet-react: see - https://stackoverflow.com/questions/64125298/react-leaflet-dynamic-markers-cannot-read-property-addlayer\n// https://codesandbox.io/s/react-leaflet-dynamic-markers-cannot-read-property-addlayer-dfjmb?file=/src/MapSearch.jsx:353-362\n\nimport \"leaflet-easybutton/src/easy-button.css\";\nimport \"leaflet-easybutton\";\n\ndelete L.Icon.Default.prototype._getIconUrl;\n\nL.Icon.Default.mergeOptions({\n iconRetinaUrl: require(\"leaflet/dist/images/marker-icon-2x.png\"),\n iconUrl: require(\"leaflet/dist/images/marker-icon.png\"),\n shadowUrl: require(\"leaflet/dist/images/marker-shadow.png\"),\n});\n\nfunction areEqual(prevProps, nextProps) {\n /*\n return true if passing nextProps to render would return\n the same result as passing prevProps to render,\n otherwise return false\n\n i.e. return `false` to update\n */\n\n const shouldUpdate =\n JSON.stringify(simplify(prevProps.children)) ===\n JSON.stringify(simplify(nextProps.children)) &&\n nextProps.style.backgroundColor === prevProps.style.backgroundColor &&\n nextProps.imageInfo.src === prevProps.imageInfo.src;\n\n // if (!shouldUpdate) {\n // console.log(`MapWithImage shouldUpdate.................`);\n // }\n\n return shouldUpdate;\n}\n\n// Note: About React.memo, Maps & Redux-form\n// Redux-Form updates form props via Redux (as the name implies), this effectively updates the maps\n// props too and causes a re-render. Re-rendering while dragging markers causes a 'snap' back to the last\n// prop/state saved. This significantly impedes usabililty.\n//\n// https://stackoverflow.com/questions/59280319/react-memo-rerendering-with-the-same-props\n//\n// The solution below is to use React.memo wrapped around the map functional component\n// to stop re-rendering of the component unless the image, or the marker pointers, have changed.\n// Markers are passed as children.\n//\n// This requires a deep, flattened, comparison of the children passed to the component.\n// If these are not flattened an object comparison will just suggest they're always\n// being on each re-render making the comparison pointless.\n//\n// #REVIEW - move functions above to support utils?\n\nexport default React.memo(MapWithImage, areEqual);\n\nfunction MapWithImage({ ...props }) {\n const _ENABLE_PAN_CONTROL = false;\n\n const {\n imageInfo,\n // HACKfix: Use zIndex to stop leaflet map from being above the Semantic-UI dropdown menus!\n //style = { height: \"600px\", width: \"100%\", position: \"relative\", zIndex: 0 },\n style,\n // style = {\n // height: \"60vh\",\n // width: \"100%\",\n // position: \"relative\",\n // zIndex: 0,\n // backgroundColor: \"white\",\n // },\n center = [0, 0],\n padBounds = 0.4,\n } = props;\n\n const [map, setMap] = useState({});\n const mapRef = useRef();\n\n const [isMapView, setIsMapView] = useState({});\n\n //console.log(\"MapWithImage - imageInfo\", imageInfo);\n const { minZoom, bounds, src } = imageInfo;\n\n //console.log(\"MapWithImage imageInfo\", imageInfo);\n\n const maxBounds = L.latLngBounds(bounds).pad(padBounds);\n\n // support for map leaflet.contextmenu\n const showCoordinates = (e) => {\n alert(e.latlng);\n };\n\n const centerMap = (e) => {\n mapRef.current.leafletElement.panTo(e.latlng);\n };\n\n const fitMap = (e, bounds) => {\n mapRef.current.leafletElement.fitBounds(bounds);\n };\n\n const zoomIn = (e) => {\n mapRef.current.leafletElement.zoomIn();\n };\n\n const zoomOut = (e) => {\n mapRef.current.leafletElement.zoomOut();\n };\n\n useEffect(() => {\n //console.log(\"xxxx map mounted\");\n\n if (mapRef && mapRef.current) {\n const map = mapRef.current.leafletElement;\n\n setMap(map); //hook to set map\n // sets to const -> 'mapRef.current.leafletElement'\n\n const minZoomCalced =\n Math.floor(Math.log2(map.getSize().x / bounds.getEast())) - 1;\n if (map.getMinZoom() !== minZoomCalced) {\n map.setMinZoom(minZoomCalced);\n map.setZoom(minZoomCalced);\n }\n\n // conditionally enable map movement/pan for leaflet map\n if (_ENABLE_PAN_CONTROL) {\n //----------------------------------------------------\n //\n // MAP MOVEMENT - DRAG ZOOM ETC\n //\n // see - https://gis.stackexchange.com/questions/54454/disable-leaflet-interaction-temporary\n //----------------------------------------------------\n\n const disableMapMovement = (map) => {\n map.dragging.disable();\n map.touchZoom.disable();\n map.doubleClickZoom.disable();\n //map.scrollWheelZoom.disable();\n map.smoothWheelZoom.disable();\n map.boxZoom.disable();\n map.keyboard.disable();\n if (map.tap) map.tap.disable();\n };\n\n const enableMapMovement = (map) => {\n map.dragging.enable();\n map.touchZoom.enable();\n map.doubleClickZoom.enable();\n //map.scrollWheelZoom.enable();\n map.smoothWheelZoom.enable();\n map.boxZoom.enable();\n map.keyboard.enable();\n if (map.tap) map.tap.enable();\n };\n\n // on startup disable map movement by user\n disableMapMovement(map);\n\n //----------------------------------------------------\n //\n // MAP MARKER ZOOM - CONTROLS\n //\n //\n // Custom zoom controls\n //\n //----------------------------------------------------\n\n // listeners for disabling buttons\n map.on(\"zoomend\", (e) => {\n const map = e.target,\n max = map.getMaxZoom(),\n min = map.getMinZoom(),\n current = map.getZoom();\n const isMapViewCurent = isMapView.current;\n if (current < max) {\n if (isMapViewCurent) {\n zoomInButton.enable();\n }\n }\n if (current >= max) {\n if (isMapViewCurent) {\n zoomInButton.disable();\n }\n }\n if (current > min) {\n if (isMapViewCurent) {\n zoomOutButton.enable();\n }\n }\n if (current <= min) {\n if (isMapViewCurent) {\n zoomOutButton.disable();\n }\n }\n });\n\n const moveMapViewZoomIn = ``;\n const moveMapViewZoomOut = ``;\n\n const zoomInButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-in-move-map-view\",\n icon: moveMapViewZoomIn,\n title: \"Zoom In\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() + 1);\n },\n },\n ],\n });\n\n const zoomOutButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-out-move-map-view\",\n icon: moveMapViewZoomOut,\n title: \"Zoom Out\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() - 1);\n },\n },\n ],\n });\n // const zoomBar = L.easyBar([zoomInButton, zoomOutButton]);\n // zoomBar.addTo(map, {\n // position: \"topleft\",\n // });\n\n //----------------------------------------------------\n //\n // MAP VIEW MOVE - CONTROLS\n //\n //----------------------------------------------------\n\n const moveMapViewShow = ``;\n const moveMapViewHide = ``;\n\n const moveMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"show-move-map-view\",\n icon: moveMapViewShow,\n title: \"Pan and Zoom\",\n onClick: (control, map) => {\n // show the zoom controls\n moveMapViewButton.disable();\n zoomOutButton.enable();\n zoomInButton.enable();\n cancelMapViewButton.enable();\n\n // enable map movement\n enableMapMovement(map);\n\n setIsMapView(true);\n },\n },\n {\n stateName: \"hide-move-map-view\",\n icon: moveMapViewHide,\n title: \"Disable move view\",\n },\n ],\n });\n\n const cancelMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"cancel-move-map-view\",\n icon: \"fa fa-times\",\n title: \"Disable Pan and Zoom\",\n onClick: (control, map) => {\n map.closePopup();\n\n // show the zoom controls\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n\n // disable map movement\n disableMapMovement(map);\n\n setIsMapView(false);\n },\n },\n ],\n });\n\n let moveMapViewBar = L.easyBar(\n [moveMapViewButton, zoomInButton, zoomOutButton, cancelMapViewButton],\n { position: \"topleft\" }\n );\n moveMapViewBar.addTo(map);\n\n // startup hide - zoom buttons\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER REFRESH - CONTROLS\n //\n //----------------------------------------------------\n\n const refreshMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"reset-marker-positions\",\n icon: \"fa fa-redo\",\n title: \"Refresh Map\",\n onClick: (e) => {\n map.fitBounds(bounds);\n },\n },\n ],\n });\n\n let refreshMapBar = L.easyBar([refreshMarkerPositionsButton], {\n position: \"topleft\",\n });\n refreshMapBar.addTo(map);\n }\n\n //console.log(\"xxxx map:\", { map });\n }\n }, [map]);\n\n return (\n fitMap(e, bounds),\n },\n \"-\",\n {\n text: \"Zoom in\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-in.png\",\n callback: zoomIn,\n },\n {\n text: \"Zoom out\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-out.png\",\n callback: zoomOut,\n },\n ]}\n // turn off default zoom control (replaced by easyButton)\n zoomControl={!_ENABLE_PAN_CONTROL}\n // scroll wheel zoom smoothing\n scrollWheelZoom={false} // disable original zoom function\n smoothWheelZoom={true} // enable smooth zoom\n smoothSensitivity={1.5} // zoom speed. default is 1\n >\n \n\n {props.children}\n \n );\n}\n\n//export default MapWithImage;\n","// #NOTE -\n/* \nLook into viewports and view port control as a replacement of rthe current leaflet-react implementation.\nSee \n* https://codepen.io/vgrem/pen/KKVbyJe\n* https://stackoverflow.com/questions/48264529/how-to-get-map-object-in-react-leaflet-on-zoom-change-event\n* https://stackoverflow.com/questions/60381912/setstate-in-onviewportchanged-results-in-crash-when-clicking-marker-with-off-map\n*/\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Map, ImageOverlay } from \"react-leaflet\";\nimport { withMineLevel, MineLevelContext } from \"ApplicationContexts\";\nimport { getAreaById } from \"components/WebWorker/reducer\";\nimport { reactChildrenToFlatArray } from \"utils/propsChildren\";\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\nimport { imageCheck } from \"utils/imageCheck\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\n// --------------------------------------\n// Marker not appearing for Simple Example\n// Fix - https://github.com/PaulLeCam/react-leaflet/issues/453\n//\nimport L from \"leaflet\";\nimport \"leaflet/dist/leaflet.css\";\nimport \"leaflet-contextmenu\";\nimport \"leaflet-contextmenu/dist/leaflet.contextmenu.css\";\nimport \"leaflet.smoothwheelzoom\";\n\n// 'react-leaflet-markercluster' styles\nimport \"react-leaflet-markercluster/dist/styles.min.css\";\n\ndelete L.Icon.Default.prototype._getIconUrl;\n\nL.Icon.Default.mergeOptions({\n iconRetinaUrl: require(\"leaflet/dist/images/marker-icon-2x.png\"),\n iconUrl: require(\"leaflet/dist/images/marker-icon.png\"),\n shadowUrl: require(\"leaflet/dist/images/marker-shadow.png\"),\n});\n\nfunction SimpleCRSImageMap({ ...props }) {\n const {\n mineLevel,\n mapViewState: rxMapViewState,\n mapViewType,\n style,\n displayOptions,\n } = props;\n\n //console.log(\"newMapViewState - displayOptions\", displayOptions);\n\n // #WIP - corrupted???? how???\n let mapViewState = JSON?.parse(JSON?.stringify(rxMapViewState) || \"{}\"); // #WIP - deal with rxMapViewState being undefined in a better way thank this!!\n\n // defines whether to show default zoom controls or easyButton pan/zoom/lock button controls\n const isPanZoomButton =\n displayOptions?.includes(\"showPanZoomButton\") || false;\n const isShowRestoreMapViewStateButton =\n displayOptions?.includes(\"showRestoreMapViewStateButton\") || false;\n const isShowSearchControl =\n displayOptions?.includes(\"showSearchControl\") || false; // default to displaying button active\n\n // setup map objects to state\n const [map, setMap] = useState(null);\n const mapRef = useRef();\n const [isMapView, setIsMapView] = useState(null);\n\n // #TESTING - defined the leaflet map reference\n //let leafletMapRef;\n\n useEffect(() => {\n if (false) {\n console.log(\"MapViewState useEffect ------------------------------\");\n console.log(\"MapViewState useEffect map xxxxxxxxx\", map);\n console.log(\"MapViewState useEffect mapRef xxxxxxxxx\", mapRef);\n console.log(\n \"MapViewState useEffect mapRef.current xxxxxxxxx\",\n mapRef?.current\n );\n console.log(\n \"MapViewState useEffect mapRef.current isPanZoomButton\",\n isPanZoomButton,\n \"isShowRestoreMapViewStateButton\",\n isShowRestoreMapViewStateButton,\n \"isShowSearchControl\",\n isShowSearchControl\n );\n\n console.log(\n \"MapViewState useEffect \",\n \" rxMapViewState - \",\n JSON?.stringify?.(rxMapViewState),\n \" mineLevel - \",\n mineLevel,\n \" mapViewType - \",\n mapViewType\n );\n\n console.log(\"MapViewState useEffect ------------------------------\");\n }\n\n //if (!map) return;\n if (mapRef && mapRef.current) {\n const map = mapRef.current.leafletElement;\n\n setMap(map); //hook to set map\n // sets to const -> 'mapRef.current.leafletElement'\n\n // #WIP - fix this to setup the minimum zoom etc.\n //\n // const minZoomCalced =\n // Math.floor(Math.log2(map.getSize().x / bounds.getEast())) - 1;\n // if (map.getMinZoom() !== minZoomCalced) {\n // map.setMinZoom(minZoomCalced);\n // map.setZoom(minZoomCalced);\n // }\n\n //mapRef.current.leafletElement.fitBounds(bounds);\n //map.setView({ lat: 50, lng: 50 }, 0);\n //map.fitBounds(bounds);\n //map.setView({ lat: 50, lng: 50 }, 3);\n\n // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n // sets the startup centre and zoom of the map\n // sets initial view on component mount\n if (true) {\n if (\n mapViewState?.center !== undefined &&\n mapViewState?.zoom !== undefined\n ) {\n map.setView(\n { lat: mapViewState?.center[1], lng: mapViewState?.center[0] },\n zoom\n );\n } else {\n map.fitBounds(bounds);\n }\n }\n\n //\n // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n\n // conditionally enable map movement/pan for leaflet map\n if (isPanZoomButton) {\n //----------------------------------------------------\n //\n // MAP MOVEMENT - DRAG ZOOM ETC\n //\n // see - https://gis.stackexchange.com/questions/54454/disable-leaflet-interaction-temporary\n //----------------------------------------------------\n\n const disableMapMovement = (map) => {\n map.dragging.disable();\n map.touchZoom.disable();\n map.doubleClickZoom.disable();\n //map.scrollWheelZoom.disable();\n map.smoothWheelZoom.disable();\n map.boxZoom.disable();\n map.keyboard.disable();\n if (map.tap) map.tap.disable();\n };\n\n const enableMapMovement = (map) => {\n map.dragging.enable();\n map.touchZoom.enable();\n map.doubleClickZoom.enable();\n //map.scrollWheelZoom.enable();\n map.smoothWheelZoom.enable();\n map.boxZoom.enable();\n map.keyboard.enable();\n if (map.tap) map.tap.enable();\n };\n\n // on startup disable map movement by user\n disableMapMovement(map);\n\n //----------------------------------------------------\n //\n // MAP VIEW MOVE - CONTROLS - function\n //\n //\n // At least of one of these is called by the map lock\n // so needs to be defined here beforehand\n //\n //----------------------------------------------------\n const moveMapViewButtonClick = (control, map) => {\n // show the zoom controls\n moveMapViewButton.disable();\n zoomOutButton.enable();\n zoomInButton.enable();\n cancelMapViewButton.enable();\n\n // disable the view buttons\n saveMapViewStateButton.disable();\n restoreMapViewStateButton.disable();\n\n // disable the search control\n searchButton.disable();\n\n // enable map movement\n enableMapMovement(map);\n\n setIsMapView(true);\n\n // show lock button state\n mapMoveLockButton.state(\"mapMoveLock-unlock\");\n mapMoveLockButton.button.style.backgroundColor = \"orange\";\n };\n\n const cancelMapViewButtonClick = (control, map) => {\n map.closePopup();\n\n // show the zoom controls\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n\n // enable the view buttons\n saveMapViewStateButton.enable();\n isShowRestoreMapViewStateButton\n ? restoreMapViewStateButton.enable()\n : restoreMapViewStateButton.disable();\n\n // enable the search control\n searchButton.enable();\n\n // disable map movement\n disableMapMovement(map);\n\n setIsMapView(false);\n\n // show unlock button state\n mapMoveLockButton.state(\"mapMoveLock-lock\");\n mapMoveLockButton.button.style.backgroundColor = \"white\";\n };\n\n //----------------------------------------------------\n //\n // MAP MARKER ZOOM - CONTROLS - MAP LOCK INDICATOR\n //\n //\n // Indicates if map is locked\n //\n //----------------------------------------------------\n\n const mapMoveLockIcon = ``;\n const mapMoveUnLockIcon = ``;\n\n const mapMoveLockButton = L.easyButton({\n states: [\n {\n stateName: \"mapMoveLock-lock\",\n icon: mapMoveLockIcon,\n title:\n \"Map movement is locked. Click the Pan control to modify the map display.\",\n onClick: moveMapViewButtonClick,\n },\n {\n stateName: \"mapMoveLock-unlock\",\n icon: mapMoveUnLockIcon,\n title: \"Map movement is unlocked. Map drag and zoom is enabled.\",\n },\n ],\n });\n\n //----------------------------------------------------\n //\n // MAP MARKER ZOOM - CONTROLS\n //\n // Custom zoom controls\n //----------------------------------------------------\n\n // listeners for disabling buttons\n map.on(\"zoomend\", (e) => {\n const map = e.target,\n max = map.getMaxZoom(),\n min = map.getMinZoom(),\n current = map.getZoom();\n const isMapViewCurent = isMapView?.current;\n if (current < max) {\n if (isMapViewCurent) {\n zoomInButton.enable();\n }\n }\n if (current >= max) {\n if (isMapViewCurent) {\n zoomInButton.disable();\n }\n }\n if (current > min) {\n if (isMapViewCurent) {\n zoomOutButton.enable();\n }\n }\n if (current <= min) {\n if (isMapViewCurent) {\n zoomOutButton.disable();\n }\n }\n });\n\n const moveMapViewZoomIn = ``;\n const moveMapViewZoomOut = ``;\n\n const zoomInButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-in-move-map-view\",\n icon: moveMapViewZoomIn,\n title: \"Zoom In\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() + 1);\n },\n },\n ],\n });\n\n const zoomOutButton = L.easyButton({\n states: [\n {\n stateName: \"zoom-out-move-map-view\",\n icon: moveMapViewZoomOut,\n title: \"Zoom Out\",\n onClick: (control, map) => {\n map.setZoom(map.getZoom() - 1);\n },\n },\n ],\n });\n\n // const zoomBar = L.easyBar([zoomInButton, zoomOutButton]);\n // zoomBar.addTo(map, {\n // position: \"topleft\",\n // });\n\n //----------------------------------------------------\n //\n // MAP VIEW MOVE - CONTROLS\n //\n //----------------------------------------------------\n\n const moveMapViewShow = ``;\n const moveMapViewHide = ``;\n\n const moveMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"show-move-map-view\",\n icon: moveMapViewShow,\n title: \"Pan and Zoom\",\n onClick: moveMapViewButtonClick,\n },\n {\n stateName: \"hide-move-map-view\",\n icon: moveMapViewHide,\n title: \"Disable move view\",\n },\n ],\n });\n\n const cancelMapViewButton = L.easyButton({\n states: [\n {\n stateName: \"cancel-move-map-view\",\n icon: \"fa fa-times\",\n title: \"Disable Pan and Zoom\",\n onClick: cancelMapViewButtonClick,\n },\n ],\n });\n\n let moveMapViewBar = L.easyBar(\n [\n mapMoveLockButton,\n moveMapViewButton,\n zoomInButton,\n zoomOutButton,\n cancelMapViewButton,\n ],\n { position: \"topleft\" }\n );\n moveMapViewBar.addTo(map);\n\n // startup hide - zoom buttons\n moveMapViewButton.enable();\n zoomOutButton.disable();\n zoomInButton.disable();\n cancelMapViewButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER RESET VIEW - CONTROLS\n //\n //----------------------------------------------------\n // #NOTE - with current leaflet need to do action to setView\n // https://stackoverflow.com/questions/65322670/change-center-position-of-react-leaflet-map\n\n const mapViewRestoreShow = ``;\n\n const restoreMapViewStateButton = L.easyButton({\n states: [\n {\n stateName: \"map-view-restore\",\n icon: mapViewRestoreShow,\n title: \"Restore saved view\",\n onClick: (e) => {\n const center = mapViewState?.center;\n const zoom = mapViewState?.zoom;\n if (Array.isArray(center) && !isNaN(zoom)) {\n map.setView({ lat: center[1], lng: center[0] }, zoom, {\n animation: false,\n });\n }\n },\n },\n ],\n });\n\n const saveMapViewStateButton = L.easyButton({\n states: [\n {\n stateName: \"map-view-save\",\n icon: \"fas fa-save\",\n title: \"Save view\",\n onClick: (e) => {\n // get the current map center and zoom\n const coords = map.getCenter();\n const center = Object?.values?.(coords)?.reverse?.();\n const zoom = map.getZoom();\n\n // need this to get the current mapViewState 'options'\n let newMapViewState = props.componentstate.get(\n mapViewType,\n mineLevel.id\n );\n\n //console.log(\"newMapViewState 1 - options\", newMapViewState);\n\n // spread to preserve any existing `options:`\n newMapViewState = {\n ...newMapViewState,\n id: mineLevel.id,\n center: center,\n zoom: zoom,\n };\n\n // set the new system saved mapViewState\n\n const settings = {\n section: mapViewType,\n key: mineLevel.id,\n data: newMapViewState,\n };\n\n props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n props.saveUserSettingsComponentState({ settings });\n\n //console.log(\"newMapViewState 2 - options\", newMapViewState);\n\n // set system saved mapViewState with current center and zoom\n // props.componentstate.set(\n // mapViewType,\n // mineLevel.id,\n // newMapViewState\n // );\n },\n },\n ],\n });\n\n let restoreMapViewStateBar = L.easyBar(\n [restoreMapViewStateButton, saveMapViewStateButton],\n {\n position: \"topleft\",\n id: \"horizontaleasybar\",\n }\n );\n\n restoreMapViewStateBar.addTo(map);\n\n // disable the restore button on startup until check restore properties exist\n isShowRestoreMapViewStateButton\n ? restoreMapViewStateButton.enable()\n : restoreMapViewStateButton.disable();\n\n //----------------------------------------------------\n //\n // MAP MARKER REFRESH - CONTROLS\n //\n //----------------------------------------------------\n\n const refreshMarkerPositionsButton = L.easyButton({\n states: [\n {\n stateName: \"reset-marker-positions\",\n icon: \"fa fa-redo\",\n title: \"Show all\",\n onClick: (e) => {\n map.fitBounds(bounds);\n },\n },\n ],\n });\n\n let refreshMapBar = L.easyBar([refreshMarkerPositionsButton], {\n position: \"topleft\",\n });\n refreshMapBar.addTo(map);\n\n //----------------------------------------------------\n //\n // MAP MARKER SEARCH - CONTROLS\n //\n //----------------------------------------------------\n\n const mapSearchShow = ``;\n const mapSearchHide = ``;\n\n const searchButtonClick = (control, map) => {\n // get current tagMapViewState\n let newMapViewState = props.componentstate.get(\n mapViewType,\n mineLevel.id\n );\n\n let newOptions = newMapViewState?.options || [];\n\n // this detects the toggle of the searchButton, but the actual display of the search control\n // is done in e.g. TagTrackingMap with the inclusion of the component \n //\n if (newOptions.includes(\"showSearchControl\")) {\n newOptions = newOptions.filter(\n (setting) => setting !== \"showSearchControl\"\n );\n } else {\n newOptions.push(\"showSearchControl\");\n }\n\n // spread to preserve any existing settings\n newMapViewState = {\n ...newMapViewState,\n id: mineLevel.id,\n options: newOptions,\n };\n\n //console.log(\"newMapViewState - options\", newMapViewState);\n\n // set system saved mapViewState\n props.componentstate.set(mapViewType, mineLevel.id, newMapViewState);\n };\n\n const searchButton = L.easyButton({\n states: [\n {\n stateName: \"mapSearch-show\",\n icon: mapSearchShow,\n title: \"Show search\",\n onClick: searchButtonClick,\n },\n {\n stateName: \"mapSearch-hide\",\n icon: mapSearchHide,\n title: \"Hide search\",\n onClick: searchButtonClick,\n },\n ],\n });\n\n let searchBar = L.easyBar([searchButton]);\n searchBar.addTo(map);\n\n isShowSearchControl\n ? searchButton.state(\"mapSearch-hide\")\n : searchButton.state(\"mapSearch-show\");\n }\n }\n //console.log(\"xxxx map mounted\");\n }, []);\n // #NOTE - Do not link props or control bar will re-render with each prop change.\n // The original coding intention is that the component is completely re-drawn so useEffect() is only\n // draw once per render.\n\n const { image_info, url } = mineLevel;\n const { width = 10000, height = 8000, backgroundColor } = image_info;\n\n let newStyle = style;\n\n if (backgroundColor) {\n newStyle = {\n ...style,\n backgroundColor: `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`,\n };\n }\n\n if (_isEmpty(width) === undefined || _isEmpty(height) === undefined) {\n return (\n
\n `Error With Image Dimensions: width ${width}, height ${height}`\n
\n );\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // Conversion from (x, y) raster image coordinates to equivalent of latLng\n // Taken from Leaflet tutorial \"Non-geographical maps\"\n // http://leafletjs.com/examples/crs-simple/crs-simple.html\n ////////////////////////////////////////////////////////////////////////////\n var yx = L.latLng;\n var xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n };\n\n // #WIP - add these to config options\n var minZoom = -5;\n var maxZoom = 5;\n\n const img = [\n width, // original width of image `level.jpg` - undercut 800 conversion example => x / ~longitude (0 is left, width, 13234 is right)\n height, // original height of image => y / ~ reverse of latitude (0 is top, height, 9356 is bottom)\n ];\n\n L.CRS.MySimple = L.extend({}, L.CRS.Simple, {\n // coefficients: a b c d\n transformation: new L.Transformation(1 / 64, 0, 1 / 64, 0),\n });\n\n // center calculation based on original pixel dimensions\n // _or_ from mapView prop if this has been set\n //\n let center = [img[0] / 2, img[1] / 2];\n let zoom = 2;\n\n // sets the startup centre and zoom of the map\n if (true) {\n if (mapViewState?.center !== undefined) {\n const newCenter = mapViewState?.center; // Object.values(mapViewState?.center); // ?.reverse();\n if (center !== newCenter) {\n center = newCenter;\n }\n }\n if (mapViewState?.zoom !== undefined) {\n const newZoom = mapViewState?.zoom;\n if (zoom !== newZoom && !isNaN(newZoom)) {\n zoom = newZoom;\n }\n }\n }\n\n var bounds = L.latLngBounds([xy(0, 0), xy(img)]);\n\n // get map drag last center from target and set system Map settings state\n const handleMoveZoomEnd = (e) => {};\n\n // #WIP - testing layer add event\n const handleOnlayeradd = (e) => {\n //console.log(\"MapViewState handleOnlayeradd \", e);\n //mapRef.current.leafletElement.fitBounds(bounds);\n //mapRef.current.leafletElement.setView({ lat: 50, lng: 50 }, 0);\n };\n\n // support for map leaflet.contextmenu - #DEBUG message\n const showCoordinates = (e) => {\n console.log(\"MapViewState showCoordinates showCoordinates\", e.latlng);\n //alert(e.latlng);\n };\n\n const centerMap = (e) => {\n mapRef.current.leafletElement.panTo(e.latlng);\n };\n\n const fitMap = (e, bounds) => {\n mapRef.current.leafletElement.fitBounds(bounds);\n };\n\n const zoomIn = (e) => {\n mapRef.current.leafletElement.zoomIn();\n };\n\n const zoomOut = (e) => {\n mapRef.current.leafletElement.zoomOut();\n };\n\n //\n //\n // var imageBounds = bounds;\n //\n // const handleMapClickPopup = (e) => {\n // var popLocation = e.latlng;\n // var popup = L.popup()\n // .setLatLng(popLocation)\n // .setContent(\"

Select the Pan and Zoom tool to move the map

\")\n // .openOn(map);\n // };\n\n // check for touch screen\n // if (L.Browser.touch) {\n // console.log(\"L.Browser.touch\", L.Browser.touch);\n // }\n\n // see - http://jsfiddle.net/xfdxe2ea/1/\n // see - https://stackoverflow.com/questions/33569779/lealefjs-prevent-dragging-marker-out-of-imagelayer-bounds\n // see also - https://stackoverflow.com/questions/29736912/leaflet-prevent-marker-to-be-dragged-outside-the-map-container\n\n // const handleMapClick = (e) => {\n // var newPosition = e.latlng;\n\n // console.log(`handleMapClick newPosition`, newPosition);\n // console.log(`handleMapClick imageBounds`, imageBounds);\n\n // if (imageBounds.contains(newPosition)) {\n // var newMarker = L.marker(newPosition, { draggable: true }).addTo(\n // leafletMapRef\n // );\n // var lastValidPosition;\n // newMarker.on(\n // \"drag\",\n // function (event) {\n // var latLng = newMarker.getLatLng();\n // if (imageBounds.contains(latLng)) {\n // lastValidPosition = latLng;\n // } else {\n // if (lastValidPosition) {\n // newMarker.setLatLng(lastValidPosition);\n // }\n // }\n // },\n // newMarker\n // );\n // }\n // };\n\n //console.log(\"MapViewState .\n // However center and zoom are immutable and can not be changed after draw.\n // There is a solution to apply .setView with react-leaflet v3\n // see - https://stackoverflow.com/questions/65894789/react-leaflet-map-center-not-changing\n // see - https://stackoverflow.com/questions/65322670/change-center-position-of-react-leaflet-map\n // see - https://stackoverflow.com/questions/65171337/how-to-get-map-properties-and-handle-events-in-leaflet-v3-with-react-redux\n // ....\n // class MapComponent extends Component {\n // constructor(props) {\n // super(props);\n // this.mapRef = React.createRef();\n // }\n // render() {\n // return (\n //
\n // { this.mapRef.current =mapInstance }}>\n // \n // \n //
}\n // }\n\n // class AnotherApp extends React.Component {\n // //access the map with:\n // this.props.map\n // }\n // ....\n //\n // However, we are using react-leaflet v2 here (mainly because we use leaflet-draw and andrewDodd's components\n // needs to be re-done).\n //\n // This 'hack' solution\n // See - https://stackoverflow.com/questions/65763931/react-leaflet-update-map-center\n // i.e.\n // \"....Only addition to your code is the key prop, which takes the stringified center position.\n // So when the position changes, another instance of the MapContainer component is created\n // (a fresh copy ;) ), having the proper center value. ...\"\n //\n\n const mapKey = `${mapViewState?.id}-${JSON.stringify(\n mapViewState?.center\n )}-[${mapViewState?.zoom}]`;\n\n return (\n console.log(\"hhh onMouseDown!\")}\n //onDragStart={() => console.log(\"hhh onDragging!\")}\n //onClick={handleMapClickPopup}\n //onClick={handleMapClick}\n //onlayeradd={handleOnlayeradd}\n //\n attributionControl={false} // not dynamic\n //\n touchExtend={false}\n //\n contextmenu={true} // context menu plugin `npm i leaflet-contextmenu`\n contextmenuWidth={140}\n contextmenuItems={[\n // {\n // text: \"Show coordinates\",\n // callback: showCoordinates,\n // },\n {\n text: \"Center map here\",\n callback: centerMap,\n },\n {\n text: \"Show all\",\n callback: (e) => fitMap(e, bounds),\n },\n // {\n // text: \"Reset View\",\n // callback: resetView,\n // },\n \"-\",\n {\n text: \"Zoom in\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-in.png\",\n callback: zoomIn,\n },\n {\n text: \"Zoom out\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-out.png\",\n callback: zoomOut,\n },\n ]}\n // scroll wheel zoom smoothing\n scrollWheelZoom={false} // disable original zoom function\n smoothWheelZoom={true} // enable smooth zoom\n smoothSensitivity={1.5} // zoom speed. default is 1\n >\n \n {props.children}\n
\n );\n}\n\nfunction areEqual(prevProps, nextProps) {\n /*\n return true if passing nextProps to render would return\n the same result as passing prevProps to render,\n otherwise return false\n */\n\n // console.log(\"areEqual prevProps\", prevProps);\n // console.log(\"areEqual nextProps\", nextProps);\n // console.log(\"areEqual nextProps === prevProps\", nextProps === prevProps);\n // console.log(\n // \"areEqual nextProps.imageInfo === prevProps.imageInfo\",\n // JSON.stringify(nextProps.imageInfo) !== JSON.stringify(prevProps.imageInfo)\n // );\n\n //console.log(\"simplify nextProps\", nextProps);\n //console.log(\"simplify(nextProps.children)\", simplify(nextProps.children));\n\n // console.log(\n // \"simplify reactChildrenToFlatArray(nextProps.children)\",\n // reactChildrenToFlatArray(nextProps.children)\n // );\n\n return (\n reactChildrenToFlatArray(prevProps.children) ===\n reactChildrenToFlatArray(nextProps.children)\n );\n}\n\n// Note: About React.memo, Maps & Redux-form\n// Redux-Form updates form props via Redux (as the name implies), this effectively updates the maps\n// props too and causes a re-render. Re-rendering while dragging markers causes a 'snap' back to the last\n// prop/state saved. This significantly impedes usabililty.\n//\n// https://stackoverflow.com/questions/59280319/react-memo-rerendering-with-the-same-props\n//\n// The solution below is to use React.memo wrapped around the map functional component\n// to stop re-rendering of the component unless the image, or the marker pointers, have changed.\n// Markers are passed as children.\n//\n// This requires a deep, flattened, comparison of the children passed to the component.\n// If these are not flattened an object comparison will just suggest they're always\n// being on each re-render making the comparison pointless.\n//\n// #REVIEW - move functions above to support utils?\n\n// #WIP - disabled 8Feb21 as stopped NamedAreaSimple from re-rendering\n\nexport const MineLevelMap = React.memo(_MineLevelMap, areEqual);\n\nexport function _MineLevelMap({ ...props }) {\n const { error } = props.mineLevel;\n\n if (error) {\n return
{error}
;\n }\n\n //console.log(\"MineLevelMap re-render\", new Date().getTime());\n\n return {props.children};\n}\n\nconst MineLevelMapWithContext = withMineLevel(MineLevelMap);\n\nexport default MineLevelMapWithContext;\n\nfunction MineLevelMapViaContext({ mineLevel, ...props }) {\n // mapSettings\n return (\n \n \n \n );\n}\n\nconst mapStateToProps = (state, props) => {\n let mineLevel = getAreaById(state, props.mineLevelId); //\"DMLZ_Extraction\"; // getMineLevelById(state, props.mineLevelId);\n if (mineLevel === undefined) {\n mineLevel = { error: \"Unable to find area\" };\n }\n\n // check if file exists\n const folderFilesList = getFolderFileNamesListById(state, \"areas\");\n\n mineLevel.url = imageCheck(\n folderFilesList,\n mineLevel?.image_filename,\n mineLevel?.image_Info\n );\n\n return {\n mineLevel,\n };\n};\n\nexport const MineLevelMapById = withComponentStateCache(\n connect(mapStateToProps, { saveUserSettingsComponentState })(\n MineLevelMapViaContext\n )\n);\n","import React from \"react\";\nimport L from \"leaflet\";\n\nimport { Marker, Popup } from \"react-leaflet\";\n\nL.DivIcon.SVGIcon = L.DivIcon.extend({\n options: {\n circleText: \"\",\n className: \"svg-icon\",\n circleAnchor: null, // defaults to [iconSize.x/2, iconSize.x/2]\n circleColor: null, // defaults to color\n circleOpacity: null, // defaults to opacity\n circleFillColor: \"rgb(255,255,255)\",\n circleFillOpacity: null, // default to opacity\n circleRatio: 0.5,\n circleWeight: null, // defaults to weight\n color: \"rgb(0,102,255)\",\n fillColor: null, // defaults to color\n fillOpacity: 0.4,\n fontColor: \"rgb(0, 0, 0)\",\n fontOpacity: \"1\",\n fontSize: null, // defaults to iconSize.x/4\n iconAnchor: null, // defaults to [iconSize.x/2, iconSize.y] (point tip)\n iconSize: L.point(32, 48),\n opacity: 1,\n popupAnchor: null,\n weight: 2\n },\n initialize: function(options) {\n options = L.Util.setOptions(this, options);\n\n // iconSize needs to be converted to a Point object if it is not passed as one\n options.iconSize = L.point(options.iconSize);\n\n // in addition to setting option dependant defaults, Point-based options are converted to Point objects\n if (!options.circleAnchor) {\n options.circleAnchor = L.point(\n Number(options.iconSize.x) / 2,\n Number(options.iconSize.x) / 2\n );\n } else {\n options.circleAnchor = L.point(options.circleAnchor);\n }\n if (!options.circleColor) {\n options.circleColor = options.color;\n }\n if (!options.circleFillOpacity) {\n options.circleFillOpacity = options.opacity;\n }\n if (!options.circleOpacity) {\n options.circleOpacity = options.opacity;\n }\n if (!options.circleWeight) {\n options.circleWeight = options.weight;\n }\n if (!options.fillColor) {\n options.fillColor = options.color;\n }\n if (!options.fontSize) {\n options.fontSize = Number(options.iconSize.x / 4);\n }\n if (!options.iconAnchor) {\n options.iconAnchor = L.point(\n Number(options.iconSize.x) / 2,\n Number(options.iconSize.y)\n );\n } else {\n options.iconAnchor = L.point(options.iconAnchor);\n }\n if (!options.popupAnchor) {\n options.popupAnchor = L.point(0, -0.75 * options.iconSize.y);\n } else {\n options.popupAnchor = L.point(options.popupAnchor);\n }\n\n this._createPath();\n this._createCircle();\n\n options.html = this._createSVG();\n },\n _createCircle: function() {\n var cx = Number(this.options.circleAnchor.x);\n var cy = Number(this.options.circleAnchor.y);\n var radius =\n (this.options.iconSize.x / 2) * Number(this.options.circleRatio);\n var fill = this.options.circleFillColor;\n var fillOpacity = this.options.circleFillOpacity;\n var stroke = this.options.circleColor;\n var strokeOpacity = this.options.circleOpacity;\n var strokeWidth = this.options.circleWeight;\n var className = this.options.className + \"-circle\";\n\n var circle =\n '';\n\n return circle;\n },\n _createPathDescription: function() {\n var height = Number(this.options.iconSize.y);\n var width = Number(this.options.iconSize.x);\n var weight = Number(this.options.weight);\n var margin = weight / 2;\n\n var startPoint = \"M \" + margin + \" \" + width / 2 + \" \";\n var leftLine = \"L \" + width / 2 + \" \" + (height - weight) + \" \";\n var rightLine = \"L \" + (width - margin) + \" \" + width / 2 + \" \";\n var arc =\n \"A \" +\n width / 4 +\n \" \" +\n width / 4 +\n \" 0 0 0 \" +\n margin +\n \" \" +\n width / 2 +\n \" Z\";\n\n var d = startPoint + leftLine + rightLine + arc;\n\n return d;\n },\n _createPath: function() {\n var pathDescription = this._createPathDescription();\n var strokeWidth = this.options.weight;\n var stroke = this.options.color;\n var strokeOpacity = this.options.Opacity;\n var fill = this.options.fillColor;\n var fillOpacity = this.options.fillOpacity;\n var className = this.options.className + \"-path\";\n\n var path =\n '';\n\n return path;\n },\n _createSVG: function() {\n var path = this._createPath();\n var circle = this._createCircle();\n var text = this._createText();\n var className = this.options.className + \"-svg\";\n\n var style =\n \"width:\" +\n this.options.iconSize.x +\n \"px; height:\" +\n this.options.iconSize.y +\n \"px;\";\n\n var svg =\n '' +\n path +\n circle +\n text +\n \"\";\n\n return svg;\n },\n _createText: function() {\n var fontSize = this.options.fontSize + \"px\";\n var lineHeight = Number(this.options.fontSize);\n\n var x = Number(this.options.iconSize.x) / 2;\n var y = x + lineHeight * 0.35; // 35% was found experimentally\n var circleText = this.options.circleText;\n var textColor = this.options.fontColor\n .replace(\"rgb(\", \"rgba(\")\n .replace(\")\", \",\" + this.options.fontOpacity + \")\");\n\n var text =\n '' +\n circleText +\n \"\";\n\n return text;\n }\n});\n\nL.divIcon.svgIcon = function(options) {\n return new L.DivIcon.SVGIcon(options);\n};\n\nL.Marker.SVGMarker = L.Marker.extend({\n options: {\n iconFactory: L.divIcon.svgIcon,\n iconOptions: {}\n },\n initialize: function(latlng, options) {\n options = L.Util.setOptions(this, options);\n options.icon = options.iconFactory(options.iconOptions);\n this._latlng = latlng;\n },\n onAdd: function(map) {\n L.Marker.prototype.onAdd.call(this, map);\n },\n setStyle: function(style) {\n if (this._icon) {\n // var svg = this._icon.children[0]\n var iconBody = this._icon.children[0].children[0];\n var iconCircle = this._icon.children[0].children[1];\n\n if (style.color && !style.iconOptions) {\n var stroke = style.color\n .replace(\"rgb\", \"rgba\")\n .replace(\")\", \",\" + this.options.icon.options.opacity + \")\");\n var fill = style.color\n .replace(\"rgb\", \"rgba\")\n .replace(\")\", \",\" + this.options.icon.options.fillOpacity + \")\");\n iconBody.setAttribute(\"stroke\", stroke);\n iconBody.setAttribute(\"fill\", fill);\n iconCircle.setAttribute(\"stroke\", stroke);\n\n this.options.icon.fillColor = fill;\n this.options.icon.color = stroke;\n this.options.icon.circleColor = stroke;\n }\n if (style.opacity) {\n this.setOpacity(style.opacity);\n }\n if (style.iconOptions) {\n if (style.color) {\n style.iconOptions.color = style.color;\n }\n var iconOptions = L.Util.setOptions(\n this.options.icon,\n style.iconOptions\n );\n this.setIcon(L.divIcon.svgIcon(iconOptions));\n }\n }\n }\n});\n\nconst MapMarker = ({\n lat,\n lng,\n draggable = false,\n onDragend,\n color,\n fillColor,\n circleColor,\n circleText = \"\",\n size = 12,\n fillOpacity = 0.8,\n children\n}) => (\n \n \n
{children || \"No content\"}
\n
\n \n);\n\nexport default MapMarker;\n","import { formValueSelector } from \"redux-form\";\n\nconst selector = formValueSelector(\"fireflyDetailsForm\");\nexport default selector;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport MapMarker from \"components/ColorableMapMarker\";\nimport selector from \"admin/firefly/form-value-selector\";\nimport getSemanticColor from \"colorpalette\";\n\nconst SEMANTIC_BLACK = getSemanticColor(\"black\");\n\nclass FireflyMoveableMarker extends Component {\n onDragEnded = ({ target }) => {\n const ll = target.getLatLng();\n const { change, name } = this.props;\n\n // console.log(\"name.lat, ll.lat\", `${name}.lat`, ll.lat);\n // console.log(\"name.lng, ll.lng\", `${name}.lng`, ll.lng);\n\n change(`${name}.lat`, ll.lat);\n change(`${name}.lng`, ll.lng);\n };\n\n render() {\n const { position, children } = this.props;\n\n // if position lat/long is 0,0 then not commissioned.\n // if not commissioned make 'new' color i.e. yellow\n const markerColor =\n position?.lat === 0 || position?.lng === 0 ? \"yellow\" : \"blue\";\n\n const outline = SEMANTIC_BLACK;\n const fillOpacity = 0.7;\n const size = 18.0;\n\n return (\n \n {children}\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n return { position: selector(state, props.name) };\n};\n\nFireflyMoveableMarker = connect(mapStateToProps, null)(FireflyMoveableMarker);\n\nexport default FireflyMoveableMarker;\n","import React from \"react\";\nimport { connect } from \"react-redux\";\nimport { Form } from \"semantic-ui-react\";\nimport { getServerStatus } from \"components/Settings/reducer\";\n\nconst _SaveButton = ({\n submitting,\n pristine,\n disable,\n serverStatus,\n strings,\n size,\n ...props\n}) => {\n // #NOTE -\n // disable - prop passed\n // disabled - local prop to set state of button\n\n const disabled =\n submitting || pristine || disable === true || serverStatus !== \"OK\";\n\n let positive = true;\n let text = strings?.[\"Save\"];\n if (submitting) {\n text = strings?.[\"Submitting\"];\n } else if (pristine) {\n positive = false;\n text = strings?.[\"Nothing changed\"];\n }\n\n return (\n \n {text}\n \n );\n};\n\nconst mapStateToProps = (state, props) => {\n return {\n serverStatus: getServerStatus(state),\n };\n};\n\nexport const SaveButton = connect(mapStateToProps, null)(_SaveButton);\n\nexport function AlwaysSaveButton({ submitting, pristine, ...props }) {\n let text = \"Save\";\n if (submitting) {\n text = \"Submitting\";\n }\n\n return {text};\n}\n","import { LeastSquaresApproximationFourPointsSixParametersTransformation } from \"projection\";\n\nconst standardPtsUtm = () => {\n // #TODO - this is duplicated in localPts()\n const ref1utm = {\n northing: 9549076.153,\n easting: 736959.54,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref2utm = {\n northing: 9549315.041,\n easting: 737526.058,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref3utm = {\n northing: 9548885.911,\n easting: 737883.021,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const ref4utm = {\n northing: 9548630.213,\n easting: 737564.472,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n\n // rest UTM values\n const standardRef1 = { lat: ref1utm.easting, lng: ref1utm.northing };\n const standardRef2 = { lat: ref2utm.easting, lng: ref2utm.northing };\n const standardRef3 = { lat: ref3utm.easting, lng: ref3utm.northing };\n const standardRef4 = { lat: ref4utm.easting, lng: ref4utm.northing };\n\n const standardAll = [standardRef1, standardRef2, standardRef3, standardRef4];\n\n return standardAll;\n};\n\n// #NOTE - pending delete. This shoudl not be used. Instead get from defaultArea in config file\n//\n// default reference points loaded with 'Add Mine Level'\nexport const localPts = () => {\n // measured from pixel positions\n const localRef1 = {\n lat: 4764,\n lng: 4202,\n easting: 736289.88025079, //736959.54,\n northing: 9549792.19986215, //9549076.1534,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef2 = {\n lat: 3236,\n lng: 7815,\n easting: 738370.38357402, //737526.058,\n northing: 9549792.19986215, //9549315.041,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef3 = {\n lat: 5978,\n lng: 10090,\n easting: 738370.37138483, //737883.021,\n northing: 9548413.47997008, //9548885.911,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n const localRef4 = {\n lat: 7611,\n lng: 8061,\n easting: 736289.88025079, //737564.472,\n northing: 9548413.47997008, // 9548630.213,\n zoneNum: 53,\n zoneLetter: \"M\",\n };\n return [localRef1, localRef2, localRef3, localRef4];\n};\n\nexport const standardPtsUtmX = (mineLevel) => {\n const { ref_coord } = mineLevel;\n\n let result = {};\n ref_coord.forEach((coord) => {\n const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n const index = indexArray[1];\n\n result[index] = { lat: coord.utm[0], lng: coord.utm[1] };\n });\n\n // sort object by key\n Object.keys(result)\n .sort()\n .forEach(function (v, i) {\n //console.log(v, result[v]);\n });\n\n // return the values\n return Object.values(result);\n};\n\nexport const localPtsX = (mineLevel) => {\n const { ref_coord } = mineLevel;\n\n let result = {};\n ref_coord.forEach((coord) => {\n const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n const index = indexArray[1];\n\n result[index] = {\n id: coord.id,\n lat: coord.image_xy[0],\n lng: coord.image_xy[1],\n easting: coord.utm[0],\n northing: coord.utm[1],\n zoneNum: coord.utm_zone_number,\n zoneLetter: coord.utm_zone_letter,\n };\n });\n\n // sort object by key\n Object.keys(result)\n .sort()\n .forEach(function (v, i) {\n //console.log(v, result[v]);\n });\n\n // return the values\n return Object.values(result);\n};\n\n// the geometric coordinate to map pixel transformation\nconst Transform = (localPts, standardPts) => {\n const LeastSq4Pt = LeastSquaresApproximationFourPointsSixParametersTransformation.fromPoints(\n localPts,\n standardPts\n );\n return LeastSq4Pt;\n};\n\n// const transform = MineLevelMapImageProjection.fromPoints(\n// [ref1, ref2],\n// [imageRef1, imageRef2]\n// );\n\n// converts from utm points to local points\nexport const transform = Transform(localPts(), standardPtsUtm());\n// e.g.\n// const refPoints = transform.transform({\n// lat: fireflyCoord[0],\n// lng: fireflyCoord[1],\n// });\n\nexport const transformX = (area) =>\n Transform(localPtsX(area), standardPtsUtmX(area));\n","import React from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { getFireflyById } from \"components/WebWorker/reducer\";\n\nimport {\n formatDate,\n formatDateRelativeNow,\n parseDate,\n} from \"utils/format-date\";\n\nimport { StatusEnumToReadable } from \"utils/StatusEnum\";\n\nfunction Component({ statusReport }) {\n let updatedStatusReport = { ...statusReport };\n\n if (statusReport) {\n const {\n timestamp: timestampRx,\n topology: { deviceStatus: deviceStatusRx },\n } = statusReport;\n\n // format timestamp\n let timestamp;\n\n if (timestampRx !== null && timestampRx !== undefined) {\n timestamp = parseDate(timestampRx);\n timestamp =\n formatDate(timestamp) +\n \" (\" +\n formatDateRelativeNow(timestamp, new Date()) +\n \")\";\n } else {\n timestamp = \"No time information\";\n }\n\n updatedStatusReport = { ...statusReport, timestamp: timestamp };\n\n // make deviceStatus readable\n let deviceStatus;\n if (deviceStatusRx) {\n deviceStatus = deviceStatusRx.map(\n (status) => StatusEnumToReadable[status]\n );\n updatedStatusReport.topology.deviceStatus = deviceStatus;\n }\n } else {\n updatedStatusReport = null;\n }\n\n return
{JSON.stringify(updatedStatusReport, null, 2)}
;\n}\n\nexport default connect((state, { id }) => {\n const ff = getFireflyById(state, id);\n\n return { statusReport: ff };\n})(Component);\n","import React, { Component } from \"react\";\nimport { Modal, Header, Icon, Button } from \"semantic-ui-react\";\nimport isEqual from \"lodash/isEqual\";\n\nexport default class SubmissionModal extends Component {\n constructor(props) {\n super(props);\n this.state = { modalOpen: false };\n }\n\n componentDidMount() {\n const { open } = this.props;\n\n if (open) {\n this.handleOpen();\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleClose = () => {\n this.setState({ modalOpen: false });\n this.props.onResetError();\n };\n\n render() {\n const { modalMessage, errorMessage } = this.props;\n\n let message = {\n color: \"red\",\n header: { icon: \"info\", title: \"Problem Saving\" },\n content:\n \"There has been a problem saving the changes. Please address the problem and re-save, or contact your system administrator for support if the problem persists.\",\n };\n\n if (modalMessage) {\n message = modalMessage;\n }\n\n // styles\n // #NOTE - copied colors from inspect to match semantic default 'red'\n const red = { color: \"#db2828\", background: \"#ffe8e6\" };\n\n const {\n header: { icon, title },\n content,\n } = message;\n\n return (\n \n
\n \n

{content}

\n

{errorMessage}

\n
\n \n \n \n \n // \n //
\n // \n //

\n // There has been a problem saving the changes. Please address the\n // problem and re-save, or contact your system administrator for\n // support if the problem persists.\n //

\n //

{errorMessage}

\n //
\n // \n // \n // \n // \n );\n }\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport {\n isDirty,\n isSubmitting,\n getFormValues,\n hasSubmitSucceeded,\n submit,\n isValid,\n} from \"redux-form\";\nimport { Modal, Header, Icon, Button } from \"semantic-ui-react\";\nimport NavigationPrompt from \"react-router-navigation-prompt\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nclass NavigationPromptModal extends Component {\n constructor(props) {\n super(props);\n this.state = {};\n }\n\n shouldPromptSaveShow = () => {\n //console.log(`NavigationPromptModal shouldPromptSaveShow props`, this.props);\n\n const {\n submitted,\n isFormDirty,\n isSubmitting,\n submitSucceeded,\n formValues,\n } = this.props;\n\n const _action = formValues?._action;\n\n // Don't show the '\"are you sure\"\n // if the form is in the process of saving it'll be 'isSubmitting',\n // or has just submitted 'submitSucceeded',\n if (\n isSubmitting ||\n submitSucceeded ||\n submitted == true ||\n _action === \"delete\"\n )\n return false;\n\n // if the form is not dirty\n if (!isFormDirty) return false;\n\n // default\n return true;\n };\n\n promptSaveCatchAndSave = (onConfirm, onCancel) => {\n const { formValues, formName, remoteSubmit, isValid } = this.props;\n\n // check if form is valid\n\n if (isValid) {\n // #NOTE - testing remote submit instead of directly submitting the form\n // remote submit the form\n //remoteSubmit(formName);\n\n // submit the form\n this.props.onSubmit(formValues);\n\n // OK the dlg\n onConfirm();\n } else {\n console.log(`FORM DATA IS NOT VALID`);\n onCancel();\n }\n };\n\n render() {\n return (\n \n {({ onConfirm, onCancel }) => (\n \n
\n \n

\n The page changes were not saved. Do you really want to leave?\n

\n
\n \n \n \n this.promptSaveCatchAndSave(onConfirm, onCancel)}\n >\n Leave, but also Save the changes\n \n \n \n )}\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const { formName } = props;\n\n return {\n //\n isFormDirty: isDirty(formName)(state),\n isSubmitting: isSubmitting(formName)(state),\n formValues: getFormValues(formName)(state),\n submitSucceeded: hasSubmitSucceeded(formName)(state),\n isValid: isValid(formName)(state),\n };\n};\n\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n remoteSubmit: (formName) => dispatch(submit(formName)),\n };\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(NavigationPromptModal);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { withRouter, Prompt } from \"react-router\";\n\nimport { push } from \"react-router-redux\";\nimport {\n Form,\n Container,\n Button,\n Menu,\n Popup,\n Icon,\n Segment,\n Header,\n Dropdown,\n Message,\n Grid,\n Tab,\n Divider,\n} from \"semantic-ui-react\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\nimport { isDirty, isSubmitting } from \"redux-form\";\n\nimport { LayersControl } from \"react-leaflet\";\n\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroupGeoJson\";\n//import CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroup\";\n\nimport { getMineLevelCentre } from \"MineLevels/reducer\";\n\n//import { getFireflyById } from 'UPSPanelControllers/reducer'\nimport {\n getFireflyById,\n getControllerById,\n getFireflyCoordinatesById,\n} from \"components/WebWorker/reducer\";\nimport { formatRelative, parseISO } from \"date-fns\";\n\nimport { saveFirefly, deleteFirefly } from \"UPSPanelControllers/actions\";\n\nimport ChooseMineLevelField from \"components/ChooseMineLevelField\";\nimport TopologyField from \"components/TopologyField\";\n\nimport MapWithImage from \"components/Map/MapWithImage\";\n//import { MineLevelMapById } from \"components/MineLevelMap\";\nimport { MineLevelMapById } from \"components/Map/MineLevelMap\";\n\nimport MapMarker from \"components/ColorableMapMarker\";\n\nimport FireflyMoveableMarker from \"admin/firefly/FireflyMoveableMarker\";\n\nimport FireflyName from \"containers/FireflyName\";\n\nimport { renderField, renderTextArea } from \"admin/form-field\";\nimport { SaveButton, AlwaysSaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport selector from \"admin/firefly/form-value-selector\";\n\nimport isEqual from \"lodash/isEqual\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { transform } from \"components/Map/referencePoints\";\n\nimport FireflyRawStatusReport from \"admin/firefly/FireflyRawStatusReport\";\nimport { getAreaStatusesById } from \"components/WebWorker/reducer\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { fetchUPSs, fetchFireflys } from \"UPSPanelControllers/actions\";\n\nimport { getUserSettings } from \"auth/reducer\";\n\nfunction MapPositioningDisplay({ mineLevelId, children }) {\n if (!mineLevelId) {\n return
No mine level selected
;\n }\n return (\n \n {children}\n \n );\n}\n\n// class EditLocationField extends Component {\n// render() {\n// const { fireflyId, mineLevelId, lat, lng, onMarkerMoved } = this.props; // mineLevelId,\n\n// //console.log(\"FireflyDetailsForm EditLocationField this.props\", this.props);\n\n// if (!mineLevelId) {\n// return
Must select mine area
;\n// }\n// return (\n// \n// \n// \n// {fireflyId}\n// {/* */}\n// \n\n// {/* HB_1Oct20 - LayersControl was commented out as this was causing map updates\n// which were grabbing the marker from the mouse pointer.\n// Review the operation and need for marker overlays.\n// Consider putting in a detailed shouldComponentUpdate (see above) */}\n\n// \n// \n// \n// \n// \n// \n// \n// );\n// }\n// }\n\n// EditLocationField = connect((state) => ({ ...selector(state, \"position\") }))(\n// EditLocationField\n// );\n\n// class UpdateTopologyButton extends Component {\n// revert = (e) => {\n// e.preventDefault();\n// const { change, commissionedTopology } = this.props;\n// change(\"topology\", commissionedTopology);\n// };\n// update = (e) => {\n// e.preventDefault();\n// const { change, reportedTopology } = this.props;\n// change(\"topology\", reportedTopology);\n// };\n// doNothing = (e) => {\n// e.preventDefault();\n// };\n// render() {\n// const { setting, commissionedTopology, reportedTopology } = this.props;\n// let text = \"ERROR\";\n// let disabled = true;\n// let color = \"red\";\n// let onClick = this.doNothing;\n// if (isEqual(reportedTopology, commissionedTopology)) {\n// text = \"Unchanged\";\n// disabled = true;\n// color = \"grey\";\n// onClick = this.doNothing;\n// } else if (isEqual(setting, commissionedTopology)) {\n// text = \"Update\";\n// disabled = false;\n// color = \"green\";\n// onClick = this.update;\n// } else if (isEqual(setting, reportedTopology)) {\n// text = \"Revert\";\n// disabled = false;\n// color = \"orange\";\n// onClick = this.revert;\n// }\n\n// return (\n// \n// \n// {text}\n// \n// \n// );\n// }\n// }\n// UpdateTopologyButton = connect((state) => ({\n// setting: selector(state, \"topology\"),\n// commissionedTopology: selector(state, \"commissionedTopology\"),\n// reportedTopology: selector(state, \"reportedTopology\"),\n// }))(UpdateTopologyButton);\n\nconst options = [\n { key: \"1234567891\", text: \"1234567891\", value: \"1234567891\" },\n { key: \"1234567892\", text: \"1234567892\", value: \"1234567892\" },\n { key: \"1234567893\", text: \"1234567893\", value: \"1234567893\" },\n { key: \"1234567894\", text: \"1234567894\", value: \"1234567894\" },\n];\n\nconst renderCheckbox = (field) => (\n field.input.onChange(checked)}\n />\n);\n\nconst renderSelect = (field) => (\n {\n //console.log(\"BLUR\", value);\n field.input.onChange(value);\n }}\n onChange={(e, { value }) => field.input.onChange(value)}\n options={field.options}\n placeholder={field.placeholder}\n //onAddItem={this.handleAddition} // catch addition of items\n value={field.input.value}\n />\n);\n\nclass FireflyDetailsForm extends Component {\n constructor(props) {\n super(props);\n this.state = {\n options,\n collapse: false,\n errorMessage: \"\",\n };\n }\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n componentDidMount() {\n //console.log(`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj componentDidMount`);\n }\n\n componentWillUnmount() {\n //console.log(`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj componentWillUnmount`);\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n // only re-render if the firefly object has changed.\n // This stops re-rendering the map unnecessarily\n\n return (\n !isEqual(this.props.fireflyId, nextProps.fireflyId) ||\n !isEqual(this.props.fireflyNote, nextProps.fireflyNote) ||\n !isEqual(this.props.position, nextProps.position) ||\n !isEqual(this.state.collapse, nextState.collapse) ||\n !isEqual(this.state.errorMessage, nextState.errorMessage)\n // ||\n // !isEqual(this.props.submitting, this.props.submitting) ||\n // !isEqual(this.props.pristine, this.props.pristine)\n );\n }\n\n handleAddition = (e, { value }) => {\n this.setState((prevState) => ({\n options: [{ text: value, value }, ...prevState.options],\n }));\n };\n\n handleChange = (e, { value }) => this.setState({ currentValue: value });\n\n submitMyForm = (values) => {\n const { saveFirefly, transformPixelsToUtm, reset, fireflyId } = this.props;\n\n //console.log(\"submitMyForm values\", values);\n const objLatLng = transformPixelsToUtm.transform({\n lat: values.position.lat,\n lng: values.position.lng,\n });\n\n // transform position to UTM\n const newPosition = {\n position: {\n mineLevelId: values.position.mineLevelId,\n lat: objLatLng.lat,\n lng: objLatLng.lng,\n },\n };\n const newValues = { ...values, ...newPosition };\n\n //console.log(\"saveFirefly newValues\", newValues);\n\n return new Promise((resolve, reject) => {\n saveFirefly({ values: newValues, resolve, reject });\n }).then(() => {\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n const { fetchFireflys } = this.props;\n fetchFireflys({ userSettings: this.props.userSettings }); // #FETCHS\n\n // #WIP - stay on the same page when we can fetch() the update\n this.props.goto(`/admin/firefly`);\n }\n );\n });\n };\n\n requestDelete = (values) => {\n const { deleteFirefly, fireflyId, push, change } = this.props;\n\n //console.log(`deleteFirefly requestDelete`, this.props);\n\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call change to populate the formValue `_action` at the beginning of the delete process.\n // The _action value is checked in the NavigationPromptModal, which does not display.\n change(\"_action\", \"delete\");\n\n return new Promise((resolve, reject) => {\n deleteFirefly({ values: { id: fireflyId }, resolve, reject });\n }).then(\n () => {\n const { fetchFireflys } = this.props;\n fetchFireflys({ userSettings: this.props.userSettings }); // #FETCHS\n\n this.props.goto(\"/admin/firefly/\");\n },\n (errorMsg) => {\n //console.log(`deleteFirefly errorMsg`, errorMsg);\n // pop error dlg\n const message = {\n header: {\n icon: \"warning\",\n title: \"Delete Failed\",\n },\n content: \"Error when attempting to delete data.\",\n };\n this.setState({\n errorMessage: `${errorMsg}`,\n modalMessage: message,\n });\n }\n );\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n this.props.goto(\"/admin/firefly/\");\n };\n\n onDragEnded = ({ target }) => {\n const ll = target.getLatLng();\n this.props.change(\"position.lat\", ll.lat);\n this.props.change(\"position.lng\", ll.lng);\n };\n\n clickControllerIdIcon = (e) => {\n e.preventDefault();\n this.props.goto(`/admin/controller/${this.props.controllerId}`);\n };\n\n onResetError = () => {\n const { goto, submitting, submitSucceeded } = this.props;\n\n this.setState({ errorMessage: \"\" });\n\n // if we've just submit the form -> leave\n if (submitting || submitSucceeded) {\n goto(\"/\");\n }\n };\n\n render() {\n const {\n handleSubmit,\n change,\n pristine,\n submitting,\n error,\n fireflyId,\n reset,\n controllerIp,\n //controllerId,\n mineLevelId,\n // lat,\n // lng,\n // onMarkerMoved,\n //formValues,\n //\n isDeleteButton,\n strings,\n } = this.props;\n\n const {\n collapse: isCollapse,\n submitted,\n modalMessage,\n errorMessage,\n } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n //console.log(`xxxxxxxxxxx formValues`, formValues);\n\n const panes = [\n {\n menuItem: \"Position\",\n render: () => (\n \n \n \n {fireflyId}\n {/* */}\n \n \n \n \n \n \n \n \n ),\n },\n {\n menuItem: \"Latest Report\",\n render: () => (\n \n \n \n ),\n },\n ];\n\n return (\n <>\n handleSubmit(this.submitMyForm(formValues))}\n />\n this.onResetError()}\n modalMessage={modalMessage}\n errorMessage={errorMessage}\n />\n \n {error &&
{error}
}\n
\n \n \n \n {isCollapse && (\n \n \n \n \n \n \n \n }\n />\n \n \n \n \n )}\n {!isCollapse && (\n <>\n \n \n \n
\n \n \n \n Controller Config {controllerIp}\n \n this.clickControllerIdIcon(e)}\n >\n \n Controller Details\n \n \n
\n \n \n \n \n }\n />\n \n
\n
\n
\n \n \n \n {/* #NOTE - commented out as this is unlikely to ever be used. Was in first definition from Greg */}\n {/* {false && (\n \n
BLE Setup
\n\n \n \n \n \n
\n )} */}\n \n )}\n\n {/* \n \n \n \n Reset\n \n */}\n
\n\n \n \n \n \n {isDeleteButton && (\n \n \n \n )}\n \n \n \n \n \n \n \n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n\n \n \n
\n
\n
\n \n
\n \n );\n }\n}\n\n// see - import selector from \"./form-value-selector\";\n//const selector = formValueSelector(\"fireflyDetailsForm\");\n\nFireflyDetailsForm = reduxForm({\n form: \"fireflyDetailsForm\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n})(FireflyDetailsForm);\n\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n saveFirefly: (data) => dispatch(saveFirefly(data)),\n deleteFirefly: (data) => dispatch(deleteFirefly(data)),\n //\n fetchFireflys: (data) => dispatch(fetchFireflys(data)),\n };\n};\n\nconst mapStateToProps = (state, props) => {\n const { isDeleteFireflyNotCommissioned } = props;\n\n const firefly = getFireflyById(state, props.id);\n\n //console.log(`xxxx firefly`, firefly);\n\n const id = props.id;\n\n // extract out the actual \"immutable\" parts\n const { utm, topology, timestamp, fireflyNote } = firefly;\n\n const {\n area: mineLevelId,\n position: fireflyPosition,\n location: fireflyLocation,\n mac: fireflyMac,\n ups_name,\n ups_id,\n } = topology;\n\n const area = getAreaStatusesById(state, mineLevelId);\n const transformPixelsToUtm = area?.transformPixelsToUtm;\n const transformUtmToPixels = area?.transformUtmToPixels;\n\n const controller = getControllerById(state, ups_id);\n\n //console.log(`controller`, controller);\n\n const controllerIp = controller?.topology?.ip;\n const fireflyCoord = getFireflyCoordinatesById(state, id);\n const lat = fireflyCoord !== undefined ? fireflyCoord[1] : 0;\n const lng = fireflyCoord !== undefined ? fireflyCoord[0] : 0;\n\n const mdt = [];\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n\n const isBLETagDetect = \"false\";\n const idBLETag = \"12345678\";\n\n let isDeleteButton =\n area !== undefined && isDeleteFireflyNotCommissioned\n ? true\n : !_isEmpty(utm);\n\n return {\n // values,\n // submitSucceeded,\n fireflyId: selector(state, \"id\"),\n controllerIp: selector(state, \"controllerIp\"),\n controllerId: selector(state, \"controllerId\"),\n position: selector(state, \"position\"),\n fireflyNote: selector(state, \"fireflyNote\"),\n initialValues: {\n _action: \"\", // used to control dlg display\n id,\n lastStatusReport,\n fireflyLocation,\n fireflyPosition,\n fireflyMac,\n controllerName: ups_name,\n controllerId: ups_id,\n controllerIp,\n position: { mineLevelId, lat, lng },\n commissionedTopology: topology,\n //reportedTopology,\n isBLETagDetect,\n idBLETag,\n fireflyNote,\n },\n transformPixelsToUtm,\n transformUtmToPixels,\n mineLevelId,\n //\n isDeleteButton,\n //\n userSettings: getUserSettings(state) || {},\n\n //\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"onChange values\", values);\n //console.log(\"onChange props\", props);\n\n const mdtChanged = values.mdt !== previousValues.mdt;\n\n if (mdtChanged) {\n let {\n change,\n initialValues: { mdt: mdt },\n } = props;\n\n dispatch(change(\"mdt\", values.mdt));\n }\n\n const mineLevelChanged =\n values.position.mineLevelId !== previousValues.position.mineLevelId;\n if (mineLevelChanged) {\n let {\n change,\n initialValues: {\n position: { mineLevelId, lat, lng },\n },\n } = props;\n\n if (values.position.mineLevelId !== mineLevelId) {\n // const centre = getMineLevelCentre(state, values.position.mineLevelId);\n // lat = centre.lat;\n // lng = centre.lng;\n lat = 0;\n lng = 0;\n }\n dispatch(change(\"position.lat\", lat));\n dispatch(change(\"position.lng\", lng));\n }\n },\n formValues: getFormValues(\"fireflyDetailsForm\")(state), // #REVIEW - only used for debugging,\n };\n};\n\nFireflyDetailsForm = withRouter(\n connect(mapStateToProps, mapDispatchToProps)(FireflyDetailsForm)\n);\n\nexport default FireflyDetailsForm;\n","import React from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Segment, Message, List } from \"semantic-ui-react\";\n\nimport { getMqttDataLoadingResponseRequestMessageQueue } from \"components/WebWorker/reducer\";\n\nconst DataLoadingMessage = (props) => {\n const { id, dataLoadingMessageQueue, strings } = props;\n\n return (\n \n \n {strings?.[\"Data Loading Message Header\"]}\n \n \n
\n

{`${strings?.[\"Data Loading Message Content\"]} ${id}`}

\n
\n {strings?.[\"Data Loading Receiving\"]} \n {dataLoadingMessageQueue && (\n \n \n {dataLoadingMessageQueue.map((item) => {\n return {`${item}...`};\n })}\n \n \n )}\n
\n
\n );\n};\n\nconst mapStateToProps = (state, props) => {\n const dataLoadingMessageQueue =\n getMqttDataLoadingResponseRequestMessageQueue(state);\n return {\n dataLoadingMessageQueue,\n };\n};\n\nexport default connect(mapStateToProps, null)(DataLoadingMessage);\n","import React, { PureComponent } from \"react\";\nimport { push } from \"react-router-redux\";\n\nimport PropTypes from \"prop-types\";\n\nimport { Container, Header, Grid, Message } from \"semantic-ui-react\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { connect } from \"react-redux\";\n\n//import { getFireflyById } from \"UPSPanelControllers/reducer\";\nimport { getFireflyById } from \"components/WebWorker/reducer\";\n\nimport FireflyDetailsForm from \"./FireflyDetailsForm\";\n// import FireflyStatusSummary from \"./FireflyStatusSummary\";\n// import FireflyLightStatus from \"./FireflyLightStatus\";\n// import FireflyTopologyStatus from \"./FireflyTopologyStatus\";\n// import FireflyElectricalStatus from \"./FireflyElectricalStatus\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nclass FireflyDetail extends PureComponent {\n static propTypes = {\n id: PropTypes.string,\n error: PropTypes.string,\n };\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n render() {\n const { id, error, isDeleteFireflyNotCommissioned, strings } = this.props;\n\n // #WIP - ATM don't allow reload, or direct link to a firefly page.....\n // Instead redirect to the controller list page and wait for firefly to list (with next message).\n\n if (error) {\n this.props.goto(\"/admin/firefly/\");\n return null;\n // return (\n // <>\n // \n // \n // \n // );\n }\n\n return (\n
\n \n \n \n \n
FireFly Details
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n\n {/*

Firefly - {id}

\n \n \n \n \n \n
Status information
\n \n
\n
\n */}\n \n
\n
\n );\n }\n}\n\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n goto: (path) => dispatch(push(path)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n };\n};\n\nconst mapStateToProps = (state, props) => {\n const match = props.match;\n const id = match.params.id;\n const firefly = getFireflyById(state, id);\n return {\n id,\n error: firefly ? undefined : \"No FireFly for id\",\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(FireflyDetail);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\n\nimport FireflyList from \"admin/firefly/FireflyList\";\nimport FireflyDetail from \"admin/firefly/FireflyDetail\";\nimport { fetchFireflys } from \"UPSPanelControllers/actions\";\nimport { isDeleteFireflyNotCommissioned } from \"components/ConfigJs\";\n\nclass FireflyAdminPages extends Component {\n componentDidMount() {\n //\n }\n\n render() {\n const { match, strings } = this.props;\n\n return (\n \n {/* */}\n (\n \n )}\n />\n {/* */}\n (\n \n )}\n />\n \n );\n }\n}\n\nexport default withRouter(connect(null, { fetchFireflys })(FireflyAdminPages));\n","import React from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { getControllerById } from \"components/WebWorker/reducer\";\n\nimport {\n formatDate,\n formatDateRelativeNow,\n parseDate,\n} from \"utils/format-date\";\n\nfunction Component({ statusReport }) {\n let updatedStatusReport = { ...statusReport };\n\n if (statusReport) {\n const { timestamp } = statusReport;\n\n let timeRxd;\n if (timestamp !== null && timestamp !== undefined) {\n timeRxd = parseDate(timestamp);\n timeRxd =\n formatDate(timeRxd) +\n \" (\" +\n formatDateRelativeNow(timeRxd, new Date()) +\n \")\";\n } else {\n timeRxd = \"No time information\";\n }\n\n updatedStatusReport = { ...statusReport, timestamp: timeRxd };\n } else {\n updatedStatusReport = null;\n }\n\n return
{JSON.stringify(updatedStatusReport, null, 2)}
;\n}\n\nexport default connect((state, { id }) => {\n const controller = getControllerById(state, id);\n return { statusReport: controller };\n})(Component);\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { Button } from \"semantic-ui-react\";\n\nfunction ChooseEditorMode({ mode, color, onChange }) {\n return (\n \n {\n e.preventDefault();\n onChange(\"asString\");\n }}\n color={mode === \"asString\" ? color : null}\n >\n String\n \n \n {\n e.preventDefault();\n onChange(\"asIndividuals\");\n }}\n color={mode === \"asIndividuals\" ? color : null}\n >\n Individual\n \n \n );\n}\n\nChooseEditorMode.defaultProps = {};\n\nChooseEditorMode.propTypes = {\n mode: PropTypes.oneOf([\"asString\", \"asIndividuals\"]).isRequired,\n color: PropTypes.string.isRequired,\n onChange: PropTypes.func.isRequired,\n};\n\nconst ChooseEditorModeField = ({\n color,\n input: { value, onChange },\n label,\n disabled = false,\n type,\n meta: { touched, error },\n}) => {\n return ;\n};\n\nexport default ChooseEditorModeField;\n","\nconst PORT_COLORS = {\n '1': 'brown',\n '2': 'olive',\n '3': 'pink',\n '4': 'purple'\n}\n\nexport const getPortColor = (num) => {\n return PORT_COLORS[num] || 'grey'\n}\n","import React from 'react'\n\nfunction round (val, places = 4) {\n switch (typeof val) {\n case 'number':\n const rnd = Math.pow(10, places)\n return Math.round(val * rnd) / rnd\n case 'string':\n return round(Math.parseFloat(val), places)\n default:\n return val\n }\n}\n\nconst LatLngSummary = ({ position, displayDefault = '-' }) => {\n let content = displayDefault\n if (position) {\n const { lat, lng } = position\n content = [\n
Lat: {round(lat)}
,\n
Lng: {round(lng)}
\n ]\n }\n return
{content}
\n}\n\nexport default LatLngSummary\n","import { formValueSelector } from 'redux-form'\n\nconst selector = formValueSelector('upsBulkPositioningForm')\nexport default selector\n","import React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport { connect } from 'react-redux'\nimport selector from './form-value-selector'\n\nclass CommissioningStatus extends Component {\n static propTypes = {\n status: PropTypes.oneOf([\n 'ERROR',\n 'NO_CHANGES',\n 'TOPO_AND_POS',\n 'TOPO_ONLY',\n 'POS_ONLY',\n 'NOT_COMMISSIONED'\n ])\n }\n\n render () {\n const { status } = this.props\n const options = {\n ERROR: 'No item found',\n NO_CHANGES: 'No change',\n NOT_COMMISSIONED: 'Not yet commissioned',\n TOPO_AND_POS: 'Full recommissioning',\n TOPO_ONLY: 'Will update topology',\n POS_ONLY: 'Will update position'\n }\n return {options[status]}\n }\n}\n\nexport function hasTopologyChanged (fireflyFormRecord) {\n const { originalCommissioning, topology } = fireflyFormRecord\n if (!originalCommissioning) {\n return false\n }\n\n const fields = ['upsId', 'position', 'portNumber']\n for (let i = 0; i < fields.length; i++) {\n const k = fields[i]\n if (originalCommissioning.topology[k] !== topology[k]) {\n return true\n }\n }\n return false\n}\n\nexport function hasLatLngChanged (fireflyFormRecord) {\n const { originalCommissioning, position } = fireflyFormRecord\n if (!originalCommissioning) {\n return false\n }\n\n const fields = ['lat', 'lng']\n for (let i = 0; i < fields.length; i++) {\n const k = fields[i]\n if (originalCommissioning.position[k] !== position[k]) {\n return true\n }\n }\n return false\n}\n\nCommissioningStatus = connect((state, props) => {\n const ff = selector(state, props.formname)\n if (!ff) {\n return { status: 'ERROR' }\n }\n\n const { originalCommissioning } = ff\n if (!originalCommissioning) {\n return { status: 'NOT_COMMISSIONED' }\n }\n\n let diffTopo = hasTopologyChanged(ff)\n let diffPos = hasLatLngChanged(ff)\n\n let status = 'NO_CHANGES'\n if (diffTopo && diffPos) {\n status = 'TOPO_AND_POS'\n } else if (diffTopo) {\n status = 'TOPO_ONLY'\n } else if (diffPos) {\n status = 'POS_ONLY'\n }\n\n return { status }\n})(CommissioningStatus)\n\nexport default CommissioningStatus\n","import React, { Component } from \"react\";\nimport { Table } from \"semantic-ui-react\";\n\nimport FireflyName from \"containers/FireflyName\";\nimport LatLngSummary from \"components/LatLngSummary\";\nimport CommissioningStatus from \"./FireflyCommissioningStatus\";\n\nimport selector from \"./form-value-selector\";\nimport { connect } from \"react-redux\";\nimport isEqual from \"lodash/isEqual\";\n\nclass FireflyRow extends Component {\n shouldComponentUpdate(nextProps) {\n return !isEqual(this.props, nextProps);\n }\n render() {\n const { id, topology, position } = this.props;\n return (\n \n {topology.position}\n \n \n \n {/* \n \n */}\n \n \n \n \n );\n }\n}\n\nconst mapState = (state, props) => {\n const firefly = selector(state, `fireflies.${props.id}`);\n return firefly;\n};\nFireflyRow = connect(mapState)(FireflyRow);\n\nclass PortSummaryFireflyDetails extends Component {\n shouldComponentUpdate(nextProps) {\n return !isEqual(this.props, nextProps);\n }\n render() {\n const { fireflies } = this.props;\n return (\n \n \n \n Position\n Id\n {/* Lat/Lng */}\n Status\n \n \n \n {fireflies.map((id) => (\n \n ))}\n \n
\n );\n }\n}\n\nexport default PortSummaryFireflyDetails;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Field, reset, isSubmitting, isPristine } from \"redux-form\";\n\nimport {\n Header,\n Segment,\n Icon,\n Accordion,\n Form,\n Grid,\n Button,\n Popup,\n} from \"semantic-ui-react\";\n\nimport isEqual from \"lodash/isEqual\";\n\nimport { renderSelect, renderField, renderCheckbox } from \"admin/form-field\";\nimport ChooseEditorModeField from \"admin/bulk-positioning/UPSBulkEditPage/ChooseEditorModeField\";\nimport { getPortColor } from \"admin/bulk-positioning/UPSBulkEditPage/port-colors\";\nimport PortSummaryFireflyDetails from \"admin/bulk-positioning/UPSBulkEditPage/PortSummaryFireflyDetails\";\nimport selector from \"admin/bulk-positioning/UPSBulkEditPage/form-value-selector\";\nimport { getControllerById } from \"components/WebWorker/reducer\";\n\nimport {\n allowedLightColors as _allowedLightColors,\n allowedLightStates as _allowedLightStates,\n} from \"components/ConfigJs\";\n\nconst normalise = (value, type) => {\n switch (type) {\n case \"on_time\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n case \"off_time\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n case \"train\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n default:\n return value;\n }\n};\n\nclass PortSummaryField extends Component {\n state = {\n expanded: false,\n };\n\n handleClick = (e) => {\n const { expanded } = this.state;\n this.setState({ expanded: !expanded });\n };\n\n shouldComponentUpdate(nextProps, nextState) {\n if (this.state.expanded !== nextState.expanded) {\n return true;\n }\n\n return !isEqual(this.props, nextProps);\n }\n\n resetForm = (e) => {\n e.preventDefault();\n this.props.reset();\n };\n\n render() {\n const {\n portNumber,\n fireflies,\n name,\n locationHint,\n showSection,\n //\n submitting,\n pristine,\n } = this.props;\n const { expanded } = this.state;\n\n const allowedLightColors = _allowedLightColors();\n const allowedLightStates = _allowedLightStates();\n\n const color = getPortColor(portNumber);\n\n const {\n isEmergencyEventSettings,\n isTriggerEventSettings,\n form_emergencyPortEnable,\n form_triggerPortEnable,\n } = showSection;\n\n return (\n \n \n \n \n
\n Port {portNumber} {locationHint}\n
\n
\n \n \n \n \n \n {/* #NOTE - enable this section to allow control over Emergency events */}\n {false && isEmergencyEventSettings && (\n \n )}\n {isTriggerEventSettings && (\n \n )}\n \n \n \n \n this.props.onSubmit}\n disabled={pristine || submitting}\n >\n \n \n }\n />\n \n this.resetForm(e)}\n disabled={pristine || submitting}\n >\n \n \n }\n />\n \n \n \n \n \n
\n
\n {isEmergencyEventSettings && form_emergencyPortEnable && (\n \n
Emergency Event Settings
\n
\n \n \n \n normalise(value, \"off_time\")}\n component={renderField}\n style={{ paddingTop: \"0.5em\" }}\n />\n normalise(value, \"on_time\")}\n component={renderField}\n style={{ paddingTop: \"0.5em\" }}\n />\n normalise(value, \"train\")}\n component={renderField}\n style={{ paddingTop: \"0.5em\" }}\n />\n \n
\n
\n )}\n {isTriggerEventSettings && form_triggerPortEnable && (\n \n
Trigger Event Settings
\n \n \n \n normalise(value, \"off_time\")}\n component={renderField}\n style={{ paddingTop: \"0.5em\" }}\n />\n normalise(value, \"on_time\")}\n component={renderField}\n style={{ paddingTop: \"0.5em\" }}\n />\n normalise(value, \"train\")}\n component={renderField}\n style={{ paddingTop: \"0.5em\" }}\n />\n \n
\n )}\n \n
FireFlys
\n \n\n \n \n \n {fireflies.length} FireFlys\n \n \n {expanded && }\n \n \n
\n
\n );\n }\n}\n\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n reset: () => dispatch(reset(\"upsBulkPositioningForm\")),\n };\n};\n\nconst mapStateToProps = (state, props) => {\n const { name, onSubmit } = props;\n\n const values = selector(state, name);\n\n const isEmergencyEventSettings = selector(state, \"isEmergencyEventSettings\");\n const isTriggerEventSettings = selector(state, \"isTriggerEventSettings\");\n\n const form_triggerPortEnable = selector(\n state,\n `${name}.triggerEventSettings.enable`\n );\n const form_emergencyPortEnable = selector(\n state,\n `${name}.emergencyEventSettings.enable`\n );\n\n const showSection = {\n isEmergencyEventSettings,\n isTriggerEventSettings,\n form_emergencyPortEnable,\n form_triggerPortEnable,\n };\n\n const form_ups = selector(state, \"ups\");\n\n const ups = getControllerById(state, form_ups.id);\n\n const portIndex = values.portNumber - 1;\n\n const area = ups?.topology?.area;\n const location = ups?.topology?.location;\n\n let locationHint = \"\";\n\n if (area && location && location[portIndex]) {\n locationHint = `(${area} - ${location[portIndex]})`;\n }\n\n return {\n ...values,\n locationHint,\n showSection,\n //\n onSubmit,\n submitting: isSubmitting(\"upsBulkPositioningForm\")(state),\n pristine: isPristine(\"upsBulkPositioningForm\")(state),\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(PortSummaryField);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport MapMarker from \"components/ColorableMapMarker\";\nimport selector from \"admin/bulk-positioning/UPSBulkEditPage/form-value-selector\";\n\nclass UPSMoveableMarker extends Component {\n onDragEnded = ({ target }) => {\n const ll = target.getLatLng();\n const { change, name } = this.props;\n change(`${name}.lat`, ll.lat);\n change(`${name}.lng`, ll.lng);\n };\n\n render() {\n const { position, children } = this.props;\n return (\n \n {children}\n \n );\n }\n}\n\nUPSMoveableMarker = connect((state, props) => ({\n position: selector(state, props.name),\n}))(UPSMoveableMarker);\n\nexport default UPSMoveableMarker;\n","import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport \"leaflet/dist/leaflet.css\";\n\nimport MapMarker from \"components/ColorableMapMarker\";\nimport { Polyline } from \"react-leaflet\";\nimport getSemanticColor from \"colorpalette\";\nimport find from \"lodash/find\";\nimport FireflyName from \"containers/FireflyName\";\nimport isEqual from \"lodash/isEqual\";\nimport { StatusEnum } from \"utils/StatusEnum\";\n\nconst SEMANTIC_BLACK = getSemanticColor(\"black\");\n\nclass UPSPortStringMapLocationEditor extends Component {\n static propTypes = {\n fireflies: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.string.isRequired,\n position: PropTypes.shape({\n lat: PropTypes.number.isRequired,\n lng: PropTypes.number.isRequired,\n }).isRequired,\n })\n ).isRequired,\n };\n\n constructor(props) {\n super(props);\n this.onDragEnded = this.onDragEnded.bind(this);\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n return !isEqual(this.props, nextProps);\n }\n\n onDragEnded(id, newLocation) {\n const { fireflies } = this.props;\n if (this.props.asIndividuals) {\n const ff = find(fireflies, (ff) => ff.id === id);\n this.props.onRepositioned([{ ...ff, position: newLocation }]);\n return;\n }\n const first = fireflies[0];\n const last = fireflies.slice(-1)[0];\n const numItems = fireflies.length;\n const numIntevals = numItems - 1;\n const startPos = id === first.id ? newLocation : first.position;\n const endPos = id === last.id ? newLocation : last.position;\n\n const offsetLat = startPos.lat;\n const offsetLng = startPos.lng;\n\n const dLat = (endPos.lat - startPos.lat) / numIntevals;\n const dLng = (endPos.lng - startPos.lng) / numIntevals;\n const newPositions = [{ ...first, position: startPos }];\n for (var idx = 1; idx < numIntevals; idx++) {\n newPositions.push({\n ...fireflies[idx],\n position: { lat: idx * dLat + offsetLat, lng: idx * dLng + offsetLng },\n });\n }\n newPositions.push({ ...last, position: endPos });\n this.props.onRepositioned(newPositions);\n }\n\n makeOnDragEnd(id) {\n return ({ target }) => {\n this.onDragEnded(id, target.getLatLng());\n };\n }\n\n render() {\n const {\n fireflies,\n baseColor,\n asIndividuals = false,\n upsPosition,\n } = this.props;\n const color = getSemanticColor(baseColor);\n const lastIdx = fireflies.length - 1;\n const lineLocations = [{ id: \"theups\", position: upsPosition }].concat(\n ...fireflies\n );\n\n return (\n
\n {fireflies.map((ff, idx) => {\n const { id, position, topology } = ff;\n\n // if new marker make 'new' color i.e. yellow\n const markerColor = topology?.deviceStatus?.includes(\n StatusEnum.NOT_COMMISSIONED\n )\n ? \"yellow\"\n : color;\n\n return (\n \n );\n })}\n {lineLocations.slice(1).map(({ id, position }, idx) => {\n const from = position;\n const to = lineLocations[idx].position;\n return (\n \n );\n })}\n
\n );\n }\n}\n\nconst FireflyMarker = ({\n id,\n lat,\n lng,\n color,\n isMoveable,\n text,\n onDragEnd,\n PopupContent,\n}) => {\n const outline = isMoveable ? SEMANTIC_BLACK : color;\n const fillOpacity = isMoveable ? 0.8 : 0.7;\n const size = isMoveable ? 18.0 : 12.0;\n\n return (\n \n \n \n );\n};\n\nconst Cable = ({ from, to, color }) => (\n \n);\n\nexport default UPSPortStringMapLocationEditor;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport {\n Form,\n Container,\n Button,\n Menu,\n Popup,\n Icon,\n Segment,\n Header,\n Dropdown,\n Message,\n Grid,\n Tab,\n Label,\n Divider,\n} from \"semantic-ui-react\";\n\nimport { LayersControl } from \"react-leaflet\";\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroupGeoJson\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport {\n getFireflyById,\n getFireflyCoordinatesById,\n getControllerById,\n getControllerCoordinatesById,\n} from \"components/WebWorker/reducer\";\nimport { formatRelative, parseISO, isPast } from \"date-fns\";\nimport isEqual from \"lodash/isEqual\";\n\nimport UPSRawStatusReport from \"../../ups/UPSRawStatusReport\";\n\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport {\n Field,\n FieldArray,\n reduxForm,\n SubmissionError,\n change as unboundChange,\n} from \"redux-form\";\n\nimport { getUserSettings } from \"auth/reducer\";\n\nimport {\n getControllerPortsById,\n getFireflyByControllerId,\n getFireflyCoordinatesByUpsId,\n getAreaStatusesById,\n getControllerEmergencyEventSettingsById,\n getControllerTriggerEventSettingsById,\n} from \"components/WebWorker/reducer\";\n\nimport { makeTemporaryCoordsFactory } from \"MineLevels/reducer\";\nimport { fetchUPSs, fetchFireflys } from \"UPSPanelControllers/actions\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport {\n saveUPS,\n deleteUPS,\n savePositions,\n saveEmergencyEventSettings,\n saveTriggerEventSettings,\n} from \"UPSPanelControllers/actions\";\nimport { saveFirefly, deleteFirefly } from \"UPSPanelControllers/actions\";\n\nimport ChooseMineLevelField from \"components/ChooseMineLevelField\";\n\nimport { MineLevelMapById } from \"components/Map/MineLevelMap\";\n\nimport UPSName from \"containers/UPSName\";\nimport FireflyName from \"containers/FireflyName\";\nimport PortSummary from \"admin/bulk-positioning/UPSBulkEditPage/PortSummaryField\";\n\nimport UPSMoveableMarker from \"admin/bulk-positioning/UPSBulkEditPage/UPSMoveableMarker\";\nimport UPSPortStringMapLocationEditor from \"./UPSPortStringMapLocationEditor\";\nimport sortBy from \"lodash/sortBy\";\nimport { renderField, renderCheckbox } from \"admin/form-field\";\nimport { getPortColor } from \"admin/bulk-positioning/UPSBulkEditPage/port-colors\";\nimport selector from \"admin/bulk-positioning/UPSBulkEditPage/form-value-selector\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\nimport { StatusEnum } from \"utils/StatusEnum\";\n\nclass UPSBulkPositioningForm extends Component {\n // Reinstate if we really need to start worrrying about the topology\n // status having changed\n // componentDidUpdate () {\n // console.log('saving', this.props)\n // }\n\n // #REVIEW -\n // Render issue - with each heartbeat the STATE updates which causes localPts to be updated and so resets the map state\n // This stops re-rendering the map unnecessarily\n\n constructor(props) {\n super(props);\n\n this.state = {\n collapse: false,\n ctrlKey: false,\n submitted: false,\n errorMessage: \"\",\n };\n }\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n shouldComponentUpdate(nextProps, nextState) {\n // only re-render if the ups object has changed.\n // This stops re-rendering the map unnecessarily\n\n //console.log(`nextProps`, nextProps);\n return (\n !isEqual(this.props.ups, nextProps.ups) ||\n !isEqual(this.props.fireflies, nextProps.fireflies) ||\n !isEqual(this.props.ports, nextProps.ports) ||\n !isEqual(\n this.props.isEmergencyEventSettings,\n nextProps.isEmergencyEventSettings\n ) ||\n !isEqual(\n this.props.isTriggerEventSettings,\n nextProps.isTriggerEventSettings\n ) ||\n !isEqual(this.state.collapse, nextState.collapse) ||\n !isEqual(\n this.state.isIgnoreEmergencyTriggerEvents,\n nextState.isIgnoreEmergencyTriggerEvents\n ) ||\n // !isEqual(this.props.submitting, this.props.submitting) || //#WTF??????\n // !isEqual(this.props.pristine, this.props.pristine) ||\n //\n !isEqual(this.state.ctrlKey, nextState.ctrlKey) ||\n !isEqual(this.state.errorMessage, nextState.errorMessage)\n );\n }\n\n ctrlKeyDown = (e) => {\n if (e.keyCode === 17) {\n this.setState({ ctrlKey: true });\n }\n };\n\n ctrlKeyUp = (e) => {\n if (e.keyCode === 17) {\n this.setState({ ctrlKey: false });\n }\n };\n\n componentDidMount() {\n document.addEventListener(\"keydown\", this.ctrlKeyDown, false);\n document.addEventListener(\"keyup\", this.ctrlKeyUp, false);\n }\n\n componentWillUnmount() {\n document.removeEventListener(\"keydown\", this.ctrlKeyDown, false);\n document.removeEventListener(\"keyup\", this.ctrlKeyUp, false);\n }\n\n submitMyForm = (formdata) => {\n const {\n saveFirefly,\n saveUPS,\n initialValues,\n transformPixelsToUtm,\n saveEmergencyEventSettings,\n saveTriggerEventSettings,\n } = this.props;\n\n //console.log(\"xxx formdata\", formdata);\n //console.log(\"initialValues\", initialValues);\n\n const {\n ups,\n fireflies,\n ports,\n isEmergencyEventSettings,\n isTriggerEventSettings,\n } = formdata;\n\n const { mineLevelId, lat, lng } = ups.position;\n const { name: network_name } = ups;\n\n const changePositions = [];\n Object.keys(fireflies).forEach((id) => {\n const ff = fireflies[id];\n const { position, topology } = ff;\n\n const ffInitialValue = initialValues.fireflies[id];\n const { position: positionInitialValue, topology: topologyInitialValue } =\n ffInitialValue;\n\n if (!isEqual(position, positionInitialValue)) {\n const objLatLng = transformPixelsToUtm.transform({\n lat: position.lat,\n lng: position.lng,\n });\n\n // transform position to UTM\n const newPosition = {\n mineLevelId: position.mineLevelId,\n lat: objLatLng.lat,\n lng: objLatLng.lng,\n };\n\n changePositions.push({\n id: id,\n type: \"firefly\",\n position: newPosition,\n topology,\n });\n }\n });\n\n const upsPosition = { id: ups.id, position: { mineLevelId, lat, lng } };\n const { id: upsIdInitial, position: positionInitial } = initialValues.ups;\n const upsPositionsInitialValue = {\n id: upsIdInitial,\n position: {\n mineLevelId: positionInitial.mineLevelId,\n lat: positionInitial.lat,\n lng: positionInitial.lng,\n },\n };\n\n if (!isEqual(upsPosition, upsPositionsInitialValue)) {\n const objLatLng = transformPixelsToUtm.transform({\n lat: upsPosition.position.lat,\n lng: upsPosition.position.lng,\n });\n\n // transform position to UTM\n const newPosition = {\n mineLevelId: upsPosition.position.mineLevelId,\n lat: objLatLng.lat,\n lng: objLatLng.lng,\n };\n\n changePositions.push({\n id: upsPosition.id,\n type: \"controller\",\n position: newPosition,\n name: network_name,\n });\n }\n\n // update settings\n let changeSettings = [];\n\n const makeEventSettings = (enable, ports, type) => {\n let portSettings = [];\n ports.forEach((port, idx) => {\n const { emergencyEventSettings, triggerEventSettings } = port;\n\n if (type === \"emergency\") {\n portSettings[idx] = emergencyEventSettings;\n } else if (type === \"trigger\") {\n portSettings[idx] = triggerEventSettings;\n }\n });\n\n return {\n enable: enable,\n ports: portSettings,\n };\n };\n\n const emergencyEventSettings = makeEventSettings(\n isEmergencyEventSettings,\n ports,\n \"emergency\"\n );\n const initialValuesEmergencyEventSettings = makeEventSettings(\n initialValues.isEmergencyEventSettings,\n initialValues.ports,\n \"emergency\"\n );\n\n // console.log(\n // \"SAVE emergencyEventSettings, initialValuesEmergencyEventSettings\",\n // emergencyEventSettings,\n // initialValuesEmergencyEventSettings\n // );\n\n // don't send if object is unchanged\n if (!isEqual(emergencyEventSettings, initialValuesEmergencyEventSettings)) {\n changeSettings.push({\n id: ups.id,\n type: \"emergencyEventSettings\",\n settings: emergencyEventSettings,\n });\n }\n\n const triggerEventSettings = makeEventSettings(\n isTriggerEventSettings,\n ports,\n \"trigger\"\n );\n const initialValuesTriggerEventSettings = makeEventSettings(\n initialValues.isTriggerEventSettings,\n initialValues.ports,\n \"trigger\"\n );\n\n // console.log(\n // \"SAVE triggerEventSettings, initialValuesTriggerEventSettings\",\n // triggerEventSettings,\n // initialValuesTriggerEventSettings\n // );\n\n // don't send if it is not enabled\n if (!isEqual(triggerEventSettings, initialValuesTriggerEventSettings)) {\n changeSettings.push({\n id: ups.id,\n type: \"triggerEventSettings\",\n settings: triggerEventSettings,\n });\n }\n\n let promiseArray = [];\n\n // update settings\n changeSettings.forEach((changeSetting) => {\n const { id, type, settings } = changeSetting;\n switch (type) {\n case \"emergencyEventSettings\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveEmergencyEventSettings({\n values: { id, settings },\n resolve,\n reject,\n });\n })\n );\n\n break;\n case \"triggerEventSettings\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveTriggerEventSettings({\n values: { id, settings },\n resolve,\n reject,\n });\n })\n );\n break;\n default:\n break;\n }\n });\n\n // update positions\n changePositions.forEach((changePosition) => {\n const {\n id,\n type,\n position: { mineLevelId, lat, lng },\n topology,\n name,\n mdt,\n } = changePosition;\n\n switch (type) {\n case \"firefly\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveFirefly({\n values: {\n id,\n position: { mineLevelId, lat, lng },\n topology,\n name,\n mdt,\n },\n resolve,\n reject,\n });\n })\n );\n break;\n case \"controller\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveUPS({\n values: {\n id,\n position: { mineLevelId, lat, lng },\n name,\n },\n resolve,\n reject,\n });\n })\n );\n break;\n default:\n break;\n }\n });\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"UPDATING CONTROLLER/FIREFLIES\", results);\n })\n .then(\n () => {\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n const { fetchUPSs, fetchFireflys } = this.props;\n // #FETCHS\n fetchUPSs(); // #FETCHS\n fetchFireflys({ userSettings: this.props.userSettings }); // #FETCHS\n\n this.props.goto(\"/admin/controller/\");\n }\n );\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n requestDelete = (values) => {\n const { deleteUPS, id, change } = this.props;\n\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call change to populate the formValue `_action` at the beginning of the delete process.\n // The _action value is checked in the NavigationPromptModal, which does not display.\n change(\"_action\", \"delete\");\n\n return new Promise((resolve, reject) => {\n deleteUPS({ values: { id: id }, resolve, reject });\n }).then(\n () => {\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n const { fetchUPSs, fetchFireflys } = this.props;\n // #FETCHS\n fetchUPSs(); // #FETCHS\n fetchFireflys({ userSettings: this.props.userSettings }); // #FETCHS\n\n this.props.goto(\"/admin/controller/\");\n }\n );\n },\n (errorMsg) => {\n //console.log(`deleteUPS errorMsg`, errorMsg);\n // pop error dlg\n const message = {\n header: {\n icon: \"warning\",\n title: \"Delete Failed\",\n },\n content: \"Error when attempting to delete data.\",\n };\n this.setState({\n errorMessage: `${errorMsg}`,\n modalMessage: message,\n });\n }\n );\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n // this.props.goto(\"/admin/bulk-positioning/\"); // <---- reminder\n this.props.goto(\"/admin/controller/\");\n };\n\n onResetError = () => {\n const { goto, submitting, submitSucceeded } = this.props;\n\n this.setState({ errorMessage: \"\" });\n\n // if we've just submit the form -> leave\n if (submitting || submitSucceeded) {\n goto(\"/\");\n }\n };\n\n render() {\n const {\n handleSubmit,\n change,\n pristine,\n submitting,\n error,\n reset,\n ups,\n areaError,\n ports,\n //\n isIgnoreEmergencyTriggerEvents,\n //\n isDeleteButton,\n strings, // localisation\n } = this.props;\n\n const {\n submitted,\n collapse: isCollapse,\n ctrlKey,\n modalMessage,\n errorMessage,\n } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n const panes = [\n {\n menuItem: strings?.[\"Position\"],\n render: () => (\n \n \n \n {ups.id}\n {/* */}\n \n \n \n \n \n \n \n \n \n ),\n },\n {\n menuItem: strings?.[\"Latest Report\"],\n render: () => (\n \n \n \n ),\n },\n ];\n\n const isPorts = !_isEmpty(ports);\n\n return (\n <>\n handleSubmit(this.submitMyForm(formValues))}\n />\n this.onResetError()}\n modalMessage={modalMessage}\n errorMessage={errorMessage}\n />\n \n {error && }\n\n \n \n \n \n {isCollapse && (\n \n \n \n \n \n \n \n }\n />\n \n \n \n \n )}\n {!isCollapse && (\n <>\n \n \n \n
\n \n \n \n {strings?.[\"Controller Config\"]}\n \n \n
\n \n \n \n \n }\n />\n \n
\n
\n
\n \n {!areaError.error && (\n <>\n \n \n \n
{strings?.[\"Ports\"]}
\n
\n {isPorts && (\n \n \n {/* #NOTE - enable this section to allow control over Emergency events */}\n {false &&\n !isIgnoreEmergencyTriggerEvents && (\n \n )}\n\n \n \n \n )}\n {!isPorts && (\n <>\n \n \n \n \n {\n strings?.[\n \"Controller Port Message Header\"\n ]\n }\n \n {\n strings?.[\n \"Controller Port Message Content\"\n ]\n }\n \n
\n \n )}\n \n \n \n \n )}\n {areaError.error && (\n <>\n \n \n \n \n {strings?.[\"Controller Area Message Header\"]}\n \n {strings?.[\n `Controller Area Message Content`\n ]?.replace(\"areaError_id\", areaError.id)}\n \n \n \n )}\n \n \n )}\n \n\n \n \n \n \n {isDeleteButton && (\n \n \n \n )}\n \n \n \n \n \n \n \n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n\n \n \n \n {/* \n \n \n \n \n \n \n \n \n Reset\n \n \n this.cancelForm(e)}\n >\n Cancel\n \n \n \n \n \n \n */}\n \n\n {/* ********************************************************************************* */}\n\n {/* \n \n \n \n\n \n \n \n \n \n

Ports

\n \n
\n \n \n \n \n

Positioning

\n
\n \n \n \n \n \n
\n
\n\n \n \n \n \n \n \n
\n
\n */}\n\n {/***********************************/}\n \n \n
\n \n );\n }\n}\n\nconst ListPorts = ({ fields, PortComponent, change, ctrlKey }) => {\n return (\n
\n {fields.map((port, index) => {\n return (\n \n );\n })}\n
\n );\n};\n\nconst ForAllPorts = ({ PortComponent, change, ctrlKey }) => {\n return (\n \n );\n};\n\nfunction MapPositioningDisplay({ mineLevelId, children }) {\n if (!mineLevelId) {\n return
No mine level selected
;\n }\n return (\n \n {children}\n \n );\n}\n\nclass UPSPortString extends Component {\n onRepositioned = (newPositions) => {\n const { dispatch } = this.props;\n const updates = newPositions.map((ff) =>\n unboundChange(\n \"upsBulkPositioningForm\",\n `fireflies.${ff.id}.position`,\n ff.position\n )\n );\n dispatch(updates); // relies on redux-batch!!!\n };\n popup = (ffId) => ;\n render() {\n const { portNumber, upsPosition, positionMode, fireflies, ctrlKey } =\n this.props;\n\n // forces to \"asString\" if the control key is held down\n const isAsIndividuals = ctrlKey ? false : positionMode === \"asIndividuals\";\n\n return (\n \n );\n }\n}\n\nUPSPortString = connect((state, { name }) => {\n const ups = selector(state, \"ups\");\n const port = selector(state, name);\n const fireflies = selector(state, \"fireflies\");\n\n return {\n portNumber: port.portNumber,\n positionMode: port.positionMode,\n upsPosition: ups.position,\n fireflies: port.fireflies.map((id) => ({ id, ...fireflies[id] })),\n };\n})(UPSPortString);\n\n// function SaveButton({ submitting, pristine, ...props }) {\n// const disabled = submitting || pristine;\n// let positive = true;\n// let text = \"Save\";\n// if (submitting) {\n// text = \"Submitting\";\n// } else if (pristine) {\n// positive = false;\n// text = \"Nothing changed\";\n// }\n\n// return (\n// \n// {text}\n// \n// );\n// }\n\nUPSBulkPositioningForm = reduxForm({\n form: \"upsBulkPositioningForm\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n})(UPSBulkPositioningForm);\n\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n saveUPS: (data) => dispatch(saveUPS(data)), // #WIP\n savePositions: (data) => dispatch(savePositions(data)), // #WIP\n deleteUPS: (data) => dispatch(deleteUPS(data)), // #WIP\n //\n saveFirefly: (data) => dispatch(saveFirefly(data)), // #WIP\n //\n saveEmergencyEventSettings: (data) =>\n dispatch(saveEmergencyEventSettings(data)),\n saveTriggerEventSettings: (data) =>\n dispatch(saveTriggerEventSettings(data)),\n fetchUPSs: () => dispatch(fetchUPSs()),\n fetchFireflys: (data) => dispatch(fetchFireflys(data)),\n };\n};\n\nconst mapStateToProps = (state, props) => {\n //const stateUPS = getUPSById(state, props.id);\n\n const id = props.id;\n\n const stateUPS = getControllerById(state, props.id);\n\n //console.log(`xxx stateUPS`, stateUPS);\n\n const { firefly_count: fireflyCount, topology, timestamp } = stateUPS;\n const {\n area: mineLevelId,\n location,\n network_name,\n master,\n ip,\n ignore_server,\n deviceStatus,\n } = topology;\n\n // #NOTE\n // `ignore_server` denotes whether emergency and trigger events are\n // managed by the server config or the controller.\n\n let isIgnoreEmergencyTriggerEvents = false;\n if (ignore_server !== undefined) {\n isIgnoreEmergencyTriggerEvents = ignore_server == true;\n }\n\n const area = getAreaStatusesById(state, mineLevelId);\n\n const transformPixelsToUtm = area?.transformPixelsToUtm;\n\n const controllerCoord = getControllerCoordinatesById(state, id);\n\n // plot functions hereon use [lng, lat] so swap coordinates\n const lat =\n controllerCoord !== undefined && controllerCoord !== null\n ? controllerCoord[1] >= 0\n ? controllerCoord[1]\n : 0\n : 0;\n const lng =\n controllerCoord !== undefined && controllerCoord !== null\n ? controllerCoord[0] >= 0\n ? controllerCoord[0]\n : 0\n : 0;\n\n // *********************************************\n // const { id, name, created, position } = stateUPS;\n // const { mineLevelId, lat, lng } = position || {};\n\n const upsLatLng = { lat, lng };\n\n //console.log(\"mineLevelId, upsLatLng\", mineLevelId, upsLatLng);\n\n const temporaryCoordsFactory = makeTemporaryCoordsFactory(state);\n const tempCoordsProvider = temporaryCoordsFactory.ForMineLevelId(\n mineLevelId,\n upsLatLng\n );\n\n //console.log(\"tempCoordsProvider\", tempCoordsProvider);\n\n // const ups = {\n // id,\n // name,\n // created,\n // position: { mineLevelId, lat, lng },\n // };\n\n // *********************************************\n\n const lastStatusReport =\n (timestamp !== null && timestamp !== undefined)\n ? formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n })\n : \"-\";\n\n const ups = {\n id,\n name: network_name,\n created: \"2020-07-28T03:44:32.341087779Z\",\n ip,\n master,\n location,\n mineLevelId,\n lastStatusReport,\n position: { mineLevelId, lat, lng },\n };\n\n // don't show delete if controller is not commissioned\n\n //console.log(`xxx stateFireflies id`, id);\n\n const stateFireflies = getFireflyByControllerId(state, id);\n\n //console.log(`xxx stateFireflies`, stateFireflies);\n\n // initialise byPortByOrdinal to display 4 ports irrespective of whether the\n // ports have FFs connected.\n //\n let byPortByOrdinal = { 1: {}, 2: {}, 3: {}, 4: {} };\n let fireflies = {};\n\n stateFireflies.forEach((ff) => {\n const topo = ff.topology;\n const { port_number: portNumber, position } = topo;\n const portByOrdinal = byPortByOrdinal[portNumber] || {};\n const lastStatus = ff.timestamp;\n\n let deviceStatus = [];\n\n // Always bias to choosing the FF with the latest status report for a\n // given ordinal position (i.e. if a unit has been replaced, always put\n // the \"new\" unit at this position)\n if (\n !portByOrdinal[position] //|| lastStatus > fireflies[portByOrdinal[position]].lastStatus\n ) {\n portByOrdinal[position] = ff.id;\n // store this ff topology info for later port-oriented processing\n byPortByOrdinal[portNumber] = portByOrdinal;\n }\n\n const latLng = tempCoordsProvider.firefly(portNumber, position);\n const ffCoord = getFireflyCoordinatesById(state, ff.id);\n\n // [0,0] if deleted or new\n const isSomeZero =\n ffCoord === undefined ? true : ffCoord.some((item) => item === 0);\n\n if (isSomeZero) deviceStatus.push(StatusEnum.NOT_COMMISSIONED);\n\n const ffPosition = {\n // draw functions hereon use [lng, lat] so swap coordinates\n lat: !isSomeZero ? ffCoord[1] : latLng.lat,\n lng: !isSomeZero ? ffCoord[0] : latLng.lng,\n mineLevelId: ff.topology.area,\n };\n\n let originalCommissioning = null;\n if (true) {\n // if (ff.created) {\n originalCommissioning = {\n topology: ff.topology,\n position: ffPosition,\n };\n }\n\n fireflies[ff.id] = {\n id: ff.id,\n topology: { ...topo, deviceStatus },\n position: ffPosition, //latLng,\n lastStatus,\n originalCommissioning,\n };\n });\n\n const emergencyEventSettings = getControllerEmergencyEventSettingsById(\n state,\n id\n );\n const isEmergencyEventSettings =\n emergencyEventSettings?.enable && !isIgnoreEmergencyTriggerEvents;\n\n const triggerEventSettings = getControllerTriggerEventSettingsById(state, id);\n const isTriggerEventSettings =\n triggerEventSettings?.enable && !isIgnoreEmergencyTriggerEvents;\n\n const defaultPortSettings = (id) => {\n return {\n id: id,\n enable: false,\n brightness: 0,\n color: \"green\",\n led_state: \"on\",\n on_time: 10,\n off_time: 10,\n train: 1,\n };\n };\n\n const ports = Object.keys(byPortByOrdinal)\n .sort()\n .map((portNumber) => {\n const portByOrdinal = byPortByOrdinal[portNumber];\n\n return {\n portNumber,\n positionMode: \"asIndividuals\", //\"asString\",\n emergencyEventSettings:\n emergencyEventSettings?.ports?.find(\n (port) => port?.id === Number.parseInt(portNumber, 10)\n ) || defaultPortSettings(Number.parseInt(portNumber, 10)),\n triggerEventSettings:\n triggerEventSettings?.ports?.find(\n (port) => port?.id === Number.parseInt(portNumber, 10)\n ) || defaultPortSettings(Number.parseInt(portNumber, 10)),\n fireflies: sortBy(Object.keys(portByOrdinal), (i) =>\n Number.parseInt(i, 10)\n )?.map((ordinal) => portByOrdinal[ordinal]),\n };\n });\n\n return {\n areaError:\n area === undefined\n ? { error: true, id: mineLevelId }\n : { error: false, id: mineLevelId },\n ups: selector(state, \"ups\") || { position: {} },\n ports: selector(state, \"ports\"),\n fireflies: selector(state, \"fireflies\"),\n isEmergencyEventSettings: selector(state, \"isEmergencyEventSettings\"),\n isTriggerEventSettings: selector(state, \"isTriggerEventSettings\"),\n isIgnoreEmergencyTriggerEvents,\n initialValues: {\n _action: \"\", // used to control dlg display\n ups,\n ports,\n fireflies,\n isEmergencyEventSettings,\n isTriggerEventSettings,\n },\n transformPixelsToUtm,\n //\n isDeleteButton:\n mineLevelId !== undefined &&\n !deviceStatus?.includes(StatusEnum.NOT_COMMISSIONED),\n userSettings: getUserSettings(state) || {},\n\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"upsBulkPositioningForm onChange values\", values);\n // console.log(\"UPSBulkPositioningForm bulkPos onChange props\", props);\n // console.log(\n // \"ggg UPSBulkPositioningForm bulkPos onChange isEmergencyEventSettings\",\n // JSON.stringify(values.isEmergencyEventSettings)\n // );\n // console.log(\n // \"ggg UPSBulkPositioningForm bulkPos onChange isTriggerEventSettings\",\n // JSON.stringify(values.isTriggerEventSettings)\n // );\n // values.ports.forEach((port, idx) => {\n // console.log(\n // \"UPSBulkPositioningForm bulkPos onChange ports emergencyEventSettings\",\n // idx,\n // JSON.stringify(port.emergencyEventSettings)\n // );\n // console.log(\n // \"UPSBulkPositioningForm bulkPos onChange ports triggerEventSettings\",\n // idx,\n // JSON.stringify(port.triggerEventSettings)\n // );\n // });\n // console.log(\n // \"UPSBulkPositioningForm bulkPos onChange initialValues\",\n // props.initialValues\n // );\n // #REVIEW\n // #NOTE - this code is unnecessary as in v3 the mine level\n // i.e. area, can not be changed for a UPS in the web UI. Only in controller setup itself.\n //\n // Leaving code here for reference.......\n //\n // const newUps = values.ups;\n // const prevUps = previousValues.ups;\n // const mineLevelChanged =\n // newUps.position.mineLevelId !== prevUps.position.mineLevelId;\n // if (mineLevelChanged) {\n // let {\n // initialValues: { ups, fireflies },\n // } = props;\n // let { mineLevelId, lat, lng } = ups.position || {};\n // const newProvider = temporaryCoordsFactory.ForMineLevelId(\n // newUps.position.mineLevelId\n // );\n // const upsOnNewLevel = newUps.position.mineLevelId !== mineLevelId;\n // const newPositions = [];\n // function addUpdate(fieldName, coords) {\n // const { lat, lng } = coords;\n // const formname = \"upsBulkPositioningForm\";\n // newPositions.push(\n // unboundChange(formname, `${fieldName}.position.lat`, lat)\n // );\n // newPositions.push(\n // unboundChange(formname, `${fieldName}.position.lng`, lng)\n // );\n // }\n // addUpdate(\"ups\", upsOnNewLevel ? newProvider.ups() : { lat, lng });\n // Object.keys(values.fireflies).forEach((id) => {\n // const ff = values.fireflies[id];\n // addUpdate(\n // `fireflies.${id}`,\n // upsOnNewLevel\n // ? newProvider.firefly(\n // ff.topology.portNumber,\n // ff.topology.position\n // )\n // : fireflies[id].position\n // );\n // });\n // console.log(\"mine level changed!, sending new positions\", newPositions);\n // dispatch(newPositions);\n // }\n },\n };\n};\n\n// UPSBulkPositioningForm = connect(mapStateToProps, { savePositions, push })(\n// UPSBulkPositioningForm\n// );\n\nUPSBulkPositioningForm = connect(\n mapStateToProps,\n mapDispatchToProps\n)(UPSBulkPositioningForm);\n\nexport default UPSBulkPositioningForm;\n","import React, { Component } from \"react\";\nimport { push } from \"react-router-redux\";\n\nimport PropTypes from \"prop-types\";\n\nimport { Container, Header, Grid, Message, List } from \"semantic-ui-react\";\n\nimport { connect } from \"react-redux\";\n\nimport { getControllerById } from \"components/WebWorker/reducer\";\n\nimport UPSBulkPositioningForm from \"admin/bulk-positioning/UPSBulkEditPage/UPSBulkPositioningForm\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nclass UPSDetail extends Component {\n static propTypes = {\n ups: PropTypes.object,\n error: PropTypes.string,\n };\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n render() {\n const { id, error, strings } = this.props;\n\n // #WIP - ATM don't allow reload, or direct link to a controller page.....\n // Instead redirect to the controller list page and wait for controller to list (with next message).\n\n if (error) {\n this.props.goto(\"/admin/controller/\");\n return null;\n // return (\n // <>\n // \n // \n // \n // );\n }\n\n return (\n
\n \n \n \n \n
\n {strings?.[\"Header_Controller_BulkPosition\"]}\n
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n
\n
\n );\n }\n}\n\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n goto: (path) => dispatch(push(path)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n };\n};\n\nconst mapStateToProps = (state, props) => {\n const match = props.match;\n const id = match.params.id;\n\n const ups = getControllerById(state, id);\n\n return {\n id,\n error: ups ? undefined : \"No Controller for id\",\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UPSDetail);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Header,\n Grid,\n Table,\n Container,\n Input,\n Pagination,\n Dropdown,\n Icon,\n Segment,\n Button,\n Checkbox,\n Item,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport {\n fetchUPSs,\n //fetchFireflys,\n deleteUPS,\n} from \"UPSPanelControllers/actions\";\n\nimport {\n getAllControllerStatuses,\n getAllFireflyStatuses,\n} from \"components/WebWorker/reducer\";\n\nimport UPSLink from \"./UPSLink\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\nimport { formatRelative, parseISO } from \"date-fns\";\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport {\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nimport { StatusEnum } from \"utils/StatusEnum\";\n\nimport { Download } from \"components/Download\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nconst displayOptions = [\n {\n key: \"all\",\n text: \"Show all\",\n value: \"all\",\n },\n {\n key: \"ok\",\n text: \"OK\",\n value: \"ok\",\n },\n {\n key: \"commissioned\",\n text: \"New\",\n value: \"commissioned\",\n },\n {\n key: \"old\",\n text: \"No status report\",\n value: \"old\",\n },\n];\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass UPSList extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n controller: { string: \"\", include: true },\n area: { string: \"\", include: true },\n status: { string: \"\", include: true },\n location: { string: \"\", include: true },\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox delete selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n\n // default for radio button group\n statusGroup: \"all\",\n };\n }\n\n componentDidMount() {\n const {\n //\n componentstate,\n } = this.props;\n\n const filterInput = componentstate.get(\"filterInput\", \"controllerList\");\n\n //console.log(\"filterInput componentDidMount\", filterInput);\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n\n this.setState({ filterInput: filterInput });\n\n // reset the radio button states\n //\n const filterInputStatusString = filterInput?.status?.string;\n switch (filterInputStatusString) {\n case \"\":\n this.setState({ statusGroup: \"all\" });\n break;\n case \"ok\":\n this.setState({ statusGroup: \"ok\" });\n break;\n case \"Notcommissioned\":\n this.setState({ statusGroup: \"commissioned\" });\n break;\n case \"Nostatusreport\":\n this.setState({ statusGroup: \"old\" });\n break;\n default:\n break;\n }\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"controllerList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { data: dataRx } = this.props;\n const { data: prevDataRx } = prevProps;\n\n // compare new and prev data *ignoring* these:\n // controllerBulkPosLink,\n // controllerIpLink,\n // controllerLink,\n // timestamp,\n\n const data = dataRx.map(\n ({\n controllerBulkPosLink,\n controllerIpLink,\n controllerLink,\n timestamp,\n ...theRest\n }) => {\n return { ...theRest };\n }\n );\n\n const prevData = prevDataRx.map(\n ({\n controllerBulkPosLink,\n controllerIpLink,\n controllerLink,\n timestamp,\n ...theRest\n }) => {\n return { ...theRest };\n }\n );\n\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(data) !== JSON.stringify(prevData) // compare subset of data\n ) {\n let newData = dataRx; // original data - full data set is in dataRx\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n const checkItemString = item[key]?.toLowerCase()?.replace(/\\s/g, \"\"); // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n const checkMatchString = match[key]?.string?.toLowerCase();\n const checkIncludes =\n checkMatchString !== \"\" // remove item which don't match, but exclude \"\" empty case\n ? match[key].include && checkItemString.includes(checkMatchString) //'.include' = true for include, = false for exclude\n : true;\n\n checkMatch = checkMatch && checkIncludes;\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n // handleFilterStatusChange = ({ checked, value }) => { // <<--- for radio buttons\n handleFilterStatusChange = (e, data) => {\n this.setState({ statusGroup: data.value });\n\n let search = \"\";\n\n switch (data.value) {\n case \"ok\":\n search = \"ok\";\n break;\n case \"commissioned\":\n search = \"Not commissioned\";\n break;\n case \"old\":\n search = \"No status report\";\n break;\n case \"all\":\n default:\n search = \"\";\n break;\n }\n this.setFilterState({ name: \"status\", value: search }, true);\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n this.setFilterState(target, true);\n };\n\n setFilterState = ({ name, value }, include) => {\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n // update match value with most recent filter entry\n match[name].string = value.replace(/\\s/g, \"\");\n match[name].include = include;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n console.log(\"xxx upslist handleSelect id\", id);\n this.setState(\n (prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n }\n //() => console.log(\"xxx this.state.selections\", this.state.selections)\n );\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n requestAction = (action) => {\n const { selections } = this.state;\n const { deleteUPS } = this.props;\n\n let promiseArray = [];\n\n for (var selection in selections) {\n console.log(\"deleting Controller ... \", selection);\n promiseArray.push(\n // eslint-disable-next-line no-loop-func\n new Promise((resolve, reject) => {\n deleteUPS({ values: { id: selection }, resolve, reject });\n })\n );\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"DELETING CONTROLLERS: \", results);\n })\n .then(\n () => {\n this.props.goto(\"/admin/controller/\");\n },\n (msg) => {\n console.log(\"delete failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.{\" \"}\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const controllerFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let deleteButton;\n let controllerDeleteList;\n if (selectedCount > 0) {\n let controllerNames = [];\n for (var key in selections) {\n if (controllerFromDataById(key) !== undefined) {\n let controllerName = controllerFromDataById(key).controller;\n controllerNames.push(controllerName);\n }\n }\n controllerNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n controllerNames = controllerNames.join(\", \"); // separate by commas\n\n deleteButton = (\n this.requestAction(\"delete\")}\n strings={strings}\n />\n );\n\n controllerDeleteList = (\n \n Controllers selected ... \n {controllerNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
\n {strings?.[\"Header_Controller_BulkPosition\"]}\n
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n {!areAnySelected && (\n \n {viewablesPage.length} items displayed. Select items in the\n table below to apply an action.\n \n )}\n \n \n \n \n {deleteButton}\n \n
\n \n {viewablesPage.length} items displayed. {selectedCount}{\" \"}\n selected.\n \n
\n \n
\n \n {controllerDeleteList}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* */}\n \n \n \n \n \n this.handleFilterStatusChange(data)}\n />\n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strings?.[\"Controller\"]}\n \n \n {strings?.[\"Controller URL\"]}\n \n {/* Bulk Position */}\n \n {strings?.[\"Area\"]}\n \n \n {strings?.[\"Location\"]}\n \n \n {strings?.[\"Master\"]}\n \n \n {strings?.[\"Version\"]}\n \n \n {strings?.[\"DC Supply Voltage\"]}\n \n \n {strings?.[\"Battery Voltage\"]}\n \n \n {strings?.[\"Disk Used\"]}\n \n \n {strings?.[\"Memory Used\"]}\n \n \n {strings?.[\"User Relay\"]}\n \n \n {strings?.[\"Latest Report\"]}\n \n \n {strings?.[\"Status\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n controllerLink,\n controllerIp,\n controllerIpLink,\n controllerBulkPosLink,\n area,\n location,\n master,\n masterIcon,\n version,\n batteryVoltage,\n dcVoltage,\n diskUsed,\n memUsed,\n userRelay,\n lastStatusReport,\n status,\n disableDelete,\n style,\n }) => (\n \n \n this.handleSelect(id)}\n disabled={disableDelete}\n />\n \n {controllerLink}\n {controllerIpLink}\n {/* {controllerBulkPosLink} */}\n {area}\n {location}\n {masterIcon}\n {version}\n {dcVoltage}\n {batteryVoltage}\n {diskUsed}\n {memUsed}\n {userRelay}\n {lastStatusReport}\n {status || \"-\"}\n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst getStatus = (controller, controllers, allFireflyStatuses) => {\n const { id, timestamp, topology } = controller;\n\n //console.log(`getStatus controller`, controller);\n\n const controllerFireflies = allFireflyStatuses?.filter(\n (ff) => ff?.topology?.ups_id === id\n );\n\n // ... has it been commissioned?\n let isControllerCommissioned = true;\n let isControllerAllFireflysCommissioned = true;\n\n if (\n topology &&\n topology?.deviceStatus?.includes(StatusEnum.NOT_COMMISSIONED)\n ) {\n isControllerCommissioned = false;\n return {\n value: StatusEnum.NOT_COMMISSIONED,\n message: \"New Controller - Not commissioned\",\n };\n }\n\n // check for uncommissioned FFs connected to this controller.\n // Only do this check if the controller itself is commissioned.\n if (isControllerCommissioned && controllerFireflies) {\n isControllerAllFireflysCommissioned = !controllerFireflies.some(\n (ff) =>\n ff?.topology?.ups_id === id &&\n ff?.topology?.deviceStatus?.includes(StatusEnum.NOT_COMMISSIONED)\n );\n }\n\n if (!isControllerAllFireflysCommissioned) {\n return {\n value: StatusEnum.NOT_COMMISSIONED,\n message: \"New Firefly - Not commissioned\",\n };\n }\n\n // ... OK!\n return { value: StatusEnum.OK, message: \"Ok\" };\n};\n\nconst _prepData = (elements, role, allFireflyStatuses) => {\n const { allowAdmin } = role;\n let filteredElements = [];\n\n // only need a subset of data\n elements.forEach(function (element, idx) {\n const { id, topology } = element;\n const { network_name: name, area, location: locations } = topology;\n\n let master = \"-\";\n let masterIcon = \"-\";\n if (typeof element?.topology?.master === \"boolean\") {\n // checks exists and type since undefined !== boolean\n master = element.topology.master;\n if (master) masterIcon = ;\n }\n\n let controllerIpLink = \"-\";\n const controllerIp = element?.topology?.ip; // \"10.208.26.140\";\n if (controllerIp !== undefined) {\n controllerIpLink = controllerIpLink ? (\n \n {controllerIp}\n \n ) : (\n \"\"\n );\n }\n\n const controllerSoftVersion = element?.system?.sw_ver || \"-\";\n const batteryVoltage = element?.electrical?.battery?.voltage || \"-\";\n const dcVoltage = element?.electrical?.dc_supply?.voltage || \"-\";\n const diskUsed = element?.system?.disk?.replace(\"%\", \"\") || \"-\";\n const memUsed = element?.system?.mem?.replace(\"%\", \"\") || \"-\";\n const userRelay = element?.system?.user_relay || \"-\";\n\n // break down lastStatusReport as it may not be defined in object\n let lastStatusReport = \"-\";\n let timestamp = element?.timestamp;\n if (timestamp != undefined) {\n // format - previous used in tableformatters.js\n lastStatusReport = formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n });\n }\n\n // split up location array\n let newLocations = \"-\";\n if (Array.isArray(locations)) {\n locations.forEach(function (position, idx) {\n if (idx === 0) {\n newLocations = position;\n } else {\n newLocations = newLocations + \", \" + position;\n }\n });\n }\n\n const controllerUpsId = (name !== \"\" ? name : \"-\") + \" (\" + id + \")\";\n\n // styling for rows for highlight or error states\n //\n const elementStatus = getStatus(element, elements, allFireflyStatuses);\n const { value, message } = elementStatus;\n let style = null;\n let icon = \"check\";\n let color = \"green\";\n if (value !== StatusEnum.OK) {\n icon = \"warning sign\";\n const props = StatusEnum.properties[value];\n const { warning = false, error = false } = props;\n color = (error && \"red\") || (warning && \"yellow\") || \"blue\";\n style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n }\n if (value === StatusEnum.NOT_COMMISSIONED) {\n style = { backgroundColor: \"rgb(255, 255, 0, 15%)\" };\n }\n\n const status = message;\n\n // disable delete - provision for, but not used ATM\n const disableDelete = false;\n\n // fault red background\n if (batteryVoltage < 20 || dcVoltage < 20 || diskUsed > 90) {\n style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n }\n\n const controllerLink = allowAdmin ? (\n {`${name || \"\"} (${id})`}\n ) : (\n `${name || \"\"} (${id})`\n );\n\n // compose new data set\n filteredElements[idx] = {\n id: id,\n controller: controllerUpsId,\n controllerLink: controllerLink,\n area: area,\n controllerIp: `${controllerIp}`,\n controllerIpLink: controllerIpLink,\n controllerBulkPosLink: (\n \n {name} ({id})\n \n ),\n location: newLocations,\n master: master ? `${master}` : \"-\",\n masterIcon: masterIcon,\n version: controllerSoftVersion,\n diskUsed: diskUsed !== \"-\" ? `${diskUsed}%` : diskUsed,\n memUsed: memUsed !== \"-\" ? `${memUsed}%` : memUsed,\n batteryVoltage:\n batteryVoltage !== \"-\" ? `${batteryVoltage}v` : batteryVoltage,\n dcVoltage: dcVoltage !== \"-\" ? `${dcVoltage}v` : dcVoltage,\n userRelay: `${userRelay}`,\n note: \"note\", // #TODO - add support for notes in controllers\n lastStatusReport: lastStatusReport,\n status: status,\n statusValue: value,\n disableDelete: disableDelete,\n style,\n // Raw data for download report\n ups_name: name,\n ups_id: id,\n timestamp,\n };\n });\n\n return filteredElements;\n};\n\nfunction mapStateToProps(state) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n // const { isLoading, error } = state.ups;\n const isLoading = false;\n const error = false;\n\n // #REVIEW\n // this is a hack to get the mineLevel name - should be in the UPS message?!\n const { mineLevels } = state;\n const { byId: mineLevelsbyId } = mineLevels;\n\n // user roles\n const userSuper = isUserSuper(state);\n const userAdmin = isUserAdmin(state);\n const userUser = isUserUser(state);\n const userGuest = isUserGuest(state);\n const allowGuest = userGuest;\n\n const allowOperator = userSuper || userAdmin || userUser;\n const allowAdmin = userSuper || userAdmin;\n const allowSuper = userSuper;\n\n // all fireflies\n\n const allFireflyStatuses = getAllFireflyStatuses(state);\n\n const data = _prepData(\n getAllControllerStatuses(state),\n {\n allowGuest: allowGuest,\n allowOperator: allowOperator,\n allowAdmin: allowAdmin,\n allowSuper: allowSuper,\n },\n allFireflyStatuses\n );\n\n return {\n isLoading,\n error,\n data,\n };\n}\n\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n deleteUPS: (data) => dispatch(deleteUPS(data)),\n fetchUPSs: () => dispatch(fetchUPSs()),\n saveUserSettingsComponentState: (data) =>\n dispatch(saveUserSettingsComponentState(data)),\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, mapDispatchToProps)(UPSList)\n);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\n\nimport UPSBulkEditPage from \"admin/bulk-positioning/UPSBulkEditPage\";\n\nimport { fetchUPSs } from \"UPSPanelControllers/actions\";\n\n// #REVIEW - redirect back to UPS list page if link not valid instead of *unsupported bulk positioning list*\n//import BulkPositioningList from './BulkPositioningList'\nimport UPSList from \"admin/ups/UPSList\";\n\nclass BulkPositioningAdminPages extends Component {\n render() {\n const { match, strings } = this.props;\n\n return (\n \n }\n />\n {/* */}\n {/* */}\n }\n />\n \n );\n }\n}\n\nexport default withRouter(\n connect(null, { fetchUPSs })(BulkPositioningAdminPages)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Segment,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\n\nimport _ from \"lodash\";\n\nimport { fetchMineLevels } from \"MineLevels/actions\";\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\n//import { isBoomgateCrane } from \"components/ConfigJs\";\n\nclass ListNamedAreaGroups extends Component {\n constructor(props) {\n super(props);\n this.state = {\n column: null,\n data: props.data,\n direction: null,\n language: \"en-US\", // localisation\n };\n }\n\n componentDidMount() {\n //const { data, fetchMineLevels, fetchNamedAreas } = this.props;\n // if (_isEmpty(data)) {\n // // #FETCHS\n // fetchMineLevels(); // #FETCHS\n // fetchNamedAreas();\n // }\n }\n\n componentWillReceiveProps(nextProps) {\n const { data } = this.props;\n\n if (data !== nextProps.data) {\n let newData = nextProps.data;\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n render() {\n const { isLoading, error, strings } = this.props;\n const { column, data, direction } = this.state;\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n // APP_TERMINOLOGY\n const strNamedAreaGroups = strings?.[\"Lighting Control Layouts\"];\n const strArea = strings?.[\"Control Layout for Area\"];\n\n return (\n
\n \n \n \n \n
{strNamedAreaGroups}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {false && (\n \n \n
\n );\n }\n}\n\nconst _prepData = (elements) => {\n let filteredElements = [];\n\n elements.forEach(function (element, idx) {\n const {\n id,\n name,\n image_filename,\n floor,\n ceiling,\n default_color,\n default_state,\n } = element;\n\n if (!id?.includes(\"defaultArea\")) {\n // compose new data set\n filteredElements[idx] = {\n id: id,\n name: id.replaceAll(\"_\", \" \"),\n };\n }\n });\n return filteredElements;\n};\n\nfunction mapStateToProps(state) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.mineLevels;\n\n const isLoading = false;\n const error = false;\n\n const data = _prepData(getAllAreaStatuses(state));\n\n return {\n isLoading,\n error,\n data,\n };\n}\n\nexport default connect(mapStateToProps, {\n fetchMineLevels,\n fetchNamedAreas,\n})(ListNamedAreaGroups);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\n//import CreateMineLevelForm from \"./MineLevelCreateForm\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport {\n SubmissionError,\n //\n getFormValues,\n getFormInitialValues,\n getFormSyncErrors,\n getFormMeta,\n getFormAsyncErrors,\n getFormSyncWarnings,\n getFormSubmitErrors,\n getFormError,\n getFormNames,\n isDirty,\n isPristine,\n isValid,\n isInvalid,\n isSubmitting,\n hasSubmitSucceeded,\n hasSubmitFailed,\n} from \"redux-form\";\n\nimport { Dimmer, Loader } from \"semantic-ui-react\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nclass CreateNamedAreaGroups extends Component {\n state = {\n errorMessage: \"\",\n };\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n submitMyForm = (values) => {\n const { saveNewMineLevel } = this.props;\n\n return new Promise((resolve, reject) => {\n //console.log(\"values\", values);\n saveNewMineLevel({ values, resolve, reject });\n }).catch((error) => {\n console.log(`onSubmit error`, error);\n this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const { saveNewMineLevel, submitting, strings } = this.props;\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n // #NOTE-\n // #WIP - structure for a create named area group.\n // Incomplete.\n\n return (\n <>\n {/* this.onResetError()}\n errorMessage={errorMessage}\n />\n \n Saving changes\n \n this.submitMyForm(formValues)}\n />\n {\n return new Promise((resolve, reject) => {\n //console.log(\"values\", values);\n saveNewMineLevel({ values, resolve, reject });\n }).catch((error) => {\n console.log(`onSubmit ${error}`);\n this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n }}\n onSubmitSuccess={(result, dispatch) => {\n console.log(`onSubmitSuccess ${result}`);\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n this.onResetError();\n this.props.goto(\"/admin/named-area-group\");\n }\n );\n }}\n onSubmitFail={(errors) => {\n console.log(`onSubmitFail ${errors}`);\n }}\n onCancel={() => {\n this.props.goto(\"/admin/named-area-group\");\n }}\n /> */}\n \n );\n }\n}\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n // saveNewMineLevel: (data) => dispatch(saveNewMineLevel(data)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n };\n};\n\nexport default connect(\n (state) => ({\n //submitting: isSubmitting(\"createNewNamedAreaGroupForm\")(state),\n }),\n mapDispatchToProps\n)(CreateNamedAreaGroups);\n","import React from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { DragDropContext, Droppable, Draggable } from \"react-beautiful-dnd\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport { Table, Ref, Grid, Icon, Popup } from \"semantic-ui-react\";\n\nimport { getAllNamedAreaStatuses } from \"components/WebWorker/reducer\";\nimport { isKthBitSet } from \"utils/bit-operations\";\n\nimport { eventTriggerOptions as _eventTriggerOptions } from \"components/ConfigJs\";\n\nconst getItemStyle = (highlightColor, color, isDragging, draggableStyle) => ({\n // some basic styles to make the items look a bit nicer\n userSelect: \"none\",\n\n // change background colour if dragging\n background: isDragging ? highlightColor : color,\n\n // styles we need to apply on draggables\n ...draggableStyle,\n});\n\nconst getListStyle = (color, isDraggingOver) => ({\n background: isDraggingOver ? color : \"white\",\n});\n\nclass NamedAreaGroupTableSubSubItems extends React.Component {\n onClickHandler = (e, type, id, groupId) => {\n //console.log(\"onClickHandler e\", e);\n\n e.preventDefault();\n e.stopPropagation(); // stop submit to calling form\n\n //console.log(\"onClickHandler type:\", type, \" id:\", id, \" group:\", groupId);\n switch (type) {\n case \"deleteItem\":\n this.props.onClickHandler(e, \"deleteItem\", id, groupId, null);\n break;\n case \"cog\":\n this.props.onClickHandler(e, \"cog\", id, groupId, null);\n break;\n default:\n break;\n }\n //console.log(\"onClickHandler props\", id, groupId, type);\n };\n\n render() {\n const { namedAreas, groupId, NAMEDAREAS, strings, userSettings } =\n this.props;\n\n const eventTriggerOptions = _eventTriggerOptions(userSettings);\n\n // APP_TERMINOLOGY\n const strNamedAreas = strings?.[\"Polygons\"];\n\n return (\n \n \n \n \n {(provided, snapshot) => (\n \n \n {this.props.items.length ? (\n this.props.items.map((item, index) => {\n //\n\n // #WIP - this is unecessary a level will define attributes of the buttons\n // Used for debugging to check if buttons are defined in namedAreas\n //\n const priority = item?.namedArea?.button?.priority;\n const namedArea = namedAreas.find(\n (na) => na.parent === item.namedArea.id\n );\n let buttonProps;\n if (priority === undefined) {\n buttonProps = {\n color: \"????\",\n title: `Error: Priority not defined in button`,\n };\n } else {\n //console.log(\"namedAreaButtons namedArea\", namedArea);\n const namedAreaButtons = namedArea?.button;\n //console.log(\"namedAreaButtons\", namedAreaButtons);\n if (namedAreaButtons !== undefined) {\n buttonProps = namedAreaButtons.find(\n (button) => button.priority === priority\n );\n if (buttonProps === undefined) {\n buttonProps = {\n color: \"????\",\n title: `Error: No Button defined for priority ${priority}`,\n };\n }\n } else {\n buttonProps = {\n color: \"????\",\n title: `Error: No Buttons defined for the named area`,\n };\n }\n }\n\n const { title, color } = buttonProps;\n\n return (\n \n {(provided, snapshot) => (\n \n <>\n moved to \n isDragging={snapshot.isDragging}\n style={getItemStyle(\n \"rgba(144,238,144,1)\",\n //\"lightgreen\",\n \"rgba(144,238,144,0.2)\",\n snapshot.isDragging,\n provided.draggableProps.style\n )}\n >\n \n \n }\n />\n {eventTriggerOptions.map((option) => {\n const bitCheck = isKthBitSet(\n item?.settings?.permission,\n option.key\n );\n return (\n bitCheck && (\n \n )\n );\n })}\n\n {`${\n NAMEDAREAS.find(\n (na) =>\n na.namedArea.id ===\n item.namedArea.id\n )?.label\n }`}\n \n {item?.settings?.title\n ? `Custom label: \"${item.settings.title}\"`\n : ``}\n \n {/* {` id : ${item.namedArea.id} - label : ${\n NAMEDAREAS.find(\n (na) =>\n na.namedArea.id ===\n item.namedArea.id\n )?.label\n }`} */}\n {/* {item.label} - {title} - {color} -\n {`Priority ${priority}`} */}\n {/* {` id: ${item.id}`}\n {` draggingOver: ${snapshot.draggingOver}`}\n {` isDragging: ${snapshot.isDragging}`} */}\n \n \n \n this.onClickHandler(\n e,\n \"cog\",\n item.id,\n index\n )\n }\n />\n }\n />\n \n \n \n this.onClickHandler(\n e,\n \"deleteItem\", // type\n item.id, // id\n groupId // index\n )\n }\n />\n }\n />\n \n \n \n \n )}\n \n );\n })\n ) : (\n \n \n {\n strings?.[\n `Drag and drop Polygons here. Configure light states after adding Polygons.`\n ]\n }\n {provided.placeholder}\n \n \n )}\n {!_isEmpty(provided.placeholder) &&\n snapshot.isDraggingOver && (\n \n \n {provided.placeholder}\n \n \n )}\n \n \n )}\n \n
\n
\n
\n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const namedAreas = getAllNamedAreaStatuses(state);\n\n return {\n namedAreas,\n };\n}\n\nexport default connect(mapStateToProps, null)(NamedAreaGroupTableSubSubItems);\n","import React from \"react\";\nimport { DragDropContext, Droppable, Draggable } from \"react-beautiful-dnd\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport { Table, Ref, Grid, Icon, Popup } from \"semantic-ui-react\";\n\nimport NamedAreaGroupTableSubSubItems from \"./NamedAreaGroupTableSubSubItems\";\n\nimport { toWebColor } from \"utils/toWebColor\";\n\nimport \"admin/named-area-group/NamedAreaGroup.css\";\n\nimport { makeIcon, RenderSvgIcon } from \"components/Map/MakeIcon\";\n\nconst getItemStyle = (highlightColor, color, isDragging, draggableStyle) => ({\n // some basic styles to make the items look a bit nicer\n userSelect: \"none\",\n\n // change background colour if dragging\n background: isDragging ? highlightColor : color,\n\n // styles we need to apply on draggables\n ...draggableStyle,\n});\n\nconst getListStyle = (color, isDraggingOver) => ({\n background: isDraggingOver ? color : \"white\",\n});\n\nexport default class NamedAreaGroupTableSubItems extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n collapse: [],\n collapseAll: false,\n };\n }\n\n componentDidMount = () => {\n // // collapse all sections on startup\n // const groupIds = this.props.items.map((item) => item.id);\n // this.setState({ collapse: groupIds });\n // this.setState({ collapseAll: this.state.collapseAll });\n };\n\n componentDidUpdate(prevProps, prevState) {\n if (prevProps.collapseAll !== this.props.collapseAll) {\n if (this.props.collapseAll) {\n const groupIds = this.props.items.map((item) => item.id);\n this.setState({ collapse: groupIds });\n //this.setState({ collapseAll: this.state.collapseAll });\n } else {\n this.setState({ collapse: [] });\n //this.setState({ collapseAll: this.state.collapseAll });\n }\n }\n }\n\n onClickHandler = (e, type, id, groupId, data) => {\n //console.log(\"onClickHandler e\", e);\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n\n if (e.stopPropagation) {\n e.stopPropagation(); // stop submit to calling form\n }\n\n let newCollapse = this.state.collapse;\n let newCollapseAll = this.state.collapseAll;\n\n switch (type) {\n case \"deleteItem\":\n this.props.onClickHandler(e, \"deleteItem\", id, groupId, null);\n break;\n\n case \"collapse\":\n if (newCollapse.includes(id)) {\n newCollapse = newCollapse.filter((item) => item !== id);\n } else {\n newCollapse.push(id);\n }\n this.setState({ collapse: newCollapse });\n break;\n case \"cog\":\n this.props.onClickHandler(e, \"cog\", id, groupId, null);\n break;\n\n default:\n break;\n }\n };\n\n render() {\n const { items, NAMEDAREAS, groupId, strings, userSettings } = this.props;\n\n return (\n \n \n \n \n {(provided, snapshot) => (\n \n \n {items?.length ? (\n items?.map?.((item, index) => (\n \n {(provided, snapshot) => (\n \n <>\n moved to \n isDragging={snapshot.isDragging}\n style={getItemStyle(\n \"rgba(173,216,230,1)\",\n //\"lightblue\",\n \"rgba(173,216,230,0.2)\",\n snapshot.isDragging,\n provided.draggableProps.style\n )}\n >\n \n \n this.onClickHandler(\n e,\n \"collapse\", // type\n item.id, // id\n groupId, // index\n null\n )\n }\n />\n }\n />\n \n \n \n }\n />\n {/* */}\n \n {item.label}\n {/* {` id: ${item.id}`}\n {` draggingOver: ${snapshot.draggingOver}`}\n {` isDragging: ${snapshot.isDragging}`} */}\n \n \n \n this.onClickHandler(\n e,\n \"cog\",\n item.id,\n groupId,\n null\n )\n }\n />\n }\n />\n \n \n \n this.onClickHandler(\n e,\n \"deleteItem\", // type\n item.id, // id\n groupId, // index\n null\n )\n }\n />\n }\n />\n \n \n {!this.state.collapse.includes(item.id) &&\n !snapshot?.isDragging && (\n \n \n \n this.onClickHandler(\n e,\n type,\n id,\n index,\n data\n )\n }\n strings={strings}\n userSettings={userSettings}\n />\n \n \n )}\n \n \n )}\n \n ))\n ) : (\n \n \n {strings?.[\"No Levels. Add a level\"]}{\" \"}\n {provided.placeholder}\n \n \n )}\n {!_isEmpty(provided.placeholder) &&\n snapshot.isDraggingOver && (\n \n \n {provided.placeholder}\n \n \n )}\n \n \n )}\n \n
\n
\n
\n );\n }\n}\n","export const normalise = (value, type = \"integer\") => {\n switch (type) {\n case \"stringNoSpace\":\n return value.replace(\" \", \"_\");\n case \"integer\":\n return (value && Number(value)) || 0;\n case \"float\":\n //\tsee - onlyDecimal\n return value;\n case \"char\":\n return (\n (value.match(/^[A-Za-z]+$/) &&\n value.toString().toUpperCase().slice(0, 1)) ||\n \"\"\n );\n default:\n return value;\n }\n};\n\n// see - https://github.com/redux-form/redux-form/issues/1218\n\nexport const onlyDecimal = (value) => {\n let result;\n\n value = value.replace(/[^0-9.]/g, \"\"); // Remove all chars except numbers and .\n\n // Create an array with sections split by .\n const sections = value.split(\".\");\n\n // Remove any leading 0s apart from single 0\n if (sections[0] !== \"0\" && sections[0] !== \"00\") {\n sections[0] = sections[0].replace(/^0+/, \"\");\n } else {\n sections[0] = \"0\";\n }\n\n // If numbers exist after first .\n if (sections[1]) {\n // Join first two sections and truncate end section to length 2\n result = sections[0] + \".\" + sections[1].slice(0, 2);\n\n // If original value had a decimal place at the end, add it back\n } else if (value.indexOf(\".\") !== -1) {\n result = sections[0] + \".\";\n\n // Otherwise, return only section\n } else {\n result = sections[0];\n }\n\n //console.log(`xxxx result`, result);\n return result;\n};\n\n// ----------------------------------------------------------------------\n// Validation function for want a better place to put ThemeProvider\n// ----------------------------------------------------------------------\n// see - https://redux-form.com/7.0.4/examples/fieldlevelvalidation/\n//\nexport const required = (value) => (value ? undefined : \"Required\");\nexport const maxLength = (max) => (value) =>\n value && value.length > max ? `Must be ${max} characters or less` : undefined;\n//e.g. const maxLength15 = maxLength(15)\nexport const minLength = (min) => (value) =>\n value && value.length < min ? `Must be ${min} characters or more` : undefined;\n// e.g. const minLength2 = minLength(2)\nexport const number = (value) =>\n value && isNaN(Number(value)) ? \"Must be a number\" : undefined;\nexport const minValueEqual = (min) => (value) =>\n value && value < min ? `Must be >= ${min}` : undefined;\nexport const maxValueEqual = (max) => (value) =>\n value && value > max ? `Must be <= ${max}` : undefined;\n// e.g. const minValue18 = minValue(18)\n\n// example functions\nconst email = (value) =>\n value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i.test(value)\n ? \"Invalid email address\"\n : undefined;\nconst tooOld = (value) =>\n value && value > 65 ? \"You might be too old for this\" : undefined;\nconst aol = (value) =>\n value && /.+@aol\\.com/.test(value)\n ? \"Really? You still use AOL for your email?\"\n : undefined;\nconst alphaNumeric = (value) =>\n value && /[^a-zA-Z0-9 ]/i.test(value)\n ? \"Only alphanumeric characters\"\n : undefined;\nconst phoneNumber = (value) =>\n value && !/^(0|[1-9][0-9]{9})$/i.test(value)\n ? \"Invalid phone number, must be 10 digits\"\n : undefined;\nconst uniqueEmail = (value, allValues, props, name) =>\n props.allUserEmails.includes(value)\n ? \"This email has already been used\"\n : undefined;\n\nexport const numberNormalize = (value) => {\n if (value === \"\") {\n return \"\";\n }\n const onlyNums = value.replace(/[^\\d]/g, \"\");\n if (onlyNums === \"\") {\n return \"\";\n }\n return Number(onlyNums);\n};\n\nexport const numberLetterNormalize = (value) => {\n if (!value) {\n return value;\n }\n\n let patt1 = /[a-zA-Z_0-9\\-]/g;\n\n let result = value.match(patt1);\n let validString = null;\n if (result != null) {\n validString = result.join(\"\");\n }\n //console.log(\"result, validString\",result,validString)\n return validString;\n};\nexport const IPAddrNormalize = (value) => {\n if (!value) {\n return value;\n }\n\n let result = value.match(/[\\d.]/g);\n let validString = null;\n if (result != null) {\n validString = result.join(\"\");\n }\n //console.log(\"result, validString\",result,validString)\n return validString;\n};\nexport const macAddressNormalize = (value) => {\n if (!value) {\n return value;\n }\n\n let patt1 = /[a-fA-F_0-9\\:]/g;\n\n let result = value.match(patt1);\n let validString = null;\n if (result != null) {\n validString = result.join(\"\");\n }\n return validString;\n};\nexport const httpAddressNormalize = (value) => {\n if (!value) {\n return value;\n }\n\n let patt1 = /[a-zA-Z_0-9\\-\\.\\:\\/]/g;\n\n let result = value.match(patt1);\n let validString = null;\n if (result != null) {\n validString = result.join(\"\");\n }\n return validString;\n};\n\nexport const filePathNormalize = (value) => {\n if (!value) {\n return value;\n }\n\n let patt1 = /[a-zA-Z_0-9\\-\\:\\/\\.\\~]/g;\n\n let result = value.match(patt1);\n let validString = null;\n if (result != null) {\n validString = result.join(\"\");\n }\n return validString;\n};\n","import Immutable from \"seamless-immutable\";\nimport { DEFAULT_SETTINGS } from \"utils/DEFAULTS\";\n\nconst initialState = Immutable({\n users: {},\n});\n\nexport default function reduce(state = initialState, action = {}) {\n const newState = { ...state };\n const { type, payload } = action;\n\n switch (type) {\n case \"ALL_USERS_FETCH_SUCCEEDED\":\n const {\n users: { list },\n } = payload;\n\n let newList = [];\n list.forEach((item) => {\n let settings = DEFAULT_SETTINGS;\n // check settings exist or set DEFAULT\n if (item?.settings !== \"\") {\n if (item?.settings?.includes(\"display\")) {\n settings = JSON.parse(item?.settings);\n }\n }\n newList.push({ ...item, settings });\n });\n\n //console.log(\"ALL_USERS_FETCH_SUCCEEDED USERS\", newList);\n\n newState.users = newList;\n return newState;\n\n case \"RESET\":\n console.log(\"RESET! - UserAdmin\");\n return state;\n default:\n return state;\n }\n}\n\nfunction stableOrder(order, items) {\n return Immutable(order.map((k) => items[k]));\n}\nexport const getAllUsers = (state) => {\n const byId = state.userAdmin.users;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getUserById = (state, id) => {\n const allUsers = getAllUsers(state).find((user) => user.email === id);\n return allUsers;\n};\n\nexport const getAllUsersByRole = (state, role) => {\n return getAllUsers(state)?.filter((user) => user.role === role) || [];\n};\n\nexport const getAllUsersRoleUserSettingsNamedAreaGroup = (state, area) => {\n const allUsersRoleUser =\n getAllUsers(state)?.filter((user) => user.role === \"user\") || [];\n let users = [];\n allUsersRoleUser.forEach((user) => {\n //console.log(\"xxx user allUsersRoleUser\", user);\n const nagSettings =\n user?.settings?.namedAreaGroup?.filter((group) => group.area === area) ||\n [];\n //console.log(\"xxx user allUsersRoleUser nagSettings\", nagSettings);\n\n users.push({ user: user.email, settings: nagSettings });\n });\n\n return users;\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Grid,\n Segment,\n Form,\n Popup,\n Dropdown,\n Checkbox,\n Table,\n Icon,\n} from \"semantic-ui-react\";\nimport { renderSelect, renderRadio } from \"admin/form-field\";\nimport {\n Field,\n reduxForm,\n formValueSelector,\n SubmissionError,\n getFormValues,\n isDirty,\n} from \"redux-form\";\n\nconst monthOptions = (strings) => {\n return [\n {\n key: 0,\n text: \"*\",\n value: 0,\n },\n\n {\n key: 1,\n text: strings?.[\"Select Date\"],\n value: 1,\n },\n {\n key: 2,\n text: strings?.[\"january\"],\n value: 2,\n },\n {\n key: 3,\n text: strings?.[\"february\"],\n value: 3,\n },\n {\n key: 4,\n text: strings?.[\"march\"],\n value: 4,\n },\n {\n key: 5,\n text: strings?.[\"april\"],\n value: 5,\n },\n ];\n};\n\nconst dayOptions = (strings) => {\n return [\n {\n key: 0,\n text: \"*\",\n value: 0,\n },\n {\n key: 1,\n text: strings?.[\"monday\"],\n value: 1,\n },\n {\n key: 2,\n text: strings?.[\"tuesday\"],\n value: 2,\n },\n {\n key: 3,\n text: strings?.[\"wednesday\"],\n value: 3,\n },\n {\n key: 4,\n text: strings?.[\"thursday\"],\n value: 4,\n },\n {\n key: 5,\n text: strings?.[\"friday\"],\n value: 5,\n },\n {\n key: 6,\n text: strings?.[\"saturday\"],\n value: 6,\n },\n {\n key: 7,\n text: strings?.[\"sunday\"],\n value: 7,\n },\n ];\n};\n\nclass _CronWizard extends Component {\n constructor() {\n super();\n this.state = {\n //\n };\n }\n\n handleMonthChange = (e, data) => {\n const { value } = data;\n\n console.log(\"xxx data\", data);\n\n console.log(\"xxx value\", value);\n\n // custom action\n // if (value.length > 0 && value.includes(0)) {\n // const index = value.indexOf(0);\n // if (index > -1) {\n // value.splice(index, 1);\n // }\n // }\n };\n\n handleEveryCheck = (e, data) => {\n console.log(\"xxx check data\", data);\n };\n\n handleTrashClick = (e, data) => {\n console.log(\"xxx check data\", data);\n };\n\n rowContent = (id, strings) => {\n return (\n <>\n \n \n }\n />\n \n }\n />\n \n \n \n }\n />\n \n }\n />\n \n 3\n 4\n 5\n 6\n \n \n \n \n );\n };\n\n render() {\n const { strings } = this.props;\n\n return (\n \n
\n \n \n \n Month\n Day\n Hour\n Minute\n Duration\n User Relay\n \n \n \n \n \n\n \n {[0, 1, 2]?.map((row, idx) => {\n return (\n \n {this.rowContent(row, strings)}\n \n );\n })}\n \n
\n
\n
\n );\n }\n}\n\nexport const CronWizard = connect(null, null)(_CronWizard);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Field, getFormValues, formValueSelector, reduxForm } from \"redux-form\";\n\nimport { Slider } from \"react-semantic-ui-range\";\nimport \"semantic-ui-css/semantic.min.css\";\n\nimport {\n Modal,\n Header,\n Button,\n Form,\n Segment,\n Grid,\n GridColumn,\n GridRow,\n Message,\n List,\n Icon,\n Checkbox,\n Table,\n Popup,\n Pagination,\n Dropdown,\n} from \"semantic-ui-react\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport { renderSelect, renderField, renderRadio } from \"admin/form-field\";\n\nimport {\n isConfigJs,\n namedAreaIconOptions,\n isUserRelay as _isUserRelay,\n eventTriggerOptions as _eventTriggerOptions,\n allowedLightColors as _allowedLightColors,\n allowedAlternateLightColors as _allowedAlternateLightColors,\n allowedLightStates as _allowedLightStates,\n allowedMapMarkers as _allowedMapMarkers,\n} from \"components/ConfigJs\";\n\nimport { getAllNamedAreaStatuses } from \"components/WebWorker/reducer\";\nimport { minValueEqual, maxValueEqual } from \"utils/normalise\";\nimport { isKthBitSet, bit_toggle } from \"utils/bit-operations\";\n\nimport {\n getAllUsersByRole,\n getAllUsersRoleUserSettingsNamedAreaGroup,\n} from \"components/UserAdmin/reducer\";\n\nimport { filterByLocation } from \"admin/filters\";\nimport hash from \"object-hash\";\nimport { changeSettings, fetchAllUsers } from \"components/UserAdmin/actions\";\nimport { getUserSettings } from \"auth/reducer\";\nimport { CronWizard } from \"admin/named-area-group/NamedAreaGroupCronWizard\";\n\n// range limits\nconst minValueEqual0 = minValueEqual(0);\n\nconst maxValueEqual15 = maxValueEqual(15);\n\nconst checkCronExpression = true; // #TODO!!!!!!!!!!!!!!\n\n// NOT USED - left here for fun for someone to find in the future\nconst brightnessLevelOptions = [\n // OFF = value is 0 - is available but not added as there is an available state = OFF\n {\n key: \"low\",\n text: \"Low\",\n value: 1,\n },\n {\n key: \"medium\",\n text: \"Medium\",\n value: 2,\n },\n {\n key: \"high\",\n text: \"High\",\n value: 3,\n },\n {\n key: \"bright\",\n text: \"Bright\",\n value: 4,\n },\n {\n key: \"work\",\n text: \"Work\",\n value: 5,\n },\n];\n\n// do not check for 0 as falsy\nconst required = (value) => (value !== \"\" ? undefined : \"Required\");\n\nconst validate = (values) => {\n const required = [\"color\", \"icon\", \"hint\", \"on_time\", \"off_time\"];\n\n const errors = {};\n\n required.forEach((r) => {\n const value = get(values, r);\n\n if (!value && value !== 0) {\n set(errors, r, \"Required\");\n }\n });\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n switch (type) {\n case \"on_time\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n case \"off_time\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n case \"train\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n default:\n return value;\n }\n};\n\nclass NamedAreaGroupSettingsModal extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // Initialize data list sort columns\n column: \"user\", // Default to sort on user column\n data: props.data,\n direction: null,\n modalOpen: false,\n isConfigJs: isConfigJs(),\n namedAreaIconOptions: namedAreaIconOptions(),\n isUserRelay: false,\n permissions: 0,\n // Initialize pagination of data list items\n page: 1,\n itemsPerPage: 5,\n allowedLightColors: [\"red\", \"amber\", \"white\", \"green\", \"blue\"],\n allowedAlternateLightColors: [\"off\", \"red\", \"amber\", \"white\", \"green\", \"blue\"]\n };\n }\n\n componentDidMount() {\n const { open, data } = this.props;\n if (open) {\n this.handleOpen();\n }\n this.setState({ data: data });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n\n if (\n JSON.stringify(this.state.data) !== JSON.stringify(prevState.data) // if original props data changes\n ) {\n let newData = [...this.state.data]; // original data\n\n // restore sort\n const { column, direction } = this.state;\n\n //console.log(\"xxx componentDidUpdate newData\", newData);\n //console.log(\"xxx componentDidUpdate column\", column);\n //console.log(\"xxx componentDidUpdate direction\", direction);\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n\n this.setState({\n data: newData,\n });\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleCancel = () => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.resetModal();\n\n // reset the form\n this.setState({ value: \"\" }, () => this.props.reset());\n // this.props.onCancel();\n };\n\n handleReset = () => {\n const { data, reset } = this.props;\n\n // reset the accessSettings (i.e. data)\n this.setState({ data });\n\n reset();\n };\n\n handleDelete = (e, idx) => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.handleSettingsDelete(idx);\n };\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n // console.log(\n // \"xxx column, data, direction, clickedColumn\",\n // column,\n // data,\n // direction,\n // clickedColumn\n // );\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n\n return;\n }\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n saveAccessSettings = (data) => {\n const { allUserUsers, changeSettings } = this.props;\n\n // console.log(\"xxx 666 saveAccessSettings\", data);\n // console.log(\"xxx 666 allUsersUser\", allUserUsers);\n\n let promiseArray = [];\n\n data.forEach((as) => {\n // flag\n let isSaveUserChanges = false;\n\n const userUser = allUserUsers.find((u) => u.email === as.user);\n\n // deep copy to update info\n let newUserUser = JSON.parse(JSON.stringify(userUser));\n\n // console.log(\"xxx 666 newUserUser\", newUserUser);\n\n let newSettingNamedAreaGroup = newUserUser.settings.namedAreaGroup || [];\n\n // console.log(\"xxx 666 newSettingNamedAreaGroup\", newSettingNamedAreaGroup);\n // console.log(\"xxx 666 as\", as);\n\n // find existing nag setting for this user id\n const userNagSetting = newSettingNamedAreaGroup.find(\n (nag) => nag.id === as.setting.id\n );\n\n // console.log(\"xxx 666 userNagSetting \", userNagSetting);\n\n // if exists\n if (userNagSetting !== undefined) {\n // compare userNagSetting.access with as.user.setting\n // to see if changed\n // console.log(\n // \"xxx 666 changed? - userNagSetting.access\",\n // JSON.stringify(userNagSetting.access),\n // \" !== as.setting.access \",\n // JSON.stringify(as.setting.access)\n // );\n\n // if the new settings === see all (i.e. default)\n if (JSON.stringify(as.setting.access) === `[\"r\",\"w\",\"x\"]`) {\n // filter the existing setting for this group id\n newSettingNamedAreaGroup = newSettingNamedAreaGroup.filter(\n (nag) => nag.id !== as.setting.id\n );\n // queue to save\n isSaveUserChanges = true;\n } else if (\n // settings changed\n JSON.stringify(userNagSetting.access) !==\n JSON.stringify(as.setting.access)\n ) {\n // console.log(\"xxx 666 SETTINGS CHANGED\");\n //\n // filter existing setting for this group id\n newSettingNamedAreaGroup = newSettingNamedAreaGroup.filter(\n (nag) => nag.id !== as.setting.id\n );\n // push new one\n newSettingNamedAreaGroup.push(as.setting);\n // save\n isSaveUserChanges = true;\n }\n } else {\n if (JSON.stringify(as.setting.access) !== `[\"r\",\"w\",\"x\"]`) {\n // push new one\n newSettingNamedAreaGroup.push(as.setting);\n // save\n isSaveUserChanges = true;\n }\n }\n\n if (isSaveUserChanges) {\n // console.log(\n // \"xxx 666 newSettingNamedAreaGroup\",\n // newSettingNamedAreaGroup\n // );\n\n newUserUser.settings.namedAreaGroup = newSettingNamedAreaGroup;\n\n const newValues = {\n id: newUserUser.email,\n settings: newUserUser.settings,\n };\n\n // console.log(\"xxx 666 newValues \", newValues);\n // console.log(\n // \"xxx 666 newValues newSettingNamedAreaGroup\",\n // newSettingNamedAreaGroup\n // );\n\n promiseArray.push(\n new Promise((resolve, reject) => {\n changeSettings({\n values: newValues,\n resolve,\n reject,\n });\n })\n );\n }\n });\n\n //console.log(\"xxx promiseArray\", promiseArray);\n\n return Promise.all(promiseArray).then((results) => {\n //console.log(`onSubmitSuccess ${results}`);\n this.props.fetchAllUsers();\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (e, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n myHandleSubmit = (values) => {\n // Close the modal\n this.setState({ modalOpen: false });\n\n // Check/change CRON from 'cron' and 'cron_duration' to two separate cron expressions.\n let newValues = { ...values };\n\n const cronOne = newValues?.settings?.cron || \"\";\n const cronDuration = newValues?.settings?.cron_duration || 0;\n const cronUserRelay = newValues?.settings?.cron_user_relay || 0;\n\n const cronTwo = \"\";\n\n // Get wizard to work out how to make offset structure\n const newCron = JSON.stringify([\n { cron: \"0-59/10 * * * * *\", active: true, user_relay: 5 },\n { cron: \"0-59/11 * * * * *\", active: false, user_relay: 5 },\n ]);\n\n // Make sure cron setting is available in all cases\n let newSettings = { ...newValues.settings };\n newSettings.cron = newCron;\n newValues.settings = newSettings;\n\n // If accessSettings have changed, save these separately\n if (values.changedAccessSettings) {\n this.saveAccessSettings(this.state.data);\n }\n\n // Save the changes\n this.props.handleSettingsSave(newValues);\n };\n\n handleActiveColorChange = (e, data) => {\n if (data === \"off\") {\n this.props.change(\"settings.active_state\", \"off\");\n }\n };\n\n handleActiveAlternateStateChange = (e, data) => {\n };\n\n handleActiveStateChange = (e, data) => {\n if (data === \"off\") {\n this.props.change(\"settings.active_color\", \"off\");\n this.props.change(\"settings.active_alternate_color\", \"off\");\n } else if (data === \"strobe\" || data === \"forward\" || data === \"backward\" || data === \"train\") {\n this.props.change(\"settings.active_alternate_color\", \"off\");\n }\n };\n\n onChangePermission = (e, data) => {\n const { stateValuePermission, change } = this.props; \n const { optionKey } = data;\n\n let newPermissions = stateValuePermission;\n // optionKey is the bit position\n // toggle the bit position\n newPermissions = bit_toggle(newPermissions, optionKey - 1);\n\n change(\"settings.permission\", newPermissions);\n };\n\n permissionRadiosContent = (options) => {\n let content = [];\n\n if (options.length === 0) {\n content.push(\n \n \n {this.props.strings?.[\"No event sources enabled\"]}\n \n );\n }\n\n options.map((option) => {\n content.push(\n \n \n \n \n );\n });\n\n return (\n
\n \n \n
\n {this.props.strings?.[\"Allowed Event Source\"]}\n
\n
\n
\n {content}\n
\n );\n };\n\n onClickHandlerAccessIcon = (e, access, user) => {\n const { change, data: propData } = this.props;\n\n const { data } = this.state;\n let newData = [...data];\n\n // remove this user\n newData = newData.filter((setting) => setting.user !== user.user);\n\n // update access from toggled icon - deep clone\n let newUser = JSON.parse(JSON.stringify(user));\n\n switch (access) {\n case \"show\":\n if (user.setting.access?.[0] === \"r\") {\n newUser.setting.access[0] = \"-\";\n // if no show then no control too\n newUser.setting.access[2] = \"-\";\n } else {\n newUser.setting.access[0] = \"r\";\n }\n break;\n case \"control\": // i.e. eXecute\n if (user.setting.access?.[2] === \"x\") {\n newUser.setting.access[2] = \"-\";\n } else {\n newUser.setting.access[2] = \"x\";\n }\n\n break;\n\n default:\n break;\n }\n\n newData.push(newUser);\n\n // accessSettings are not a part of the form data, but\n // see if access settings have changed from original props,\n // if changed back then reset form flag\n if (isEqual(propData, newData)) {\n this.setState({ data: newData }, () => {\n change(\"changedAccessSettings\", false);\n });\n } else {\n this.setState({ data: newData }, () => {\n change(\"changedAccessSettings\", true);\n });\n }\n };\n\n accessIcon = (access, user, strings) => {\n let popupMsg = \"unknown\";\n let iconName = \"question\";\n let iconColor = \"grey\";\n switch (access) {\n case \"show\":\n popupMsg = \"Click to toggle Show/Hide\";\n user?.setting?.access?.includes(\"r\")\n ? (iconName = \"checkmark\")\n : (iconName = \"close\");\n break;\n case \"control\":\n popupMsg = \"Click to toggle Control enable/disable\";\n user?.setting?.access?.includes(\"x\")\n ? (iconName = \"checkmark\")\n : (iconName = \"close\");\n break;\n default:\n break;\n }\n\n if (iconName === \"checkmark\") iconColor = \"green\";\n\n return (\n \n this.onClickHandlerAccessIcon(\n e,\n access, // access type\n user //\n )\n }\n />\n }\n />\n );\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n reset,\n initialValues,\n change,\n namedAreas,\n eventTriggerOptions,\n stateValuePermission,\n strings,\n userSettings,\n } = this.props;\n\n const { isConfigJs, namedAreaIconOptions, column, data, direction } =\n this.state;\n\n // display section if STROBE, FORWARD, BACKWARDS\n const { isPriorityLevel, isStateOn, isStateStrobe, isStateForwardBackward } =\n this.props;\n\n // console.log(\"modal initialValues\", initialValues);\n const { namedArea, subItems } = initialValues;\n\n const isUserRelay =\n userSettings?.feature?.includes(\"showUserRelay\") || _isUserRelay();\n\n // // check if this is cog config for priority `level` i.e. priorityLevel\n // // check for namedArea object in subItems\n // let priorityLevel = false;\n // if (!_isEmpty(subItems)) {\n // priorityLevel = subItems.some((items) => !_isEmpty(items?.namedArea));\n // }\n\n let buttonOptions = [];\n\n if (namedArea) {\n let iconOptions = [];\n if (isConfigJs && namedAreaIconOptions) {\n iconOptions = namedAreaIconOptions; // from config.js file\n }\n\n // console.log(\"iconOptions\", JSON.stringify(iconOptions));\n\n const { id } = namedArea;\n\n // console.log(\"namedAreas\", namedAreas);\n\n // only need first result of named areas since all button groups are the same\n const namedAreaParentButton = namedAreas.find(\n (na) => na.parent === id\n )?.button;\n // console.log(\"namedAreaParentButton\", namedAreaParentButton);\n if (namedAreaParentButton) {\n namedAreaParentButton.forEach((button, idx) => {\n const { priority, title, icon, color, clickable } = button;\n const image = iconOptions.find(\n (option) => option.value === icon\n )?.image;\n buttonOptions.push({\n key: priority,\n value: priority,\n color: color,\n text: title,\n image: image, // { src: \"/images/SIESMIC_0.png\" },\n });\n });\n }\n }\n\n const sectionTitle = namedArea\n ? strings?.[\"Polygon\"]\n : isPriorityLevel\n ? strings?.[\"Label\"]\n : strings?.[\"Label\"]; // #NOTE #WIP - this should label \"Group Label\" and \"Level label\" but this detection of what is a Group and what is a Level is broken.\n\n const allowedLightColors = _allowedLightColors();\n const allowedAlternateLightColors = _allowedAlternateLightColors();\n const allowedLightStates = _allowedLightStates();\n const allowedMapMarkers = _allowedMapMarkers();\n\n const defaultAccessRow = (\n <>\n *\n \n \n \n \n \n \n {/* - */}\n \n );\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Total of {itemsCount} items.{\" \"}\n
\n );\n }\n\n return (\n \n
\n \n {\n e.stopPropagation();\n handleSubmit(this.myHandleSubmit)(e);\n }}\n >\n \n \n \n \n {namedArea && (\n <>\n {/* */}\n \n \n {false && (\n <>\n {/*\n // #NOTE - this works to set permissions directly. \n // Disable, but useful for testing.\n // Not localized!\n */}\n \n Enter an integer to set the bit register.\n \n \n Bit 1 - Set to enable external trigger\n control\n \n \n Bit 2 ... - For future use\n \n \n e.g. Enter \"1\" to enable external trigger\n control, enter \"0\" to disable control\n \n }\n />\n \n value !== \"\" ? Number(value) : \"\"\n }\n />\n \n )}\n \n \n {this.permissionRadiosContent(eventTriggerOptions)}\n \n \n {\n // Set CRON if Scheduled Event checked\n // #REVIEW - remove after scheduled event jobs are completed via separate page.\n //\n false && isKthBitSet(stateValuePermission, 2) && (\n \n \n \n \n \n {strings?.[\"Scheduled Event Settings\"]}\n \n \n \n \n \n \n \n \n \n value !== \"\" ? parseInt(value) : \"\"\n }\n //className={disabled ? \"disabled-form-field\" : null}\n //disabled={disabled}\n />\n \n \n \n value !== \"\" ? Number(value) : \"\"\n }\n />\n \n \n \n \n )\n }\n
\n {/* #WIP #TODO */}\n \n
\n \n )}\n
\n
\n
\n {isPriorityLevel && (\n <>\n \n
{strings?.[\"Light Settings\"]}
\n \n \n \n {(isStateOn || isStateStrobe || isStateForwardBackward) && (\n
\n \n
\n )}\n {isStateStrobe && (\n
\n \n
\n )}\n {false && (\n \n )}\n
\n \n \n \n {(isStateStrobe || isStateForwardBackward) && (\n
\n \n normalise(value, \"off_time\")\n }\n component={renderField}\n />\n normalise(value, \"on_time\")}\n component={renderField}\n />\n
\n )}\n {isStateForwardBackward && (\n
\n normalise(value, \"train\")}\n component={renderField}\n />\n
\n )}\n
\n
\n
\n
\n {isStateForwardBackward && (\n \n \n \n )}\n {isUserRelay && (\n \n
{strings?.[\"Relay Settings\"]}
\n \n \n \n \n \n \n \n \n \n \n
\n )}\n \n )}\n {!isPriorityLevel && !namedArea && (\n \n
{strings?.[\"Access Settings\"]}
\n \n \n \n {strings?.[\"ACCESS_MESSAGE\"]}\n \n \n \n \n \n \n \n \n \n {strings?.[\"User\"]}\n \n \n {strings?.[\"Permission\"]}\n \n {/* \n }\n />\n */}\n \n \n \n {strings?.[\"Show\"]}\n \n \n {strings?.[\"Control\"]}\n \n \n \n \n {viewablesPage.length < 1 ? (\n {defaultAccessRow}\n ) : (\n viewablesPage.map((user) => (\n \n {user.user}\n \n {this.accessIcon(\"show\", user, strings)}\n \n \n {this.accessIcon(\"control\", user, strings)}\n \n {/* \n \n */}\n \n ))\n )}\n \n
\n {pagination}\n
\n
\n
\n
\n )}\n\n \n \n \n {/* \n this.handleDelete(e, buttonIdx)}\n />\n */}\n \n \n \n \n \n {strings?.[\"Save\"]}\n \n \n \n {strings?.[\"Reset\"]}\n \n \n \n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n \n
\n \n );\n }\n}\n\nNamedAreaGroupSettingsModal = reduxForm({\n form: \"namedAreaGroupSettingsModal\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n})(NamedAreaGroupSettingsModal);\n\nconst selector = formValueSelector(\"namedAreaGroupSettingsModal\");\n\nfunction mapStateToProps(state, props) {\n const { initialValues, areaId } = props;\n const namedAreas = getAllNamedAreaStatuses(state);\n\n const { subItems } = initialValues;\n // check if this is cog config for priority `level` i.e. priorityLevel\n // check for namedArea object in subItems\n let isPriorityLevel = false;\n\n // #NOTE #WIP - this does not work to determine if it is a level.\n // If there are no namedAreas added the title will default to GROUP\n //\n if (!_isEmpty(subItems)) {\n isPriorityLevel = subItems.some((items) => !_isEmpty(items?.namedArea));\n }\n\n const stateValueActiveState = selector(state, \"settings.active_state\");\n const isStateOn = [\"on\"].includes(\n stateValueActiveState\n );\n const isStateStrobe = [\"strobe\"].includes(\n stateValueActiveState\n );\n const isStateForwardBackward = [\"forward\", \"backward\"].includes(\n stateValueActiveState\n );\n\n const userSettings = getUserSettings(state);\n\n // console.log(\"xxx modal userSettings\", userSettings);\n\n // setup permission radio button\n const eventTriggerOptionsTemplate = _eventTriggerOptions(userSettings); // load setup for permission register\n const stateValuePermission = selector(state, \"settings.permission\");\n\n let eventTriggerOptions = [];\n\n // console.log(\n // \"xxx modal eventTriggerOptionsTemplate \",\n // eventTriggerOptionsTemplate\n // );\n\n eventTriggerOptionsTemplate.forEach((item) => {\n const isBitSet = isKthBitSet(stateValuePermission, item.key) || false;\n\n eventTriggerOptions.push({ ...item, value: isBitSet });\n });\n\n // console.log(\"xxx modal eventTriggerOptions \", eventTriggerOptions);\n\n const allUserUsers = getAllUsersByRole(state, \"user\");\n\n //console.log(\"xxx 123 allUserUsers\", allUserUsers);\n\n const allAccessSettings = getAllUsersRoleUserSettingsNamedAreaGroup(\n state,\n areaId\n );\n\n // console.log(\"xxx 123 allAccessSettings\", allAccessSettings);\n\n // filter for this group\n const accessSettings = allAccessSettings.map((item) => {\n let defaultSettings = {\n id: initialValues.id,\n area: areaId,\n access: [\"r\", \"w\", \"x\"],\n };\n\n let newSettings = item.settings?.find?.(\n (nag) => nag.id === initialValues.id\n );\n\n // console.log(\"xxx 123 newSettings item\", item);\n // console.log(\"xxx 123 newSettings initialValues\", initialValues);\n // console.log(\"xxx 123 newSettings\", newSettings);\n\n if (newSettings === undefined) {\n newSettings = defaultSettings;\n }\n\n return {\n user: item.user,\n setting: newSettings,\n };\n });\n\n const sortAccessSettings = accessSettings.sort((a, b) =>\n a.user > b.user ? 1 : -1\n );\n\n //console.log(\"xxx initialValues\", initialValues);\n //console.log(\"xxx areaId\", areaId);\n //console.log(\"xxx 123 accessSettings\", accessSettings);\n\n // get user access permissions\n // add access settings flag to initial settings\n const newInitialValues = { ...initialValues, changedAccessSettings: false };\n\n return {\n initialValues: newInitialValues, // props passed to redux-form loads these as (predictably), initial values\n namedAreas,\n isStateOn,\n isStateStrobe,\n isStateForwardBackward,\n isPriorityLevel,\n eventTriggerOptions,\n stateValuePermission,\n data: sortAccessSettings, // page 'data'\n allUserUsers,\n formValues: getFormValues(\"namedAreaGroupSettingsModal\")(state), // #REVIEW - only used for debugging,\n onChange: (values, dispatch, props, previousValues) => {\n const { change, isPriorityLevel, namedArea } = props;\n\n //console.log(\"onChange values\", values);\n //console.log(\"onChange props\", values);\n\n if (!namedArea && !isPriorityLevel) {\n //console.log(\"xxx onChange values\", values);\n }\n\n if (isPriorityLevel) {\n const {\n settings: { active_color },\n } = values;\n\n dispatch(change(\"settings.color\", active_color));\n }\n },\n };\n}\n\nexport default connect(mapStateToProps, {\n changeSettings,\n fetchAllUsers,\n})(NamedAreaGroupSettingsModal);\n","import React, { Component } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { DragDropContext, Droppable, Draggable } from \"react-beautiful-dnd\";\nimport {\n Table,\n Ref,\n Grid,\n Button,\n Icon,\n Message,\n Segment,\n Popup,\n} from \"semantic-ui-react\";\nimport { v4 as uuid } from \"uuid\";\n\nimport _isEqual from \"lodash/isEqual\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport NamedAreaGroupTableSubItems from \"./NamedAreaGroupTableSubItems\";\nimport SettingsModal from \"admin/named-area-group/NamedAreaGroupSettingsModal\";\n\nimport ContainerDimensions from \"react-container-dimensions\";\n\nconst getItemStyle = (highlightColor, color, isDragging, draggableStyle) => ({\n // some basic styles to make the items look a bit nicer\n userSelect: \"none\",\n\n // change background colour if dragging\n background: isDragging ? highlightColor : color,\n\n // styles we need to apply on draggables\n ...draggableStyle,\n});\n\nconst getListStyle = (color, isDraggingOver) => ({\n background: isDraggingOver ? color : \"white\",\n});\n\n// a little function to help us with reordering the result\nconst reorder = (list, startIndex, endIndex) => {\n const result = Array.from(list);\n const [removed] = result.splice(startIndex, 1);\n result.splice(endIndex, 0, removed);\n\n return result;\n};\n\nconst copy = (source, destination, droppableSource, droppableDestination) => {\n const sourceClone = Array.from(source);\n const destClone = Array.from(destination);\n const item = sourceClone[droppableSource.index];\n\n destClone.splice(droppableDestination.index, 0, { ...item, id: uuid() });\n return destClone;\n};\n\n// find each object parent\nconst findParent = (id, items) => {\n let result;\n const itemsKeys = Object.keys(items);\n for (const item of itemsKeys) {\n result = items[item].find((item) => item.id === id);\n if (result !== undefined) {\n return result;\n }\n }\n return result;\n};\n\nconst MergeSettings = (obj1, obj2) => {\n if (obj2) {\n var obj3 = {};\n for (let attrname in obj1) {\n obj3[attrname] = obj1[attrname];\n }\n for (let attrname in obj2) {\n obj3[attrname] = obj2[attrname];\n }\n return obj3;\n } else {\n return obj1;\n }\n};\n\nexport default class NamedAreaGroupTable extends Component {\n constructor(props) {\n super(props);\n this.state = {\n items: [],\n collapse: [],\n collapseAll: false,\n collapseLevel: false,\n NAMEDAREAS: [],\n initialValues: {},\n //\n // modal settings dlg for button options\n isOpenSettingsModal: false,\n modalSettings: {},\n };\n }\n\n componentDidMount() {\n const { data, initialValues } = this.props;\n const { listOfNamedAreas } = initialValues;\n\n if (data !== undefined) {\n this.setState({ items: data });\n }\n if (initialValues !== undefined) {\n this.setState({ initialValues: initialValues });\n }\n if (listOfNamedAreas !== undefined) {\n this.setState({ NAMEDAREAS: listOfNamedAreas });\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (prevState.items !== this.state.items && prevProps.data !== undefined) {\n // check undefined to stop circular update on startup\n // maintain the state of the calling form\n this.props.onItemsChange(this.state.items);\n }\n // update the list state from the calling form if reset\n if (JSON.stringify(prevProps.data) !== JSON.stringify(this.props.data)) {\n this.setState({ items: this.props.data });\n }\n }\n\n onDragStart = (result) => {\n // type:\n // \"droppableSubSubItem\" - named areas\n // \"droppableSubItem\" - levels\n // \"droppableItem\" - groups\n\n // while dragging sections are collapsed\n // set collapseAll, collapseLevel\n const { type } = result;\n switch (type) {\n case \"droppableItem\":\n this.setState({ collapseAll: true });\n break;\n case \"droppableSubItem\":\n // collapse levels\n this.setState({ collapseLevel: true });\n\n break;\n\n default:\n break;\n }\n };\n\n onDragEnd = (result) => {\n // console.log(\"onDragEnd result\", result);\n // console.log(\"onDragEnd result.source\", result.source);\n // console.log(\"onDragEnd result.destination\", result.destination);\n\n const { source, destination } = result;\n\n const { items } = this.state;\n const cloneItems = JSON.parse(JSON.stringify(items));\n\n // dropped outside the list\n if (!result.destination) {\n return;\n }\n\n // delete from groups\n if (destination.droppableId.includes(\"DELETE\")) {\n // can't delete named area items\n if (source.droppableId === \"NAMEDAREAS\") {\n return;\n }\n return;\n }\n\n // while dragging sections are collapsed\n // reset collapseAll, collapseLevel\n\n // type:\n // \"droppableSubSubItem\" - named areas\n // \"droppableSubItem\" - levels\n // \"droppableItem\" - groups\n const { type } = result;\n switch (type) {\n case \"droppableItem\":\n this.setState({ collapseAll: false });\n break;\n\n case \"droppableSubItem\":\n this.setState({ collapseLevel: false });\n break;\n\n default:\n break;\n }\n\n // add named area\n if (source.droppableId === \"NAMEDAREAS\") {\n // case \"NAMEDAREAS\":\n // groups = this.state.groups;\n // groups[destination.droppableId] = copy(\n // NAMEDAREAS,\n // this.state.groups[destination.droppableId],\n // source,\n // destination\n // );\n // this.setState({ groups: groups });\n\n // break;\n\n const sourceClone = Array.from(this.state.NAMEDAREAS);\n let item = sourceClone[source.index];\n\n // console.log(\"sourceClone\", sourceClone);\n // console.log(\"source item\", item);\n\n const itemSubItemMap = cloneItems.reduce((acc, item) => {\n acc[item.id] = item.subItems;\n return acc;\n }, {});\n\n const destParentId = destination.droppableId;\n const destParentObject = findParent(destParentId, itemSubItemMap);\n\n // console.log(\"source destParentObject\", destParentObject);\n\n const { settings } = destParentObject;\n // update item button settings from priority level settings and default\n // add button information for the namedArea based on settings for the level\n\n const buttonTemplate = (itemId, namedAreaId) => {\n const obj = {\n id: itemId,\n named_area: namedAreaId,\n // clickable: true,\n // icon: \"icon-earthquake123\",\n // priority: 0,\n // title: \"Seismic 1\",\n // alt: \"Level 1\",\n // color: \"red\",\n // group: 0,\n // type: \"SEISMIC1_EVENT\",\n // hint: \"Level 0\",\n // default: true,\n // active_state: \"on\",\n // active_color: \"red\",\n // active_alternate_color: \" off\",\n // state: \"on\",\n // on_time: 0,\n // off_time: 0,\n // train: 0,\n // active: true,\n // marker: \"\",\n };\n return obj;\n };\n\n const button = MergeSettings(\n settings,\n buttonTemplate(item.id, item.namedArea.id)\n );\n //console.log(\"button merge\", button);\n\n item.namedArea.button = button;\n\n const destClone = destParentObject.subItems;\n destClone.splice(destination.index, 0, {\n ...item,\n id: uuid(),\n parent: destParentObject.id,\n });\n\n //console.log(\"source destClone\", destClone);\n\n // update items state based on destParentObject.id (parent)\n let newItems = [];\n let i = 0;\n // groups\n cloneItems.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n newSubItem[j] = item;\n if (item.id === destParentObject.id) {\n // named areas - subSubItems\n newSubItem[j].subItems = destClone;\n }\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n //console.log(\"source newItems\", JSON.stringify(newItems));\n\n this.setStateNewItems(newItems);\n //this.setState({ items: newItems });\n\n //#########\n return;\n }\n\n const sourceIndex = result.source.index;\n const destIndex = result.destination.index;\n\n if (result.type === \"droppableItem\") {\n const items = reorder(cloneItems, sourceIndex, destIndex);\n // console.log(\"onDragEnd reorder items\", items);\n this.setState({\n items,\n });\n } else if (result.type === \"droppableSubItem\") {\n const itemSubItemMap = cloneItems.reduce((acc, item) => {\n acc[item.id] = item.subItems;\n return acc;\n }, {});\n\n // console.log(\"onDragEnd itemSubItemMap\", itemSubItemMap);\n\n const sourceParentId = result.source.droppableId;\n const destParentId = result.destination.droppableId;\n\n // console.log(\"onDragEnd sourceParentId\", sourceParentId);\n // console.log(\"onDragEnd destParentId\", destParentId);\n\n const sourceSubItems = itemSubItemMap[sourceParentId];\n const destSubItems = itemSubItemMap[destParentId];\n\n // console.log(\"onDragEnd sourceSubItems\", sourceSubItems);\n // console.log(\"onDragEnd destSubItems\", destSubItems);\n\n let newItems = [...cloneItems];\n\n /** In this case subItems are reOrdered inside same Parent */\n if (sourceParentId === destParentId) {\n // console.log(\n // \"onDragEnd reorder sourceSubItems,sourceIndex,destIndex\",\n // sourceSubItems,\n // sourceIndex,\n // destIndex\n // );\n const reorderedSubItems = reorder(\n sourceSubItems,\n sourceIndex,\n destIndex\n );\n newItems = newItems.map((item) => {\n if (item.id === sourceParentId) {\n item.subItems = reorderedSubItems;\n }\n return item;\n });\n this.setStateNewItems(newItems);\n //this.setState({items: newItems,});\n } else {\n let newSourceSubItems = [...sourceSubItems];\n const [draggedItem] = newSourceSubItems.splice(sourceIndex, 1);\n\n let newDestSubItems = [...destSubItems];\n newDestSubItems.splice(destIndex, 0, draggedItem);\n newItems = newItems.map((item) => {\n if (item.id === sourceParentId) {\n item.subItems = newSourceSubItems;\n } else if (item.id === destParentId) {\n item.subItems = newDestSubItems;\n }\n return item;\n });\n this.setStateNewItems(newItems);\n //this.setState({items: newItems,});\n }\n } else if (result.type === \"droppableSubSubItem\") {\n const itemSubItemMap = cloneItems.reduce((acc, item) => {\n acc[item.id] = item.subItems;\n return acc;\n }, {});\n\n // console.log(\"onDragEnd reorder itemSubItemMap\", itemSubItemMap);\n\n const sourceParentId = result.source.droppableId;\n const destParentId = result.destination.droppableId;\n\n const sourceParentObject = findParent(sourceParentId, itemSubItemMap);\n const sourceSubItems = sourceParentObject?.subItems;\n\n const destParentObject = findParent(destParentId, itemSubItemMap);\n const destSubItems = destParentObject?.subItems;\n\n // #DEBUG - useful debugs messages\n if (false) {\n console.log(\"onDragEnd sourceParentId\", sourceParentId);\n console.log(\"onDragEnd destParentId\", destParentId);\n console.log(\"onDragEnd sourceParentObject\", sourceParentObject);\n console.log(\"onDragEnd sourceSubItems\", sourceSubItems);\n console.log(\"onDragEnd destParentObject\", destParentObject);\n console.log(\"onDragEnd destSubItems\", destSubItems);\n }\n\n // don't allow moving sub sub items across group boundaries\n if (sourceSubItems === undefined || destSubItems === undefined) {\n return;\n }\n\n let newItems = [...cloneItems];\n\n // CASE - subItems are reOrdered inside same Parent\n if (sourceParentId === destParentId) {\n const reorderedSubItems = reorder(\n sourceSubItems,\n sourceIndex,\n destIndex\n );\n\n // console.log(\"onDragEnd newItems\", newItems);\n\n for (const [i, subItems] of newItems.entries()) {\n // console.log(\"onDragEnd subItems\", i, subItems);\n for (const [j, subItem] of subItems.subItems.entries()) {\n // console.log(\"onDragEnd subItem j\", j, subItem);\n if (subItem.id === sourceParentId) {\n if (subItem.parent === sourceParentObject.parent) {\n // console.log(\"onDragEnd subItem - found it!\", subItem);\n // console.log(\n // \"onDragEnd newItems[i][j] - found it!\",\n // newItems[i].subItems[j].subItems\n // );\n newItems[i].subItems[j].subItems = reorderedSubItems;\n }\n }\n }\n }\n\n // console.log(\"onDragEnd newItems\", newItems);\n\n this.setStateNewItems(newItems);\n //this.setState({items: newItems});\n }\n // CASE - subItems are moved between different parents\n else {\n let newSourceSubItems = [...sourceSubItems];\n\n const [draggedItem] = newSourceSubItems.splice(sourceIndex, 1);\n\n let newDestSubItems = [...destSubItems];\n newDestSubItems.splice(destIndex, 0, draggedItem);\n\n // newItems = newItems.map((item) => {\n // if (item.id === sourceParentId.toString()) {\n // item.subItems = newSourceSubItems;\n // } else if (item.id === destParentId.toString()) {\n // item.subItems = newDestSubItems;\n // }\n // return item;\n // });\n\n // console.log(\n // \"onDragEnd subItems are moved between different parents --------\"\n // );\n for (const [i, subItems] of newItems.entries()) {\n //console.log(\"onDragEnd subItems\", i, subItems);\n for (const [j, subItem] of subItems.subItems.entries()) {\n //console.log(\"onDragEnd subItem j\", j, subItem);\n\n // #REVIEW - WHEN DOES id === sourceParentId????????????????\n //\n\n if (subItem.id === sourceParentId) {\n //console.log(\"onDragEnd subItem - subItem.id === sourceParentId\");\n if (subItem.parent === sourceParentObject.parent) {\n // console.log(\n // \"onDragEnd subItem - subItem.parent === sourceParentObject.parent\"\n // );\n\n // console.log(\"onDragEnd subItem - found it!\", subItem);\n // console.log(\n // \"onDragEnd newItems[i][j] - found it!\",\n // newItems[i].subItems[j].subItems,\n // \"newSourceSubItems - \",\n // newSourceSubItems\n // );\n newItems[i].subItems[j].subItems = newSourceSubItems;\n }\n }\n if (subItem.id === destParentId) {\n //console.log(\"onDragEnd subItem - subItem.id === destParentId\");\n if (subItem.parent === destParentObject.parent) {\n // console.log(\n // \"onDragEnd subItem - subItem.parent === destParentObject.parent)\"\n // );\n // console.log(\"onDragEnd subItem - found it!\", subItem);\n // console.log(\n // \"onDragEnd newItems[i][j] - found it!\",\n // newItems[i].subItems[j].subItems,\n // \"newDestSubItems - \",\n // newDestSubItems\n // );\n\n // #WIP - update settings of newDestSubItems from settings of subItem\n // The item has been dragged to a new level.\n // In this situation update the item's settings to match the new level settings.\n //\n let updatedNewDestSubItems = [];\n // go over every item is the level\n newDestSubItems.forEach((item) => {\n // copy the item\n let newItem = { ...item };\n // get the button (settings)\n let newButton = item?.namedArea?.button;\n //console.log(\"onDragEnd newButton \", newButton);\n // console.log(\n // \"onDragEnd subItem?.settings \",\n // subItem?.settings\n // );\n // merge the level settings with the button settings, using the subItem (level) settings to overwrite/update existing values\n //\n if (newButton) {\n newButton = { ...newButton, ...subItem?.settings };\n //console.log(\"onDragEnd newButton \", newButton);\n newItem.namedArea.button = newButton;\n }\n // save the updated items\n updatedNewDestSubItems.push(newItem);\n });\n\n newItems[i].subItems[j].subItems = updatedNewDestSubItems; // newDestSubItems;\n }\n }\n }\n }\n\n this.setStateNewItems(newItems);\n //this.setState({items: newItems});\n\n //console.log(\"onDragEnd newItems\", newItems);\n }\n // console.log(\"onDragEnd newItems\", JSON.stringify(newItems));\n }\n };\n\n findItem = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return object === id\n\n let findItem = {};\n\n let i = 0;\n // groups\n items.forEach((item) => {\n if (item.id === id) {\n findItem = item;\n } else {\n // levels - subItems\n let j = 0;\n item.subItems.forEach((item) => {\n if (item.id === id) {\n findItem = item;\n } else {\n // named areas - subSubItems\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.id === id) {\n findItem = item;\n } else {\n k = k + 1;\n }\n });\n j = j + 1;\n }\n });\n i = i + 1;\n }\n });\n return findItem;\n };\n\n updateItem = (items, newItem) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and replace object by id\n\n const { id } = newItem;\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n if (item.id !== id) {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n if (item.id !== id) {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.id !== id) {\n newSubSubItem[k] = item;\n } else {\n newSubSubItem[k] = newItem;\n }\n k = k + 1;\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n } else {\n const prevSettings = item?.settings;\n newSubItem[j] = newItem;\n const settings = newItem.settings;\n // if subItem (i.e. priority) settings changed update subItems.namedArea.button\n if (!_isEqual(prevSettings, settings)) {\n //console.log(\"settings changed\");\n newSubItem[j].settings = MergeSettings(prevSettings, settings);\n // update subItems\n newSubItem[j].subItems.map(\n (item) =>\n (item.namedArea.button = MergeSettings(\n item.namedArea.button,\n settings\n ))\n );\n }\n }\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n } else {\n newItems[i] = newItem;\n }\n i = i + 1;\n });\n return newItems;\n };\n\n setStateNewItems = (newItems) => {\n this.setState({\n items: newItems,\n });\n };\n\n deleteItem = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n if (item.id !== id) {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n if (item.id !== id) {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n }\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n }\n });\n\n return newItems;\n };\n\n onClickHandler = (e, type, id, groupId, data) => {\n // #NOTE -\n // * 'data' was added to the structure to pass misc. data around between\n // subsections, but has not been used so 'null' is passed in all cases.\n\n //console.log(\"onClickHandler e\", e);\n if (e.preventDefault) {\n e.preventDefault();\n }\n\n if (e.stopPropagation) {\n e.stopPropagation(); // stop submit to calling form\n }\n\n // console.log(\n // \"drag onClickHandler - type:\",\n // type,\n // \" id:\",\n // id,\n // \" groupId:\",\n // groupId,\n // \" data:\",\n // data\n // );\n\n const { items } = this.state;\n const cloneItems = !_isEmpty(items)\n ? JSON.parse(JSON.stringify(items))\n : [];\n\n //console.log(\"cloneItems\", cloneItems);\n\n let newCollapse = this.state.collapse;\n let newCollapseAll = this.state.collapseAll;\n let newItems = [];\n\n const openSettingsModal = (items, id) => {\n // console.log(\"openSettingsModal items\", items);\n // console.log(\"openSettingsModal id\", id);\n const findItem = this.findItem(items, id);\n //console.log(\"openSettingsModal findItem\", findItem);\n\n this.setState({\n isOpenSettingsModal: true,\n modalSettings: findItem,\n });\n };\n\n const buttonTemplate = (itemId, namedAreaId) => {\n const obj = {\n //id: itemId,\n //named_area: namedAreaId,\n clickable: true,\n icon: \"icon-earthquake123\",\n priority: 0,\n title: \"Seismic 1\",\n alt: \"Level 1\",\n color: \"red\",\n group: 0,\n type: \"SEISMIC1_EVENT\",\n hint: \"Level 0\",\n default: true,\n active_state: \"on\",\n active_color: \"red\",\n active_alternate_color: \"off\",\n active_brightness_level: 1,\n state: \"on\",\n on_time: 0,\n off_time: 0,\n train: 0,\n active: true,\n marker: \"RoundMarker\",\n siren_state: \"off\",\n origin: \"clientOrigin2\",\n operator: \"clientOperator2\",\n permission: 0,\n };\n return obj;\n };\n\n switch (type) {\n case \"add\":\n const newId = uuid();\n const newId2 = uuid();\n\n if (groupId === \"group\") {\n const newGroup = {\n id: newId,\n label: \"New group\",\n // automatically insert a default level for each new group\n subItems: [\n {\n id: newId2,\n parent: newId,\n label: \"New level\",\n subItems: [],\n settings: buttonTemplate(newId2, \"placeholder\"),\n },\n ],\n };\n newItems = [...cloneItems, newGroup];\n\n // if this is the 1st group added, don't collapse\n if (_isEmpty(cloneItems)) {\n newCollapseAll = false;\n }\n } else if (groupId === \"level\") {\n const newLevel = {\n id: newId,\n parent: id,\n label: \"New level\",\n subItems: [],\n settings: buttonTemplate(newId, \"placeholder\"),\n };\n\n // update items state based on id (parent)\n cloneItems.forEach((item, idx) => {\n newItems[idx] = item;\n if (item.id === id) {\n newItems[idx].subItems = [...item.subItems, newLevel];\n }\n });\n }\n\n this.setStateNewItems(newItems);\n //this.setState({items: newItems});\n\n //console.log(\"add newItems\", newItems);\n\n // pop modal dlg to edit item label\n openSettingsModal(newItems, newId);\n\n break;\n\n case \"deleteItem\":\n // object structure is three levels deep\n // all id are unique\n // search over all levels and delete id\n\n newItems = this.deleteItem(cloneItems, id);\n\n this.setStateNewItems(newItems);\n //this.setState({ items: newItems });\n\n break;\n case \"collapse\":\n // collapse does not change item state\n newItems = cloneItems;\n\n const groupIds = cloneItems.map((item) => item.id);\n\n if (id === \"all\") {\n if (!this.state.collapseAll) {\n newCollapse = groupIds;\n newCollapseAll = true;\n } else {\n newCollapse = [];\n newCollapseAll = false;\n }\n } else {\n if (newCollapse.includes(id)) {\n newCollapse = newCollapse.filter((item) => item !== id);\n newCollapseAll = false;\n } else {\n newCollapse.push(id);\n\n // check if all collapsed?\n if (\n newCollapse.sort().join(\",\") === groupIds.sort().join(\",\") &&\n !_isEmpty(newCollapse)\n ) {\n newCollapseAll = true;\n } else {\n newCollapseAll = false;\n }\n }\n }\n this.setState({ collapse: newCollapse });\n this.setState({ collapseAll: newCollapseAll });\n break;\n case \"cog\":\n openSettingsModal(cloneItems, id);\n\n // cog does not change item state - see `handleSettingsSave`\n newItems = cloneItems;\n\n this.setStateNewItems(newItems);\n //this.setState({ items: newItems });\n break;\n\n default:\n break;\n }\n\n //console.log(\"newItems\", JSON.stringify(newItems));\n //console.log(\"newCollapse\", newCollapse);\n //console.log(\"newCollapseAll\", newCollapseAll);\n };\n\n resetModal = () => {\n this.setState({ isOpenSettingsModal: false });\n };\n\n handleSettingsSave = (values) => {\n const { items } = this.state;\n const cloneItems = JSON.parse(JSON.stringify(items));\n const newItems = this.updateItem(cloneItems, values);\n\n console.log(\"handleSettingsSave newItems\", newItems);\n\n this.setStateNewItems(newItems);\n //this.setState({ items: newItems });\n\n // close modal\n this.setState({ isOpenSettingsModal: false });\n };\n\n render() {\n const {\n NAMEDAREAS,\n items,\n collapse,\n collapseAll,\n collapseLevel,\n modalSettings,\n isOpenSettingsModal,\n } = this.state;\n\n const { strings, mineLevelId, userSettings } = this.props; // localisation\n\n // APP_TERMINOLOGY\n let strNamedAreas = strings?.[\"Polygons\"];\n\n // sort the NAMEDAREAS list by \"label\"\n const sortAlphaNum = (a, b) =>\n a?.label?.localeCompare(b?.label, \"en\", { numeric: true });\n NAMEDAREAS.sort(sortAlphaNum);\n\n return (\n \n {({ width, height }) => (\n <>\n {this.state.isOpenSettingsModal && (\n this.handleSettingsSave(values)}\n resetModal={() => this.resetModal(false)}\n strings={strings}\n userSettings={userSettings}\n />\n )}\n\n \n 1400\n ? { width: \"1200px\", margin: \"auto\" }\n : { width: \"80%\", margin: \"auto\" }\n }\n >\n \n \n \n \n {strNamedAreas}\n \n \n \n {(provided, snapshot) => (\n \n \n {NAMEDAREAS.map((item, index) => (\n \n {(provided, snapshot) => (\n <>\n \n moved to \n isDragging={snapshot.isDragging}\n style={getItemStyle(\n \"rgba(144,238,144,1)\",\n //\"lightgreen\",\n \"rgba(144,238,144,0.2)\",\n snapshot.isDragging,\n provided.draggableProps.style\n )}\n >\n \n \n }\n />\n {item.label}\n \n \n \n \n )}\n \n ))}\n \n \n )}\n \n
\n
\n \n {/* #NOTE - no longer used but kept here JIC want to restore warning in future */}\n {/* \n \n \n Saving changes to the Control Layout will clear all\n current light states for all Areas! Re-enable all lights\n on polygons after saving changes to the Control layout.\n \n */}\n \n \n \n {items.length !== 0 && (\n \n \n this.onClickHandler(\n e,\n \"collapse\", // type\n \"all\", // id\n 0, // index\n null //data\n )\n }\n />\n }\n />\n \n )}\n \n {strings?.[\"Groups\"]}\n \n \n {\n //console.log(\"onClick!!! Add\");\n\n this.onClickHandler(\n e,\n \"add\", // type\n \"group\", // id\n \"group\", // index\n null\n );\n }}\n >\n \n \n }\n />\n \n \n \n\n \n {(provided, snapshot) => (\n \n \n {items.length ? (\n items.map((item, index) => (\n \n {(provided, snapshot) => (\n \n <>\n moved to \n isDragging={snapshot.isDragging}\n style={getItemStyle(\n \"rgba(255,182,193,1)\",\n //\"lightpink\",\n \"rgba(255,182,193,0.2)\",\n snapshot.isDragging,\n provided.draggableProps.style\n )}\n >\n \n \n this.onClickHandler(\n e,\n \"collapse\", // type\n item.id, // id\n \"level\", // group\n null\n )\n }\n />\n }\n />\n \n \n \n }\n />\n {item.label}\n {/* {` id: ${item.id}`}\n {` draggingOver: ${snapshot.draggingOver}`}\n {` isDragging: ${snapshot.isDragging}`} */}\n \n \n {!collapseAll &&\n !collapse.includes(item.id) && (\n \n this.onClickHandler(\n e,\n \"add\",\n item.id,\n \"level\",\n null\n )\n }\n >\n \n \n }\n />\n )}\n \n \n \n this.onClickHandler(\n e,\n \"cog\",\n item.id,\n \"level\",\n null\n )\n }\n />\n }\n />\n \n \n \n this.onClickHandler(\n e,\n \"deleteItem\", // type\n item.id, // id\n \"level\",\n null\n )\n }\n />\n }\n />\n \n \n {!collapseAll &&\n !snapshot?.isDragging &&\n !collapse.includes(item.id) && (\n \n \n \n this.onClickHandler(\n e,\n type,\n id,\n index,\n data\n )\n }\n collapseAll={collapseLevel}\n strings={strings}\n userSettings={userSettings}\n />\n \n \n )}\n \n \n )}\n \n ))\n ) : (\n \n \n {strings?.[\"No Groups. Add a group.\"]}\n \n \n )}\n {!_isEmpty(provided.placeholder) &&\n snapshot.isDraggingOver && (\n \n \n {provided.placeholder}\n \n \n )}\n \n \n )}\n \n
\n
\n \n \n \n )}\n
\n );\n }\n}\n","import React, { Component, useDebugValue } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Form,\n Container,\n Label,\n Header,\n Grid,\n Message,\n Segment,\n Table,\n Icon,\n Popup,\n Dimmer,\n Loader,\n Button,\n} from \"semantic-ui-react\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\n\nimport { push } from \"react-router-redux\";\n\nimport isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport { renderField } from \"admin/form-field\";\nimport { SaveButton } from \"admin/SaveButton\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport NamedAreaGroupTableItems from \"admin/named-area-group/NamedAreaGroupTableItems\";\n\nconst validate = (values) => {\n const required = [];\n\n const errors = {};\n\n required.forEach((r) => {\n if (!get(values, r)) {\n set(errors, r, \"Required\");\n }\n });\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n switch (type) {\n default:\n return value;\n }\n};\n\nclass EditNamedAreaGroupForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n contentLoading: true,\n errorMessage: \"\",\n submitted: false,\n };\n }\n\n componentDidMount() {\n this.setState({ contentLoading: false });\n }\n\n submitMyForm = (values) => {\n //console.log(`form submitted: values`, values);\n this.props.onSubmit(values);\n };\n\n resetForm = (e) => {\n e.preventDefault();\n this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // abort page changes\n this.props.onCancel();\n };\n\n onItemsChange = (data) => {\n this.props.change(\"data\", data);\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n reset,\n mineLevelId,\n listOfNamedAreas,\n data,\n initialValues,\n //\n strings, // localisations\n userSettings,\n } = this.props;\n\n // console.log(\"xxx EditNamedAreaGroupForm - strings\", strings);\n\n // APP_TERMINOLOGY\n const strNamedAreaGroup = strings?.[\"Control Layout\"];\n\n if (mineLevelId === undefined) {\n return (\n <>\n \n \n \n );\n }\n\n const { contentLoading } = this.state;\n if (contentLoading) {\n return (\n \n Loading data\n \n );\n } else {\n return (\n
\n \n \n \n \n
{`${strNamedAreaGroup} - ${mineLevelId.replace(\n \"_\",\n \" \"\n )}`}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {/* ***************Create Form ************************ */}\n {error && (\n \n )}\n\n \n \n \n \n \n \n \n \n \n this.resetForm(e)}\n >\n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n \n this.onItemsChange(data)}\n strings={strings}\n userSettings={userSettings}\n />\n \n \n
\n
\n );\n }\n }\n}\n\nconst selector = formValueSelector(\"editNamedAreaGroupForm\");\n\nEditNamedAreaGroupForm = reduxForm({\n form: \"editNamedAreaGroupForm\",\n // Note - to reinitialize values in componentDidMount\n // Make sure you set the values of enableReinitialize & keepDirtyOnReinitialize to true\n // See - https://stackoverflow.com/questions/44273099/redux-form-initialization-with-props-initialize\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(EditNamedAreaGroupForm);\n\nconst mapStateToProps = (state, props) => {\n const { initialValues } = props;\n const { mineLevelId, listOfNamedAreas, data } = initialValues;\n\n // console.log('selector(state, \"data\"),', selector(state, \"data\"));\n\n return {\n mineLevelId,\n listOfNamedAreas,\n data: selector(state, \"data\"), //data,\n initialValues: initialValues,\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"reduxForm onChange values\", values);\n\n if (values.mineLevelId !== previousValues.mineLevelId) {\n //console.log(\"onChange\", values);\n // dispatch(change(\"data\", data);\n }\n },\n reduxFormValues: getFormValues(\"editNamedAreaGroupForm\")(state),\n };\n};\n\nconst mapDispatchToProps = (dispatch) => ({});\n\nEditNamedAreaGroupForm = connect(\n mapStateToProps,\n mapDispatchToProps\n)(EditNamedAreaGroupForm);\n\nexport default EditNamedAreaGroupForm;\n","import Immutable from \"seamless-immutable\";\n\nconst initialState = Immutable({\n prevNamedAreaGroup: {},\n prevNamedAreaGroupButtonStates: {},\n});\n\nexport default function reduce(state = initialState, action = {}) {\n const newState = { ...state };\n const { type, payload } = action;\n\n switch (type) {\n case \"UPDATE_NAMED_AREA_GROUP_PREVIOUS\":\n let newPrevNamedAreaGroup = { ...newState.prevNamedAreaGroup };\n newPrevNamedAreaGroup[payload.id] = payload.data;\n newState.prevNamedAreaGroup = newPrevNamedAreaGroup;\n // console.log(\n // \"UPDATE_NAMED_AREA_GROUP_PREVIOUS newPrevNamedAreaGroup\",\n // newPrevNamedAreaGroup\n // );\n return newState;\n case \"UPDATE_NAMED_AREA_GROUP_BUTTON_STATES_PREVIOUS\":\n let newPrevNamedAreaGroupButtonStates = {\n ...newState.prevNamedAreaGroupButtonStates,\n };\n newPrevNamedAreaGroupButtonStates[payload.id] = payload.data;\n newState.prevNamedAreaGroupButtonStates =\n newPrevNamedAreaGroupButtonStates;\n // console.log(\n // \"UPDATE_NAMED_AREA_GROUP_BUTTON_STATES_PREVIOUS newPrevNamedAreaGroupButtonStates\",\n // newPrevNamedAreaGroupButtonStates\n // );\n return newState;\n\n case \"RESET\":\n console.log(\"RESET! - Settings\");\n return initialState;\n default:\n return state;\n }\n}\n\nexport const getPrevNamedAreaGroups = (state) => {\n return Immutable(state.namedAreaGroups.prevNamedAreaGroup);\n};\n\nexport const getPrevNamedAreaGroupButtonStates = (state) => {\n return Immutable(state.namedAreaGroups.prevNamedAreaGroupButtonStates);\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Modal, Header, Icon, Button } from \"semantic-ui-react\";\nimport isEqual from \"lodash/isEqual\";\n\nimport {\n getAllAreaStatuses,\n getAllNamedAreaEvents,\n getButtonPrioritysInNamedAreaGroups,\n getNamedAreaEventButtonGroupState,\n} from \"components/WebWorker/reducer\";\n\nimport {\n getPrevNamedAreaGroups,\n getPrevNamedAreaGroupButtonStates,\n} from \"NamedAreaGroups/reducer\";\n\nimport {\n activateNamedAreaEvent,\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n updateButtonGroupState,\n} from \"OperationalChanges/actions\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport { area } from \"@turf/turf\";\n\n/*\n\nIf the Lighting Control layout is changed, e.g. through add, delete, move of namedAreas, Levels or Groups, \nthere may be some events which have not been impacted. \n\nrestorePrevActiveEvents() attempts to restore active events where possible.\n\nWhen the namedAreaGroup changes are saved middleware (see - src/NamedAreaGroups/middleware.js) intercepts \nthe 'UPDATE_NAMED_AREA_GROUP' message and saves a pre-save state of the namedAreaGroup and active events.\n\nAfter successful updates to the namedAreaGroup the active events are cleared.\nSee - src/admin/named-area-group/NamedAreaGroupEditPage.js > EditNamedAreaGroup > submitMyForm > then() callback > MQTT > \"system/clear/event\"\n\nThe user is then prompted with the option to \n#1 - continue on with the system cleared of events -> continue\n#2 - attempt to restore previously active events -> run restorePrevActiveEvents()\n\nsee - src/admin/named-area-group/NamedAreaGroupPostSaveOptionsModal.js\n\nWhy offer a choice?\n\nIf the users have substantially changed the Lighting Control layout it may not be necessary to restore events.\nFor example if all the current groups and levels are deleted and the layout is rebuilt, then any current events \nare unlikely to be relevant.\n\n*/\n\nconst _restorePrevActiveEvents = (areaId, { ...props }) => {\n const {\n namedAreaEvents,\n namedAreaGroupButtons,\n updateButtonGroupState,\n buttonGroupStates,\n activateNamedAreaEvent,\n prevNamedAreaGroups,\n prevNamedAreaGroupButtonStates,\n } = props;\n\n // console.log(\n // `report UPDATE_NAMED_AREA_GROUP ---------xxxxxxxxx-------------`,\n // areas,\n // namedAreaEvents,\n // namedAreaGroupButtons\n // );\n\n //console.clear();\n // console.log(`report UPDATE_NAMED_AREA_GROUP ---------${areaId}-------------`);\n // console.log(\n // `report UPDATE_NAMED_AREA_GROUP ---------namedAreaEventsByAreaId-------------`,\n // namedAreaEvents\n // );\n\n // fitler for test_area, active\n const activeAllNamedAreaEvents = namedAreaEvents\n .filter((event) => event.active && event.area === areaId)\n .map((event) => {\n const { id, priority } = event;\n return { id, priority };\n });\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP sortFilteredAllNamedAreaEvents\",\n // sortActiveAllNamedAreaEvents\n // );\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtons\",\n // namedAreaGroupButtons\n // );\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP activeAllNamedAreaEvents\",\n // activeAllNamedAreaEvents\n // );\n\n let namedAreaGroupButtonStates = [];\n namedAreaGroupButtons[areaId].forEach((button) => {\n const {\n id: buttonId,\n priority: buttonPriority,\n event: buttonEvent,\n level,\n group,\n } = button;\n\n const isActiveEvent = activeAllNamedAreaEvents.some(\n (event) =>\n event.id.includes(buttonId) && event.priority === buttonPriority\n );\n\n namedAreaGroupButtonStates.push({\n id: buttonId,\n priority: buttonPriority,\n active: isActiveEvent,\n buttonEvent: buttonEvent,\n level,\n group,\n });\n });\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP >>>>>>> namedAreaGroupButtonStates\",\n // namedAreaGroupButtonStates\n // );\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP >>>>>>> prevNamedAreaGroupButtonStates\",\n // prevNamedAreaGroupButtonStates\n // );\n\n // ------------------------------\n // restore to previous state\n // ------------------------------\n\n //\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP buttonGroupState\",\n // buttonGroupStates\n // );\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates -------------------------\"\n // );\n\n let newButtonGroupState = { ...buttonGroupStates };\n let newActiveEventList = [];\n\n namedAreaGroupButtonStates.forEach((button, index) => {\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates namedAreaGroupButtonState\",\n // button\n // );\n\n const { id, buttonEvent, level, group, priority } = button;\n\n // search for previous events with the same id on the same level and same group\n const prevNamedAreaGroupButtonState = prevNamedAreaGroupButtonStates?.[\n areaId\n ]?.filter(\n (button) =>\n button.id === id && button.level === level && button.group === group\n );\n // if find more than one event determine which, if any, to restore to previous state\n //\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates prevNamedAreaGroupButtonState\",\n // prevNamedAreaGroupButtonState\n // );\n\n // initially lets deal with first/top .............\n //\n // #NOTE - since the events are stepped through from highest priority first,\n // the next highest priority event will be set active.\n //\n // #REVIEW\n // - set the lowest active?\n // - only set if in same group?\n // - only set if on same level?\n //\n //\n // default to restore the highest priority button - typically only one, and we choose the first\n let restoreToButton = prevNamedAreaGroupButtonState?.[0]; // #NOTE - returns 1st array result which *should* have highest priority\n // however if there are multiple buttons decide on which to restore.\n if (prevNamedAreaGroupButtonState?.length > 1) {\n // If one is/was active, restore it\n const activeButton = prevNamedAreaGroupButtonState.filter(\n (button) => button.active\n );\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates restoreToButton activeButton \",\n // activeButton\n // );\n\n if (_isEmpty(activeButton)) {\n restoreToButton = activeButton;\n }\n }\n\n // if a previous event was found and event was active\n if (restoreToButton && restoreToButton?.active) {\n //\n // and if the event has not already been set here (only one event per polygon)\n if (!newActiveEventList.includes(id)) {\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates restoreToButton ####### ---> \",\n // restoreToButton,\n // \"buttonEvent \",\n // buttonEvent\n // );\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates restoreToButton ####### newButtonGroupState ---> \",\n // newButtonGroupState\n // );\n\n newButtonGroupState[id] = { 0: priority };\n updateButtonGroupState(newButtonGroupState);\n activateNamedAreaEvent(buttonEvent);\n newActiveEventList.push(id);\n }\n }\n });\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP prevNamedAreaGroups\",\n // prevNamedAreaGroups\n // );\n\n // console.log(\n // \"report UPDATE_NAMED_AREA_GROUP prevNamedAreaGroups ---------------------\"\n // );\n\n return null;\n};\n\nclass NamedAreaGroupPostSaveOptionsModal extends Component {\n constructor(props) {\n super(props);\n this.state = {\n modalOpen: false,\n restoreButton: { disabled: true, label: \"Please wait...\" },\n };\n }\n\n componentDidMount() {\n const { open } = this.props;\n\n if (open) {\n this.handleOpen();\n }\n\n // console.log(\n // \"UPDATE_NAMED_AREA_GROUP TurnOnOffPokeTheWorker ON !!!!!!!!!!!!!\"\n // );\n }\n\n componentWillUnmount() {\n // turn off data collection\n const { isPokeTheWorker } = this.props;\n if (isPokeTheWorker) {\n this.props.TurnOnOffPokeTheWorker(false);\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n }\n\n handleOpen = () => {\n // after the modal opens\n // enable data collection\n // Note - unmount disables again\n const { isPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n // set a timer so that the restore lights button can not be\n // activated until all the previous lighting resets have propogated\n // around the system\n //\n setTimeout(() => {\n this.setState({\n restoreButton: { disabled: false, label: \"\" },\n });\n }, 4000); // wait for a timeout before making button active\n\n this.setState({ modalOpen: true });\n };\n\n handleClose = () => {\n this.setState({ modalOpen: false });\n this.props.onResetError();\n };\n\n handleRestore = () => {\n // restore the lights --> FOR ALL AREAS!!!!!!!!!!!\n\n const { areas = [] } = this.props;\n\n areas.forEach((area) => {\n _restorePrevActiveEvents(area.id, this.props);\n });\n this.setState({ modalOpen: false });\n this.props.onResetError();\n };\n\n render() {\n // console.log(\n // \"UPDATE_NAMED_AREA_GROUP --------------- this.props\",\n // this.props\n // );\n\n return (\n <>\n \n
\n \n

\n Changes to the Lighting Control layout resets all lights,{\" \"}\n in all Areas, to the default state. Do you want\n to restore the lights to their previous states?{\" \"}\n {this.state.restoreButton.label}\n

\n
\n \n \n Yes, restore the lights\n \n \n {/* */}\n \n \n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n return {\n areas: getAllAreaStatuses(state),\n // namedAreaEventsByAreaId: getNamedAreaEventsByAreaId(state, areaId),\n namedAreaEvents: getAllNamedAreaEvents(state),\n // namedAreaGroupButtons: getButtonPrioritysInNamedAreaGroupByAreaId(\n // state,\n // areaId\n // ),\n namedAreaGroupButtons: getButtonPrioritysInNamedAreaGroups(state),\n namedAreaEventButtonGroupState: getNamedAreaEventButtonGroupState(state),\n buttonGroupStates: getNamedAreaEventButtonGroupState(state),\n prevNamedAreaGroups: getPrevNamedAreaGroups(state),\n prevNamedAreaGroupButtonStates: getPrevNamedAreaGroupButtonStates(state),\n isPokeTheWorker: isOnOffPokeTheWorker(state),\n };\n};\n\nexport default connect(mapStateToProps, {\n //\n activateNamedAreaEvent,\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n updateButtonGroupState,\n TurnOnOffPokeTheWorker,\n})(NamedAreaGroupPostSaveOptionsModal);\n","export function updateNamedAreaGroup(payload) {\n return { type: \"UPDATE_NAMED_AREA_GROUP\", payload };\n}\n\nexport function updateNamedAreaButtonsByParentIdMqtt(payload) {\n return {\n type: \"UPDATE_BUTTONS_IN_NAMED_AREAS_BY_PARENT_MQTT\",\n payload,\n };\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Dimmer, Loader } from \"semantic-ui-react\";\n\nimport { v4 as uuid } from \"uuid\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport {\n getNamedAreaParentStatusesByAreaId,\n getAreaStatusesById,\n} from \"components/WebWorker/reducer\";\nimport EditNamedAreaGroupForm from \"admin/named-area-group/NamedAreaGroupEditForm\";\nimport SubmissionModal from \"admin/SubmissionModal\";\nimport NamedAreaGroupPostSaveOptionsModal from \"admin/named-area-group/NamedAreaGroupPostSaveOptionsModal\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport {\n updateNamedAreaGroup,\n updateNamedAreaButtonsByParentIdMqtt,\n} from \"NamedAreaGroups/actions\";\n\nimport {\n SubmissionError,\n //\n // getFormValues,\n // getFormInitialValues,\n // getFormSyncErrors,\n // getFormMeta,\n // getFormAsyncErrors,\n // getFormSyncWarnings,\n // getFormSubmitErrors,\n // getFormError,\n // getFormNames,\n // isDirty,\n // isPristine,\n // isValid,\n // isInvalid,\n isSubmitting,\n hasSubmitSucceeded,\n // hasSubmitFailed,\n} from \"redux-form\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { messageToken } from \"utils/messageToken\";\nimport { mqttPublish } from \"components/WebWorker/actions\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { isMqttNotApiPost } from \"components/ConfigJs\";\n\nimport { getAllNamedAreaStatuses } from \"components/WebWorker/reducer\";\nimport { sendNamedAreaButtonUpdateByParent } from \"components/WebWorker/sendNamedAreaButtonUpdateByParent\";\nimport {\n saveNewNamedArea, //deleteNamedArea\n} from \"NamedAreas/actions\";\n\nclass EditNamedAreaGroup extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n initialValues: {},\n submitted: false,\n saveSuccess: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n //console.log(\"this.getInitialValues()\", this.getInitialValues());\n this.setState({ initialValues: this.getInitialValues() });\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n getInitialValues = () => {\n const { areaId, namedAreaParents, namedAreaGroup } = this.props;\n //console.log(`xxx namedAreaParents`, namedAreaParents);\n const namedAreas = namedAreaParents.filter(\n (na) =>\n na.type.toLowerCase() === \"polygon\" &&\n na.sub_type?.toLowerCase() === \"region\"\n );\n\n //console.log(`getInitialValues`, namedAreas);\n\n let listOfNamedAreas = [];\n namedAreas.map((namedArea) => {\n listOfNamedAreas.push({\n id: uuid(),\n label: `${namedArea.namedArea}`,\n namedArea: {\n id: namedArea.id,\n priority: 1,\n label: `${namedArea.namedArea}`,\n },\n });\n });\n\n const initialValues = {\n mineLevelId: areaId,\n listOfNamedAreas,\n data: namedAreaGroup,\n };\n\n return initialValues;\n };\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n\n const { goto, submitting, submitSucceeded } = this.props;\n\n this.setState({ errorMessage: \"\" });\n\n // if we've just submit the form -> leave\n if (submitting || submitSucceeded) {\n goto(\"/\");\n }\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n setItemsPriority = (items) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and replace object by id\n\n // keep a record of the buttons/priority to be defined for named areas\n let namedAreaParentsChanges = {};\n // e.g.\n // Indicates the button (i.e. event) settings for particular priorities. Other priorities can be empty objects {}.\n // namedAreaParentsChanges = {\n // \"DMLZ_Extraction:AREA_A\": {\n // 5: {\n // priority: 0,\n // id: \"\",\n // named_area: \"\",\n // clickable: true,\n // icon: \"icon-earthquake0\",\n // title: \"Seismic 0\",\n // alt: \"Level 0\",\n // color: \"green\",\n // group: 0,\n // type: \"SEISMIC0_EVENT\",\n // hint: \"Level 0\",\n // default: true,\n // active_state: \"on\",\n // active_color: \"green\",\n // active_alternate_color: \"off\",\n // state: \"on\",\n // on_time: 0,\n // off_time: 0,\n // train: 0,\n // active: true,\n // },\n // 7: {\n // priority: 0,\n // id: \"\",\n // named_area: \"\",\n // ...........\n // train: 0,\n // active: true,\n // },\n // },\n // };\n\n let newItems = JSON.parse(JSON.stringify(items));\n //console.log(\"setItemsPriority newItems\", newItems);\n\n let priorityBase = 1;\n\n for (let indexGroup = newItems.length - 1; indexGroup >= 0; indexGroup--) {\n const group = newItems[indexGroup];\n //console.log(\"setItemsPriority group\", group);\n const { subItems: levels } = group;\n\n if (levels !== undefined) {\n for (\n let indexLevel = levels.length - 1;\n indexLevel >= 0;\n indexLevel--\n ) {\n const level = levels[indexLevel];\n //console.log(\"setItemsPriority level\", level);\n const { subItems: namedAreas } = level;\n if (namedAreas !== undefined) {\n for (\n let indexNamedArea = namedAreas.length - 1;\n indexNamedArea >= 0;\n indexNamedArea--\n ) {\n const namedArea = namedAreas[indexNamedArea];\n newItems[indexGroup].subItems[indexLevel].subItems[\n indexNamedArea\n ].namedArea.button.priority = priorityBase;\n\n const temp =\n namedAreaParentsChanges[namedArea.namedArea.id] || {};\n temp[priorityBase] = namedArea.namedArea.button;\n namedAreaParentsChanges[namedArea.namedArea.id] = temp;\n\n // console.log(\n // \"save setItemsPriority namedArea ... update priority\",\n // priorityBase,\n // namedAreaParentsChanges,\n // namedArea.namedArea.id\n // );\n priorityBase++;\n }\n }\n }\n }\n }\n\n return { newItems, namedAreaParentsChanges };\n };\n\n submitMyForm = (values) => {\n //console.log(`submitMyForm values`, values);\n\n const { mineLevelId, data } = values;\n\n const { namedAreaParents, namedAreaStatuses } = this.props;\n\n const { newItems, namedAreaParentsChanges } = this.setItemsPriority(data);\n\n // console.log(\n // \"EditNamedAreaGroupForm onSubmit namedAreaParents\",\n // namedAreaParents\n // );\n\n let buttonChanges = [];\n\n // #WIP - add a button to all namedAreas\n namedAreaParents.forEach((parent) => {\n const { id, type } = parent;\n\n // console.log(\"id\", id);\n // console.log(\"namedAreaParentsChanges\", namedAreaParentsChanges);\n\n if (type.toLowerCase() === \"polygon\") {\n const buttons = namedAreaParentsChanges[id];\n if (buttons !== undefined) {\n // console.log(\"buttons\", buttons);\n\n const setButtonsByPriority = Object.keys(buttons).sort();\n // console.log(\"setButtonsByPriority\", setButtonsByPriority);\n\n const maxPriority = Math.max(...setButtonsByPriority);\n // console.log(\"maxPriority\", maxPriority);\n\n let newButtons = [];\n for (let index = 0; index < maxPriority + 1; index++) {\n if (setButtonsByPriority.includes(index.toString())) {\n newButtons[index] = buttons[index];\n } else {\n // #WIP #TODO - move button template elsewhere\n\n newButtons[index] = {\n id: uuid(),\n named_area: id,\n clickable: false,\n icon: \"icon-earthquake0\",\n priority: index,\n title: \"Seismic 0\",\n alt: \"Level 0\",\n color: \"green\",\n group: 0,\n type: \"SEISMIC0_EVENT\",\n hint: \"Level 0\",\n default: true,\n active_state: \"on\",\n active_color: \"green\",\n active_alternate_color: \"off\",\n state: \"on\",\n on_time: 0,\n off_time: 0,\n train: 0,\n active: false,\n marker: \"RoundMarker\",\n };\n }\n }\n\n buttonChanges.push({ parentId: id, buttons: newButtons });\n\n //console.log(\"newButtons\", newButtons);\n\n //this.props.updateNamedAreaButtonsByParentId()\n // const { id, type, settings } = changeSetting;\n // const namedAreaPayload = {\n // topic: `named_area/${namedAreaMsg.id}/change`,\n // qos: 0,\n // message: namedAreaMsg,\n // retained: false,\n // };\n // this.props.updateNamedAreas({ newValues, resolve, reject})\n\n //console.log(\"save namedAreaParents\", parent);\n }\n }\n //console.log(\"buttonChanges\", buttonChanges);\n });\n\n // #NOTE - create a function\n // see - src/admin/named-area-simple/NamedAreaSimpleList.js\n // get current area info\n const {\n id,\n image_filename,\n image_info,\n slug,\n coordinatesUtm,\n ref_coord,\n floor,\n ceiling,\n default_color,\n default_state,\n } = this.props.area;\n\n let bounds = [];\n\n // protect against no coordinates set\n if (!_isEmpty(coordinatesUtm)) {\n if (coordinatesUtm[0].length === 4) {\n bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n const firstPoint = bounds[0];\n bounds.push(firstPoint);\n }\n }\n\n // create new Area with updated namedAreaGroup\n const newArea = {\n id,\n image_filename,\n image_info: JSON.stringify(image_info),\n slug,\n bounds: bounds,\n ref_coord,\n floor,\n ceiling,\n default_color: default_color.toUpperCase(),\n default_state: default_state.toUpperCase(),\n named_area_group: JSON.stringify(newItems),\n };\n\n const newValues = { id: id, data: newArea };\n //console.log(\"newValues\", newValues);\n\n let promiseArray = [];\n\n // with changes to button states, resend the button structure for the namedAreas\n //\n buttonChanges.forEach((change) => {\n const { parentId, buttons } = change;\n\n // if MQTT msg for 'named_area/id/change', then prepare and publish a mqtt message\n if (isMqttNotApiPost()) {\n this.props.updateNamedAreaButtonsByParentIdMqtt({\n parentId,\n buttons,\n });\n // else if API POST then send post a /change_named_area message\n } else {\n const publishChanges = sendNamedAreaButtonUpdateByParent(\n namedAreaStatuses,\n parentId,\n buttons\n );\n publishChanges.forEach((change) => {\n // this is destructured b/c reusing a message intended to be published 'message' via mqtt\n const { message } = change;\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.saveNewNamedArea({\n values: message,\n resolve,\n reject,\n })\n )\n );\n });\n }\n });\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.updateNamedAreaGroup({\n values: newValues,\n resolve,\n reject,\n })\n )\n );\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\".... change named areas.\", results);\n })\n .then(() => {\n console.log(\"CLEAR ALL SYSTEM EVENTS - system/event/clear\");\n // after namedAreaGroup has changed, clear the existing events.\n\n //\n // #WIP\n // - this needs to change to clear only defined AREAS\n // - change to API which can be resolved\n // -\n this.props.mqttPublish({\n topic: `system/event/clear`,\n qos: 0,\n message: {\n clear_events: true,\n token: messageToken(),\n },\n retained: false,\n });\n\n this.setState({ saveSuccess: true });\n })\n .then(() => {\n if (false) {\n // at this stage, pop a dlg informing the user that they need to reset the control screen polygons\n const message = {\n header: {\n icon: \"warning\",\n title: \"Review Lighting Controls\",\n },\n content:\n \"You have saved changes to the Lighting Layout. Saving changes to the Control Layout will clear all current light states for all Areas! ---#WIP--THIS SHOULD POPUP A MODAL INSTEAD!\",\n };\n this.setState({\n errorMessage:\n \"Re-enable all lights on polygons after saving changes to the Control layout.\",\n modalMessage: message,\n });\n //this.onResetError();\n //this.props.goto(\"/\");\n }\n })\n .catch((error) => {\n console.log(`onSubmit error`, error);\n this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const { error, submitting, areaId, strings, userSettings } = this.props;\n const { modalMessage, errorMessage, initialValues } = this.state;\n\n //console.log(\"xxx EditNamedAreaGroup - strings\", strings);\n\n const openModal = errorMessage !== \"\";\n\n if (error) {\n return (\n <>\n \n \n \n );\n }\n\n return (\n <>\n this.onResetError()}\n id={areaId}\n />\n this.onResetError()}\n modalMessage={modalMessage}\n errorMessage={errorMessage}\n />\n \n Saving changes\n \n this.submitMyForm(formValues)}\n />\n this.submitMyForm(values)}\n strings={strings}\n userSettings={userSettings}\n // #NOTE - disabled as this is fired as soon as submit,\n // *not* after successful completion of the Promise!!\n // onSubmitSuccess={(result, dispatch) => {\n // //console.log(`onSubmitSuccess ${result}`);\n // // wait for state change before redirecting page\n // this.setState(\n // {\n // submitted: true,\n // },\n // () => {\n // // at this stage, pop a dlg informing the user that they need to reset the control screen polygons\n // const message = {\n // header: {\n // icon: \"warning\",\n // title: \"Review Lighting Controls\",\n // },\n // content:\n // \"You have saved changes to the Lighting Layout. Saving changes to the Control Layout will clear all current light states for all Areas! \",\n // };\n // this.setState({\n // errorMessage:\n // \"Re-enable all lights on polygons after saving changes to the Control layout.\",\n // modalMessage: message,\n // });\n // //this.onResetError();\n // //this.props.goto(\"/\");\n // }\n // );\n // }}\n onSubmitFail={(errors) => {\n console.log(`onSubmitFail ${errors}`);\n }}\n onCancel={() => {\n this.props.goto(\"/admin/named-area-group\");\n }}\n />\n \n );\n }\n}\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n mqttPublish: (msg) => dispatch(mqttPublish(msg)),\n goto: (path) => dispatch(push(path)),\n updateNamedAreaGroup: (data) => dispatch(updateNamedAreaGroup(data)),\n updateNamedAreaButtonsByParentIdMqtt: (data) =>\n dispatch(updateNamedAreaButtonsByParentIdMqtt(data)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n saveNewNamedArea: (data) => dispatch(saveNewNamedArea(data)),\n };\n};\n\n//export default connect(null, { updateMineLevel })(EditMineLevel);\n\nfunction mapStateToProps(state, props) {\n const match = props.match;\n const id = match.params.id;\n // const nameArray = id.split(\":\");\n // const mineLevelId = nameArray[0];\n\n // #REVIEW - this code is used in a few places\n // let name;\n // if (nameArray[1] === undefined) {\n // // for edit form use namedArea name (i.e. not `Level Wide (${nameArray[0]})`)\n // name = nameArray[0];\n // } else {\n // name = nameArray[1];\n // }\n\n const namedAreaParents = getNamedAreaParentStatusesByAreaId(state, id);\n const area = getAreaStatusesById(state, id);\n const namedAreaGroup = area?.namedAreaGroup || [];\n\n // console.log(\"NamedAreaGroupEditPage namedAreaGroup\", namedAreaGroup);\n // console.log(\"NamedAreaGroupEditPage namedAreaParents\", namedAreaParents);\n\n return {\n areaId: id,\n namedAreaParents,\n namedAreaGroup,\n area,\n namedAreaStatuses: getAllNamedAreaStatuses(state),\n submitting: isSubmitting(\"editNamedAreaGroupForm\")(state),\n submitSucceeded: hasSubmitSucceeded(\"editNamedAreaGroupForm\")(state),\n\n // error: namedAreaGroup === undefined ? \"Named Area Group not found\" : null,\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(EditNamedAreaGroup);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\n\nimport ListNamedAreaGroup from \"admin/named-area-group/NamedAreaGroupList\";\nimport CreateNamedAreaGroup from \"admin/named-area-group/NamedAreaGroupCreatePage\";\nimport EditNamedAreaGroup from \"admin/named-area-group/NamedAreaGroupEditPage\";\n\nclass NamedAreaGroupAdminPages extends Component {\n componentDidMount() {\n //this.props.fetchNamedAreaGroups() // --- ??????????\n }\n\n render() {\n const { match, strings, userSettings } = this.props;\n\n // console.log(\"xxx NamedAreaGroupAdminPages - strings\", strings);\n\n return (\n \n (\n \n )}\n />\n (\n \n )}\n />\n (\n \n )}\n />\n \n );\n }\n}\n\nexport default withRouter(connect(null, null)(NamedAreaGroupAdminPages));\n","import React, { Component } from \"react\";\nimport { Modal, Header, Icon, Button } from \"semantic-ui-react\";\n\nexport default class EnableDisableButton extends Component {\n state = { open: false };\n\n clicked = (e) => {\n const { onClick, id } = this.props;\n onClick(id);\n };\n close = () => this.setState({ open: false });\n open = () => this.setState({ open: true });\n\n render() {\n const { open } = this.state;\n const { label, color, disabled = false, size = \"large\" } = this.props;\n return (\n {\n e.preventDefault(); // Stop any form validation\n this.open();\n }}\n disabled={disabled}\n size={size}\n >\n {label}\n \n }\n basic\n size=\"small\"\n >\n
\n \n

Are you sure you want to {label.toLowerCase()}?

\n
\n \n \n \n \n \n );\n }\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\n//import { getAllNamedAreas } from \"NamedAreas/reducer\";\n\nimport {\n getAllNamedAreaStatuses,\n getAllAreaStatuses,\n} from \"components/WebWorker/reducer\";\nimport { deleteNamedArea } from \"NamedAreas/actions\";\nimport { updateNamedAreaGroup } from \"NamedAreaGroups/actions\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ListNamedAreas extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n namedArea: \"\",\n area: \"\",\n id: \"\",\n subType: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n //const { data, fetchNamedAreas } = this.props;\n // if (_isEmpty(data)) {\n // // #FETCHS\n // fetchNamedAreas(); // #FETCHS\n // }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n // #NOTE - create a function\n // src/admin/named-area-group/NamedAreaGroupTableItems.js\n deleteItemByNamedAreaParentId = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n // #NOTE - create a function\n // see - src/admin/named-area-group/NamedAreaGroupEditPage.js\n\n newNamedAreaGroup = (allAreas, allNamedAreas, namedAreaId) => {\n const namedArea = allNamedAreas.find(\n (namedArea) => namedArea.id === namedAreaId\n );\n const { area: areaId, parent: parentId } = namedArea;\n\n if (_isEmpty(areaId)) {\n return null;\n }\n\n const area = allAreas.find((area) => area.id === areaId);\n\n if (_isEmpty(area)) {\n return null;\n }\n\n // get current area info\n const {\n id,\n image_filename,\n image_info,\n slug,\n coordinatesUtm,\n ref_coord,\n floor,\n ceiling,\n default_color,\n default_state,\n namedAreaGroup,\n } = area;\n\n // update namedAreaGroup - delete current namedArea if exists\n if (_isEmpty(namedAreaGroup)) {\n return null;\n }\n\n const cloneItems = !_isEmpty(namedAreaGroup)\n ? JSON.parse(JSON.stringify(namedAreaGroup))\n : [];\n\n const newItems = this.deleteItemByNamedAreaParentId(cloneItems, parentId);\n\n let bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n const firstPoint = bounds[0];\n bounds.push(firstPoint);\n\n // create new Area with updated namedAreaGroup\n const newArea = {\n id,\n image_filename,\n image_info: JSON.stringify(image_info),\n slug,\n bounds: bounds,\n ref_coord,\n floor,\n ceiling,\n default_color: default_color.toUpperCase(),\n default_state: default_state.toUpperCase(),\n named_area_group: JSON.stringify(newItems),\n };\n\n const newValues = { id: id, data: newArea };\n\n return newValues;\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n const {\n allNamedAreas,\n allAreas,\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n } = this.props;\n\n let namedAreas = [];\n for (var key in selections) {\n const selection = key;\n allNamedAreas.forEach((namedArea, idx) => {\n const { id, parent } = namedArea;\n // selections are parents, so match whole parent. eg.\"DMLZ_Extraction:1234\" in \"DMLZ_Extraction:1234:1604620816915\"\n if (parent === selection) {\n namedAreas.push(id);\n }\n });\n }\n\n let promiseArray = [];\n\n namedAreas.forEach((namedArea) => {\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({ values: { id: namedArea }, resolve, reject })\n )\n );\n\n const newNamedAreaGroup = this.newNamedAreaGroup(\n allAreas,\n allNamedAreas,\n namedArea\n );\n\n // in loop because could be named area from different areas\n promiseArray.push(\n new Promise((resolve, reject) =>\n updateNamedAreaGroup({\n values: newNamedAreaGroup,\n resolve,\n reject,\n })\n )\n );\n });\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\".... deleted named areas.\", results);\n })\n .then(\n () => {\n push(\"/admin/named-area-advanced\");\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error } = this.props;\n const { column, data, direction } = this.state;\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const namedAreaFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let enableButton;\n let disableButton;\n let deleteButton;\n let namedAreaSelectedList;\n if (selectedCount > 0) {\n let namedAreaNames = [];\n //console.log(\"data\", data);\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (namedAreaFromDataById(key) !== undefined) {\n let namedAreaName = namedAreaFromDataById(key).namedArea;\n\n // namedAreaName = namedAreaName.substring(\n // 0,\n // namedAreaName.indexOf(\" (\")\n // ); // strip off the trailing ip\n namedAreaNames.push(namedAreaName);\n }\n }\n namedAreaNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n namedAreaNames = namedAreaNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n size=\"large\"\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n size=\"large\"\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")}\n size=\"large\"\n />\n );\n\n namedAreaSelectedList = (\n \n {`${strNamedAreas} selected ...`} \n {namedAreaNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{`Advanced Parent ${strNamedAreas}`}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n \n \n {deleteButton}\n {/* \n {enableButton}\n \n {disableButton} */}\n \n
\n
\n {viewablesPage.length} items displayed.\n
\n \n {namedAreaSelectedList}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strNamedArea}\n \n \n ID\n \n \n Type\n \n \n Area\n \n \n \n \n \n {_.map(viewablesPage, ({ id, namedAreaLink, area, subType }) => (\n \n \n this.handleSelect(id)}\n />\n \n {namedAreaLink}\n {id}\n {subType}\n {area || \"-\"}\n \n \n ))}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements) => {\n // list only unique parents\n const uniqueParents = elements\n .map((item) => item.parent)\n .filter((value, index, self) => self.indexOf(value) === index);\n\n let filteredParents = [];\n uniqueParents.forEach(function (uniqueParent, idx) {\n const namedAreaParentInfo = elements.find(\n (item) => item.parent === uniqueParent\n );\n\n const {\n area,\n active,\n sub_type,\n parent_name: parentName,\n } = namedAreaParentInfo;\n\n const id = uniqueParent;\n const nameArray = uniqueParent.split(\":\");\n\n // #NOTE\n // This is historical code when LEVEL_WIDE was listed as a named areas for\n // config. ALL_AREAS, LEVEL_WIDE are excluded from the list for now.\n // See comments `exclude ALL_AREAS, LEVEL_WIDE`\n\n let name;\n if (parentName.length <= 0) {\n if (nameArray.length < 2) {\n // ALL_AREAS, LEVEL_WIDE named area\n name = `Level Wide (${nameArray[0]})`;\n // exclude ALL_AREAS, LEVEL_WIDE\n // filteredParents[idx] = { ....}\n } else {\n name = nameArray[1];\n // compose new data set\n }\n } else {\n name = parentName;\n }\n\n filteredParents[idx] = {\n id: id,\n active: true, // active,\n namedArea: name,\n namedAreaLink: (\n {name} \n ),\n subType: sub_type,\n area: area,\n };\n });\n\n return filteredParents;\n};\n\nfunction mapStateToProps(state) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.namedAreas;\n const isLoading = false;\n const error = false;\n\n // exclude ALL_AREAS, LEVEL_WIDE\n const allNamedAreas = getAllNamedAreaStatuses(state).filter(\n (na) => na.type !== \"LEVEL_WIDE\" && na.type !== \"ALL_AREAS\"\n );\n\n const allAreas = getAllAreaStatuses(state);\n\n const data = _prepData(allNamedAreas);\n\n return {\n isLoading,\n error,\n data,\n allNamedAreas,\n allAreas,\n };\n}\n\nexport default connect(mapStateToProps, {\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n fetchNamedAreas,\n})(ListNamedAreas);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\n//import { getAllNamedAreas } from \"NamedAreas/reducer\";\n\nimport {\n getAllNamedAreaStatuses,\n getAllAreaStatuses,\n} from \"components/WebWorker/reducer\";\nimport { deleteNamedArea } from \"NamedAreas/actions\";\nimport { updateNamedAreaGroup } from \"NamedAreaGroups/actions\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ListAllNamedAreas extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n id: \"\",\n parentName: \"\",\n area: \"\",\n type: \"\",\n subType: \"\",\n relayEventActive: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n const { data, fetchNamedAreas } = this.props;\n // if (_isEmpty(data)) {\n // // #FETCHS\n // fetchNamedAreas(); // #FETCHS\n // }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n // #NOTE - create a function\n // src/admin/named-area-group/NamedAreaGroupTableItems.js\n deleteItemByNamedAreaParentId = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n // #NOTE - create a function\n // see - src/admin/named-area-group/NamedAreaGroupEditPage.js\n\n newNamedAreaGroup = (allAreas, allNamedAreas, namedAreaId) => {\n const namedArea = allNamedAreas.find(\n (namedArea) => namedArea.id === namedAreaId\n );\n const { area: areaId, parent: parentId } = namedArea;\n\n if (_isEmpty(areaId)) {\n return null;\n }\n\n const area = allAreas.find((area) => area.id === areaId);\n\n if (_isEmpty(area)) {\n return null;\n }\n\n // get current area info\n const {\n id,\n image_filename,\n image_info,\n slug,\n coordinatesUtm,\n ref_coord,\n floor,\n ceiling,\n default_color,\n default_state,\n namedAreaGroup,\n } = area;\n\n // update namedAreaGroup - delete current namedArea if exists\n if (_isEmpty(namedAreaGroup)) {\n return null;\n }\n\n const cloneItems = !_isEmpty(namedAreaGroup)\n ? JSON.parse(JSON.stringify(namedAreaGroup))\n : [];\n\n const newItems = this.deleteItemByNamedAreaParentId(cloneItems, parentId);\n\n let bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n const firstPoint = bounds[0];\n bounds.push(firstPoint);\n\n // create new Area with updated namedAreaGroup\n const newArea = {\n id,\n image_filename,\n image_info: JSON.stringify(image_info),\n slug,\n bounds: bounds,\n ref_coord,\n floor,\n ceiling,\n default_color: default_color.toUpperCase(),\n default_state: default_state.toUpperCase(),\n named_area_group: JSON.stringify(newItems),\n };\n\n const newValues = { id: id, data: newArea };\n\n return newValues;\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n const {\n allNamedAreas,\n allAreas,\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n } = this.props;\n\n let namedAreas = [];\n for (var key in selections) {\n const selection = key;\n allNamedAreas.forEach((namedArea, idx) => {\n const { id, parent } = namedArea;\n // selections are parents, so match whole parent. eg.\"DMLZ_Extraction:1234\" in \"DMLZ_Extraction:1234:1604620816915\"\n if (parent === selection) {\n namedAreas.push(id);\n }\n });\n }\n\n let promiseArray = [];\n\n namedAreas.forEach((namedArea) => {\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({ values: { id: namedArea }, resolve, reject })\n )\n );\n\n const newNamedAreaGroup = this.newNamedAreaGroup(\n allAreas,\n allNamedAreas,\n namedArea\n );\n\n // in loop because could be named area from different areas\n promiseArray.push(\n new Promise((resolve, reject) =>\n updateNamedAreaGroup({\n values: newNamedAreaGroup,\n resolve,\n reject,\n })\n )\n );\n });\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\".... deleted named areas.\", results);\n })\n .then(\n () => {\n push(\"/admin/named-area-advanced/all\");\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error } = this.props;\n const { column, data, direction } = this.state;\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const namedAreaFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let enableButton;\n let disableButton;\n let deleteButton;\n let namedAreaSelectedList;\n if (selectedCount > 0) {\n let namedAreaNames = [];\n //console.log(\"data\", data);\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (namedAreaFromDataById(key) !== undefined) {\n let namedAreaName = namedAreaFromDataById(key).namedArea;\n\n // namedAreaName = namedAreaName.substring(\n // 0,\n // namedAreaName.indexOf(\" (\")\n // ); // strip off the trailing ip\n namedAreaNames.push(namedAreaName);\n }\n }\n namedAreaNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n namedAreaNames = namedAreaNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")} />\n );\n\n namedAreaSelectedList = (\n \n {`${strNamedAreas} selected ...`} \n {namedAreaNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{`Advanced All ${strNamedAreas}`}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n {false && (\n \n \n \n {deleteButton}\n {/* \n {enableButton}\n \n {disableButton} */}\n \n
\n
\n {viewablesPage.length} items displayed.\n
\n \n {namedAreaSelectedList}\n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* this.handleSelectAll(viewablesPage)}\n /> */}\n \n \n {strNamedArea}\n \n \n Parent\n \n \n Type\n \n \n Sub Type\n \n \n Area\n \n \n Relay Event Active\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n name,\n area,\n type,\n subType,\n parentName,\n relayEventActive,\n }) => (\n \n \n {/* this.handleSelect(id)}\n /> */}\n \n {id}\n {parentName}\n {type}\n {subType}\n {area}\n {relayEventActive}\n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements) => {\n let filtered = [];\n elements.forEach(function (element, idx) {\n const {\n id,\n name,\n area,\n type,\n sub_type,\n parent_name,\n relay_event_active,\n relay_event_inactive,\n } = element;\n\n filtered[idx] = {\n id,\n name,\n area,\n type,\n subType: sub_type,\n parentName: parent_name,\n relayEventActive: `${relay_event_active}`,\n\n //relay_event_inactive,\n };\n });\n\n return filtered;\n};\n\nfunction mapStateToProps(state) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.namedAreas;\n const isLoading = false;\n const error = false;\n\n const allNamedAreas = getAllNamedAreaStatuses(state);\n const allAreas = getAllAreaStatuses(state);\n const data = _prepData(allNamedAreas);\n\n return {\n isLoading,\n error,\n data,\n allNamedAreas,\n allAreas,\n };\n}\n\nexport default connect(mapStateToProps, {\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n fetchNamedAreas,\n})(ListAllNamedAreas);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n Popup,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\n//import { getAllNamedAreas } from \"NamedAreas/reducer\";\n\nimport {\n getAllNamedAreaEvents,\n getAllAreaStatuses,\n} from \"components/WebWorker/reducer\";\nimport { deleteNamedArea } from \"NamedAreas/actions\";\nimport { updateNamedAreaGroup } from \"NamedAreaGroups/actions\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { mqttPublish } from \"components/WebWorker/actions\";\nimport { messageToken, getUserSessionIp } from \"utils/messageToken\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ListAllNamedAreaEvents extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search id: \"\",\n active: \"\",\n priority: \"\",\n activeColor: \"\",\n activeState: \"\",\n button: \"\",\n relayEventActive: \"\",\n origin: \"\",\n operator: \"\",\n disable: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n //const { data, fetchNamedAreas } = this.props;\n // if (_isEmpty(data)) {\n // // #FETCHS\n // fetchNamedAreas(); // #FETCHS\n // }\n\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"allNamedAreaEventsList\"\n );\n\n if (!_isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"allNamedAreaEventsList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n //console.log(`xxx item[key]`, item[key]);\n //console.log(`xxx match[key]`, match[key]);\n\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n sendEventClearMsg = () => {\n this.props.mqttPublish({\n topic: `system/event/clear`,\n qos: 0,\n message: {\n clear_events: true,\n token: messageToken(),\n },\n retained: false,\n });\n };\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n // #NOTE - create a function\n // src/admin/named-area-group/NamedAreaGroupTableItems.js\n deleteItemByNamedAreaParentId = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n // #NOTE - create a function\n // see - src/admin/named-area-group/NamedAreaGroupEditPage.js\n\n newNamedAreaGroup = (allAreas, allNamedAreas, namedAreaId) => {\n const namedArea = allNamedAreas.find(\n (namedArea) => namedArea.id === namedAreaId\n );\n const { area: areaId, parent: parentId } = namedArea;\n\n if (_isEmpty(areaId)) {\n return null;\n }\n\n const area = allAreas.find((area) => area.id === areaId);\n\n if (_isEmpty(area)) {\n return null;\n }\n\n // get current area info\n const {\n id,\n image_filename,\n image_info,\n slug,\n coordinatesUtm,\n ref_coord,\n floor,\n ceiling,\n default_color,\n default_state,\n namedAreaGroup,\n } = area;\n\n // update namedAreaGroup - delete current namedArea if exists\n if (_isEmpty(namedAreaGroup)) {\n return null;\n }\n\n const cloneItems = !_isEmpty(namedAreaGroup)\n ? JSON.parse(JSON.stringify(namedAreaGroup))\n : [];\n\n const newItems = this.deleteItemByNamedAreaParentId(cloneItems, parentId);\n\n let bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n const firstPoint = bounds[0];\n bounds.push(firstPoint);\n\n // create new Area with updated namedAreaGroup\n const newArea = {\n id,\n image_filename,\n image_info: JSON.stringify(image_info),\n slug,\n bounds: bounds,\n ref_coord,\n floor,\n ceiling,\n default_color: default_color.toUpperCase(),\n default_state: default_state.toUpperCase(),\n named_area_group: JSON.stringify(newItems),\n };\n\n const newValues = { id: id, data: newArea };\n\n return newValues;\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n const {\n allNamedAreas,\n allAreas,\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n } = this.props;\n\n let namedAreas = [];\n for (var key in selections) {\n const selection = key;\n allNamedAreas.forEach((namedArea, idx) => {\n const { id, parent } = namedArea;\n // selections are parents, so match whole parent. eg.\"DMLZ_Extraction:1234\" in \"DMLZ_Extraction:1234:1604620816915\"\n if (parent === selection) {\n namedAreas.push(id);\n }\n });\n }\n\n let promiseArray = [];\n\n namedAreas.forEach((namedArea) => {\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({ values: { id: namedArea }, resolve, reject })\n )\n );\n\n const newNamedAreaGroup = this.newNamedAreaGroup(\n allAreas,\n allNamedAreas,\n namedArea\n );\n\n // in loop because could be named area from different areas\n promiseArray.push(\n new Promise((resolve, reject) =>\n updateNamedAreaGroup({\n values: newNamedAreaGroup,\n resolve,\n reject,\n })\n )\n );\n });\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\".... deleted named areas.\", results);\n })\n .then(\n () => {\n push(\"/admin/named-area-advanced/all-events\");\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const namedAreaFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let enableButton;\n let disableButton;\n let deleteButton;\n let namedAreaSelectedList;\n if (selectedCount > 0) {\n let namedAreaNames = [];\n //console.log(\"data\", data);\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (namedAreaFromDataById(key) !== undefined) {\n let namedAreaName = namedAreaFromDataById(key).namedArea;\n\n // namedAreaName = namedAreaName.substring(\n // 0,\n // namedAreaName.indexOf(\" (\")\n // ); // strip off the trailing ip\n namedAreaNames.push(namedAreaName);\n }\n }\n namedAreaNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n namedAreaNames = namedAreaNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")} />\n );\n\n namedAreaSelectedList = (\n \n {`${strNamedAreas} selected ...`} \n {namedAreaNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{`Advanced All Events`}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n \n \n }\n />\n\n {false && !areAnySelected && (\n Select items in the table below to apply an action.\n )}\n \n \n {selectedCount} selected\n \n \n \n {deleteButton}\n {/* \n {enableButton}\n \n {disableButton} */}\n \n
\n
\n {viewablesPage.length} items displayed.\n
\n \n {namedAreaSelectedList}\n \n \n \n \n {/* \n \n */}\n {/* \n \n */}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* \n this.handleSelectAll(viewablesPage)}\n />\n */}\n {/* \n Disabled\n */}\n \n Event\n \n \n Active\n \n \n Priority\n \n \n Active Color\n \n \n Active State\n \n \n State Info ( On | Off | Train)\n \n {\"Range (Start -> End)\"}\n \n Button Info\n \n \n Relay Event Active\n \n \n Origin\n \n \n Operator\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n active,\n priority,\n activeColor,\n activeState,\n button,\n relayEventActive,\n activeStateInfo,\n range,\n origin,\n operator,\n disable,\n style,\n }) => (\n \n {/* \n this.handleSelect(id)}\n />\n */}\n {/* {disable} */}\n {id}\n {active}\n {priority}\n {activeColor}\n {activeState}\n {activeStateInfo}\n {range}\n {button}\n {relayEventActive}\n {origin}\n {operator}\n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements) => {\n let filtered = [];\n elements.forEach(function (element, idx) {\n const {\n id,\n active,\n active_color,\n active_state,\n priority,\n button_groups,\n relay_event_active,\n //relay_event_inactive,\n on_time,\n off_time,\n train,\n start,\n end,\n origin,\n operator,\n disable,\n note,\n password,\n } = element;\n\n let style = null;\n // set style of disabled events\n if (disable === true) {\n style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n }\n\n filtered[idx] = {\n id,\n active: `${active}`,\n activeColor: active_color,\n activeState: active_state,\n activeStateInfo: `${on_time || \"-\"} | ${off_time || \"-\"} | ${\n train || \"-\"\n }`,\n range: `${start | \"-\"} -> ${end | \"-\"}`,\n priority: `${priority}`,\n button: JSON.stringify(button_groups),\n relayEventActive: `${relay_event_active || \"-\"}`,\n //relay_event_inactive, // #NOTE - not supported ATM\n origin: origin,\n operator: operator,\n disable: `${disable}`,\n note,\n password,\n style,\n };\n });\n\n return filtered;\n};\n\nfunction mapStateToProps(state) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.namedAreas;\n const isLoading = false;\n const error = false;\n\n const allNamedAreaEvents = getAllNamedAreaEvents(state);\n\n const allAreas = getAllAreaStatuses(state);\n\n const data = _prepData(allNamedAreaEvents);\n\n return {\n isLoading,\n error,\n data,\n allAreas,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n mqttPublish,\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n fetchNamedAreas,\n saveUserSettingsComponentState,\n })(ListAllNamedAreaEvents)\n);\n","import React from \"react\";\nimport { Table } from \"semantic-ui-react/\";\n\nclass DraggableTableRow extends React.Component {\n onDragStart = (ev, i) => {\n ev.dataTransfer.setData(\"index\", i);\n };\n\n onDragOver = (ev) => {\n ev.preventDefault();\n };\n\n onDrop = (ev, a) => {\n let b = ev.dataTransfer.getData(\"index\");\n this.props.action(parseInt(a, 10), parseInt(b, 10));\n };\n\n // sets the row styling based on rowStyles which is changed when a row is selected for deletion\n rowStyle = (i) => {\n const { rowStyles } = this.props;\n\n if (rowStyles[i]) {\n return rowStyles[i]; // { opacity: \"0.3\", backgroundColor: \"red\" };\n } else {\n return null;\n }\n };\n\n render() {\n const { i } = this.props;\n return (\n this.onDragStart(e, i)}\n onDragOver={(e) => this.onDragOver(e)}\n onDrop={(e) => {\n this.onDrop(e, i);\n }}\n >\n {this.props.children}\n \n );\n }\n}\n\nexport default DraggableTableRow;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Field, formValueSelector, reduxForm } from \"redux-form\";\n\nimport {\n Modal,\n Header,\n Button,\n Form,\n Segment,\n Grid,\n GridColumn,\n GridRow,\n} from \"semantic-ui-react\";\n\nimport isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport { renderSelect, renderField } from \"admin/form-field\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport {\n isConfigJs,\n namedAreaIconOptions,\n allowedLightStates as _allowedLightStates,\n allowedMapMarkers as _allowedMapMarkers,\n} from \"components/ConfigJs\";\n\nconst validate = (values) => {\n const required = [\"color\", \"icon\", \"hint\", \"on_time\", \"off_time\"];\n\n const errors = {};\n\n required.forEach((r) => {\n const value = get(values, r);\n\n if (!value && value !== 0) {\n set(errors, r, \"Required\");\n }\n });\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n switch (type) {\n case \"on_time\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n case \"off_time\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n case \"train\":\n return (value >= 0 && parseInt(value, 10)) || 0;\n default:\n return value;\n }\n};\n\n//let initialValues = {};\nclass NamedAreaButtonSettingsModal extends Component {\n constructor(props) {\n super(props);\n this.state = { modalOpen: false };\n }\n\n componentDidMount() {\n const { open } = this.props;\n if (open) {\n this.handleOpen();\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleCancel = () => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.resetModal();\n\n // reset the form\n this.setState({ value: \"\" }, () => this.props.reset());\n // this.props.onCancel();\n };\n\n handleDelete = (e, idx) => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.handleSettingsDelete(idx);\n };\n\n myHandleSubmit = (values) => {\n //console.log(\"myHandleSubmit e\", e);\n //console.log(\"myHandleSubmit values\", values);\n\n // prevents form submit, the most recent being the create or edit forms!\n //e.preventDefault();\n\n // close the modal\n this.setState({ modalOpen: false });\n\n // save the changes\n this.props.handleSettingsSave(values);\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n reset,\n initialValues,\n change,\n } = this.props;\n\n // display section if STROBE, FORWARD, BACKWARDS\n const { isStateStrobe, isStateForwardBackward } = this.props;\n\n const buttonIdx = initialValues.idx;\n\n let iconOptions = [];\n if (isConfigJs() && namedAreaIconOptions()) {\n iconOptions = namedAreaIconOptions(); // from config.js file\n }\n\n const handleIconChange = (event, value) => {\n const newOptions = iconOptions.find((option) => option.value === value);\n const { text, hint } = newOptions;\n change(\"title\", text);\n change(\"hint\", hint);\n };\n\n const allowedLightStates = _allowedLightStates();\n const allowedMapMarkers = _allowedMapMarkers();\n\n return (\n \n
\n \n {\n e.stopPropagation();\n handleSubmit(this.myHandleSubmit)(e);\n }}\n >\n \n \n \n \n \n \n \n \n \n \n \n \n {isStateStrobe && (\n
\n normalise(value, \"off_time\")}\n component={renderField}\n />\n normalise(value, \"on_time\")}\n component={renderField}\n />\n
\n )}\n {isStateForwardBackward && (\n
\n normalise(value, \"train\")}\n component={renderField}\n />\n
\n )}\n
\n
\n
\n \n \n \n \n this.handleDelete(e, buttonIdx)}\n />\n \n \n \n \n \n this.myHandleSubmit(e)}\n >\n Save\n \n \n \n Reset\n \n \n \n Cancel\n \n \n \n \n \n \n \n
\n \n );\n }\n}\n\nNamedAreaButtonSettingsModal = reduxForm({\n form: \"NamedAreaButtonSettingsModal\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(NamedAreaButtonSettingsModal);\n\nconst selector = formValueSelector(\"NamedAreaButtonSettingsModal\");\n\nfunction mapStateToProps(state, props) {\n const { initialValues } = props;\n\n const stateValue = selector(state, \"state\");\n const isStateStrobe = [\"strobe\", \"forward\", \"backward\"].includes(stateValue);\n const isStateForwardBackward = [\"forward\", \"backward\"].includes(stateValue);\n\n return {\n initialValues: initialValues, // props passed to redux-form loads these as (predictably), initial values\n isStateStrobe,\n isStateForwardBackward,\n };\n}\n\nexport default connect(mapStateToProps, null)(NamedAreaButtonSettingsModal);\n","// https://medium.com/@subalerts/create-dynamic-table-from-json-in-react-js-1a4a7b1146ef\n// draggable row - https://codesandbox.io/s/4jw25r7l19?file=/src/index.js:1333-1353\n// hooks parent to children- https://stackoverflow.com/questions/55726886/react-hook-send-data-from-child-to-parent-component\n\nimport React, { Component, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport {\n Table,\n Checkbox,\n Icon,\n Button,\n Input,\n Popup,\n Image,\n} from \"semantic-ui-react\";\n\nimport IconSVG from \"components/Icon\";\n\nimport \"admin/named-area/NamedAreaTableIcons.css\";\n\nimport isEmpty from \"lodash/isEmpty\";\n\nimport { messageToken, getUserSessionIp } from \"utils/messageToken\";\n\nimport DraggableTableRow from \"admin/named-area/DraggableTableRow\";\n\nimport { mqttPublish } from \"components/WebWorker/actions\";\n\nimport {\n namedAreaSetDeleteSelections,\n namedAreaClearDeleteSelections,\n namedAreaSetShowHideSelections,\n namedAreaClearShowHideSelections,\n namedAreasSetIsDirty,\n namedAreasClearIsDirty,\n} from \"components/WebWorker/actions\";\n\nimport { updateButtonGroupState } from \"OperationalChanges/actions\";\n\nimport {\n getNamedAreaInfos,\n GetMapNamedAreasReducedProperties,\n getIsDirty,\n getNamedAreaEventButtonGroupState,\n} from \"components/WebWorker/reducer\";\n\nimport { GetLocalMap } from \"components/Map/reducer.js\";\n\nimport { GeoJsonToMqttNamedAreaChange } from \"admin/named-area/utils-mqttMessages\";\n\nimport SettingsModal from \"admin/named-area/NamedAreaButtonSettingsModal\";\n\nimport { microTime } from \"utils/microTime\";\n\nimport { selectColor } from \"admin/named-area/region-colors\";\n\nclass TableMade extends Component {\n constructor(props) {\n super(props);\n this.state = {\n data: [],\n deleteSelected: [], // named area ids of the rows selected to be deleted\n hideSelected: [], // named area ids of the rows selected to be hidden\n isDirty: false,\n acks: [],\n namedAreaIdValue: \"\",\n namedAreaParentName: \"\",\n //\n // modal settings dlg for button options\n isOpenSettingsModal: false,\n editSettingsButton: 0,\n };\n }\n\n componentDidMount() {\n this.setState({ data: this.props.data });\n this.setState({ namedAreaIdValue: this.props.namedAreaIdValue });\n this.setState({ namedAreaParentName: this.props.namedAreaParentName });\n this.setState({ buttonGroupState: this.props.buttonGroupState });\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (prevProps.namedAreaIdValue !== this.props.namedAreaIdValue) {\n this.setState({ namedAreaIdValue: this.props.namedAreaIdValue });\n }\n\n if (prevProps.namedAreaParentName !== this.props.namedAreaParentName) {\n this.setState({ namedAreaParentName: this.props.namedAreaParentName });\n }\n\n if (prevProps.buttonGroupState !== this.props.buttonGroupState) {\n this.setState({ buttonGroupState: this.props.buttonGroupState });\n }\n\n // #REVIEW -\n // if any setting has been changed (i.e. isDirty) no longer update from mqtt state\n // _but_ update if there is a new item properties.status = \"drawn\"\n //\n // if there is an current event then after setting change this will be resent to update the event.\n const { isDirty } = this.state;\n\n // #REVIEW/ #TODO - need to support passing the parentId through here\n // set global state if dirty\n const parentId = \"parentNamedArea\";\n\n // #REVIEW / TODO\n // move this filter to a common location\n const isParentDirty =\n this.props.parentIsDirty.filter((namedArea) => namedArea === parentId)\n .length > 0;\n\n if (isParentDirty && !isDirty) {\n this.setState({ isDirty: true });\n }\n\n // this form is dirty\n if (!isParentDirty && isDirty) {\n // but the parent is not currently dirty\n this.props.namedAreasSetIsDirty(parentId); // make it dirty\n }\n\n //\n // Update new named area data\n //\n\n let prevDataNamedArea = {};\n let thisDataNamedArea = {};\n if (prevProps?.data !== undefined && this.props?.data !== undefined) {\n prevProps.data.forEach(\n (na, idx) => (prevDataNamedArea[na.properties.id] = na)\n );\n this.props.data.forEach(\n (na, idx) => (thisDataNamedArea[na.properties.id] = na)\n );\n }\n\n // console.log(\"ggg prevDataNamedArea\", prevDataNamedArea);\n // console.log(\"ggg thisDataNamedArea\", thisDataNamedArea);\n\n // const keys = Object.keys(prevDataNamedArea);\n // console.log(\"ggg keys\", keys);\n // let updateData = false;\n // for (let i = 0; i < keys.length; i++) {\n // console.log(\"ggg prevDataNamedArea[keys[i]]\", prevDataNamedArea[keys[i]]);\n // if (prevDataNamedArea[keys[i]] !== thisDataNamedArea[keys[i]])\n // updateData = true;\n // }\n\n if (\n // JSON.stringify(prevProps.data) !== JSON.stringify(this.props.data) &&\n JSON.stringify(prevDataNamedArea) !== JSON.stringify(thisDataNamedArea) &&\n this.props.data.length\n ) {\n // #REVIEW #TODO #WIP - WORK OUT A BETTER STRATEGY TO COMPARE OBJECTS!!!!!\n\n // console.log(\"ggg this.props.data\", JSON.stringify(prevDataNamedArea));\n // console.log(\"ggg prevProps.data\", JSON.stringify(thisDataNamedArea));\n\n // check if any namedAreas have been drawn i.e. isDirty\n // if properties.status === \"drawn\" then set the form as dirty\n this.props.data.forEach((item, idx) => {\n if (item.properties.status === \"drawn\") {\n // set to dirty\n this.setState({ isDirty: true });\n }\n });\n\n // if Dirty we do not want to update/overwrite the current color state of the check boxes\n // when there is an updated data message\n // make a copy of the button arrays from this state\n // overwrite the incoming data giving preference to the current state\n\n // #REVIEW - this gives copies this.state unless doesn't exist at which point it collects the next sequential values from this.props\n // BUT this assumes sequential\n // need to fix to reference namedArea IDs instead\n // this.props.data is the incoming update\n // this.state.data is the current data\n let newData = this.props.data;\n\n // sort the incoming data (which is, at this point, not reordered) by the properties.priority\n newData.sort(\n (a, b) =>\n parseFloat(a.properties.priority) - parseFloat(b.properties.priority)\n );\n\n // if the form is dirty need to retain all setting for the current data i.e. row posn, state of eye check, color box settings etc.\n // append any new data as the last row.\n\n if (isDirty) {\n let mergedData = [];\n newData.forEach((namedArea, idx) => {\n // if an existing namedArea (i.e. same propertie.id) exists overwrite the newData to keep dirty changes\n const index = this.state.data.findIndex(\n (x) => x.properties.id === namedArea.properties.id\n );\n if (index > -1) {\n mergedData[idx] = this.state.data[index];\n } else {\n mergedData[idx] = namedArea;\n }\n });\n\n // sort the merge data by existing row order\n\n // get a list of the current rows by Id\n let currentNamedRowIds = [];\n this.state.data.forEach((namedArea, idx) => {\n currentNamedRowIds.push(namedArea.properties.id);\n });\n\n // sort newData (properties.id) based on order of currentNamedRowIds\n // #REVEW - NOTE: the new namedArea will be added at the top!\n mergedData.sort(function (a, b) {\n return (\n currentNamedRowIds.indexOf(a.properties.id) -\n currentNamedRowIds.indexOf(b.properties.id)\n );\n });\n\n newData = mergedData;\n }\n\n // make all buttons the same for new named areas\n const homoNamedAreas = this.homogoniseButtonsForAllNamedAreas(\n newData, // recently sorted and merged\n this.state.data // compare with the existing state\n );\n\n this.setState({ data: homoNamedAreas }); //was `newData` //\n }\n\n //\n }\n\n // #NOTE -\n //\n // #1 - if the number of buttons is the same for an existing named areas don't homogonise (i.e. new area has 1 button)\n // #2 - only update the `new` incoming named areas,\n //\n // na goes to the top and copies the previous top named areas's colors\n\n homogoniseButtonsForAllNamedAreas = (incomingData, currentState) => {\n // deep clone the objects. Was having trouble with memory corruption\n const prevNamedAreas = JSON.parse(JSON.stringify(currentState));\n let homoNamedAreas = JSON.parse(JSON.stringify(incomingData));\n\n // get any existing named area as a template\n let buttons = prevNamedAreas[0]?.properties?.button;\n\n if (buttons !== undefined) {\n const currentNumberOfButtons = buttons?.length;\n\n //console.log(\"hhh currentNumberOfButtons\", currentNumberOfButtons);\n\n incomingData.forEach((namedArea, idx) => {\n // console.log(\n // \"hhh namedArea.properties.button\",\n // namedArea.properties.button\n // );\n\n // #1 -\n if (namedArea.properties.button.length !== currentNumberOfButtons) {\n // update button info\n let updateButtonsId = [];\n buttons.forEach((button, idx) => {\n // deep clone a copy of the button object before reassigning properties\n\n updateButtonsId[idx] = JSON.parse(JSON.stringify(button));\n // correct the id in the button object when updating\n updateButtonsId[idx].id = namedArea.properties.id;\n // update priority of the button\n updateButtonsId[idx].priority = idx;\n });\n homoNamedAreas[idx].properties.button = updateButtonsId;\n } else {\n homoNamedAreas[idx].properties.button = namedArea.properties.button;\n }\n });\n return homoNamedAreas;\n }\n return incomingData;\n };\n\n swap = (a, b) => {\n let { data } = this.state;\n\n console.log(\"qqq swap before data\", data);\n data[a] = data.splice(b, 1, data[a])[0];\n this.setState({\n ...this.state,\n data,\n });\n console.log(\"qqq swap after data\", data);\n\n // row moved i.e. draw layer order has changed so now isDirty\n this.setState({ isDirty: true });\n };\n\n onColorClick = (props) => {\n // #WIP - disable dirty if color change -\n // now color change is for events in testing\n //\n if (true) {\n this.setState({ isDirty: true });\n }\n\n const { row, column } = props;\n const { data } = this.state;\n // #REVIEW - why need to deepClone here?\n\n let newData = JSON.parse(JSON.stringify(data)); /// <---deepClone\n\n // #REVIEW - move to load from server\n const colors = [\n \"green\",\n \"amber\",\n \"white\",\n \"blue\",\n \"red\",\n \"white\",\n \"no_change\",\n \"off\",\n ];\n\n const currentColor = newData[row].properties.button[column].color;\n const index = colors.findIndex((x) => x === currentColor);\n let newColor;\n index + 1 > colors.length - 1\n ? (newColor = colors[0])\n : (newColor = colors[index + 1]);\n\n newData[row].properties.button[column].color = newColor;\n\n this.setState({ data: newData });\n };\n\n onDeleteClick = (props) => {\n // console.log(\"qqq onDeleteClick \", props);\n // console.log(\"qqq this.state.deleteSelected\", this.state.deleteSelected);\n\n const { row } = props;\n const { data } = this.state;\n\n const deleteRowId = data[row].properties.id;\n\n // deleteSelected keeps record rows which have been selected for deletion\n let { deleteSelected } = this.state;\n\n if (deleteSelected.includes(deleteRowId)) {\n // remove it\n deleteSelected.splice(deleteSelected.indexOf(deleteRowId), 1);\n\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n // console.log(\"namedAreaClearDeleteSelections deleteRowId\", deleteRowId);\n // this.props.namedAreaClearDeleteSelections({\n // area: \"DMLZ_Extraction\",\n // id: deleteRowId,\n // });\n // also hide it too!\n this.props.namedAreaClearShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: deleteRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n // add it\n else {\n deleteSelected.push(deleteRowId);\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n // this.props.namedAreaSetDeleteSelections({\n // area: \"DMLZ_Extraction\",\n // id: deleteRowId,\n // });\n // also hide it too!\n this.props.namedAreaSetShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: deleteRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n\n // updated state sent, so no longer dirty\n this.setState({ deleteSelected: deleteSelected });\n\n // updated state sent, so no longer dirty\n this.setState({ isDirty: true });\n };\n\n onShowHideClick = (props) => {\n const { row } = props;\n const { data } = this.state;\n\n const hideRowId = data[row].properties.id;\n\n // hideSelected keeps record rows which have been selected for hide\n let { hideSelected } = this.state;\n\n if (hideSelected.includes(hideRowId)) {\n // remove it\n hideSelected.splice(hideSelected.indexOf(hideRowId), 1);\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n this.props.namedAreaClearShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: hideRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n // add it\n else {\n hideSelected.push(hideRowId);\n // #REVIEW/TODO - hard coded area. See also namedAreaSetDeleteSelections\n //\n this.props.namedAreaSetShowHideSelections({\n area: \"DMLZ_Extraction\",\n id: hideRowId,\n });\n // #FIX - passing hideRowId because otherwise it make the structure\n // [{area: area, id: [id1, id2]}] rather than the required [{area: area, id: id1} , {area: area, id: id2}]\n // need to change to be consistent with namedAreaSetDeleteSelections\n }\n\n // updated state of show and hide\n this.setState({ hideSelected: hideSelected });\n\n // show & hide do not change data so not dirty\n // this.setState({ isDirty: true });\n };\n\n getRowIcons = () => {\n const { data: items } = this.state;\n\n // #TODO - use the items list to determine which check box is selected\n // and change the background color\n if (items === undefined) return null;\n\n // Note - all button groups for a named area are the same\n // Use first named area item button group as template\n //\n const buttons = items[0]?.properties?.button;\n if (buttons === undefined) return null;\n\n const handleCogClick = (value, idx) => {\n this.setState({ isOpenSettingsModal: value, editSettingsButton: idx });\n };\n\n const handleLinkClick = (idx) => {\n // don't do anything for 1st button\n if (idx === 0) return null;\n\n const { isDirty, data } = this.state;\n\n let newData = JSON.parse(JSON.stringify(data));\n\n //console.log(\"handleLinkClick\", idx, newData);\n\n // Note - all button groups for a named area are the same\n // Use first named area item button group as template\n //\n let buttons = newData[0]?.properties?.button;\n if (buttons === undefined) return null;\n\n // use first named area as reference for buttons since buttons are the same for the whole named area\n const leftButtonGroup = buttons[idx - 1].group;\n\n //console.log(\"leftButtonGroup\", leftButtonGroup);\n let thisButtonGroup = buttons[idx].group;\n //console.log(\"thisButtonGroup\", thisButtonGroup);\n\n if (leftButtonGroup !== undefined && thisButtonGroup !== undefined) {\n if (leftButtonGroup === thisButtonGroup) {\n // already linked, so toggle un-link\n // ... make separate group (+1)\n for (let index = idx; index < buttons.length; index++) {\n buttons[index].group = buttons[index].group + 1;\n }\n } else {\n // link left to right\n buttons[idx].group = leftButtonGroup;\n // decrement all buttons to the right\n for (let index = idx + 1; index < buttons.length; index++) {\n buttons[index].group = buttons[index].group - 1;\n }\n //\n //\n }\n }\n\n console.log(\"buttons newButtonGroupArray\", buttons);\n\n // #TODO #WIP\n // NOte this is repeated #BUTTONSGROUPUPDATE\n\n const newButtonGroupArray = buttons.map((but) => but.group);\n\n // newButtonGroupArray\n // e.g. [0,1,1,2]\n // means button one in group 0, button two and three in group 1, button four in group 2\n console.log(\"handleLinkClick newButtonGroupArray\", newButtonGroupArray);\n\n newData.forEach((namedArea, index) => {\n newData[index].properties.button[idx].group = newButtonGroupArray[idx];\n });\n\n this.setState({ data: newData });\n\n // if not dirty make it so!\n if (!isDirty) {\n this.setState({ isDirty: true });\n }\n };\n\n const leftPaddingHeaderCells = (\n <>\n \n \n \n \n Edit Button\n \n \n );\n\n const rightPaddingHeaderCells = (\n <>\n \n \n );\n\n return (\n <>\n {leftPaddingHeaderCells}\n handleCogClick(value, idx)}\n handleLinkClick={(idx) => handleLinkClick(idx)}\n />\n\n {/* */}\n {rightPaddingHeaderCells}\n \n );\n };\n\n getRowDefaults = () => {\n const { data: items } = this.state;\n\n // #TODO - use the items list to determine which check box is selected\n // and change the background color\n if (items === undefined) return null;\n\n // Note - all button groups for a named area are the same\n // Use first named area item button group as template\n //\n const buttons = items[0]?.properties?.button;\n if (buttons === undefined) return null;\n\n const leftPaddingHeaderCells = (\n <>\n \n \n \n \n Button Default Color\n \n \n );\n\n const rightPaddingHeaderCells = (\n <>\n \n \n );\n\n return (\n <>\n {leftPaddingHeaderCells}\n \n {rightPaddingHeaderCells}\n \n );\n };\n\n getRowsData = () => {\n const { data: items, deleteSelected } = this.state;\n\n // #TODO - use the items list to determine which check box is selected\n // and change the background color\n if (items === undefined) return null;\n\n // Set style for each row.\n // This is setup RenderRowoutside the .map below as rows area draggable, and styles\n // need to be preserved with the drag.\n //\n let rowStyles = [];\n //e.g.\n // [{ opacity: \"0.3\", backgroundColor: \"red\" },\n // { opacity: \"1\", backgroundColor: \"blue\" },...]\n items.forEach((item, idx) => {\n // filter deleteSelected and return an array in row order\n // e.g. rowStyles = [false, true, false];\n //rowStyles.push(deleteSelected.includes(item?.properties?.id));\n\n if (deleteSelected.includes(item?.properties?.id)) {\n rowStyles[idx] = { opacity: \"0.3\", backgroundColor: \"red\" };\n } else {\n const rowPropertieStyle = item?.properties?.style;\n if (rowPropertieStyle !== undefined) {\n const { fillColor } = rowPropertieStyle;\n rowStyles[idx] = {\n opacity: \"0.8\",\n backgroundColor: fillColor !== undefined ? fillColor : \"orange\",\n };\n } else {\n rowStyles[idx] = { opacity: \"0.8\", backgroundColor: \"grey\" };\n }\n }\n\n //console.log(\"rowStyles\", rowStyles);\n });\n\n // items sorted by \"priority\"\n // priority may be integer or string.\n // #REVIEW - force to integer for now\n // const items = this.state.data.sort((a, b) => {\n // return a.priority.toString().localeCompare(b.priority);\n // });\n\n const itemsLength = items.length;\n\n return items.map((row, index) => {\n return (\n \n \n \n );\n });\n };\n\n getRowButtonActives = () => {\n const { data: items } = this.state;\n\n if (items === undefined) return null;\n\n // Note - all button groups for a named area are the same\n // Use first named area item button group as template\n //\n const buttons = items[0]?.properties?.button;\n if (buttons === undefined) return null;\n\n const onButtonActiveToggle = (buttonIndex, buttonState) => {\n console.log(\"onButtonActiveToggle\", buttonIndex, buttonState);\n\n const { isDirty, data } = this.state;\n\n let newData = JSON.parse(JSON.stringify(data));\n\n newData.forEach((namedArea, idx) => {\n // update button info\n newData[idx].properties.button[buttonIndex].active = buttonState;\n });\n\n this.setState({ data: newData });\n\n // if not dirty make it so!\n if (!isDirty) {\n this.setState({ isDirty: true });\n }\n };\n\n const onButtonAdd = () => {\n const { isDirty, data } = this.state;\n\n // #NOTE\n // Adding a button duplicates the previous last button (rhs)\n // Since this new button has the same button group it'll be 'linked'\n // to the previous button.\n\n // copy existing region row data\n let newData = JSON.parse(JSON.stringify(data));\n\n for (let index = 0; index < newData.length; index++) {\n const namedArea = newData[index];\n let newButtons = namedArea.properties.button;\n\n // copy the last button\n let lastButton = JSON.parse(\n JSON.stringify(newButtons[newButtons.length - 1])\n );\n // increment the priority of the button\n lastButton.priority = Number(lastButton.priority) + 1;\n // append new button to the data\n newData[index].properties.button = [...newButtons, lastButton];\n // console.log(\n // \"newData[index].properties.button\",\n // newData[index].properties.button\n // );\n }\n\n this.setState({ data: newData });\n\n // if not dirty make it so!\n if (!isDirty) {\n this.setState({ isDirty: true });\n }\n };\n\n const leftPaddingHeaderCells = (\n <>\n \n \n \n \n Enable/Disable Button\n \n \n );\n\n const rightPaddingHeaderCells = <>; // no padding on this row\n\n return (\n <>\n {leftPaddingHeaderCells}\n onButtonActiveToggle(idx)}\n setButtonActive={(idx, active) => onButtonActiveToggle(idx, active)}\n />\n \n {rightPaddingHeaderCells}\n \n );\n };\n\n getRowButtonDeletes = () => {\n const { data: items } = this.state;\n\n if (items === undefined) return null;\n\n // Note - all button groups for a named area are the same\n // Use first named area item button group as template\n //\n const buttons = items[0]?.properties?.button;\n if (buttons === undefined) return null;\n\n const leftPaddingHeaderCells = (\n <>\n \n \n \n \n \n );\n\n const rightPaddingHeaderCells = (\n <>\n \n \n ); // no padding on this row\n\n return (\n <>\n {leftPaddingHeaderCells}\n \n {rightPaddingHeaderCells}\n \n );\n };\n\n // [SAVE CHANGES] button\n sendNamedAreaSetupMqtt = () => {\n let isOkToSend = true;\n\n const { data: namedAreas } = this.state;\n const { namedAreaIdValue, namedAreaParentName } = this.state; // value entered into the forms' named area field\n let { deleteSelected } = this.state; // let -> modified when appending drawn shapes for cleanup\n\n //console.log(\"namedAreas\", namedAreas);\n\n if (namedAreas === undefined) return null;\n\n // process namedAreas\n\n // 1 - if namedAreas marker for deletion, send these 1st and delete from namedAreas\n // 2 - then send updated namedAreas in reverse order and with priority saved\n // 3 - send updated event messages applying to 'changed' named areas\n\n // 1 - ...........\n let changedNamedAreas = [];\n\n namedAreas.forEach((namedArea, idx) => {\n const {\n properties: { id },\n } = namedArea;\n\n // if named area is selected for deletion\n if (deleteSelected.includes(id)) {\n // send a delete message\n this.props.onSendMqtt({\n topic: `named_area/${id}/delete`,\n qos: 0,\n message: {\n id: id,\n delete: true,\n token: messageToken(),\n },\n retained: false,\n });\n } else {\n changedNamedAreas.push(namedArea);\n }\n });\n\n // 2 - send changed namedAreas\n //\n // send the messages in reverse so the top namedArea in the UI (row 0) is sent last.\n // namedAreas of the same priority apply in order, so last received has highest priority.\n\n //console.log(\"changedNamedAreas\", changedNamedAreas);\n\n changedNamedAreas.reverse().forEach((namedArea, idx) => {\n const {\n properties: { id, name, parent, area, origin, button, style },\n } = namedArea;\n\n //console.log(\"updatedNamedArea style\", style);\n\n // #polygonStyle\n // convert style to string since it's structure may change in map\n // and the go server does not break down to json\n\n const newStyle = JSON.stringify(style);\n\n // if parent is from create new named area form and contains \"parent\"\n // replace it with the correct named area\n let newParent = parent;\n let newId = id;\n let newButton = button;\n let newParentName =\n namedAreaParentName !== \"\" ? namedAreaParentName : `parent-${name}`;\n\n if (namedAreaIdValue !== \"\" && namedAreaParentName !== \"\") {\n if (\n id.includes(\"createNewNamedArea\") &&\n parent.includes(\"createNewNamedArea\")\n ) {\n newId = id.replace(\"createNewNamedArea\", namedAreaIdValue);\n newParent = parent.replace(\"createNewNamedArea\", namedAreaIdValue);\n\n // update button\n newButton.forEach((button, idx) => {\n newButton[idx].id = button.id.replace(\n \"createNewNamedArea\",\n namedAreaIdValue\n );\n newButton[idx].named_area = button.named_area.replace(\n \"createNewNamedArea\",\n namedAreaIdValue\n );\n });\n }\n }\n\n // priority is set by the row position\n // since the messages are sent out in reverse the priority is also reversed\n // lowest priority is 0\n const priority = namedAreas.length - idx;\n\n const {\n geometry: { coordinates, type },\n } = namedArea;\n\n // #TODO\n // #REVIEW - add these to config dlg\n const DEFAULT_default_color = \"GREEN\";\n const DEFAULT_default_state = \"ON\";\n const DEFAULT_on_time = 10;\n const DEFAULT_off_time = 10;\n const DEFAULT_train = 10;\n\n // prepare message token\n const userSessionIp = getUserSessionIp();\n const token = messageToken(userSessionIp);\n\n // sets final named area object\n const updatedNamedArea = {\n id: newId,\n area,\n name,\n parent_name: newParentName, // i.e. \"namedAreaParentName\"\n coordinates,\n type,\n priority,\n origin,\n parent: newParent,\n button: newButton,\n default_color: DEFAULT_default_color,\n default_state: DEFAULT_default_state,\n active_color: DEFAULT_default_color,\n active_state: DEFAULT_default_state,\n on_time: DEFAULT_on_time,\n off_time: DEFAULT_off_time,\n train: DEFAULT_train,\n style: newStyle,\n token,\n };\n\n // create named_area mqtt message\n const namedAreaMsg = GeoJsonToMqttNamedAreaChange(updatedNamedArea);\n\n console.log(\"CREATED NEW UPDATED NAMED AREA: \", namedAreaMsg);\n\n const namedAreaPayload = {\n topic: `named_area/${namedAreaMsg.id}/change`,\n qos: 0,\n message: namedAreaMsg,\n retained: false,\n };\n\n //console.log(\"namedAreaMsg\", namedAreaMsg);\n\n if (isOkToSend) {\n this.props.onSendMqtt(namedAreaPayload);\n }\n\n // update button group state for (possible) changed button settings\n const buttonGroupState = this.state.buttonGroupState;\n let newButtonGroupState = JSON.parse(JSON.stringify(buttonGroupState));\n // console.log(\"newButtonGroupState ddd\", newButtonGroupState);\n\n // create new button group state based on current buttons.\n // Note - we could have compared to see if buttons had changed, but why bother!\n // Just make a new one.\n //\n newButtonGroupState[newParent] = {};\n for (let i = 0; i < newButton.length; i++) {\n newButtonGroupState[newParent][i] = -1;\n }\n\n // NOTE\n // 'buttonGroupState' is communicated across the system via the event messages.\n // If buttons states have been changed in a named area:\n // * add/delete button\n // * enable/disable button\n // the `buttonGroupState` needs to be updated by sending an event message for each named area.\n //\n // Steps:\n // 1 - check if there is a current event on the named area\n // 2 - resent 'active' : false event message\n // NOTE: if a named area is changed any current event will be disabled.\n\n // Use the first button as a basis for the DEFAULT event settings\n //\n\n const eventMsg = {\n id: newId,\n priority: 0, // reset event to lowest priority\n active: false, // turn off any events\n active_color: DEFAULT_default_color, //active_button.color,\n active_state: DEFAULT_default_state, //active_button.state,\n on_time: DEFAULT_on_time,\n off_time: DEFAULT_off_time,\n train: DEFAULT_train,\n button_groups: JSON.stringify(newButtonGroupState[newParent]),\n timestamp: microTime(),\n precanned: 0, // not used ATM\n token: token,\n };\n\n //console.log(\"eventMsg\", eventMsg.button_groups);\n\n const eventPayload = {\n topic: `named_area/${eventMsg.id}/event`,\n qos: 0,\n message: eventMsg,\n retained: true,\n };\n\n if (isOkToSend) {\n this.props.onSendMqtt(eventPayload);\n }\n // #REVEIW #WIP\n // This is old code which updated local state only.\n // See above.\n\n if (false) {\n // initialise button group records\n // update button group state for (possible) changed button settings\n // Note - this is also done in PrecannedOperations\n // make button groups object for the current named area\n if (\n newButtonGroupState[newParent] !== undefined ||\n !isEmpty(newButtonGroupState[newParent])\n ) {\n // if the # of buttons has changed .....\n if (\n Object.keys(newButtonGroupState[newParent])?.length !==\n newButton?.length\n ) {\n // reset the button group\n newButtonGroupState[newParent] = {};\n for (let i = 0; i < newButton.length; i++) {\n newButtonGroupState[newParent][i] = -1;\n }\n console.log(\"newButtonGroupState 1 xxx\", newButtonGroupState);\n // update locally\n this.setState({ buttonGroupState: newButtonGroupState });\n // and globally\n this.props.updateButtonGroupState(newButtonGroupState);\n }\n } else {\n // create a new button group\n newButtonGroupState[newParent] = {};\n for (let i = 0; i < newButton.length; i++) {\n newButtonGroupState[newParent][i] = -1;\n }\n console.log(\"newButtonGroupState 2 xxx\", newButtonGroupState);\n // set a new button group for this named area\n // update locally\n this.setState({ buttonGroupState: newButtonGroupState });\n // and globally\n this.props.updateButtonGroupState(newButtonGroupState);\n }\n }\n });\n\n // send all namedAreas to be deleted from the map\n // note - namdAreas includes those deleted or changed\n const parentId = \"parentNamedArea\";\n namedAreas.forEach((namedArea, idx) => {\n this.props.namedAreaSetDeleteSelections({\n area: parentId,\n id: namedArea.properties.id,\n });\n });\n\n // updated named area state sent, so no longer dirty\n // locally\n this.setState({ isDirty: false });\n\n // globally\n this.props.namedAreasClearIsDirty(parentId);\n };\n\n resetIsDirty = () => {\n // reset changes\n\n // #REVIEW/TODO/FIX - this is a fudge until the components are modularised so can pass reset to map component etc\n console.log(\n \"FIX THIS - RESET RELOADS THE PAGE. INSTEAD RELOAD THE COMPONENT\"\n );\n window.location.reload(false);\n\n this.setState({ isDirty: false });\n };\n\n isDeleteAllSelected = () => {};\n\n onDeleteAllClicked = () => {};\n\n resetModal = () => {\n this.setState({ isOpenSettingsModal: false });\n };\n\n handleSettingsSave = (values) => {\n //console.log(\"handleSettingsSave\", values);\n\n const { isDirty, editSettingsButton, data } = this.state;\n\n let newData = JSON.parse(JSON.stringify(data));\n\n newData.forEach((namedArea, idx) => {\n const buttonSettings = namedArea.properties.button[editSettingsButton];\n let updatedButton = { ...buttonSettings, ...values };\n newData[idx].properties.button[editSettingsButton] = updatedButton;\n });\n\n this.setState({ data: newData });\n\n //console.log(\"handleSettingsSave newData\", newData);\n\n // if not dirty make it so!\n if (!isDirty) {\n this.setState({ isDirty: true });\n }\n\n // close modal\n this.setState({ isOpenSettingsModal: false });\n //return Promise.resolve;\n };\n\n handleSettingsDelete = (idx) => {\n // #REVIEW - note. didn't need `idx` as already had `editSettingsButton` ...argghhh.\n // leave as-is.\n\n //console.log(\"handleSettingsDelete\", idx);\n\n const { isDirty, editSettingsButton, data } = this.state;\n\n let newData = JSON.parse(JSON.stringify(data));\n\n // Note - all button groups for a named area are the same\n // Use first named area item button group as template\n //\n let buttons = newData[0]?.properties?.button;\n\n // #REVIEW - move adding default buttons to here rather than in MAP function\n // To do this added button template when no button defined\n if (buttons === undefined) return null;\n\n // don't delete the last button!!! i.e. buttons.length-2 = 0\n if (buttons.length - 1 === 0) return null;\n // #REVIEW - should pop a dlg to announce this! i.e. can't delete last button\n\n //console.log(\"handleSettingsDelete buttons\", editSettingsButton, buttons);\n\n // delete selected button from button array, keeping the rest\n //buttons = buttons.splice(0, 3); //editSettingsButton, buttons.length);\n\n let buttonsDeleted = [];\n for (let index = 0; index < buttons.length; index++) {\n if (index !== editSettingsButton) {\n buttonsDeleted = buttonsDeleted.concat(buttons[index]);\n }\n }\n\n //console.log(\"handleSettingsDelete buttons buttonsDeleted\", buttonsDeleted);\n\n newData.forEach((namedArea, idx) => {\n //console.log(\"onButtonAdd namedArea\", namedArea.properties.id);\n\n // update button info\n let updateButtonsId = [];\n buttonsDeleted.forEach((button, idx) => {\n // deep clone a copy of the button object before reassigning properties\n updateButtonsId[idx] = JSON.parse(JSON.stringify(button));\n // correct the id in the button object when updating\n updateButtonsId[idx].id = namedArea.properties.id;\n // update priority of the button\n updateButtonsId[idx].priority = idx;\n });\n\n newData[idx].properties.button = updateButtonsId;\n });\n\n //console.log(\"handleSettingsDelete newData\", newData);\n\n // reset editSettingsButton to 0 in case we've deleted this record and upon re-render modal it fails to find it.\n // This happens when we delete the last button.\n this.setState({ editSettingsButton: 0 });\n\n let buttonSettings = buttons[this.state.editSettingsButton];\n\n this.setState({ data: newData });\n\n // if not dirty make it so!\n if (!isDirty) {\n this.setState({ isDirty: true });\n }\n\n // close modal\n this.setState({ isOpenSettingsModal: false });\n };\n\n render() {\n // #TODO - style the row if it is selected for Deletion - deleteSelected\n //const myReference = this.rowStyle1.current; // The DOM element\n //myReference.style.backgroundColor = \"red\"; // The style you want to apply\n //this.refs.rowStyle1.style.background = \"red\";\n //\n\n const { isDirty } = this.state;\n\n const iconButtons = {\n padding: \"0.5em\",\n };\n\n // padding cell for top row\n // 4: drag, active checkbox, show/hide eye icon, named area description\n const headerCellsRowTop = (\n <>\n \n \n \n \n \n );\n\n const { data: items } = this.state;\n if (items === undefined) return null;\n\n if (items.length === 0)\n return (\n
\n No regions are defined. Use the Map controls to create new regions.\n
\n );\n\n const buttons = items[0]?.properties?.button;\n if (buttons === undefined) return null;\n\n // deep clone button settings as we're going to delete some of the properties\n let buttonSettings = JSON.parse(\n JSON.stringify(buttons[this.state.editSettingsButton])\n );\n // don't keep the .id (which is unique to the region)\n delete buttonSettings.id;\n buttonSettings.idx = this.state.editSettingsButton;\n\n return (\n
\n \n this.handleSettingsSave(values)}\n resetModal={() => this.resetModal()}\n handleSettingsDelete={(idx) => this.handleSettingsDelete(idx)}\n />\n \n \n {this.getRowButtonActives()}\n {this.getRowIcons()}\n {/* #WIP - put functionality into setup button */}\n {/* {this.getRowDefaults()} */}\n \n {this.getRowsData()}\n \n {/* #WIP - put functionality into setup button */}\n {/* {this.getRowButtonDeletes()} */}\n \n \n \n Save Changes\n \n {/* #NOTE - no longer using this reset process */}\n {/* #NOTE - no longer using this reset processon\n disabled={!isDirty}\n size=\"small\"\n onClick={this.resetIsDirty}\n >\n Reset Changes\n */}\n \n \n \n
\n
\n );\n }\n}\n\n// NOTE - previously used to display icon buttons.\n// Superceded for \n//\nconst RenderRowIcons = (props) => {\n const { data: buttons } = props;\n\n if (buttons === undefined) return null;\n\n const handleClick = (e, idx) => {\n e.preventDefault();\n\n console.log(\"button handleClick idx\", idx);\n // update data!\n };\n\n return buttons.map((button, idx) => {\n console.log(\"button\", button);\n const color = button.color || \"red\";\n // const iconColor = isActive && buttonActive ? \"white\" : color;\n const buttonActive = true;\n const iconColor = buttonActive ? \"white\" : color;\n const iconName = button.icon;\n\n return (\n <>\n \n handleClick(e, idx)}\n basic={!buttonActive}\n style={{ padding: \"0.5em\" }}\n size={\"large\"}\n >\n \n \n }\n content={`${button.title} - ${button.hint}`}\n position=\"top right\" // bottom center\n basic\n />\n \n \n );\n });\n};\n\nconst RenderCogLinkIcon = (props) => {\n const { data: buttons } = props;\n\n if (buttons === undefined) return null;\n\n const handleLinkClick = (e, idx) => {\n props.handleLinkClick(idx);\n };\n\n const handleCogClick = (e, idx) => {\n props.handleCogClick(true, idx);\n };\n\n const colorBoxStyle = {\n borderRadius: 0,\n //border: \"1px outset black\",\n height: \"100%\",\n margin: \".25em\",\n };\n\n const iconSVG = process.env.PUBLIC_URL + \"/icons/activity.svg\";\n const iconCOG = process.env.PUBLIC_URL + \"/icons/icon-cog.svg\";\n const iconLink = process.env.PUBLIC_URL + \"/icons/icon-link.svg\";\n const iconUnLink = process.env.PUBLIC_URL + \"/icons/icon-unlink.svg\";\n\n const buttonsLen = buttons.length;\n\n return buttons.map((button, idx) => {\n const color = button.color || \"red\";\n // const iconColor = isActive && buttonActive ? \"white\" : color;\n const buttonActive = true;\n // const iconColor = buttonActive ? \"white\" : color;\n const iconName = process.env.PUBLIC_URL + \"/icons/\" + button.icon + \".svg\";\n const iconHint = button.hint;\n\n let iconBg;\n let iconColor;\n let iconOpacity;\n\n switch (color) {\n case \"red\":\n iconBg = \"#db2828\";\n iconColor = \"#fff\";\n break;\n case \"blue\":\n iconBg = \"#2185d0\";\n iconColor = \"#fff\";\n break;\n case \"orange\":\n case \"amber\":\n iconBg = \"#fbbd08\";\n iconColor = \"#fff\";\n break;\n case \"white\":\n iconBg = \"#fbbd08\";\n iconColor = \"#000\";\n break;\n case \"black\":\n case \"off\":\n iconBg = \"#2f3032\";\n iconColor = \"#fff\";\n break;\n case \"no_change\":\n case \"green\":\n default:\n iconBg = \"#21ba45\";\n iconColor = \"#fff\";\n break;\n }\n\n const getLinkText = () => {\n if (buttonsLen === idx + 1) {\n // last one\n return `Click to Link/Unlink button ${idx + 1} to button ${idx}. `;\n } else if (idx === 0) {\n // first one\n return `Linking has no effect on the first button.`;\n } else {\n // not first or last\n return `Click to Link/Unlink button ${idx + 1} to button ${idx}. `;\n }\n };\n\n const getLinkIcon = () => {\n if (idx === 0) {\n // first one\n return iconLink;\n }\n // compare button group with previous button, if same = linked\n else if (button.group === buttons[idx - 1].group) {\n return iconLink;\n } else {\n return iconUnLink;\n }\n };\n\n return (\n <>\n \n {/* \n \"\"\n handleClick(e, idx)}\n style={{ cursor: \"pointer\" }}\n />\n handleClick(e, idx)}\n style={{ cursor: \"pointer\" }}\n />\n \n }\n content={`Click the Link the default light color for button ${\n idx + 1\n }`}\n position=\"top right\" // bottom center\n basic\n /> */}\n\n \n }\n content={`Button ${idx + 1}`}\n position=\"top right\" // bottom center\n basic\n />\n handleCogClick(e, idx)}\n style={{ cursor: \"pointer\" }}\n />\n }\n content={`Click to edit the settings for Button ${idx + 1}`}\n position=\"top right\" // bottom center\n basic\n />\n\n handleLinkClick(e, idx)}\n />\n }\n content={getLinkText()}\n position=\"top right\" // bottom center\n basic\n />\n \n \n \n );\n });\n};\n\nconst RenderRowDefaults = (props) => {\n const { data: buttons } = props;\n\n console.log(\"RenderRowDefaults buttons\", buttons);\n\n if (buttons === undefined) return null;\n\n const handleClick = (e, idx) => {\n //e.preventDefault();\n\n console.log(\"button handleClick idx\", idx);\n // update data!\n };\n\n const colorBoxStyle = {\n borderRadius: 0,\n border: \"1px outset black\",\n height: \"100%\",\n margin: \".25em\",\n };\n\n return buttons.map((button, idx) => {\n let buttonColor = \"green\";\n switch (button.color) {\n case \"green\":\n buttonColor = \"green\";\n break;\n case \"red\":\n buttonColor = \"red\";\n break;\n case \"amber\":\n case \"orange\":\n buttonColor = \"orange\";\n break;\n case \"white\":\n buttonColor = \"grey\";\n break;\n case \"no_change\":\n buttonColor = \"white\";\n break;\n case \"off\":\n buttonColor = \"black\";\n break;\n default: // #REVIEW - this shouldn't be necessary as I thought I'd caught these previously but THIS MAKES SURE!\n // not \"GREEN\" as used by the FF controller but \"green\" used by the semantic ui CSS\n buttonColor = button.color.toLowerCase();\n break;\n }\n\n return (\n <>\n \n handleClick(e, idx)}\n >\n \n \n }\n content={`Click to change the default light color for button ${\n idx + 1\n }`}\n position=\"top right\" // bottom center\n basic\n />\n \n \n );\n });\n};\n\nconst RenderRowButtonActives = (props) => {\n const { data: buttons } = props;\n\n if (buttons === undefined) return null;\n\n const isCheckSelected = (idx) => {\n const buttonState = buttons !== undefined ? buttons[idx]?.active : false;\n\n return buttonState;\n };\n\n const handleCheckClick = (e, idx) => {\n const { active } = buttons[idx];\n if (active !== undefined) {\n if (active) {\n props.setButtonActive(idx, false);\n } else {\n props.setButtonActive(idx, true);\n }\n }\n };\n\n return buttons.map((button, idx) => {\n return (\n <>\n \n handleCheckClick(e, idx)}\n />\n }\n content={`Click enable/disable Button ${idx + 1}`}\n position=\"top right\" // bottom center\n basic\n />\n
\n \n );\n });\n};\n\nconst RenderRowAddButton = (props) => {\n const { data: buttons } = props;\n\n if (buttons === undefined) return null;\n\n const handleAddButtonClick = (e) => {\n e.preventDefault();\n\n console.log(\"add button clicked!\");\n\n props.onButtonAdd();\n };\n\n return (\n <>\n \n handleAddButtonClick(e)}\n color=\"blue\"\n >\n \n \n }\n content={`Click to add a new button to the named area`}\n position=\"top right\" // bottom center\n basic\n />\n
\n \n );\n};\n\nconst RenderRowButtonDeletes = (props) => {\n const { data: buttons } = props;\n\n if (buttons === undefined) return null;\n\n // const isCheckSelected = (e, idx) => {\n // //console.log(\"qqq isDeleteSelected e\", e);\n // };\n\n const handleCheckClick = (e, idx) => {\n //e.preventDefault();\n console.log(`delete button ${idx} clicked!!!`);\n };\n\n return buttons.map((button, idx) => {\n return (\n <>\n \n handleCheckClick(e, idx)}\n />\n }\n content={`Click to delete button column ${idx + 1}`}\n position=\"top right\" // bottom center\n basic\n />\n\n {/* handleCheckClick(e, idx)}\n /> */}\n
\n \n );\n });\n};\n\nconst RenderRowTop_hack = (props) => {\n const [open, setOpen] = useState(true); // declare new state variable \"open\" with setter\n\n const color = \"black\";\n\n const isItemSelected = (e) => {\n // console.log(\"qqq isItemSelected e\", e);\n };\n\n const handleSelect = (e) => {\n // console.log(\"qqq handleSelect e\", e);\n };\n\n const handleClick = (e, key) => {\n // console.log(\"qqq key\", key);\n\n e.preventDefault();\n\n setOpen(!open);\n };\n\n const isDeleteSelected = (e) => {\n //console.log(\"qqq isDeleteSelected e\", e);\n };\n\n const handleDeleteClick = (e, key) => {\n e.preventDefault();\n\n const row = props.index;\n\n // update data!\n props.onDeleteClick({ row });\n };\n\n const handleShowHideClick = (e, key) => {\n e.preventDefault();\n\n const row = props.index;\n\n // toggle eye icon on button\n setOpen(!open);\n\n // update data!\n props.onShowHideClick({ row });\n };\n\n const eyeIcon = open ? \"eye\" : \"eye slash\";\n\n const iconButtons = {\n padding: \"0.5em\",\n };\n\n return (\n <>\n \n handleClick(e, props.index)}\n >\n \n \n \n \n handleSelect(e, props.index)}\n />\n \n \n handleShowHideClick(e, props.index)}\n //toggle\n //active={isShowHideSelected(props.index)}\n >\n \n \n \n \n \n \n \n \n handleDeleteClick(e, props.index)}\n />\n \n \n );\n};\n\nconst RenderRow = (props) => {\n const [open, setOpen] = useState(true); // declare new state variable \"open\" with setter\n\n const color = \"black\";\n\n const isItemSelected = (e) => {\n // console.log(\"qqq isItemSelected e\", e);\n };\n\n const handleSelect = (e) => {\n // console.log(\"qqq handleSelect e\", e);\n };\n\n const handleClick = (e, key) => {\n // console.log(\"qqq key\", key);\n\n e.preventDefault();\n\n setOpen(!open);\n };\n\n const isDeleteSelected = (e) => {\n //console.log(\"qqq isDeleteSelected e\", e);\n };\n\n const handleDeleteClick = (e, key) => {\n e.preventDefault();\n\n const row = props.index;\n\n // update data!\n props.onDeleteClick({ row });\n };\n\n const handleShowHideClick = (e, key) => {\n e.preventDefault();\n\n const row = props.index;\n\n // toggle eye icon on button\n setOpen(!open);\n\n // update data!\n props.onShowHideClick({ row });\n };\n\n const eyeIcon = open ? \"eye\" : \"eye slash\";\n\n const iconButtons = {\n padding: \"0.5em\",\n };\n\n return (\n <>\n \n {/* handleClick(e, props.index)}\n >\n \n */}\n handleClick(e, props.index)}\n />\n }\n content={`Grab and drag row to change priority`}\n position=\"top right\" // bottom center\n basic\n />\n \n \n handleSelect(e, props.index)}\n />\n }\n content={`Check to enable/disable this region`}\n position=\"top right\" // bottom center\n basic\n />\n \n \n {/* handleShowHideClick(e, props.index)}\n //toggle\n //active={isShowHideSelected(props.index)}\n >\n \n */}\n\n handleShowHideClick(e, props.index)}\n />\n }\n content={`Toggle to show/hide the region`}\n position=\"top right\" // bottom center\n basic\n />\n \n \n \n }\n content={`Unique region idenitifier`}\n position=\"top right\" // bottom center\n basic\n />\n \n \n \n handleDeleteClick(e, props.index)}\n />\n }\n content={`Check to mark region for deletion`}\n position=\"top right\" // bottom center\n basic\n />\n \n \n );\n};\n\n// priority: integer - order of items in list <-- or just sort the object?\n// active: boolean - checkbox status\n// show: boolean - show/hide on map (eye icon)\n// name: string - named area polygon shape name <-- could be generated\n// button: array of button color settings\n\nconst RenderRowColorBox = (props) => {\n //console.log(\"qqq RenderRowColorBox props\", props);\n\n const [open, setOpen] = useState(true); // declare new state variable \"open\" with setter\n\n const handleClick = (e, key) => {\n e.preventDefault();\n\n //let data = props.data;\n const row = props.index;\n const column = key;\n\n // update data!\n props.onColorClick({ row, column });\n\n setOpen(!open);\n };\n\n let colorBoxStyle = {\n borderRadius: 0,\n border: \"1px outset black\",\n height: \"100%\",\n margin: \".25em\",\n };\n\n let colorBoxIcon = {};\n\n const buttons = props.data.properties.button;\n\n return buttons.map((button, index) => {\n // console.log(\n // \"qqq RenderRowColorBox buttons.color\",\n // index,\n // \" \",\n // button.color\n // );\n\n let buttonColor = \"green\";\n switch (button.color) {\n case \"green\":\n buttonColor = \"green\";\n break;\n case \"red\":\n buttonColor = \"red\";\n break;\n case \"amber\":\n case \"orange\":\n buttonColor = \"orange\";\n break;\n case \"white\":\n buttonColor = \"grey\";\n break;\n case \"no_change\":\n buttonColor = \"white\";\n colorBoxStyle.border = \"1px inset white\";\n colorBoxIcon = { name: \"dont\" };\n break;\n case \"off\":\n buttonColor = \"black\";\n break;\n default: // #REVIEW - this shouldn't be necessary as I thought I'd caught these previously but THIS MAKES SURE!\n // not \"GREEN\" as used by the FF controller but \"green\" used by the semantic ui CSS\n buttonColor = button.color.toLowerCase();\n break;\n }\n\n // console.log(\n // \"qqq index, button.title, button.color, buttonColor\",\n // index,\n // button.title,\n // button.color,\n // buttonColor\n // );\n\n return (\n \n handleClick(e, index)}\n >\n \n \n }\n content={`Click to change the light color for button ${\n index + 1\n } for this region`}\n position=\"top right\" // bottom center\n basic\n />\n \n );\n });\n};\n\nclass NamedAreaTable extends Component {\n constructor(props) {\n super(props);\n this.state = {\n tableData: [],\n events: [],\n acks: [],\n };\n }\n\n componentDidMount() {\n this.setState({ tableData: this.props.namedAreas });\n // this.setState({ acks: this.props.acks });\n }\n\n componentDidUpdate(prevProps, prevState) {\n // check if namedAreas have been changed\n // properties.status =\"drawn\" - come from local map state\n // properties.status =\"mqtt\" - come from system state update (updates only happen if page is not dirty)\n //\n if (\n JSON.stringify(prevProps.namedAreas) !==\n JSON.stringify(this.props.namedAreas)\n ) {\n this.setState({ tableData: this.props.namedAreas });\n }\n\n if (\n JSON.stringify(prevProps.mineLevelId) !==\n JSON.stringify(this.props.mineLevelId)\n ) {\n console.log(\"gggg reset it!!\");\n }\n }\n\n render() {\n return (\n this.props.mqttPublish(mqttMsg)}\n namedAreaSetDeleteSelections={(deleteSelection) =>\n this.props.namedAreaSetDeleteSelections(deleteSelection)\n }\n namedAreaClearDeleteSelections={(deleteSelection) =>\n this.props.namedAreaClearDeleteSelections(deleteSelection)\n }\n namedAreaSetShowHideSelections={(hideSelection) =>\n this.props.namedAreaSetShowHideSelections(hideSelection)\n }\n namedAreaClearShowHideSelections={(hideSelection) =>\n this.props.namedAreaClearShowHideSelections(hideSelection)\n }\n namedAreasSetIsDirty={(id) => this.props.namedAreasSetIsDirty(id)}\n namedAreasClearIsDirty={(id) => this.props.namedAreasClearIsDirty(id)}\n parentIsDirty={this.props.parentIsDirty}\n namedAreaIdValue={this.props.namedAreaIdValue}\n namedAreaParentName={this.props.namedAreaParentName}\n buttonGroupState={this.props.buttonGroupState}\n updateButtonGroupState={(buttons) =>\n this.props.updateButtonGroupState(buttons)\n }\n />\n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const { namedAreaIdValue, mineLevelId, namedAreaParentName } = props;\n\n // namedAreas direct from mqtt\n //const geoJSONNamedAreasUtm = getNamedAreaInfos(state); // #REVEW - direct connection to mqtt\n const namedAreasReduced = GetMapNamedAreasReducedProperties(state);\n\n // namedAreas from local map which includes shapes added (but not necessarily in server db)\n const localMapState = GetLocalMap(state);\n\n // #REVIEW - may not be used. Was WIP for idea. Delete?\n // a subset of local map to allow comparison of common data between mqtt and drawn\n //const localNamedAreasReduced = GetLocalMapNamedAreasReducedProperties(state);\n\n const { namedArea: parentIsDirty } = getIsDirty(state);\n\n const namedAreas =\n localMapState.namedAreas !== undefined\n ? localMapState.namedAreas.features\n : [];\n\n const buttonGroupState = getNamedAreaEventButtonGroupState(state);\n\n return {\n mineLevelId,\n namedAreaIdValue,\n namedAreaParentName,\n namedAreasReduced,\n //localNamedAreasReduced,\n //geoJSONNamedAreasUtm,\n //localMapState,\n namedAreas,\n parentIsDirty,\n buttonGroupState,\n };\n}\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n namedAreaSetDeleteSelections: (deleteSelection) => {\n dispatch(namedAreaSetDeleteSelections(deleteSelection));\n },\n namedAreaClearDeleteSelections: (deleteSelection) => {\n dispatch(namedAreaClearDeleteSelections(deleteSelection));\n },\n namedAreaSetShowHideSelections: (hideSelection) => {\n dispatch(namedAreaSetShowHideSelections(hideSelection));\n },\n namedAreaClearShowHideSelections: (hideSelection) => {\n dispatch(namedAreaClearShowHideSelections(hideSelection));\n },\n namedAreasSetIsDirty: (id) => {\n dispatch(namedAreasSetIsDirty(id));\n },\n namedAreasClearIsDirty: (id) => {\n dispatch(namedAreasClearIsDirty(id));\n },\n updateButtonGroupState: (buttons) => {\n dispatch(updateButtonGroupState(buttons));\n },\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(NamedAreaTable);\n","export function GeoJsonToMqttNamedAreaChange(values) {\n const {\n id,\n area,\n name,\n coordinates,\n type,\n priority,\n origin,\n parent,\n parent_name,\n button,\n default_color,\n default_state,\n style,\n token,\n } = values;\n\n // duplicate first coordinate in shape to close the ring\n // e.g. coordinates\n // [\n // [\n // [737076.1835723922, 9549038.410007201],\n // [737092.1832776744, 9549024.94413115],\n // [737129.8460999232, 9549065.317777187],\n // [737110.3945287307, 9549077.532396676],\n // ],\n // ],\n\n let shape;\n // NOTE - only supports a single polygon shape, not multi-, so get the first shape in coordinates array\n shape = coordinates[0];\n // check first point and last should be the same\n if (shape[0] !== shape[shape.length - 1]) {\n // or append first to end point to close the polygon ring\n shape = [...shape, shape[0]];\n }\n\n return {\n id: id,\n area: area,\n name: name,\n shape: shape,\n type: type,\n priority: priority,\n origin: origin,\n parent: parent,\n parent_name: parent_name,\n button: button,\n default_color: default_color,\n default_state: default_state,\n style,\n token: token,\n };\n}\n","import React, { Component, useState } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport L from \"leaflet\";\nimport \"leaflet-draw\";\nimport \"leaflet-contextmenu\";\nimport \"leaflet.smoothwheelzoom\";\n\nimport { greenIcon } from \"assets/leaflet/leaflet-color-markers\";\n\nimport { LeastSquaresApproximationFourPointsSixParametersTransformation } from \"projection\";\nimport {\n transformGeoJsonUtmToPixels,\n transformGeoJsonPixelsToUtm,\n transformUtmToPixels,\n transformPixelsToUtm,\n standardPtsUtmX,\n localPtsX,\n} from \"components/Map/util-geoJsonToPixels\";\n\nimport {\n getAreaById,\n getNamedAreaStatusesById,\n getMapState,\n getFireflyCoordinates,\n getFireflyCoordinatesByAreaId,\n getNamedAreaInfos,\n getNamedAreaInfosById,\n getNamedAreaInfosByAreaId,\n getNamedAreaInfosByParentId,\n getNamedAreaDeleteSelections,\n getNamedAreaHideSelections,\n getIsDirty,\n} from \"components/WebWorker/reducer\";\n\nimport {\n namedAreaClearDeleteSelections,\n namedAreasSetIsDirty,\n mqttPublish,\n} from \"components/WebWorker/actions\";\n\nimport { GetLocalMap } from \"components/Map/reducer\";\nimport { UpdateLocalMap } from \"components/Map/actions\";\n\nimport { round } from \"utils/number-utils.js\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport * as turf from \"@turf/turf\";\n\n// import plugin's css (if present)\n// note, that this is only one of possible ways to load css\nimport \"leaflet-contextmenu/dist/leaflet.contextmenu.css\";\nimport { messageToken } from \"utils/messageToken\";\nimport { id } from \"date-fns/locale\";\n\nimport { selectColor } from \"admin/named-area/region-colors\";\n\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\nimport { imageCheck } from \"utils/imageCheck\";\n\n// #REVIEW - move this.locationGroupLayers etc. to state rather than forced via \"this.\"\n// use setState to update once groups are defined\n\n// const polygonStyleDefault = {\n// color: \"grey\",\n// fillColor: \"grey\",\n// fillOpacity: 0.3,\n// opacity: 1,\n// weight: 1,\n// };\n\nclass Map extends React.Component {\n constructor(props) {\n super(props);\n\n this.state = {\n refPts: {},\n thislocalMapState: {},\n map: { area: \"\" }, //\"DMLZ_Extraction\"\n heartBeat: true,\n };\n }\n\n // styling for polygons\n\n // #polygonStyle\n polygonStyle = () => {\n const numberofEditableLayers = this.editableLayers.getLayers().length;\n const numberofGeoJsonLayers =\n this.geoJSONNamedAreaGroupLayer.getLayers().length;\n\n // #NOTE\n // named area regions are initially loaded onto the geoJsonLayer.\n // So a count of this layer gives existing content.\n // After the first change geoJsonLayers are copied to editableLayer, as are any subsequent\n // newly drawn layers, so editableLayers gives the count of any changes/additions and will be\n // >= geoJson after the first change.\n //\n // For the color base choose which his greater geoJson or editable layers.\n //\n const numberLayers = Math.max(\n numberofEditableLayers,\n numberofGeoJsonLayers\n );\n\n const color = selectColor(numberLayers + 1);\n\n //console.log(\"numberofGeoJsonLayers\", numberofGeoJsonLayers);\n //console.log(\"numberofEditableLayers\", numberofEditableLayers);\n //console.log(\"numberLayers\", numberLayers);\n //console.log(\"color\", color);\n\n return {\n color: color,\n fillColor: color,\n fillOpacity: 0.5,\n opacity: 1,\n weight: 1,\n };\n };\n\n // #polygonStyle\n geojsonPolygonStyle = (feature) => {\n // #polygonStyle\n const polygonStyle = feature?.properties?.style;\n return polygonStyle !== undefined ? polygonStyle : this.polygonStyle();\n };\n\n markerPts = (img) => {\n const { width, height } = img;\n\n // image pixel positions = lat,lng\n // geometric refernece coord = easting, northing, zoneNum, zoneLetter,\n // {lat, lng, easting, northing, zoneNum, zoneLetter}\n\n const markerOrigin = {\n id: \"corner\",\n lat: 0,\n lng: 0,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n const markerMiddle = {\n id: \"center\",\n lat: height / 2,\n lng: width / 2,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n const markerMax = {\n id: \"corner\",\n lat: height,\n lng: width,\n easting: 0,\n northing: 0,\n zoneNum: 53,\n zoneLetter: \"M\",\n z: 0,\n };\n\n return [markerOrigin, markerMiddle, markerMax];\n };\n\n // creates a geoJson object for the map reference points\n // pass in map pixel ref lat,lng and the coord reference easting, northing\n // geometry coordinats are in pixels\n //\n // e.g. localPtsGeoJson([{ lat: 0, lng: 0, easting: 0, northing: 0, zoneNum: 53, zoneLetter: \"M\", z: 0 },...[...]);\n //\n // still using lat and lng because leaflet uses these references.\n //\n localPtsGeoJson = (points) => {\n let localPtsGeoJson = [];\n points.map(\n ({ lat, lng, easting, northing, zoneNum, zoneLetter, id }, idx) => {\n const objLatLng = { lat: lng, lng: lat }; // #REVIEW - have swapped around lat and long **ADRESS THIS**\n const point = Object.values(objLatLng);\n\n // structure geoJSON object\n\n const geojsonFeature = {\n type: \"Feature\",\n properties: {\n index: idx,\n id: id,\n area: \"refArea\",\n location: \"refPt\",\n position: idx,\n easting: easting,\n northing: northing,\n utm_zone_number: zoneNum,\n utm_zone_letter: zoneLetter,\n z: 0,\n color: \"toBeDone\",\n },\n geometry: {\n type: \"Point\",\n coordinates: point,\n },\n };\n localPtsGeoJson.push(geojsonFeature);\n }\n );\n return {\n type: \"FeatureCollection\",\n features: localPtsGeoJson,\n };\n };\n\n // create geojson markerData\n markerToGeoJSON = (markersData, transform) => {\n const geoJSONMarkersData = [];\n\n markersData.map(\n ({ id, lat, lng, name, color, position, location }, idx) => {\n // transform the point from latlng to pixels\n const objLatLng = { lat: lat, lng: lng };\n const point = Object.values(transform.transform(objLatLng));\n\n // structure geoJSON object\n const geojsonFeature = {\n type: \"Feature\",\n properties: {\n id: id,\n name: name,\n color: color,\n position: position,\n location: location,\n },\n geometry: {\n type: \"Point\",\n coordinates: point,\n },\n };\n geoJSONMarkersData.push(geojsonFeature);\n }\n );\n return {\n type: \"FeatureCollection\",\n features: geoJSONMarkersData,\n };\n };\n\n // support for map leaflet.contextmenu\n showCoordinates = (e) => {\n alert(e.latlng);\n };\n\n centerMap = (e) => {\n this.map.panTo(e.latlng);\n };\n\n fitMap = (e, bounds) => {\n this.map.fitBounds(bounds);\n };\n\n zoomIn = (e) => {\n this.map.zoomIn();\n };\n\n zoomOut = (e) => {\n this.map.zoomOut();\n };\n\n // draw\n drawTheMap = (\n mapId,\n mineLevel,\n namedAreaId,\n geoJSONMarkersData,\n geoJSONNamedAreas,\n folderFilesList\n ) => {\n const {\n id: mineLevelId,\n image_filename,\n image_info,\n\n localPtsX,\n } = mineLevel;\n\n const { width = 10000, height = 8000 } = image_info;\n\n //const url = process.env.PUBLIC_URL + \"/areas/\" + image_filename; // \"extraction.png\";\n const url = imageCheck(folderFilesList, image_filename, image_info);\n\n ////////////////////////////////////////////////////////////////////////////\n // Conversion from (x, y) raster image coordinates to equivalent of latLng\n // Taken from Leaflet tutorial \"Non-geographical maps\"\n // http://leafletjs.com/examples/crs-simple/crs-simple.html\n ////////////////////////////////////////////////////////////////////////////\n var yx = L.latLng;\n var xy = function (x, y) {\n if (L.Util.isArray(x)) {\n // When doing xy([x, y]);\n return yx(x[1], x[0]);\n }\n return yx(y, x); // When doing xy(x, y);\n };\n\n var minZoom = 2; // no need for zoom out completely\n var maxZoom = 6; // ...as defined by tile generation\n // const width = 13234;\n // const height = 9356;\n\n const img = [\n width, // original width of image `level.jpg` - undercut 800 conversion example => x / ~longitude (0 is left, width, 13234 is right)\n height, // original height of image => y / ~ reverse of latitude (0 is top, height, 9356 is bottom)\n ];\n\n // center calculation based on original pixel dimensions\n const center = [width / 2, height / 2];\n\n var bounds = L.latLngBounds([xy(0, 0), xy(img)]);\n\n let base = L.tileLayer(url, {\n bounds: bounds,\n noWrap: true,\n });\n\n // #REVEW / #WIP - put up 'loading' banners\n // events to show loading progress\n //base.on(\"loading\", console.log(\"base loading\"));\n //base.on(\"tileload\", console.log(\"base loaded\"));\n\n base.on(\"tileerror\", (error, tile) => {\n console.log(`Error ${error} loading tile ${tile}`);\n });\n\n // define the map\n\n this.map = L.map(mapId, {\n crs: L.CRS.Simple,\n // maxBounds: bounds.pad(0.5), // http://leafletjs.com/reference-1.0.3.html#map-maxbounds\n minZoom: -5, // minZoom,\n //maxZoom: maxZoom,\n attributionControl: false,\n contextmenu: true, // context menu plugin `npm i leaflet-contextmenu`\n contextmenuWidth: 140,\n contextmenuItems: [\n // {\n // text: \"Show coordinates\",\n // callback: this.showCoordinates,\n // },\n {\n text: \"Center map here\",\n callback: this.centerMap,\n },\n {\n text: \"Show all\",\n callback: (e) => this.fitMap(e, bounds),\n },\n \"-\",\n {\n text: \"Zoom in\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-in.png\",\n callback: this.zoomIn,\n },\n {\n text: \"Zoom out\",\n icon: process.env.PUBLIC_URL + \"/images/zoom-out.png\",\n callback: this.zoomOut,\n },\n ],\n // scroll wheel zoom smoothing\n scrollWheelZoom: false, // disable original zoom function\n smoothWheelZoom: true, // enable smooth zoom\n smoothSensitivity: 1.5, // zoom speed. default is 1\n }).setView(xy(center), 2); // move view to center pixel position\n\n // set single image background\n const image = L.imageOverlay(url, bounds);\n image.addTo(this.map);\n\n this.map.fitBounds(bounds);\n\n // ****************************************************\n // setup a pen for waylaid fireflies\n //\n // ****************************************************\n\n // #WIP - pen\n // #REVIEW\n // - https://www.npmjs.com/package/@turf/boolean-point-in-polygon\n // - http://turfjs.org/\n\n // holding pen\n\n // #REVIEW - would have put pen in top right but points random location in pen is defined in\n // src/components/Map/util-geoJsonToPixels.js\n // and this does not have image height and width ATM to define\n\n const holdingPenPolygon_topRight = [\n [height, width * 0.85],\n [height, width],\n [height * 0.85, width],\n [height * 0.85, width * 0.85],\n ];\n\n const holdingPenPolygon_bottomLeft = [\n [0, 0],\n [height * 0.15, 0],\n [height * 0.15, width * 0.15],\n [0, width * 0.15],\n ];\n\n this.holdingPen = L.polygon(holdingPenPolygon_bottomLeft).addTo(this.map);\n // -> see randomPointInPoly function\n\n // ****************************************************\n // setup layers for fireflies\n //\n // ****************************************************\n\n //\n this.layerlistFireflies = {};\n\n //\n this.testExternalStr = \"Point:\"; // test passing variable outside into ....\n\n // add popup information\n const onEachFeatureFirefly = (feature, layer) => {\n // #REVIEW - does this feature have a property named popupContent?\n\n const { properties } = feature;\n const {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_number,\n utm_zone_letter,\n z,\n color,\n } = properties;\n const { geometry } = feature;\n\n // coord geom is reversed\n const X = round(geometry.coordinates[0], 2);\n const Y = round(geometry.coordinates[1], 2);\n\n if (feature.properties && feature.properties.id) {\n layer.bindPopup(\n `
${id}
\n
${this.testExternalStr} ${area}:${location}:${position}
\n
Geom: E:${round(easting, 2)} N:${round(\n northing,\n 2\n )} Z${Math.trunc(z)} ${utm_zone_number} ${utm_zone_letter}
\n
Image: X:${X} Y:${Y}
\n
Color: ${color}
`\n );\n\n this.layerlistFireflies[feature.properties.id] = layer;\n }\n\n if (feature.properties && feature.properties.location) {\n // adds a separate layer specifically for location\n this[`${feature.properties.location}`].addLayer(layer);\n }\n };\n\n // set the points markers. See - https://leafletjs.com/examples/geojson/\n const pointToLayer = (feature, latlng) => {\n return L.circleMarker(latlng);\n };\n\n // set style of firefly markers\n const fireflyStyle = (feature) => {\n let setFillColor;\n if (feature.properties.color) {\n switch (feature.properties.color) {\n case \"green\":\n setFillColor = \"green\";\n break;\n case \"blue\":\n setFillColor = \"blue\";\n break;\n case \"amber\":\n setFillColor = \"orange\";\n break;\n case \"white\":\n setFillColor = \"white\";\n break;\n case \"red\":\n setFillColor = \"red\";\n break;\n\n default:\n setFillColor = \"green\";\n break;\n }\n }\n\n return {\n radius: 6,\n fillColor: setFillColor,\n color: \"#000\",\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n };\n\n // determine unique properties array from geoJson\n //\n let uniqueProperties = geoJSONMarkersData.features.reduce(\n (acc, { properties }) => {\n Object.entries(properties).forEach(([key, val]) => {\n acc[key] = acc[key] || new Set();\n acc[key].add(val);\n });\n\n return acc;\n },\n {}\n );\n\n // sort the locations so they list in order on the screen\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let locations = [];\n this.locationGroupLayers = {};\n if (uniqueProperties[\"location\"]) {\n locations = [...uniqueProperties[\"location\"]].sort(sortAlphaNum);\n locations.forEach((value, idx) => {\n //console.log(\"locations[idx]\", value);\n\n // -> this makes location group a separate layer\n // disabled for now so does not crowd the layer control\n this[value] = L.featureGroup().addTo(this.map);\n this.locationGroupLayers[value] = this[value];\n });\n }\n\n // #REVIEW - Issue is that with growing array location groups are not created on startup.\n // Need to make these with each update of the state geoJson\n // constrain to area\n const filterArea = (feature, layer) => {\n return feature.properties.area === mineLevelId; // this.state.map.area; // \"DMLZ_Extraction\";\n };\n\n // add firefly markers to the map\n this.geoJSONGroupLayer = L.geoJSON(geoJSONMarkersData, {\n pointToLayer: pointToLayer,\n onEachFeature: onEachFeatureFirefly,\n style: fireflyStyle,\n //coordsToLatLng: coordsToLatLng, // <<--- #REVIEW I still don't underestand what this does\n filter: filterArea,\n }).addTo(this.map);\n\n // ********************************************************************************\n //\n // Set and draw the marker points - map scaling points and origin/centre/max markers\n //\n // ********************************************************************************\n\n // setup scaling coord reference point markers\n const onEachFeatureMarker = (feature, layer) => {\n layer.bindPopup(\n \"ref pt:\" +\n JSON.stringify(feature.properties.index) +\n \" => \" +\n JSON.stringify(feature.geometry.coordinates)\n );\n layer.on(\"dragend\", function (e) {\n const marker = e.target;\n const position = marker.getLatLng();\n //console.log(\"xxx dragend refPt position\", position);\n marker\n .setLatLng(position, { draggable: \"true\" })\n .bindPopup(\"\" + position) // #REVIEW \"\" is hack as bindPopup will not accept just numbers\n .update();\n });\n layer.on(\"click\", (e) => {\n // transform from pixels to points\n //const transform = this.Transform(\n // this.standardPtsUtm(),\n // this.localPts()\n //);\n\n const transformPixelsToUtm = this.props.mineLevel.transformPixelsToUtm;\n\n const marker = e.target;\n const position = marker.getLatLng();\n //console.log(\"xxx dragend refPt position\", JSON.stringify(position));\n\n const objLatLng = transformPixelsToUtm.transform({\n //transform\n lat: position.lat,\n lng: position.lng,\n });\n\n console.log(\n \"xxx feature.properties\",\n JSON.stringify(feature.properties)\n );\n\n const id = `ID:${feature.properties.id}`;\n\n // original geoJson coordinates\n const geoJsonPt = `E:${feature.properties.easting}, N:${feature.properties.northing}`;\n // image coordinates\n const imagePt = Object.values(position).reverse(); // map is y, x referenced. Reverse to display as x,y.\n // transformed image -> physical\n const coordPt = Object.values(objLatLng).reverse();\n\n marker\n .setLatLng(position, { draggable: \"true\" })\n .bindPopup(\n `
${id}
\n
GeoJ: ${geoJsonPt}
\n
Image: X: ${round(imagePt[0], 2)}, Y: ${round(\n imagePt[1],\n 2\n )}
\n
Coord: E: ${round(coordPt[0], 2)}, N: ${round(\n coordPt[1],\n 2\n )}
`\n )\n .update();\n\n console.log(`xxx clicked - Ref Pt marker - UTM Coords:[${coordPt}]`);\n });\n };\n\n // ******************************************************************\n // add markers to map\n // ******************************************************************\n this.markerGroupLayer = L.geoJSON(\n this.localPtsGeoJson(this.markerPts({ width, height })),\n {\n pointToLayer: function (feature, latlng) {\n return L.marker(latlng, {\n //icon: greenIcon, // <--- #TODO FIX THIS!\n draggable: true,\n });\n },\n onEachFeature: onEachFeatureMarker,\n }\n ).addTo(this.map);\n\n // ******************************************************************\n // add coord reference point markers to map\n // ******************************************************************\n\n //this.localPtsX();\n this.refPtGroupLayer = L.geoJSON(this.localPtsGeoJson(localPtsX), {\n pointToLayer: function (feature, latlng) {\n return L.marker(latlng, {\n //icon: greenIcon, // <--- #TODO FIX THIS!\n draggable: true,\n });\n },\n onEachFeature: onEachFeatureMarker,\n }).addTo(this.map);\n\n // ********************************************************************************\n //\n // Setup and draw the named area polygons\n //\n // ********************************************************************************\n\n // list of named area polygons\n this.layerlistNamedAreas = {};\n\n const onEachFeatureNamedAreas = (feature, layer) => {\n if (feature.properties && feature.properties.id) {\n this.layerlistNamedAreas[feature.properties.id] = layer;\n }\n layer.on(\"click\", (e) => {\n //console.log(\"na click feature.properties.id\", feature.properties.id);\n\n const id = feature.properties.id.split(\":\")[2]; // eg. from \"DMLZ_Extraction:Area_A:182736182736\" -> \"182736182736\"\n const namedAreaPolygon = e.target;\n namedAreaPolygon.bindPopup(`
Region: ${id}
`);\n });\n };\n\n // ********************************************************************************\n //\n // Add named area polygons to the map\n //\n // ********************************************************************************\n //\n this.geoJSONNamedAreaGroupLayer = L.geoJSON(geoJSONNamedAreas, {\n style: this.geojsonPolygonStyle,\n onEachFeature: onEachFeatureNamedAreas,\n coordsToLatLng: function (coords) {\n // swaps the coordinate references around so when polygons are created the pixel refer are [x,y] , not [y,x]\n // latitude , longitude, altitude\n return new L.LatLng(coords[1], coords[0], coords[2]); //<------ Normal behavior\n //return new L.LatLng(coords[0], coords[1], coords[2]);\n },\n }).addTo(this.map);\n\n // update leaflet id to properties (used to delete.edit shapes in local state)\n this.geoJSONNamedAreaGroupLayer.eachLayer(function (layer) {\n layer.feature.properties._leaflet_id = layer._leaflet_id; //#TODO - change to L.Stamp()\n });\n\n //#TODO - change to L.Stamp()\n // Also note that .getLayers() works for LayerGroup (and FeatureGroup and GeoJson), but not for L.Map.\n // Usage of \"private\" properties and methods like _layers or _leaflet_id or _latlng is discouraged.\n\n // add layers to the local maps state\n const geoJsonPixels = this.geoJSONNamedAreaGroupLayer.toGeoJSON();\n\n //const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n\n //console.log(\"qqq add layers to the local maps state geoJson\", geoJsonUtm);\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // push layer to back layer.bringToFront()\n this.geoJSONNamedAreaGroupLayer.bringToBack();\n\n // ********************************************************************************\n //\n // Setup the map layers into control groups and display controls\n //\n // ********************************************************************************\n\n // setup layer groups\n let baseLayers = { MineMap: base };\n // setup layer groups overlayers (see also https://leafletjs.com/reference-1.6.0.html#control-layers-addoverlay)\n let overLayers = {\n // \" Firefly\": this\n // .geoJSONGroupLayer,\n FireFlys: this.geoJSONGroupLayer,\n //Marker: this.markerGroupLayer,\n //RefPt: this.refPtGroupLayer,\n Polygons: this.geoJSONNamedAreaGroupLayer,\n //Cable: this.polylineGroupLayers,\n };\n\n // spread the objects to join the location layers to the overlay\n\n if (false) {\n overLayers = {\n ...overLayers,\n ...this.locationGroupLayers,\n };\n }\n\n // define layer control\n var layerControl = L.control.layers(null, overLayers, {\n collapsed: true, //\n });\n\n // add it to the map\n layerControl.addTo(this.map);\n\n // https://stackoverflow.com/questions/34384905/leaflet-how-to-toggle-all-layers-either-off-or-on-at-once/34392545#34392545\n //https://github.com/ismyrnow/leaflet-groupedlayercontrol\n\n // events to show loading progress\n this.map.on(\n \"baselayerchange \"\n //console.log(\"layerControl baselayerchange \")\n );\n\n // // see - https://groups.google.com/forum/#!searchin/leaflet-js/control$20onadd/leaflet-js/rKMZX3PKFuI\n // // then remove the control container\n // layerControl._container.remove();\n\n // // append the control container to the other div\n // document\n // .getElementById(\"custom-map-controls\")\n // .appendChild(layerControl.onAdd(this.map));\n\n // ********************************************************************************\n //\n // Set polylines joining the Fireflies\n //\n //\n // NOTE: this has to be done after the locationGroupLayers has been rendered\n // ...probably more likely need layer control defined before start adding groups\n //\n // #REVEW <--- reorder the code\n // ********************************************************************************\n\n // // step through the list of locationGroupLayers\n // this.polylineGroupLayers = {};\n\n // for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n // // create an object with the posObject[position] = latlng coordinates\n // let posObject = {};\n\n // // loop each layer - #REVIEW - this could be labourious - perhaps only do if selected to display?\n // // eslint-disable-next-line no-loop-func\n // value.eachLayer(function (layer) {\n // posObject[layer.feature.properties.position] = layer.getLatLng();\n // });\n\n // // sort the posObject by position order (i.e. object key) so line draws from position 1 -> n\n\n // // see - https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key\n // const ordered = {};\n // Object.keys(posObject)\n // .sort()\n // .forEach(function (key) {\n // ordered[key] = posObject[key];\n // });\n\n // // plot a polyline using ordered array of values\n // // create name object from layer name (i.e. key is the POSITION)\n // const layerName = \"poly_\" + key;\n // this[layerName] = L.polyline(Object.values(ordered)).addTo(this.map); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n\n // // add this layer to layer group to add to control layer later\n // this.polylineGroupLayers[layerName] = this[layerName];\n // }\n\n // // add group to overlays by iterating over the object\n // // https://stackoverflow.com/questions/55471295/adding-multiple-overlays-to-leaflets-layers-control\n // for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n // layerControl.addOverlay(value, key); // #REVIEW <---- ENABLE THIS TO PUT CABLES ON\n // }\n // // *****************************************************************************************\n\n // add group to overlays by iterating over the object\n // https://stackoverflow.com/questions/55471295/adding-multiple-overlays-to-leaflets-layers-control\n //for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n // layerControl.addOverlay(value, key);\n //}\n\n // #REVIEW - setup ordering layers for all levels with toggle\n // setup layer control events\n // https://stackoverflow.com/questions/14103489/leaflet-layer-control-events\n this.map.on(\"overlayadd\", onOverlayAdd);\n\n function onOverlayAdd(e) {\n // https://gis.stackexchange.com/questions/137061/how-to-change-layer-order-in-leaflet-js\n // push layer to back layer.bringToFront()\n\n if (e.name === \"Polygon\") {\n e.layer.bringToBack();\n }\n //console.log(\"onOverlayAdd e\", e);\n }\n\n // ********************************************************************************\n //\n // Setup polygons drawn on the map\n //\n //\n // NOTE: uses leaflet.draw leaflet-draw\n //\n // ********************************************************************************\n\n // Truncate value based on number of decimals\n var _round = function (num, len) {\n return Math.round(num * Math.pow(10, len)) / Math.pow(10, len);\n };\n // Helper method to format LatLng object (x.xxxxxx, y.yyyyyy)\n var strLatLng = function (latlng) {\n return \"(\" + _round(latlng.lat, 6) + \", \" + _round(latlng.lng, 6) + \")\";\n };\n\n // Generate popup content based on layer type\n // - Returns HTML string, or null if unknown object\n var getPopupContent = function (layer) {\n // Marker - add lat/long\n if (layer instanceof L.Marker || layer instanceof L.CircleMarker) {\n return strLatLng(layer.getLatLng());\n // Circle - lat/long, radius\n } else if (layer instanceof L.Circle) {\n var center = layer.getLatLng(),\n radius = layer.getRadius();\n return (\n \"Center: \" +\n strLatLng(center) +\n \"
\" +\n \"Radius: \" +\n _round(radius, 2) +\n \" m\"\n );\n // Rectangle/Polygon - area\n } else if (layer instanceof L.Polygon) {\n var latlngs = layer._defaultShape\n ? layer._defaultShape()\n : layer.getLatLngs();\n\n // get the pixel coordinates of the shape\n var coords = latlngs.map(function (point) {\n return [point.lng, point.lat]; // #REVIEW - reverse display lat, long = YX\n });\n\n return (\n \"Coords: \" +\n JSON.stringify(coords) +\n \"
_leaflet_id: \" +\n L.stamp(layer)\n );\n // Polyline - distance\n } else if (layer instanceof L.Polyline) {\n var latlngs = layer._defaultShape\n ? layer._defaultShape()\n : layer.getLatLngs(),\n distance = 0;\n if (latlngs.length < 2) {\n return \"Distance: N/A\";\n } else {\n for (var i = 0; i < latlngs.length - 1; i++) {\n distance += latlngs[i].distanceTo(latlngs[i + 1]);\n }\n return \"Distance: \" + _round(distance, 2) + \" m\";\n }\n }\n return null;\n };\n\n // create the editable layers to drawn on\n\n // #REVIEW - the use of VAR here is an issue.\n // this.editableLayers is only accessible to componentDidMount, not componentDidUpdate\n // needs to go to STATE\n //\n this.editableLayers = L.featureGroup().addTo(this.map);\n // this.map.addLayer(this.editableLayers);\n\n // console.log(\n // \"hasLayer this.map.hasLayer(this.editableLayers)\",\n // this.map.hasLayer(this.editableLayers)\n // );\n\n // localisation of drawing tools\n L.drawLocal = {\n draw: {\n toolbar: {\n // #TODO: this should be reorganized where actions are nested in actions\n // ex: actions.undo or actions.cancel\n actions: {\n title: \"Cancel drawing\",\n text: \"Cancel\",\n },\n finish: {\n title: \"Finish drawing\",\n text: \"Finish\",\n },\n undo: {\n title: \"Delete last point drawn\",\n text: \"Delete last point\",\n },\n buttons: {\n polyline: \"- your text-\",\n polygon: \"Add polygon region\",\n rectangle: \"Add rectangle region\",\n circle: \"- your text-\",\n marker: \"- your text-\",\n circlemarker: \"- your text-\",\n },\n },\n handlers: {\n circle: {\n tooltip: {\n start: \"- your text-\",\n },\n radius: \"- your text-\",\n },\n circlemarker: {\n tooltip: {\n start: \"- your text-.\",\n },\n },\n marker: {\n tooltip: {\n start: \"- your text-.\",\n },\n },\n polygon: {\n tooltip: {\n start: \"Click to start drawing a region\",\n cont: \"Click to continue drawing this region\",\n end: \"Click first point to close this shape\",\n },\n },\n polyline: {\n error: \"Error: shape edges cannot cross!\",\n tooltip: {\n start: \"Click to start drawing line.\",\n cont: \"Click to continue drawing line.\",\n end: \"Click last point to finish line.\",\n },\n },\n rectangle: {\n tooltip: {\n start: \"Click to start drawing a region\",\n },\n },\n simpleshape: {\n tooltip: {\n end: \"Release mouse to finish drawing.\",\n },\n },\n },\n },\n edit: {\n toolbar: {\n actions: {\n save: {\n title: \"Save changes\",\n text: \"Save\",\n },\n cancel: {\n title: \"Cancel editing, discards all changes\",\n text: \"Cancel\",\n },\n clearAll: {\n title: \"Clear all regions\",\n text: \"Clear All\",\n },\n },\n buttons: {\n edit: \"Edit regions\",\n editDisabled: \"No regions to edit\",\n remove: \"Delete regions\",\n removeDisabled: \"No regions to delete\",\n },\n },\n handlers: {\n edit: {\n tooltip: {\n text: \"Drag handles or markers to edit features.\",\n subtext: \"Click cancel to undo changes.\",\n },\n },\n remove: {\n tooltip: {\n text: \"3Click on a feature to remove.\",\n },\n },\n },\n },\n };\n\n // see - https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#options\n const drawPluginOptions = {\n position: \"topleft\",\n draw: {\n polygon: {\n allowIntersection: false, // Restricts shapes to simple polygons\n showArea: false, // removes adding area to drawn area\n drawError: {\n color: \"#e1e100\", // Color the shape will turn when intersects\n message: \"Oh snap! you can't draw that!\", // Message that will show when intersect\n },\n shapeOptions: this.polygonStyle(), // polygonStyleDefault,\n },\n polyline: false, // disable toolbar item by setting it to false\n circle: false, // removet the circle marker\n rectangle: {\n showArea: false, // removes adding area to drawn area\n shapeOptions: this.polygonStyle(), // polygonStyleDefault,\n },\n marker: false, // removes the marker point\n circlemarker: false, // removed the circlemarker\n },\n edit: {\n featureGroup: this.editableLayers, //REQUIRED!!\n edit: {\n // https://github.com/Leaflet/Leaflet.draw/issues/295\n // changes colour when in edit mode\n // this property shouldn't be needed\n selectedPathOptions: {\n // this property should be one level up\n color: \"#000\",\n fillColor: \"#000\",\n },\n },\n remove: false, // disables the trash can remove function\n },\n };\n\n // Initialise the draw control and pass it the FeatureGroup of editable layers\n this.drawControl = new L.Control.Draw(drawPluginOptions);\n this.map.addControl(this.drawControl);\n\n // position in center\n // https://stackoverflow.com/questions/23762176/leaflet-custom-control-position-center/49036235#49036235\n\n // set popup event on created object\n // view-source:http://leaflet.github.io/Leaflet.draw/docs/examples/popup.html\n\n // get and set style\n // layer.setStyle({\n // weight: 5,\n // color: '#666',\n // dashArray: '',\n // fillOpacity: 0,\n // opacity: 0.9,\n // });\n\n // layer.options\n\n // Object created - bind popup to layer, add to feature group\n // draw:created\n this.map.on(L.Draw.Event.CREATED, (event) => {\n //console.log(\"xxx draw:created layer\", event.layer);\n //console.log(\"xxx draw:created layer.options\", event.layer.options);\n\n // create layer\n let layer = event.layer;\n // Setup layer for geoJSON\n // Intialize layer.feature\n let feature = (layer.feature = layer.feature || {});\n // Intialize feature.type\n feature.type = feature.type || \"Feature\";\n // Intialize feature.properties\n let props = (feature.properties = feature.properties || {});\n\n // create default geoJson object properties for named area\n\n // #TODO/REVIEW - give shape an id. Must be unique so give timecode from epoch\n\n const namedAreaTimestamp = new Date().getTime(); // timestamp;\n const namedAreaRegionId = `${namedAreaId}:${namedAreaTimestamp}`;\n const parentNamedArea = `${namedAreaId}`;\n\n console.log(\"parentNamedArea\", parentNamedArea);\n\n props.id = namedAreaRegionId; // this.state.map.area + \":\" + namedAreaTimestamp;\n props._leaflet_id = L.stamp(layer); // leaflet id\n props.name = `${namedAreaTimestamp}`;\n props.parent = parentNamedArea; // `${mineLevelId}:${namedAreaId}`;\n props.area = mineLevelId; //this.state.map.area;\n props.priority = 1;\n props.Firefly_List = [];\n props.type = \"Polygon\"; // #TODO - get type from shape created? If only support Polygon restrict entry.\n\n // #REVEW #TODO\n // ...these should be region setup values\n props.default_state = \"off\";\n props.default_color = \"green\";\n\n // # polygonStyle\n props.style = layer.options; // polygonStyleDefault,\n // #REVIEW / TODO\n // add one button.\n // 1 - if new area, add buttons manually\n // 2 - if other regions exist buttons will add automatically\n\n // #REVIEW / #TODO - move this to get from common server setup\n\n // #NOTE - this is the default for the first button created for a new region\n //\n props.button = [\n // #TODO - getDefaultButtonSet() - ATM just do 4 buttons for testing\n {\n priority: 0,\n type: \"SEISMIC0_EVENT\",\n clickable: true,\n icon: \"icon-earthquake0\",\n color: \"green\",\n hint: \"Level 0\",\n title: \"Seismic 0\",\n alt: \"Level 0\",\n\n // named area info\n id: namedAreaRegionId,\n named_area: parentNamedArea,\n\n // group info\n group: 0, // grouping of columns\n default: true, // default for the group\n\n // #REVIEW/TODO/WIP - yet to be implemented\n // namedArea buttons info\n active: true, // allows enable/disable of button column\n column: 0, // index for position of column - as different to priority\n\n // event properties\n //\n state: \"on\",\n active_color: \"green\",\n active_state: \"on\",\n on_time: 0,\n off_time: 0,\n train: 0,\n marker: \"RoundMarker\",\n },\n ];\n\n // 'status' - used to track the status of the object on maps and in lists\n // options:\n // drawn - drawn on the localmap. i.e. not a named area source from the messages/db\n // mqtt - defined by the messages/db\n // [proposed] deleted - marked for deletion\n props.status = \"drawn\";\n\n // create a polygon style\n // this.editableLayers\n\n // #TODO -\n // getDefaultButtonSet () => {\n // get # of buttons in named area group based on 'parent'\n // append default button set\n // }\n\n console.log(\"DRAW: CREATED - parentNamedArea props\", props);\n\n // DISABLE - only used for debugging\n if (false) {\n let content = getPopupContent(layer);\n console.log(\"popup content\", content);\n if (content !== null) {\n layer.bindPopup(content);\n }\n }\n\n // add named area name popup onClick event\n layer.bindPopup(`
Region: ${props.name}
`);\n\n console.log(\"qqq props created\", props);\n // add to editable layes\n this.editableLayers.addLayer(layer); // Note - .style.display = 'block' for default\n\n // NO - don't do this unless the area is saved!\n // ..........\n // add to layer list\n // this.layerlistNamedAreas[props.id] = layer;\n\n // update the localMapState\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n\n // console.log(\"hhh geoJsonPixels\", geoJsonPixels);\n\n //const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n\n console.log(\"geoJsonPixels mineLevelObj\", mineLevelObj);\n console.log(\"geoJsonPixels\", geoJsonPixels);\n console.log(\"geoJsonPixels -> geoJsonUtm\", geoJsonUtm);\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n console.log(\n \"xxx draw:created this.props.localMapState\",\n this.props.localMapState\n );\n console.log(\n \"xxx draw:created thislocalMapState\",\n this.state.thislocalMapState\n );\n\n // #polygonStyle\n // update the polygon style in the drawcontrol\n // *after* the editable layer is created\n //\n const newPolygonStyle = this.polygonStyle();\n //console.log(\"xxx draw:created newPolygonStyle\", event.layer.options);\n\n this.drawControl.setDrawingOptions({\n polygon: {\n shapeOptions: newPolygonStyle,\n },\n rectangle: {\n shapeOptions: newPolygonStyle,\n },\n });\n });\n\n // editableLayers onClick event\n // adding this click event displays the popupContent\n // to display named area name\n this.editableLayers.on(\"click\", (e) => {\n const transformPixelsToUtm = this.props.mineLevel.transformPixelsToUtm;\n\n // const marker = e.target;\n // const position = marker.getLatLng();\n // console.log(\"xxx dragend refPt position\", JSON.stringify(position));\n\n // const objLatLng = transformPixelsToUtm.transform({\n // //transform\n // lat: position.lat,\n // lng: position.lng,\n // });\n const polygon = e.target;\n const bounds = polygon.getBounds();\n const southWest = bounds.getSouthWest();\n const northEast = bounds.getNorthEast();\n console.log(\n `xxx clicked - editableLayers polygon - Image Bounds Coords:[ [${southWest.lat}, ${southWest.lng}],[${northEast.lat}, ${northEast.lng}]]`\n );\n });\n\n // Object(s) edited - update popups\n // draw:edited\n this.map.on(L.Draw.Event.EDITED, (event) => {\n var layers = event.layers,\n content = null;\n layers.eachLayer(function (layer) {\n console.log(\"qqq this.editableLayers edit \" + L.stamp(layer));\n\n content = getPopupContent(layer);\n console.log(\"popup content\", content);\n if (content !== null) {\n layer.setPopupContent(content);\n }\n });\n\n // #REVIEW / TODO - pass in parentId\n // mark the form as dirty\n const parentId = \"parentNamedArea\";\n this.props.namedAreasSetIsDirty(parentId);\n\n // #REVIEW / TODO - pass in parentId\n // move this to a common 'update()' function\n\n // update the localMapState\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n\n //const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n });\n\n // Named Areas edited - update state\n // draw:editstop\n this.map.on(L.Draw.Event.EDITSTOP, (event) => {\n //console.log(\"xxx draw:editstop \", event);\n //const { layer } = event;\n //console.log(\"xxx EDITSTOP click \" + L.stamp(layer));\n //console.log(\"xxx DRAWSEDITSTOPTOP - _leaflet_id \" + layer._leaflet_id);\n // console.log(\"xxx this.props.localMapState\", this.props.localMapState);\n // console.log(\"xxx thislocalMapState\", this.state.thislocalMapState);\n });\n\n // Named Areas edited - update state\n // draw:drawstop\n this.map.on(L.Draw.Event.DRAWSTOP, (event) => {\n //console.log(\"xxx draw:drawstop \", event);\n });\n\n // Named Areas edited - update state\n // draw:deleted\n this.map.on(L.Draw.Event.DELETED, (event) => {\n //console.log(\"xxx draw:deleted \", event);\n\n // return list of deleted layers...\n const editedlayers = event.layers;\n //console.log(\"xxx draw:deleted layers\", editedlayers);\n\n // update the localMapState\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n\n //const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // const {\n // namedAreas: { features },\n // } = this.props.localMapState;\n\n // // make a new list without the deleted layers\n // let newNamedAreas = [];\n // console.log(\"xxx newNamedAreas\", newNamedAreas);\n // editedlayers.eachLayer((layer) => {\n // features.forEach((feature, index, arr) => {\n // if (feature.properties._leaflet_id !== layer._leaflet_id) {\n // newNamedAreas.push(feature);\n // }\n // });\n // });\n\n // // update state as geoJson\n // this.props.UpdateLocalMap({\n // namedAreas: {\n // type: \"FeatureCollection\",\n // features: newNamedAreas,\n // },\n // });\n // this.setState({\n // thislocalMapState: {\n // type: \"FeatureCollection\",\n // features: newNamedAreas,\n // },\n // });\n });\n\n // yet another this.editableLayers on click event to\n // output the maps state for debugging\n // this.editableLayers.on(\"click\", (event) => {\n // console.log(\"xxx this.props.localMapState\", this.props.localMapState);\n // console.log(\"xxx thislocalMapState\", this.state.thislocalMapState);\n // });\n\n // https://stackoverflow.com/questions/40088421/returning-clicked-layer-leaflet\n // see - https://jsfiddle.net/3v7hd2vx/108/\n // attached to this.editableLayers group\n\n // DISABLE THIS ONCLICK ACTION - but leave in code for debugging\n if (false) {\n this.editableLayers.on(\"click\", (event) => {\n const { layer } = event;\n\n // console.log(\"xxx this.editableLayers click \" + L.stamp(layer));\n // console.log(\"xxx this.editableLayers - _leaflet_id \" + layer._leaflet_id);\n\n // Note 'layer.edited' only true after handles moved\n //&& layer.edited\n if (layer instanceof L.Polygon || layer instanceof L.Rectangle) {\n // rectangle, polygon, circle\n const colors = [\"green\", \"orange\", \"blue\", \"red\"];\n const currentColor = layer.options.fillColor;\n const index = colors.findIndex((x) => x === currentColor);\n let newColor;\n index + 1 > colors.length - 1\n ? (newColor = colors[0])\n : (newColor = colors[index + 1]);\n\n layer.setStyle({ color: newColor, fillColor: newColor });\n layer.feature.properties.color = layer.options.fillColor; // set fillColor as active color in geoJSON\n\n // console.log(\n // \"xxx this.editableLayers - UTM Coords:\",\n // JSON.stringify(convertPixelsToUtm(event))\n // );\n }\n });\n }\n\n const convertPixelsToUtm = (event) => {\n const latlngs = event.layer._latlngs[0]; // <----------only one lat longs array????? #REVIEW - could be more if multi-Polygo?\n // transform from pixels to points\n const transform = this.Transform(this.standardPtsUtm(), this.localPts());\n // get the pixel coordinates of the shape\n const utmPoints = latlngs.map(function (point) {\n const objUtm = transform.transform({\n lat: point.lat,\n lng: point.lng,\n });\n return [objUtm.lat, objUtm.lng];\n });\n return utmPoints;\n };\n\n // add existing layer to editable layer so can edit existing/loaded polygons\n //let that=this; // pass editable layer into function\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n console.log(\n \"Adding mqtt Named Area to this.editableLayers -> \",\n layer._leaflet_id\n ); // KEEP AS PERMANENT INDICATOR THAT MAP GROUPS ARE UPDATING\n\n layer.getElement().style.display = \"block\"; // this resets any hidden layer actions\n this.editableLayers.addLayer(layer);\n });\n\n // --- LAYER INFORMATION TO OUTSIDE MAP\n\n // check what layers are drawn.......\n this.editableLayers.eachLayer(function (layer) {\n //console.log(\"this.editableLayers layer\", layer);\n // Pass this information through Redux to outside\n });\n\n // --- LAYER CONTROL TO SEPARATE HTML\n\n // see - https://groups.google.com/forum/#!searchin/leaflet-js/control$20onadd/leaflet-js/rKMZX3PKFuI\n // then remove the control container\n // layerControl._container.remove();\n\n // append the control container to the other div\n if (false) {\n // disable this for the moment\n document\n .getElementById(\"custom-map-controls\")\n .appendChild(layerControl.onAdd(this.map));\n }\n\n // map drawn!!!!!!!!\n };\n\n convertGeoJsonPixelsToUtm = (geoJsonPixels, mineLevel) => {\n // Output coordinates of shape in UTM\n // returns geoJSON\n\n // convert pixel coordinates in geoJson Pixels to utm\n\n // deep clone - to stop geometry being converted on raw *utm data\n geoJsonPixels = JSON.parse(JSON.stringify(geoJsonPixels));\n const geoJsonUtm = transformGeoJsonPixelsToUtm(geoJsonPixels, mineLevel);\n\n // #TODO - NOTE: 'drawnItemsToJSON' below strips out the properties!\n // - needs to be updated to preserve PROPERTIES\n // - do not use until fixed\n\n // preserve styling of polygon in geoJson\n //\n //geoJson = this.drawnItemsToJSON(this.editableLayers);\n return geoJsonUtm;\n };\n\n // transformGeoJsonPixelsToUtm_disabled = (geoJson) => {\n // const transform = this.Transform(this.standardPtsUtmX(), this.localPtsX());\n // const geoJsonTransform = [];\n\n // geoJson.features.map((value, idx) => {\n // let newFeature = value;\n // // transform the point from pixels to pixels\n // const arrayLatLng = newFeature.geometry.coordinates.slice();\n // let arrayPoints = [];\n // const shapeType = newFeature.geometry.type;\n // switch (shapeType.toLowerCase()) {\n // case \"point\":\n // // convert to LatLng, transform, then convert back to array\n // arrayPoints = Object.values(\n // transform.transform({\n // // lat: arrayLatLng[1], // <-- **NOTE: lat & lng are swapped! **\n // // lng: arrayLatLng[0],\n // lat: arrayLatLng[0], // <-- **NOTE: lat & lng are swapped! **\n // lng: arrayLatLng[1],\n // })\n // ); //.reverse();\n // break;\n // case \"polygon\":\n // // iterate the geojons coord array\n // arrayLatLng.forEach((value, i, arr) => {\n // arrayPoints.push([]);\n // value.forEach((value, j) => {\n // // convert to LatLng, transform, then convert back to array\n // let arrayPoint = Object.values(\n // transform.transform({\n // // lat: value[1], // <-- **NOTE: lat & lng are swapped! **\n // // lng: value[0],\n // lat: value[0], // <-- **NOTE: lat & lng are swapped! **\n // lng: value[1],\n // })\n // ).reverse();\n\n // // accumulate results\n // arrayPoints[i][j] = arrayPoint;\n // });\n // });\n // break;\n // default:\n // break;\n // }\n // // update geometry\n // newFeature.geometry.coordinates = arrayPoints;\n // geoJsonTransform.push(newFeature);\n // });\n\n // return {\n // type: \"FeatureCollection\",\n // features: geoJsonTransform,\n // };\n // };\n\n // transformGeoJsonUtmToPixels transforms geoJson based on transform passed\n // Note:\n // * only supports points and polygons\n // * only supports single polygon shapes. i.e. not multi shapes or shapes with holes\n //\n // transformGeoJsonUtmToPixels_disabled = (geoJson) => {\n // const transform = this.Transform(this.localPtsX(), this.standardPtsUtmX());\n\n // console.log(\"transformGeoJsonUtmToPixels geoJson .... \", geoJson);\n\n // var yx = L.latLng;\n // var xy = function (x, y) {\n // if (L.Util.isArray(x)) {\n // // When doing xy([x, y]);\n // return yx(x[1], x[0]);\n // }\n // return yx(y, x); // When doing xy(x, y);\n // };\n\n // const geoJsonTransform = [];\n // geoJson.features.map((value, idx) => {\n // let newFeature = value;\n // // transform the point from latlng to pixels\n // const arrayLatLng = newFeature.geometry.coordinates.slice();\n\n // // check if rx an un positioned marker i.e. [0,0]\n // const isAllZero = arrayLatLng.every((item) => item === 0);\n\n // // if (isAllZero) {\n // // console.log(\n // // \"isAllZero feature\",\n // // newFeature.properties.id,\n // // JSON.stringify(newFeature)\n // // );\n // // }\n // // check if map has the holding pen setup\n\n // // #REVIEW/TODO #WIP\n // // make sure there is a default pen point\n // let randomHoldingPenCoordinate = [0, 0];\n // // why is this undefined on startup? img is defined ok?!\n // // if (this.holdingPen !== undefined) {\n // // const hasHoldingPen = this.map.hasLayer(this.holdingPen);\n // // if (isAllZero && hasHoldingPen) {\n // // randomHoldingPenCoordinate = this.randomPointInPoly(this.holdingPen)\n // // .geometry.coordinates;\n // // console.log(\n // // \"randomholdingPenCoordinate\",\n // // newFeature.properties.id,\n // // randomHoldingPenCoordinate\n // // );\n // // }\n // // }\n\n // let arrayPoints = [];\n // const shapeType = newFeature.geometry.type;\n // console.log(\"transformGeoJsonUtmToPixels shapeType .... \", shapeType);\n\n // switch (shapeType.toLowerCase()) {\n // case \"point\":\n // console.log(\n // \"transformGeoJsonUtmToPixels arrayPoints .... \",\n // arrayPoints\n // );\n\n // // convert to LatLng, transform, then convert back to array\n // if (!isAllZero) {\n // arrayPoints = Object.values(\n // transform.transform({\n // lat: arrayLatLng[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n // lng: arrayLatLng[1],\n // })\n // );\n // } else {\n // arrayPoints = randomHoldingPenCoordinate;\n // }\n\n // break;\n // case \"polygon\":\n // // iterate the geojons coord array\n // arrayLatLng.forEach((value, i, arr) => {\n // arrayPoints.push([]);\n // value.forEach((value, j) => {\n // // convert to LatLng, transform, then convert back to array\n // let arrayPoint;\n // if (!isAllZero) {\n // arrayPoint = Object.values(\n // transform.transform({\n // lat: value[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n // lng: value[1],\n // })\n // );\n // } else {\n // arrayPoint = randomHoldingPenCoordinate;\n // }\n\n // // accumulate results\n // arrayPoints[i][j] = arrayPoint;\n // });\n // });\n // break;\n // default:\n // break;\n // }\n\n // // update geometry\n // newFeature.geometry.coordinates = arrayPoints;\n // geoJsonTransform.push(newFeature);\n // });\n\n // return {\n // type: \"FeatureCollection\",\n // features: geoJsonTransform,\n // };\n // };\n\n // find a random point in the holding pen\n\n randomPointInPoly = function (polygon) {\n var bounds = polygon.getBounds();\n var x_min = bounds.getEast();\n var x_max = bounds.getWest();\n var y_min = bounds.getSouth();\n var y_max = bounds.getNorth();\n\n var lat = y_min + Math.random() * (y_max - y_min);\n var lng = x_min + Math.random() * (x_max - x_min);\n\n var point = turf.point([lng, lat]);\n var poly = polygon.toGeoJSON();\n var inside = turf.inside(point, poly);\n\n if (inside) {\n return point;\n } else {\n return this.randomPointInPoly(polygon);\n }\n };\n\n shouldComponentUpdate(nextProps, nextState) {\n return !nextProps.error;\n }\n\n componentDidMount() {\n const { mineLevelId, error } = this.props;\n\n this.setState({ map: { area: mineLevelId } });\n // #REVIEW #WIP ... can't use below as mineLevel is undefined\n // on page reload/refresh/direct link as state is not built\n // this.setState({ map: { area: mineLevel.id } });\n\n if (!error) {\n this.mapMount();\n }\n }\n\n // standardPtsUtmX = () => {\n // const { mineLevel } = this.props;\n // const { ref_coord } = mineLevel;\n\n // let result = [];\n\n // ref_coord.forEach((coord) => {\n // result.push({ lat: coord.utm[0], lng: coord.utm[1] });\n // });\n // return result;\n // };\n\n // standardPtsUtmX = () => {\n // const { mineLevel } = this.props;\n // const { ref_coord } = mineLevel;\n\n // let result = {};\n // ref_coord.forEach((coord) => {\n // const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n // const index = indexArray[1];\n\n // result[index] = { lat: coord.utm[0], lng: coord.utm[1] };\n // });\n\n // // sort object by key\n // Object.keys(result)\n // .sort()\n // .forEach(function (v, i) {\n // //console.log(v, result[v]);\n // });\n\n // // return the values\n // return Object.values(result);\n // };\n\n // localPtsX = () => {\n // const { mineLevel } = this.props;\n // const { ref_coord } = mineLevel;\n\n // let result = [];\n // ref_coord.forEach((coord) => {\n // result.push({\n // id: coord.id,\n // lat: coord.image_xy[0],\n // lng: coord.image_xy[1],\n\n // easting: coord.utm[0],\n // northing: coord.utm[1],\n // zoneNum: coord.utm_zone_number,\n // zoneLetter: coord.utm_zone_letter,\n // });\n // });\n // return result;\n // };\n\n // localPtsX = () => {\n // const { mineLevel } = this.props;\n // const { ref_coord } = mineLevel;\n\n // let result = {};\n // ref_coord.forEach((coord) => {\n // const indexArray = coord.id.split(\":\"); // e.g. \"DMLZ_Extaction:1\"\n // const index = indexArray[1];\n\n // result[index] = {\n // // used for transformation\n // lat: coord.image_xy[0],\n // lng: coord.image_xy[1],\n // // used for display on marker popups\n // id: coord.id,\n // easting: coord.utm[0],\n // northing: coord.utm[1],\n // zoneNum: coord.utm_zone_number,\n // zoneLetter: coord.utm_zone_letter,\n // };\n // });\n\n // // sort object by key\n // Object.keys(result)\n // .sort()\n // .forEach(function (v, i) {\n // //console.log(v, result[v]);\n // });\n\n // // return the values\n // return Object.values(result);\n // };\n\n mapMount = () => {\n const { render } = this.props;\n const mapId = \"map-\" + render;\n\n const { mineLevel, namedAreaId } = this.props;\n const { geoJSONMarkersDataUtm, geoJSONNamedAreasUtm, folderFilesList } =\n this.props;\n\n let geoJSONMarkersData;\n\n // #REVIEW - issue here is that the component mounts before the mqtt messages have populated the objecet -> redux -> component etc.\n // need to ensure .features exists to transform...\n\n // update fireflies\n if (\n typeof geoJSONMarkersDataUtm.features !== \"undefined\" &&\n geoJSONMarkersDataUtm.features.length\n ) {\n // #REVIEW - this now happens in WebWorker reducer for fireflies\n // deep clone - to stop geometry being converted on raw *utm data\n //geoJSONMarkersData = JSON.parse(JSON.stringify(geoJSONMarkersDataUtm));\n //geoJSONMarkersData = this.transformGeoJsonUtmToPixels(geoJSONMarkersData);\n\n geoJSONMarkersData = geoJSONMarkersDataUtm;\n } else {\n // add an empty geoJson featurecollection\n geoJSONMarkersData = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // update named area\n let geoJSONNamedAreas;\n\n if (\n typeof geoJSONNamedAreasUtm.features !== \"undefined\" &&\n geoJSONNamedAreasUtm.features.length\n ) {\n // deep clone - to stop geometry being converted on raw *utm data\n geoJSONNamedAreas = JSON.parse(JSON.stringify(geoJSONNamedAreasUtm));\n\n // #REVIEW - named areas are filtered for the parent here rather than via mapPropsToState\n // b/c updates were too frequent and caused lifecycle to exceed updates\n\n const namedAreaByParent = getNamedAreaInfosByParentId_local(\n geoJSONNamedAreas,\n namedAreaId\n );\n\n // console.log(\"hhh namedAreaByParent\", namedAreaByParent);\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n geoJSONNamedAreas = transformGeoJsonUtmToPixels(\n namedAreaByParent, //geoJSONNamedAreas,\n mineLevelObj,\n 1,\n false\n );\n } else {\n // add an empty geoJson featurecollection\n geoJSONNamedAreas = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n // draw the map\n this.drawTheMap(\n mapId,\n mineLevel,\n namedAreaId,\n geoJSONMarkersData,\n geoJSONNamedAreas,\n folderFilesList\n );\n };\n\n componentDidUpdate(prevProps, prevState) {\n const { mineLevel, namedAreaId, error } = this.props;\n\n // if map did not load with didComponentMount due to error, then mount it now\n if (prevProps.error) {\n this.setState({ map: { area: mineLevel.id } });\n this.mapMount();\n }\n\n // if the area (mine level) has changed, remove the map and remount it all again\n if (\n prevProps.mineLevelId !== this.props.mineLevelId ||\n prevProps.namedAreaId !== this.props.namedAreaId\n ) {\n // console.log(\n // \"hhh componentDidUpdate mineLevel, namedAreaId\",\n // mineLevel,\n // namedAreaId\n // );\n\n this.map.off();\n this.map.remove();\n this.setState({ map: { area: mineLevel.id } });\n this.mapMount();\n }\n\n // // respond to checkbox settings\n // // toggle display of marker group\n // if (this.markerGroupLayer) {\n // if (true) {\n // //this.props.parentState.isCheckboxMarker\n // this.map.addLayer(this.markerGroupLayer);\n // } else {\n // //this.map.addLayer(this.markerGroupLayer);\n // this.map.removeLayer(this.markerGroupLayer);\n // }\n // }\n\n // // toggle display of Fireflies group\n // if (this.refPtGroupLayer) {\n // if (true) {\n // //this.props.parentState.isCheckboxRefMarker\n // this.map.addLayer(this.refPtGroupLayer);\n // } else {\n // //this.map.addLayer(this.refPtGroupLayer);\n // this.map.removeLayer(this.refPtGroupLayer);\n // }\n // }\n\n // use this to control layers, named areas etc.\n if (this.locationGroupLayers && this.polylineGroupLayers) {\n if (false) {\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n //console.log(\"key\", key);\n this.map.addLayer(value);\n }\n } else {\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n this.map.removeLayer(value);\n }\n }\n\n if (false) {\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n //console.log(\"key\", key);\n this.map.addLayer(value);\n }\n } else {\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n this.map.removeLayer(value);\n }\n }\n }\n\n // ---------------------------------------\n\n const parentId = \"parentNamedArea\";\n\n // #REVIEW / TODO - move this filter to a common area\n const isParentDirty =\n this.props?.isDirty?.namedArea.filter(\n (namedArea) => namedArea === parentId\n ).length > 0;\n\n // ---------------------------------------------------------------\n // remove layers queued for deletion (via named areas UI)\n\n // This processes any named areas which have been 'deleted' when an update to the named area is performed.\n // This ensures immediate update to the local map so user get feedback of the action.\n // Otherwise it is necessary to wait for the mqtt send/receive process to update the map, and the\n // user is left wondering whether their request has been submitted.\n\n // get array of named_areas to delete\n // e.g. [{ area: \"DMLZ_Extraction\", id: \"DMLZ_Extraction:1594276143541\" },...]\n\n //#REVIEW/TODO - merge this with namedAreaHideSelection\n // INSTEAD OF DELETING JUST HIDE THE LEVEL\n // i.e. HIDDEN = DELETED????????????\n\n const namedAreaDeleteSelections = this.props.namedAreaDeleteSelections;\n\n let namedAreaDeleted = false; // flag to make the map update quicker after something deleted\n namedAreaDeleteSelections.forEach((selection, idx) => {\n // find the selection by id, by checking every layer in editableLayers\n\n this.editableLayers.eachLayer((layer) => {\n if (layer.feature.properties.id === selection.id) {\n console.log(\"----> namedAreaDeleteSelections remove\", selection.id);\n\n // delete from editableLayers, when named areas area updated below the 'UpdateLocalMap' will remove this item\n // and consequently from the named area list (as this populates via redux)\n this.editableLayers.removeLayer(layer); // <----------- this is the most important bit\n\n // delete from\n this.props.namedAreaClearDeleteSelections(selection);\n namedAreaDeleted = true;\n }\n });\n });\n\n // ---------------------------------------------------------------\n\n // check if raw data has changed\n // update fireflies\n // if\n // * not empty\n // _and_\n // * props have changed\n\n // #REVIEW/TODO - make a function out of this ....\n // incoming objects (current and prevProps) are different even though JSON content is the same.\n // compare the strings to stop unnecessary updates\n const prevGeoJSONMarkersDataUtm = JSON.stringify(\n prevProps.geoJSONMarkersDataUtm\n );\n const newGeoJSONMarkersDataUtm = JSON.stringify(\n this.props.geoJSONMarkersDataUtm\n );\n\n let isChangedgeoJSONMarkerUtm = false;\n\n // if each object has content\n if (\n !_isEmpty(prevGeoJSONMarkersDataUtm) &&\n !_isEmpty(newGeoJSONMarkersDataUtm)\n ) {\n // are they changed?\n isChangedgeoJSONMarkerUtm =\n prevGeoJSONMarkersDataUtm !== newGeoJSONMarkersDataUtm ? true : false;\n }\n\n if (\n //#WIP - disabled to make the update happen periodically so can test hide/delete options\n // isChangedgeoJSONMarkerUtm\n\n _isEmpty(this.props.geoJSONMarkersDataUtm) !== true &&\n this.props.geoJSONMarkersDataUtm !== prevProps.geoJSONMarkersDataUtm\n ) {\n // console.log(\n // \"map componentDidUpdate this.props.geoJSONMarkersDataUtm\",\n // this.props.geoJSONMarkersDataUtm\n // );\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONMarkersData = JSON.parse(\n JSON.stringify(this.props.geoJSONMarkersDataUtm)\n );\n\n // #REVIEW/TODO #WIP\n // check for [0,0] or out of rage points and move them to the pen\n // const transform = this.Transform(this.localPts(), this.standardPtsUtm());\n // const geoJsonTransform = [];\n\n // #WIP - test for out of range too!\n geoJSONMarkersData.features.map((value, idx) => {\n const arrayLatLng = value.geometry.coordinates.slice();\n // check if rx an un positioned marker i.e. [0,0]\n const isAllZero = arrayLatLng.every((item) => item === 0);\n if (isAllZero) {\n // console.log(\n // \"Found FF isAllZero value.properties.id -> \",\n // value.properties.id\n // );\n\n // update FF value.properties.id with new coordinate in the pen\n let randomHoldingPenCoordinate;\n if (this.holdingPen !== undefined) {\n const hasHoldingPen = this.map.hasLayer(this.holdingPen);\n if (isAllZero && hasHoldingPen) {\n randomHoldingPenCoordinate = this.randomPointInPoly(\n this.holdingPen\n );\n // console.log(\n // \"isAllZero randomHoldingPenCoordinate\",\n // randomHoldingPenCoordinate\n // );\n\n // change the value properties coordinates with new holding pen point\n //console.log(\"isAllZero value\", JSON.stringify(value));\n let newValue = JSON.parse(JSON.stringify(value));\n newValue.geometry = randomHoldingPenCoordinate.geometry;\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n // convert to Utm values\n const newPointUtm = this.convertGeoJsonPixelsToUtm(\n {\n type: \"FeatureCollection\",\n features: [newValue],\n },\n mineLevelObj\n ).features[0].geometry.coordinates.slice();\n\n // #REVIEW/TODo #FIX!!!!!!!!!!!! - should filter to find the id, ATM just grab first one (and only) one which comes back\n\n //console.log(\"isAllZero newPointUTtm\", newPointUTtm);\n\n // send via mqtt for change\n // #WIP....send FF update within map\n\n const changeTopic = `firefly/${newValue.properties.id}/change`;\n\n const changeMsg = {\n id: newValue.properties.id,\n mac: newValue.properties.mac,\n utm_zone_number: 53,\n utm_zone_letter: \"M\",\n Z: 0,\n utm: [newPointUtm[0], newPointUtm[1]],\n token: messageToken(),\n };\n\n //console.log(\"isAllZero changeFF\", changeMsg);\n\n // #WIP - the issue here is this sends out lots of messages until the changes is made...flooding the system.\n // need to log the send, wait for an ack, clear it.\n // disabled pending implement ack management\n if (false) {\n this.props.mqttPublish({\n topic: changeTopic,\n qos: 0,\n message: changeMsg,\n retained: false,\n });\n }\n }\n }\n }\n });\n\n // transform the coordinates to pixel image references\n\n // #REVIEW - this now happens in WebWorker reducer for fireflies\n //geoJSONMarkersData = this.transformGeoJsonUtmToPixels(geoJSONMarkersData);\n\n // update markers for geoJSON\n this.updateFireflyMarkersGeoJSON(this.map, geoJSONMarkersData);\n }\n\n // ****************************************************************************************\n //\n // update named area\n //\n // ****************************************************************************************\n\n // update from source data if\n // * not empty\n // * props have changed\n // _or_\n // * named areas have been locally deleted\n\n // WIP HERE - previously allowed update if (OR) namedAreaDeleted = true even if no changes to data to stop redraw of namedAreas <------\n // || namedAreaDeleted\n // ...working though?\n\n // #REVIEW/TODO - make a function out of this\n\n // incoming objects (current and prevProps) are different even though JSON content is the same.\n // compare the strings to stop unnecessary updates\n const prevGeoJSONNamedAreasUtm = JSON.stringify(\n prevProps.geoJSONNamedAreasUtm\n );\n const newGeoJSONNamedAreasUtm = JSON.stringify(\n this.props.geoJSONNamedAreasUtm\n );\n\n let isChangedgeoJSONNamedAreasUtm = false;\n\n // if each object has content\n if (\n !_isEmpty(prevGeoJSONNamedAreasUtm) &&\n !_isEmpty(newGeoJSONNamedAreasUtm)\n ) {\n // are they changed?\n isChangedgeoJSONNamedAreasUtm =\n prevGeoJSONNamedAreasUtm !== newGeoJSONNamedAreasUtm ? true : false;\n }\n\n if (\n // isChangedgeoJSONNamedAreasUtm ||\n // namedAreaDeleted\n (!_isEmpty(this.props.geoJSONNamedAreasUtm) &&\n this.props.geoJSONNamedAreasUtm !== prevProps.geoJSONNamedAreasUtm) ||\n namedAreaDeleted\n // || heartBeatChanged\n ) {\n // console.log(\"componentDidUpdate namedAreaHiddenSelections - updating!\");\n\n // #WIP - check if localMapState and incoming data differ\n // with view to filtering localMapState data for delete and hidden namedAreas\n\n // deep clone - to stop geometry being converted on raw *utm data\n let geoJSONNamedAreas = JSON.parse(\n JSON.stringify(this.props.geoJSONNamedAreasUtm)\n );\n\n // #REVIEW - named areas are filtered for the parent here rather than via mapPropsToState\n // b/c updates were too frequent and caused lifecycle to exceed updates\n\n const namedAreaByParent = getNamedAreaInfosByParentId_local(\n geoJSONNamedAreas,\n namedAreaId\n );\n\n // console.log(\"hhh namedAreaByParent\", namedAreaByParent);\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n // transform the coordinates to pixel image references\n geoJSONNamedAreas = transformGeoJsonUtmToPixels(\n namedAreaByParent, //geoJSONNamedAreas,\n mineLevelObj,\n 1,\n false\n );\n\n //#WIP - merge geoJSONNamedAreas and localMapState, giving priority to geoJSONNamedAreas if propertie.id is same\n //i.e. get geoJSONNamedAreas and import all\n\n const local = this.props.localMapState?.features;\n const mqtt = geoJSONNamedAreas?.features;\n\n let localIds = [];\n let mqttIds = [];\n\n if (local) {\n local.forEach((item, idx) => {\n localIds[item.properties.id] = idx;\n });\n }\n // console.log(\"componentDidUpdate local\", local);\n if (mqtt) {\n mqtt.forEach((item, idx) => {\n mqttIds[item.properties.id] = idx;\n });\n }\n if (!isParentDirty) {\n // update markers for geoJSON\n this.updateNamedAreasGeoJSON(this.map, geoJSONNamedAreas);\n }\n\n // update localMapState with all objects in the editable layer\n if (this.map.hasLayer(this.editableLayers)) {\n // add geoJSONNamedAreaGroupLayer layer to editable layer so can edit existing/loaded polygons\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n // console.log(\n // \"Adding mqtt Named Area to this.editableLayers -> \",\n // layer._leaflet_id\n // ); // KEEP AS PERMANENT INDICATOR THAT MAP GROUPS ARE UPDATING\n this.editableLayers.addLayer(layer);\n });\n\n const geoJsonPixels = this.editableLayers.toGeoJSON();\n\n //#REVEW/TODO - this should only happen if the shape has changed otherwise use the coordinates in the features.properties.coordinatesUtm\n // ----->\n //const transform = this.props.mineLevel.transform;\n\n const mineLevel = this.props.mineLevel;\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n const geoJsonUtm = this.convertGeoJsonPixelsToUtm(\n geoJsonPixels,\n mineLevelObj\n );\n // <-----\n\n this.props.UpdateLocalMap({ namedAreas: geoJsonUtm });\n this.setState({ thislocalMapState: geoJsonUtm });\n\n // console.log(\n // \"map componentDidUpdate this.props.localMapState - after update\",\n // JSON.stringify(geoJsonUtm)\n // );\n\n const geo = geoJsonUtm?.features;\n let geoIds = [];\n if (geo) {\n geo.forEach((item, idx) => {\n geoIds[item.properties.id] = idx;\n });\n }\n // console.log(\"componentDidUpdate geoIds\", geoIds);\n\n //#WIP - testing hide and show layers\n\n // #REVIEW/TODO\n // THIS NEEDS TO BE RE_WRITTEN TO RUN OVER ALL EDITABLE LAYERS\n //\n this.editableLayers.eachLayer((layer) => {\n layer.getElement().style.display = \"block\"; // this resets any hidden layer actions\n });\n\n //#REVIEW/TODO - namedAreaHiddenSelections and namedAreaDeleteSelections are 'same' make function or restructure message/object\n\n const namedAreaHiddenSelections = this.props.namedAreaHideSelections;\n //#REVIEW/TODO - filter by parentId - currently ignore id\n const namedAreasHidden = namedAreaHiddenSelections.map((na) => na.id);\n // console.log(\"namedAreasHidden\", namedAreasHidden);\n\n // const namedAreaDeleteSelections = this.props.namedAreaDeleteSelections;\n // //#REVIEW/TODO - filter by parentId - currently ignore id\n // const namedAreasDeleted = namedAreaDeleteSelections.map((na) => na.id);\n // // console.log(\"namedAreasDeleted\", namedAreasDeleted);\n\n this.editableLayers.eachLayer((layer) => {\n const includesNamedAreaHidden = namedAreasHidden.includes(\n layer.feature.properties.id\n );\n // const includesNamedAreaDeleted = namedAreasDeleted.includes(\n // layer.feature.properties.id\n // );\n\n if (!includesNamedAreaHidden) {\n //\n return;\n }\n layer.getElement().style.display = \"none\";\n });\n\n this.editableLayers.bringToBack();\n this.geoJSONNamedAreaGroupLayer.bringToBack();\n }\n }\n\n // use this to control layers, named areas etc.\n if (this.locationGroupLayers && this.polylineGroupLayers) {\n if (this.props.parentState.isCheckboxFireflies) {\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n //console.log(\"key\", key);\n this.map.addLayer(value);\n }\n } else {\n for (const [key, value] of Object.entries(this.locationGroupLayers)) {\n this.map.addLayer(value);\n // this.map.removeLayer(value);\n }\n }\n\n if (this.props.parentState.isCheckboxPolyline) {\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n //console.log(\"key\", key);\n this.map.addLayer(value);\n }\n } else {\n for (const [key, value] of Object.entries(this.polylineGroupLayers)) {\n //this.map.addLayer(value);\n this.map.removeLayer(value);\n }\n }\n }\n\n // Check if isAddPolygonClicked\n if (this.props.parentState.isAddPolygonClicked) {\n // console.log(\n // \"isAddPolygonClicked\",\n // this.props.parentState.isAddPolygonClicked\n // );\n // https://github.com/Leaflet/Leaflet.draw/issues/179\n // programmatically click on toolbar\n // #REVIEW - disable until work out how to have transitional action\n // this.drawControl._toolbars.draw._modes.rectangle.handler.enable();\n }\n\n // check what layers are drawn.......\n // this.editableLayers.eachLayer(function(layer) {\n // console.log(\"this.editableLayers layer\", layer);\n // });\n }\n\n // based on\n // https://stackoverflow.com/questions/34501524/in-place-update-leaflet-geojson-feature\n // here for reference\n // these are not used yet..........\n addNewFeatureToGeoJsonLayerGroup = (myGeoJsonLayerGroup, newGeoJsonData) => {\n myGeoJsonLayerGroup.addData(newGeoJsonData);\n };\n\n updateFeature = (updatedGeoJsonData) => {\n this.deleteFeature(updatedGeoJsonData); // Remove the previously created layer.\n this.addNewFeatureToGeoJsonLayerGroup(updatedGeoJsonData); // Replace it by the new data.\n };\n\n deleteFeature = (myGeoJsonLayerGroup, myFeaturesMap, deletedGeoJsonData) => {\n var deletedFeature = myFeaturesMap[deletedGeoJsonData.properties.objectID];\n myGeoJsonLayerGroup.removeLayer(deletedFeature);\n };\n\n updateFireflyMarkersGeoJSON(map, geoJSONMarkersData) {\n const blueMarker = {\n radius: 6,\n fillColor: \"blue\",\n };\n\n const redMarker = {\n radius: 6,\n fillColor: \"red\",\n };\n\n const orangeMarker = {\n radius: 6,\n fillColor: \"orange\",\n };\n\n const whiteMarker = {\n radius: 6,\n fillColor: \"white\",\n };\n\n const greenMarker = {\n radius: 6,\n fillColor: \"green\",\n };\n\n // map the geoJSONMarkersData and delete all the markers who have changed propertie\n // and accumulate these markers\n // add them all at the end\n\n // find the fireflies which have changed in geojsonMarkerOptions object\n geoJSONMarkersData.features.map(({ properties }, idx) => {\n const { id, color, location, position } = properties;\n\n // Make sure there is a layergroup for new markers.\n // layer groups are defined by LOCATION.\n // If a new LOCATION is added, check and add if necessary.\n //\n if (this.map.hasLayer(this[location])) {\n } else {\n this[location] = L.featureGroup().addTo(this.map);\n this.locationGroupLayers[location] = this[location];\n }\n\n // if the marker is in the layerlistFireflies\n if (this.layerlistFireflies[id]) {\n // if new color is not the same as the old\n if (this.layerlistFireflies[id].feature.properties.color !== color) {\n // #REVIEW - no longer remove the layer, instead just update it\n //remove the layer\n //map.removeLayer(this.layerlistFireflies[id]);\n\n // get style for new marker\n\n let newStyle;\n\n switch (color) {\n case \"red\":\n newStyle = redMarker;\n break;\n case \"blue\":\n newStyle = blueMarker;\n break;\n case \"amber\":\n newStyle = orangeMarker;\n break;\n case \"white\":\n newStyle = whiteMarker;\n break;\n case \"green\":\n newStyle = greenMarker;\n break;\n\n default:\n break;\n }\n\n // #REVIEW - no need to replace layer, instead just update the color\n // place a new layer with the new style\n // this.layerlistFireflies[id].addTo(map).setStyle(newStyle);\n\n this.layerlistFireflies[id].setStyle(newStyle);\n // update the color property\n this.layerlistFireflies[id].feature.properties.color = color;\n }\n } else {\n // console.log(\n // \"hasLayer componentDidUpdate updateFireflyMarkersGeoJSON this.map.hasLayer(this.geoJSONGroupLayer)\",\n // this.map.hasLayer(this.geoJSONGroupLayer)\n // );\n\n // if it's not in the layer list add it..........\n // note pointToLayer and onEachFeature are defined in ComponentDidMount()\n this.geoJSONGroupLayer.addData(geoJSONMarkersData.features[idx]);\n }\n });\n }\n\n updateNamedAreasGeoJSON(map, geoJSONPolygonData) {\n // #TODO - !\n // map the geoJSONPolygonData and delete all the shapes who have changed propertie\n // and accumulate these shapes\n // add them all at the end\n\n // check if a named area has been removed\n // get list of IDs for current named area (i.e. layers)\n const layersIds = Object.keys(this.layerlistNamedAreas);\n\n // get the Ids for the incoming update of named area data\n let namedAreaIds = [];\n for (const namedArea in geoJSONPolygonData.features) {\n namedAreaIds.push(geoJSONPolygonData.features[namedArea].properties.id);\n }\n\n // check for a difference\n // filter each item and return it if it is *not* in the namedAreas\n const inLayerNotInNamedArea = layersIds.filter(\n (i) => !namedAreaIds.includes(i)\n );\n\n inLayerNotInNamedArea.forEach((layer, idx) => {\n // delete any layers which are in layersIds but *not* in namedAreaIds\n // remove the layer from layer groups\n this.editableLayers.removeLayer(this.layerlistNamedAreas[layer]);\n this.geoJSONNamedAreaGroupLayer.removeLayer(\n this.layerlistNamedAreas[layer]\n );\n // to be really sure remove it from the map completely\n this.map.removeLayer(this.layerlistNamedAreas[layer]);\n // delete the layer from the list\n delete this.layerlistNamedAreas[layer];\n // update localMapstate\n });\n\n // find the named areas which have changed in geoJSONPolygonData object\n geoJSONPolygonData.features.map(({ properties }, idx) => {\n const { id } = properties;\n\n // if the shape is not in the layer list\n if (!this.layerlistNamedAreas[id]) {\n // add it\n // note pointToLayer and onEachFeature are defined in ComponentDidMount() <--- #REVIEW - is it? i.e. for namedArea?\n this.geoJSONNamedAreaGroupLayer.addData(\n geoJSONPolygonData.features[idx]\n );\n } else {\n // if the shape exists but has changed, update it\n\n // #WIP - should also review updates to shape coordinates\n\n // AFAIK the only way to update is to go through every layer until finding the match!\n // thankfully there are not many layers for namedAreas\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n if (layer === this.layerlistNamedAreas[id]) {\n layer.feature.properties = properties;\n }\n });\n }\n });\n\n // update leaflet id to properties (used to delete.edit shapes in local state) <--- #REVIEW - is it? may not be necessary now\n this.geoJSONNamedAreaGroupLayer.eachLayer((layer) => {\n layer.feature.properties._leaflet_id = layer._leaflet_id;\n });\n }\n\n // heartBeat = () => {\n // const heartBeat = this.state.heartBeat;\n // //console.log(\"heartBeat\", heartBeat);\n // this.setState({ heartBeat: !heartBeat });\n // };\n\n render() {\n const { render } = this.props;\n const mapId = \"map-\" + render;\n\n return (\n <>\n
\n
\n \n {/*
*/}\n
\n
\n \n );\n }\n}\n\n// #REVIEW\n// moved from reducer to debug why update cycle is breaking when calling this from reducer\nconst getNamedAreaInfosByParentId_local = (namedAreas, parentId) => {\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (namedAreas?.features !== undefined) {\n filteredgeojson.features = namedAreas.features.filter(\n (item) => item.properties.parent === parentId\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nfunction mapStateToProps(state, props) {\n const mineLevelId = props.mineLevelId;\n\n const mineLevel = getAreaById(state, mineLevelId); // #REVIEW - change this to getAreaStatusesById\n\n const fireflyMarkers = getFireflyCoordinatesByAreaId(state, mineLevelId);\n\n const namedAreaId = props.namedAreaId;\n const namedAreas = getNamedAreaInfos(state);\n\n const namedAreasByParentId = getNamedAreaInfosByParentId(\n namedAreas,\n namedAreaId\n ); // getNamedAreaInfosByParentId(state, namedAreaId);\n\n // console.log(\"namedAreasByParentId\", namedAreasByParentId);\n // console.log(\"namedAreasByParentId namedAreas\", namedAreas);\n\n const markersData = getMapState(state);\n const localMapState = GetLocalMap(state);\n const namedAreaDeleteSelections = getNamedAreaDeleteSelections(state);\n const namedAreaHideSelections = getNamedAreaHideSelections(state);\n const isDirty = getIsDirty(state);\n\n // don't load if mineLevel or namedAreas are not loaded yet (i.e. undefined or empty).\n const error = _isEmpty(mineLevel) || _isEmpty(namedAreas);\n\n return {\n error,\n mineLevel,\n namedAreaId,\n markersData,\n geoJSONMarkersDataUtm: fireflyMarkers,\n localMapState,\n geoJSONNamedAreasUtm: namedAreas, //namedAreasByParentId,\n namedAreaDeleteSelections,\n namedAreaHideSelections,\n isDirty,\n folderFilesList: getFolderFileNamesListById(state, \"areas\"),\n };\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n UpdateLocalMap: (mapState) => {\n dispatch(UpdateLocalMap(mapState));\n },\n namedAreaClearDeleteSelections: (parentId) => {\n dispatch(namedAreaClearDeleteSelections(parentId));\n },\n namedAreasSetIsDirty: (id) => {\n dispatch(namedAreasSetIsDirty(id));\n },\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(Map);\n","export const selectColor = (number) => {\n const hue = number * 137.508; // use golden angle approximation\n return `hsl(${hue},50%,75%)`;\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Form,\n Container,\n Label,\n Header,\n Grid,\n Message,\n Segment,\n Table,\n Icon,\n Popup,\n Dimmer,\n Loader,\n Button,\n} from \"semantic-ui-react\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\n\nimport { push } from \"react-router-redux\";\n\nimport isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport ChooseMineLevelField from \"components/ChooseMineLevelField\";\n\nimport { deleteNamedArea } from \"NamedAreas/actions\";\nimport { renderField } from \"admin/form-field\";\nimport { SaveButton } from \"admin/SaveButton\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport FlashMessagesList from \"FlashMessages\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { reset } from \"testdouble\";\n\nimport NamedAreaTable from \"admin/named-area/NamedAreaTable\";\n\nimport { GetLocalMap } from \"components/Map/reducer\";\nimport { ClearLocalMap } from \"components/Map/actions\";\n\nimport Map from \"./NamedAreaMap\";\n\nimport {\n getNamedAreaStatusesByAreaId,\n getAllNamedAreaStatuses,\n} from \"components/WebWorker/reducer\";\n\n// based on\n// - https://embed.plnkr.co/Gvei5I0S9yEo6fCYXPuy/\n// see -> from \"./TestMapTilesMap\";\n\n// --------------------------------------\n// Marker not appearing for Simple Example\n// Fix - https://github.com/PaulLeCam/react-leaflet/issues/453\n//\nimport \"leaflet/dist/leaflet.css\";\nimport L from \"leaflet\";\n\ndelete L.Icon.Default.prototype._getIconUrl;\n\nL.Icon.Default.mergeOptions({\n iconRetinaUrl: require(\"leaflet/dist/images/marker-icon-2x.png\"),\n iconUrl: require(\"leaflet/dist/images/marker-icon.png\"),\n shadowUrl: require(\"leaflet/dist/images/marker-shadow.png\"),\n});\n// --------------------------------------\n// HACKfix: Use zIndex to stop leaflet map from being above the Semantic-UI dropdown menus!\nconst DEFAULT_MAP_STYLE = {\n height: \"800px\",\n width: \"100%\",\n position: \"relative\",\n zIndex: 0,\n};\n\nconst validate = (values) => {\n const required = [\"namedAreaIdValue\", \"mineLevelId\"];\n\n const errors = {};\n\n required.forEach((r) => {\n if (!get(values, r)) {\n set(errors, r, \"Required\");\n }\n });\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n if (type === \"noSpaces\") {\n return value.replace(\" \", \"_\");\n } else {\n return value;\n }\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst isNamedAreaNameOK = (value, allValues, props, name) => {\n const { namedAreaIdValue: id } = allValues;\n\n const { uniqueNamedAreaParentIds } = props;\n const valueNoSpace = value.replace(\" \", \"_\");\n\n const notIncludingThisId = uniqueNamedAreaParentIds\n .filter((item) => !item.id.includes(id))\n .map((item) => item.parentName);\n\n //console.log(`notIncludingThisId `, notIncludingThisId);\n\n if (notIncludingThisId?.includes(valueNoSpace)) {\n return \"This name has already been used\";\n } else {\n return undefined;\n }\n};\n\nclass CreateNamedAreaForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n contentLoading: true,\n errorMessage: \"\",\n id: props.id,\n };\n }\n\n // #REVIEW -\n // Render issue - with each heartbeat the STATE updates which causes localPts to be updated and so resets the map state\n\n // This stops re-rendering the map unnecessarily\n // #WIP\n\n componentDidMount() {\n // clear the map from any previous edits\n this.props.ClearLocalMap();\n // #WIP - set temporarily\n this.setState({ contentLoading: false });\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n // update component when state changes, not when props change or\n // initial props will clobber form edits\n\n // console.log(\"shouldComponentUpdate this.props\", this.props);\n // console.log(\"shouldComponentUpdate nextProps\", nextProps);\n\n return !isEqual(this.props, nextProps); //!isEqual(this.state, nextState); //!isEqual(this.props, nextProps);\n }\n\n requestDelete = (id) => {\n const { handleSubmit, deleteNamedArea, push } = this.props;\n\n console.log(\"requestDelete\", handleSubmit, deleteNamedArea, push);\n\n console.log(\"WIP.......\");\n };\n\n // onSubmit = (e) => {\n // e.preventDefault();\n // console.log(\"onSubmit e\", e);\n\n // // submitToReview () {\n // // const formValues = this.props.study.values; // map form to props.\n // // const valueToSubmit = Object.assign({}, formValues, {state: 'REVIEWING'}); // update value.\n // // this.onSubmit(valueToSubmit, this.props.dispatch); // call onSubmit directly\n // // }\n\n // this.props.handleSubmit(this); // calls prop.onSubmit()\n // };\n\n submitMyForm = (values) => {\n //console.log(`form submitted: values`, values);\n this.props.onSubmit(values);\n };\n\n resetForm = (e) => {\n e.preventDefault();\n\n //this.setState(setInitialValues);\n this.props.ClearLocalMap();\n this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // abort page changes\n this.props.onCancel();\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n //reset,\n mineLevelId,\n //namedAreaId,\n namedAreaIdValue,\n namedAreaParentName,\n strings,\n } = this.props;\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n\n //const { id } = this.state;\n\n const refLocationsComponent = (areaId, namedAreaIdValue) => {\n const namedAreaId = `${areaId}:${namedAreaIdValue}`;\n\n if (!areaId) {\n return
Select a mine level to display the map
;\n }\n return (\n
\n \n
\n );\n };\n\n const { contentLoading } = this.state;\n\n if (contentLoading) {\n return (\n \n Loading data\n \n );\n } else {\n return (\n
\n \n \n \n \n
{strNamedArea}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {/* ***************Create Form ************************ */}\n {error && (\n \n )}\n\n \n \n \n \n \n
{`Add ${strNamedArea}`}
\n \n \n normalise(value, \"noSpaces\")}\n />\n
\n \n \n \n \n \n Use the map controls to add a new polygon\n \n Click on the map's Polygon or Rectangle icon to draw a\n new polygon shape. A shape must be drawn to be able to\n save the form.\n \n \n \n \n
{strNamedAreas}
\n \n
\n
\n \n {false && (\n \n \n {\"\"}\n \n \n \n \n \n {/* this.resetForm(e)}\n >\n Reset\n \n */}\n this.cancelForm(e)}\n >\n Cancel\n \n \n \n \n \n \n )}\n \n
Map
\n {refLocationsComponent(mineLevelId, \"createNewNamedArea\")}\n
\n
\n
\n
\n \n\n \n
\n
\n );\n }\n }\n}\n\nconst selector = formValueSelector(\"createNewNamedAreaForm\");\n\nCreateNamedAreaForm = reduxForm({\n form: \"createNewNamedAreaForm\",\n // Note - to reinitialize values in componentDidMount\n // Make sure you set the values of enableReinitialize & keepDirtyOnReinitialize to true\n // See - https://stackoverflow.com/questions/44273099/redux-form-initialization-with-props-initialize\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(CreateNamedAreaForm);\n\nconst mapStateToProps = (state, props) => {\n const namedAreaId = props.id;\n\n const localMapState = GetLocalMap(state);\n const mineLevelId = selector(state, \"mineLevelId\");\n\n // collect an array of existing named area parent names to validate against new named area name\n const allNamedAreaStatuses = getNamedAreaStatusesByAreaId(state, mineLevelId); // getAllNamedAreaStatuses(state);\n const uniqueNamedAreaParentIds = allNamedAreaStatuses\n .map((item) => {\n return { id: item.parent, parentName: item.parent_name };\n }) // .parent\n .filter(\n (value, index, self) =>\n index ===\n self.findIndex(\n (t) => t.id === value.id && t.parentName === value.parentName\n )\n );\n // .filter((value, index, self) => self.indexOf(value) === index);\n //.map((item) => item.split(\":\")[1]);\n\n //console.log(`uniqueNamedAreaParentIds`, uniqueNamedAreaParentIds);\n\n return {\n localMapState,\n mineLevelId,\n namedAreaIdValue: namedAreaId, // selector(state, \"namedAreaIdValue\"),\n namedAreaParentName: selector(state, \"namedAreaParentName\"),\n initialValues: {\n namedAreaIdValue: namedAreaId,\n regions: [],\n },\n uniqueNamedAreaParentIds,\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"reduxForm onChange values\", values);\n\n if (values.mineLevelId !== previousValues.mineLevelId) {\n //console.log(\"onChange\", values);\n const {\n change,\n initialValues: { mineLevelId, regions },\n } = props;\n // if (values.mineLevelId === mineLevelId) {\n // dispatch(change(\"regions\", regions));\n // } else {\n // dispatch(change(\"regions\", []));\n // }\n }\n },\n reduxFormValues: getFormValues(\"createNewNamedAreaForm\")(state), // #REVIEW - only used for debugging,\n };\n};\n\nconst mapDispatchToProps = (dispatch) => ({\n ClearLocalMap: () => {\n dispatch(ClearLocalMap());\n },\n});\n\nCreateNamedAreaForm = connect(\n mapStateToProps,\n mapDispatchToProps\n)(CreateNamedAreaForm);\n\nexport default CreateNamedAreaForm;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport { Container } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Grid from \"semantic-ui-react/dist/commonjs/collections/Grid\";\n\nimport { saveNewNamedArea } from \"NamedAreas/actions\";\n\n//import NamedAreaForm from \"./NamedAreaForm\";\n\nimport CreateNamedAreaForm from \"admin/named-area/NamedAreaCreateForm\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport {\n SubmissionError,\n //\n getFormValues,\n getFormInitialValues,\n getFormSyncErrors,\n getFormMeta,\n getFormAsyncErrors,\n getFormSyncWarnings,\n getFormSubmitErrors,\n getFormError,\n getFormNames,\n isDirty,\n isPristine,\n isValid,\n isInvalid,\n isSubmitting,\n hasSubmitSucceeded,\n hasSubmitFailed,\n} from \"redux-form\";\n\nimport { Dimmer, Loader } from \"semantic-ui-react\";\n\nimport { v4 as uuid } from \"uuid\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nclass CreateNamedArea extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n submitMyForm = (values) => {\n const { saveNewNamedArea } = this.props;\n\n return new Promise((resolve, reject) => {\n console.log(\"values\", values);\n //saveNewNamedArea({ values, resolve, reject });\n })\n .then(() => {\n //this.onResetError();\n\n this.props.fetchNamedAreas();\n this.props.fetchNamedAreaEvents();\n this.props.goto(`/admin/named-area-advanced`);\n })\n .catch((error) => {\n console.log(`onSubmit error`, error);\n this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const { saveNewNamedArea, submitting, error } = this.props;\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n if (error) {\n return (\n <>\n \n \n );\n }\n\n return (\n <>\n this.onResetError()}\n errorMessage={errorMessage}\n />\n \n Saving changes\n \n\n {/* #NOTE - NavigationPromptModal is disabled for advanced named areas because it does\n not currently support form submit. */}\n\n {/* this.submitMyForm(formValues)}\n /> */}\n this.submitMyForm(values)}\n // #NOTE - disabled as this is fired as soon as submit,\n // *not* after successful completion of the Promise!!\n onSubmitSuccess={(result, dispatch) => {\n //console.log(`onSubmitSuccess ${result}`);\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n this.onResetError();\n this.props.goto(\"/admin/named-area-advanced\");\n }\n );\n }}\n onSubmitFail={(errors) => {\n console.log(`onSubmitFail ${errors}`);\n }}\n onCancel={() => {\n this.props.goto(\"/admin/named-area-advanced\");\n }}\n />\n \n );\n }\n}\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n // saveNewNamedArea: (data) => dispatch(saveNewNamedArea(data)), // #WIP\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n };\n};\n\nexport default connect(\n (state) => ({\n // values: getFormValues(\"createNewMineLevelForm\")(state),\n // initialValues: getFormInitialValues(\"createNewMineLevelForm\")(state),\n // formSyncErrors: getFormSyncErrors(\"createNewMineLevelForm\")(state),\n // fields: getFormMeta(\"createNewMineLevelForm\")(state),\n // formAsyncErrors: getFormAsyncErrors(\"createNewMineLevelForm\")(state),\n // syncWarnings: getFormSyncWarnings(\"createNewMineLevelForm\")(state),\n // submitErrors: getFormSubmitErrors(\"createNewMineLevelForm\")(state),\n // formError: getFormError(\"createNewMineLevelForm\")(state),\n // names: getFormNames()(state),\n // dirty: isDirty(\"createNewMineLevelForm\")(state),\n // pristine: isPristine(\"createNewMineLevelForm\")(state),\n // valid: isValid(\"createNewMineLevelForm\")(state),\n // invalid: isInvalid(\"createNewMineLevelForm\")(state),\n submitting: isSubmitting(\"createNewNamedAreaForm\")(state),\n // submitSucceeded: hasSubmitSucceeded(\"createNewMineLevelForm\")(state),\n // submitFailed: hasSubmitFailed(\"createNewMineLevelForm\")(state),\n }),\n mapDispatchToProps\n)(CreateNamedArea);\n","import React, { Component, useDebugValue } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Form,\n Container,\n Label,\n Header,\n Grid,\n Message,\n Segment,\n Table,\n Icon,\n Popup,\n Dimmer,\n Loader,\n Button,\n} from \"semantic-ui-react\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\n\nimport { push } from \"react-router-redux\";\n\nimport isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport ChooseMineLevelField from \"components/ChooseMineLevelField\";\n\nimport { deleteNamedArea } from \"NamedAreas/actions\";\nimport { renderField } from \"admin/form-field\";\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport { reset } from \"testdouble\";\n\nimport NamedAreaTable from \"admin/named-area/NamedAreaTable\";\n\nimport { GetLocalMap } from \"components/Map/reducer\";\nimport { ClearLocalMap } from \"components/Map/actions\";\n\nimport Map from \"admin/named-area/NamedAreaMap\";\n\nimport {\n getNamedAreaStatusesByAreaId,\n getAllNamedAreaStatuses,\n} from \"components/WebWorker/reducer\";\n\n// based on\n// - https://embed.plnkr.co/Gvei5I0S9yEo6fCYXPuy/\n// see -> from \"./TestMapTilesMap\";\n\n// --------------------------------------\n// Marker not appearing for Simple Example\n// Fix - https://github.com/PaulLeCam/react-leaflet/issues/453\n//\nimport \"leaflet/dist/leaflet.css\";\nimport L from \"leaflet\";\n\ndelete L.Icon.Default.prototype._getIconUrl;\n\nL.Icon.Default.mergeOptions({\n iconRetinaUrl: require(\"leaflet/dist/images/marker-icon-2x.png\"),\n iconUrl: require(\"leaflet/dist/images/marker-icon.png\"),\n shadowUrl: require(\"leaflet/dist/images/marker-shadow.png\"),\n});\n// --------------------------------------\n// HACKfix: Use zIndex to stop leaflet map from being above the Semantic-UI dropdown menus!\nconst DEFAULT_MAP_STYLE = {\n height: \"800px\",\n width: \"100%\",\n position: \"relative\",\n zIndex: 0,\n};\n\nconst validate = (values) => {\n const required = [\"namedAreaIdValue\", \"mineLevelId\"];\n\n //console.log(`xxxx validate values `, values);\n\n const errors = {};\n\n required.forEach((r) => {\n if (!get(values, r)) {\n set(errors, r, \"Required\");\n }\n });\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n if (type === \"noSpaces\") {\n return value.replace(\" \", \"_\");\n } else {\n return value;\n }\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst isNamedAreaNameOK = (value, allValues, props, name) => {\n const { namedAreaIdValue: id } = allValues;\n\n const { uniqueNamedAreaParentIds } = props;\n const valueNoSpace = value.replace(\" \", \"_\");\n\n const notIncludingThisId = uniqueNamedAreaParentIds\n .filter((item) => !item.id.includes(id))\n .map((item) => item.parentName);\n\n //console.log(`notIncludingThisId `, notIncludingThisId);\n\n if (notIncludingThisId?.includes(valueNoSpace)) {\n return \"This name has already been used\";\n } else {\n return undefined;\n }\n};\n\nclass EditNamedAreaForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n contentLoading: true,\n errorMessage: \"\",\n id: props.id,\n };\n }\n\n // #REVIEW -\n // Render issue - with each heartbeat the STATE updates which causes localPts to be updated and so resets the map state\n\n // This stops re-rendering the map unnecessarily\n // #WIP\n\n componentDidMount() {\n // clear the map from any previous edits\n this.props.ClearLocalMap();\n\n // #WIP - set temporarily\n this.setState({ contentLoading: false });\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n // update component when state changes, not when props change or\n // initial props will clobber form edits\n\n // console.log(\"shouldComponentUpdate this.props\", this.props);\n // console.log(\"shouldComponentUpdate nextProps\", nextProps);\n\n return !isEqual(this.props, nextProps); //!isEqual(this.state, nextState); //!isEqual(this.props, nextProps);\n }\n\n requestDelete = (id) => {\n const { handleSubmit, deleteNamedArea, push } = this.props;\n\n console.log(\"requestDelete\", handleSubmit, deleteNamedArea, push);\n console.log(\"WIP.......\");\n };\n\n // onSubmit = (e) => {\n // e.preventDefault();\n // this.props.handleSubmit(this); // calls prop.onSubmit()\n // };\n\n submitMyForm = (values) => {\n //console.log(`form submitted: values`, values);\n this.props.onSubmit(values);\n };\n\n resetForm = (e) => {\n e.preventDefault();\n this.props.ClearLocalMap();\n this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // abort page changes\n this.props.onCancel();\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n //reset,\n mineLevelId,\n namedAreaIdValue,\n namedAreaParentName,\n strings,\n } = this.props;\n\n // APP_TERMINOLOGY\n const strNamedArea = \"Polygon\";\n const strNamedAreas = \"Polygons\";\n\n const { id } = this.state;\n\n if (id === undefined) {\n return (\n <>\n \n \n \n );\n }\n\n const refLocationsComponent = (mineLevelId) => {\n if (!mineLevelId) {\n return
Must select mine area
;\n }\n return (\n
\n \n
\n );\n };\n\n const { contentLoading } = this.state;\n\n function getNested(obj, ...args) {\n return args.reduce((obj, level) => obj && obj[level], obj);\n }\n const tempArray = []; // getNested(localMapState, \"namedAreas\", \"features\") || [];\n\n if (contentLoading) {\n return (\n \n Loading data\n \n );\n } else {\n return (\n
\n \n \n \n \n
{strNamedArea}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {/* ***************Create Form ************************ */}\n {error && (\n \n )}\n\n \n \n \n \n \n
{`Edit ${strNamedArea}`}
\n\n \n \n normalise(value, \"normalise\")}\n />\n normalise(value, \"normalise\")}\n disabled={true}\n />\n
\n \n \n \n \n \n Use the map controls to add a new polygon\n \n Click on the map's Polygon or Rectangle icon to draw a\n new polygon shape. A shape must be drawn to be able to\n save the form.\n \n \n \n \n
{strNamedAreas}
\n \n
\n \n \n \n \n About 'Save Changes'\n Modify a polygon, or colors, to enable 'Save Changes'.\n To 'Delete' named areas, check the box at the end of\n each row to mark for deletion, then save the changes.\n Mark all rows for deletion to delete the entire named\n area.\n \n \n \n
\n \n {false && (\n \n \n \n \n \n \n \n \n \n \n \n \n {/* this.resetForm(e)}\n >\n Reset\n \n */}\n this.cancelForm(e)}\n >\n Cancel\n \n \n \n \n \n \n )}\n \n
Map
\n {refLocationsComponent(mineLevelId)}\n
\n
\n
\n
\n \n\n \n
\n
\n );\n }\n }\n}\n\nconst selector = formValueSelector(\"editNamedAreaForm\");\n\nEditNamedAreaForm = reduxForm({\n form: \"editNamedAreaForm\",\n // Note - to reinitialize values in componentDidMount\n // Make sure you set the values of enableReinitialize & keepDirtyOnReinitialize to true\n // See - https://stackoverflow.com/questions/44273099/redux-form-initialization-with-props-initialize\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(EditNamedAreaForm);\n\nconst mapStateToProps = (state, props) => {\n const { id, mineLevelId, initialValues } = props;\n const { namedAreaIdValue } = initialValues;\n\n // collect an array of existing named area parent names to validate against named area name changes\n const allNamedAreaStatuses = getNamedAreaStatusesByAreaId(state, mineLevelId); // getAllNamedAreaStatuses(state);\n const uniqueNamedAreaParentIds = allNamedAreaStatuses\n .map((item) => {\n return { id: item.parent, parentName: item.parent_name };\n }) // .parent\n .filter(\n (value, index, self) =>\n index ===\n self.findIndex(\n (t) => t.id === value.id && t.parentName === value.parentName\n )\n );\n // .filter((value, index, self) => self.indexOf(value) === index);\n //.map((item) => item.split(\":\")[1]);\n\n //console.log(`uniqueNamedAreaParentIds`, uniqueNamedAreaParentIds);\n\n // # REVIEW #NOTE - duplicate props. mineLevelId is also in initialValues object. Fix this.\n\n const localMapState = GetLocalMap(state);\n\n // Render issue - with each heartbeat the STATE updates which causes localPts to be updated and so resets the map state\n // See console.log below - note grab action is cancelled when the time changes.\n //console.log(\"ggg render issue ref1\", ref1, new Date(Date.now()));\n // See - shouldComponentUpdate\n\n return {\n id,\n mineLevelId,\n localMapState,\n namedAreaIdValue,\n namedAreaParentName: selector(state, \"namedAreaParentName\"),\n initialValues,\n uniqueNamedAreaParentIds,\n //namedAreaIdValue: selector(state, \"namedAreaId\"),\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"reduxForm onChange validate values\", values);\n\n if (values.mineLevelId !== previousValues.mineLevelId) {\n //console.log(\"onChange\", values);\n const {\n change,\n initialValues: { namedAreaIdValue, mineLevelId, regions },\n } = props;\n // if (values.mineLevelId === mineLevelId) {\n // dispatch(change(\"regions\", regions));\n // } else {\n // dispatch(change(\"regions\", []));\n // }\n }\n },\n reduxFormValues: getFormValues(\"editNamedAreaForm\")(state), // #REVIEW - only used for debugging,\n };\n};\n\nconst mapDispatchToProps = (dispatch) => ({\n ClearLocalMap: () => {\n dispatch(ClearLocalMap());\n },\n});\n\nEditNamedAreaForm = connect(\n mapStateToProps,\n mapDispatchToProps\n)(EditNamedAreaForm);\n\nexport default EditNamedAreaForm;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport { Container } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Grid from \"semantic-ui-react/dist/commonjs/collections/Grid\";\n\nimport { saveNewNamedArea, updateNamedArea } from \"NamedAreas/actions\";\n\nimport {\n getNamedAreaStatusesById,\n getAllNamedAreaStatuses,\n} from \"components/WebWorker/reducer\";\n\nimport EditNamedAreaForm from \"admin/named-area/NamedAreaEditForm\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport {\n SubmissionError,\n //\n getFormValues,\n getFormInitialValues,\n getFormSyncErrors,\n getFormMeta,\n getFormAsyncErrors,\n getFormSyncWarnings,\n getFormSubmitErrors,\n getFormError,\n getFormNames,\n isDirty,\n isPristine,\n isValid,\n isInvalid,\n isSubmitting,\n hasSubmitSucceeded,\n hasSubmitFailed,\n} from \"redux-form\";\n\nimport { Dimmer, Loader } from \"semantic-ui-react\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nclass EditNamedArea extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n submitMyForm = (values) => {\n const { updateNamedArea } = this.props;\n\n return new Promise((resolve, reject) => {\n //console.log(\"values\", values);\n //updateNamedArea({ values, resolve, reject });\n }).catch((error) => {\n console.log(`onSubmit error`, error);\n this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const {\n id,\n mineLevelId,\n //updateNamedArea,\n error,\n initialValues,\n submitting,\n } = this.props;\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n return (\n <>\n this.onResetError()}\n errorMessage={errorMessage}\n />\n \n Saving changes\n \n\n {/* #NOTE - NavigationPromptModal is disabled for advanced named areas because it does\n not currently support form submit. */}\n\n {/* this.submitMyForm(formValues)}\n /> */}\n\n this.submitMyForm(values)}\n // #NOTE - disabled as this is fired as soon as submit,\n // *not* after successful completion of the Promise!!\n onSubmitSuccess={(result, dispatch) => {\n //console.log(`onSubmitSuccess ${result}`);\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n this.onResetError();\n this.props.goto(\"/admin/named-area-advanced\");\n }\n );\n }}\n onSubmitFail={(errors) => {\n console.log(`onSubmitFail ${errors}`);\n }}\n onCancel={() => {\n this.props.goto(\"/admin/named-area-advanced\");\n }}\n />\n \n );\n }\n}\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n // updateNamedArea: (data) => dispatch(updateNamedArea(data)), // #WIP\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n };\n};\n\n//export default connect(null, { saveNewMineLevel })(CreateMineLevel);\n\nfunction mapStateToProps(state, props) {\n const match = props.match;\n const id = match.params.id;\n const nameArray = id.split(\":\");\n const mineLevelId = nameArray[0];\n\n // #REVIEW - this code is used in a few places\n let name;\n if (nameArray[1] === undefined) {\n // for edit form use namedArea name (i.e. not `Level Wide (${nameArray[0]})`)\n name = nameArray[0];\n } else {\n name = nameArray[1];\n }\n\n // for edit form named area\n const namedAreaIdValue = name;\n\n const allNamedAreas = getAllNamedAreaStatuses(state);\n\n // console.log(`allNamedAreas`, allNamedAreas);\n\n const namedAreaParent = allNamedAreas?.find((na) => na.parent === id);\n\n const namedAreaParentName = namedAreaParent?.parent_name;\n const namedAreaSubType = namedAreaParent?.sub_type;\n\n const initialValues = {\n mineLevelId: mineLevelId,\n namedAreaIdValue: namedAreaIdValue,\n namedAreaParentName: namedAreaParentName || \"unknown\",\n namedAreaSubType: namedAreaSubType || \"unknown\",\n };\n\n return {\n id,\n mineLevelId,\n //namedArea,\n // error: namedArea === undefined ? \"Named Area not found\" : null,\n initialValues: initialValues, // props passed to redux-form loads these as (predictably), initial values\n\n //\n //values: getFormValues(\"editNamedAreaForm\")(state),\n //initialValues: getFormInitialValues(\"editNamedAreaForm\")(state),\n //formSyncErrors: getFormSyncErrors(\"editNamedAreaForm\")(state),\n //fields: getFormMeta(\"editNamedAreaForm\")(state),\n //formAsyncErrors: getFormAsyncErrors(\"editNamedAreaForm\")(state),\n //syncWarnings: getFormSyncWarnings(\"editNamedAreaForm\")(state),\n //submitErrors: getFormSubmitErrors(\"editNamedAreaForm\")(state),\n //formError: getFormError(\"editNamedAreaForm\")(state),\n //names: getFormNames()(state),\n //dirty: isDirty(\"editNamedAreaForm\")(state),\n //pristine: isPristine(\"editNamedAreaForm\")(state),\n //valid: isValid(\"editNamedAreaForm\")(state),\n //invalid: isInvalid(\"editNamedAreaForm\")(state),\n submitting: isSubmitting(\"editNamedAreaForm\")(state),\n //submitSucceeded: hasSubmitSucceeded(\"editNamedAreaForm\")(state),\n //submitFailed: hasSubmitFailed(\"editNamedAreaForm\")(state),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(EditNamedArea);\n","import React from \"react\";\n// import { Container, Header, Image } from 'semantic-ui-react'\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\n\nconst NoMatch = ({ location }) => (\n
\n
Page not found
\n

\n No match for {location.pathname}\n

\n
\n);\n\nexport default NoMatch;\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\n\nimport ListNamedAreas from \"admin/named-area/NamedAreaList\";\nimport ListAllNamedAreas from \"admin/named-area/NamedAreaListAll\";\nimport ListAllNamedAreaEvents from \"admin/named-area/NamedAreaListAllEvents\";\nimport CreateNamedArea from \"admin/named-area/NamedAreaCreatePage\";\nimport EditNamedArea from \"admin/named-area/NamedAreaEditPage\";\n\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\n\nimport NoMatch from \"components/NoMatch\";\n\nclass NamedAreaPage extends Component {\n render() {\n const { match } = this.props;\n return (\n \n \n \n \n \n \n \n \n );\n }\n}\n\nexport default withRouter(connect(null, { fetchNamedAreas })(NamedAreaPage));\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Popup,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\n//import { getAllNamedAreas } from \"NamedAreas/reducer\";\n\nimport {\n getAllNamedAreaStatuses,\n getAllAreaStatuses,\n} from \"components/WebWorker/reducer\";\nimport { saveNewNamedArea, deleteNamedArea } from \"NamedAreas/actions\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { updateNamedAreaGroup } from \"NamedAreaGroups/actions\";\n\nimport { v4 as uuid } from \"uuid\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ListNamedAreasSimple extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n namedArea: \"\",\n area: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n // const { fetchNamedAreas } = this.props;\n\n // // #FETCHS\n // fetchNamedAreas();// #FETCHS\n\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"namedAreaSimpleList\"\n );\n\n //console.log(\"filterInput componentDidMount\", filterInput);\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"namedAreaSimpleList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column: rxColumn, direction } = this.state;\n\n // if undefined, default sort to 'namedArea'\n let column = rxColumn ? rxColumn : \"namedArea\";\n\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n // #NOTE - create a function\n // src/admin/named-area-group/NamedAreaGroupTableItems.js\n deleteItemByNamedAreaParentId = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n // #NOTE - create a function\n // see - src/admin/named-area-group/NamedAreaGroupEditPage.js\n\n newNamedAreaGroup = (allAreas, allNamedAreas, namedAreaId) => {\n const namedArea = allNamedAreas.find(\n (namedArea) => namedArea.id === namedAreaId\n );\n const { area: areaId, parent: parentId } = namedArea;\n\n if (_isEmpty(areaId)) {\n return null;\n }\n\n const area = allAreas.find((area) => area.id === areaId);\n\n if (_isEmpty(area)) {\n return null;\n }\n\n // get current area info\n const {\n id,\n image_filename,\n image_info,\n slug,\n coordinatesUtm,\n ref_coord,\n floor,\n ceiling,\n default_color,\n default_state,\n namedAreaGroup,\n } = area;\n\n // update namedAreaGroup - delete current namedArea if exists\n if (_isEmpty(namedAreaGroup)) {\n return null;\n }\n\n const cloneItems = !_isEmpty(namedAreaGroup)\n ? JSON.parse(JSON.stringify(namedAreaGroup))\n : [];\n\n const newItems = this.deleteItemByNamedAreaParentId(cloneItems, parentId);\n\n let bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n const firstPoint = bounds[0];\n bounds.push(firstPoint);\n\n // create new Area with updated namedAreaGroup\n const newArea = {\n id,\n image_filename,\n image_info: JSON.stringify(image_info),\n slug,\n bounds: bounds,\n ref_coord,\n floor,\n ceiling,\n default_color: default_color.toUpperCase(),\n default_state: default_state.toUpperCase(),\n named_area_group: JSON.stringify(newItems),\n };\n\n const newValues = { id: id, data: newArea };\n\n return newValues;\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n const {\n allNamedAreas,\n allAreas,\n deleteNamedArea,\n saveNewNamedArea,\n updateNamedAreaGroup,\n push,\n namedAreaSubType,\n strings,\n } = this.props;\n\n let promiseArray = [];\n\n if (action === \"delete\") {\n let namedAreas = [];\n for (var key in selections) {\n const selection = key;\n allNamedAreas.forEach((namedArea, idx) => {\n const { id, parent } = namedArea;\n // selections are parents, so match whole parent. eg.\"DMLZ_Extraction:1234\" in \"DMLZ_Extraction:1234:1604620816915\"\n if (parent === selection) {\n namedAreas.push(id);\n }\n });\n }\n\n namedAreas.forEach((namedAreaId) => {\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({ values: { id: namedAreaId }, resolve, reject })\n )\n );\n\n const newNamedAreaGroup = this.newNamedAreaGroup(\n allAreas,\n allNamedAreas,\n namedAreaId\n );\n\n // null returned if the namedArea group is empty\n if (newNamedAreaGroup !== null) {\n // in loop because could be named area from different areas\n promiseArray.push(\n new Promise((resolve, reject) =>\n updateNamedAreaGroup({\n values: newNamedAreaGroup,\n resolve,\n reject,\n })\n )\n );\n }\n });\n }\n\n if (action === \"copy\") {\n for (var key in selections) {\n const namedAreaParentId = key;\n const newNamedAreaParent = uuid();\n allNamedAreas.forEach((namedArea, idx) => {\n const { id, parent } = namedArea;\n if (parent === namedAreaParentId) {\n // console.log(`xxxx -------------`);\n // console.log(`xxxx namedArea.id`, namedArea.id);\n // console.log(`xxxx -------------`);\n\n const newNamedAreaName = new Date().getTime();\n const copyString = `(${strings?.[\"copy\"]})`;\n\n let newNamedArea = JSON.parse(JSON.stringify(namedArea));\n\n newNamedArea.id = `${namedArea.area}:${newNamedAreaParent}:${newNamedAreaName}`;\n newNamedArea.parent = `${namedArea.area}:${newNamedAreaParent}`;\n newNamedArea.parent_name = `${namedArea.parent_name} ${copyString}`;\n newNamedArea.name = `${newNamedAreaName}`;\n newNamedArea.style = JSON.stringify(namedArea.style);\n newNamedArea.type = \"Polygon\";\n newNamedArea.sub_type = namedAreaSubType;\n\n // append 1st point to close loop\n const lengthCoord = namedArea.coordinatesUtm[0].length;\n newNamedArea.shape = [...namedArea.coordinatesUtm[0]];\n newNamedArea.shape[lengthCoord] = namedArea.coordinatesUtm[0][0];\n\n // update button\n namedArea.button.forEach((butt, idx) => {\n newNamedArea.button[idx].id = newNamedArea.id;\n newNamedArea.button[idx].named_area = newNamedArea.parent;\n });\n\n // delete unnecessary objects\n const { Firefly_List, coordinatesUtm, ...copyNamedArea } =\n newNamedArea;\n\n // console.log(`xxxx originalNamedArea`, namedArea);\n // console.log(`xxxx copyNamedArea`, copyNamedArea);\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n saveNewNamedArea({ values: copyNamedArea, resolve, reject })\n )\n );\n }\n });\n }\n }\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\" .... processed named areas.\", results);\n })\n .then(\n () => {\n push(`/admin/named-area/${namedAreaSubType}`);\n },\n (errorMsg) => {\n console.log(\"action failed\", errorMsg); // #TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, namedAreaSubType, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // APP_TERMINOLOGY\n let strNamedArea = strings?.[\"Polygon\"];\n let strNamedAreas = strings?.[\"Polygons\"];\n\n switch (namedAreaSubType) {\n case \"tagzone\":\n strNamedArea = strings?.[\"Tag Zone\"];\n strNamedAreas = strings?.[\"Tag Zones\"];\n break;\n case \"forced\":\n strNamedArea = strings?.[\"Forced FireFly\"];\n strNamedAreas = strings?.[\"Forced FireFlys\"];\n break;\n case null:\n default:\n break;\n }\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const namedAreaFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let addButton;\n let updateButton;\n let enableButton;\n let disableButton;\n let deleteButton;\n let copyButton;\n let namedAreaSelectedList;\n\n addButton = (\n \n \n }\n />\n );\n\n if (selectedCount > 0) {\n let namedAreaNames = [];\n //console.log(\"data\", data);\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (namedAreaFromDataById(key) !== undefined) {\n let namedAreaName = namedAreaFromDataById(key).namedArea;\n\n // namedAreaName = namedAreaName.substring(\n // 0,\n // namedAreaName.indexOf(\" (\")\n // ); // strip off the trailing ip\n namedAreaNames.push(namedAreaName);\n }\n }\n namedAreaNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n namedAreaNames = namedAreaNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n size=\"large\"\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n size=\"large\"\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")}\n strings={strings}\n size=\"large\"\n />\n );\n\n copyButton = (\n this.requestAction(\"copy\")}\n size=\"large\"\n />\n );\n\n namedAreaSelectedList = (\n \n {`${strNamedAreas} selected ...`} \n {namedAreaNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{strNamedAreas}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n {!areAnySelected && (\n <>\n \n {namedAreaSubType !== \"forced\" && addButton}\n \n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n \n )}\n \n \n \n {namedAreaSubType !== \"forced\" && }\n {namedAreaSubType !== \"forced\" && copyButton}\n {namedAreaSubType !== \"forced\" && }\n {deleteButton}\n {/* {enableButton}\n \n {disableButton} */}\n \n
\n \n {viewablesPage.length} items displayed. {selectedCount} selected\n \n \n {namedAreaSelectedList}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strNamedArea}\n \n \n {strings?.[\"Area\"]}\n \n \n \n \n \n {_.map(viewablesPage, ({ id, namedAreaLink, area }) => (\n \n \n this.handleSelect(id)}\n />\n \n {namedAreaLink}\n {area || \"-\"}\n \n \n ))}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements, namedAreaSubType) => {\n // filter out sub_types\n const newElements = elements.filter((el) => el.sub_type === namedAreaSubType);\n\n // list only unique parents\n const uniqueParents = newElements\n .map((item) => item.parent)\n .filter((value, index, self) => self.indexOf(value) === index);\n\n //console.log(`uniqueParents`, uniqueParents);\n\n let filteredParents = [];\n uniqueParents.forEach(function (uniqueParent, idx) {\n const namedAreaParentInfo = newElements.find(\n (item) => item.parent === uniqueParent\n );\n\n const { area, active, parent_name: parentName } = namedAreaParentInfo;\n\n const id = uniqueParent;\n const nameArray = uniqueParent.split(\":\");\n\n // #NOTE\n // This is historical code when LEVEL_WIDE was listed as a named areas for\n // config. ALL_AREAS, LEVEL_WIDE are excluded from the list for now.\n // See comments `exclude ALL_AREAS, LEVEL_WIDE`\n\n let name;\n if (parentName.length <= 0) {\n if (nameArray.length < 2) {\n // ALL_AREAS, LEVEL_WIDE named area\n name = `Level Wide (${nameArray[0]})`;\n // exclude ALL_AREAS, LEVEL_WIDE\n // filteredParents[idx] = { ....}\n } else {\n name = nameArray[1];\n // compose new data set\n }\n } else {\n name = parentName;\n }\n\n filteredParents[idx] = {\n id: id,\n active: true, // active,\n namedArea: name,\n namedAreaLink: (\n \n {name}{\" \"}\n \n ),\n area: area,\n };\n });\n\n return filteredParents;\n};\n\nconst mapStateToProps = (state, props) => {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.namedAreas;\n const isLoading = false;\n const error = false;\n\n // exclude ALL_AREAS, LEVEL_WIDE\n const allNamedAreas = getAllNamedAreaStatuses(state).filter(\n (na) => na.type !== \"LEVEL_WIDE\" && na.type !== \"ALL_AREAS\"\n );\n\n const allAreas = getAllAreaStatuses(state);\n const data = _prepData(allNamedAreas, props.namedAreaSubType || \"polygon\");\n\n return {\n isLoading,\n error,\n data,\n allNamedAreas,\n allAreas,\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n fetchNamedAreas,\n saveNewNamedArea,\n saveUserSettingsComponentState,\n })(ListNamedAreasSimple)\n);\n","import concat from 'lodash/concat'\nimport slice from 'lodash/slice'\n\nfunction rotate (arr, n) {\n return concat(slice(arr, n), slice(arr, 0, n))\n}\n\nfunction isFirstSmaller (first, second) {\n return first < second\n}\n\nfunction indexOfSmallest (arr) {\n let smallest = null\n let index = null\n arr.forEach((item, idx) => {\n if (smallest === null || isFirstSmaller(item, smallest)) {\n smallest = item\n index = idx\n }\n })\n return index\n}\n\nexport function sanitizeRegionShape (points) {\n const smallest = indexOfSmallest(points)\n return rotate(points, smallest)\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Form } from \"semantic-ui-react\";\n\nimport { sanitizeRegionShape } from \"utils/RegionShape\";\nimport { MineLevelMapById } from \"components/Map/MineLevelMap\";\nimport { Polygon, LayersControl, FeatureGroup } from \"react-leaflet\";\nimport { EditControl } from \"react-leaflet-draw\";\n\nimport { EditControlFeatureGroup } from \"@andrewdodd/react-leaflet-draw\";\n\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroupGeoJson\";\n\nimport { SetMapMoving } from \"components/Map/actions\";\n\nconst buildNewRegion = (points) => {\n const namedAreaTimestamp = new Date().getTime();\n\n return {\n id: namedAreaTimestamp, //cuid(),\n points: sanitizeRegionShape(points),\n };\n};\n\nconst regionListWithoutId = (list, id) =>\n list.filter((region) => region.id !== id);\n\nclass CreateRegionsField extends Component {\n constructor(props) {\n super(props);\n this.state = { editing: false };\n }\n\n addRegion = (evt) => {\n //console.log(\"addRegion\", evt);\n\n const points = evt.layer.getLatLngs()[0];\n // console.log(\"addRegion points\", points);\n // console.log(\"addRegion points\", JSON.stringify(points));\n // console.log(\"addRegion this.props\", this.props);\n\n const newRegionList = [...this.props.input.value, buildNewRegion(points)];\n this.props.input.onChange(newRegionList);\n };\n\n addRegion_New = (e) => {\n //console.log(\"addRegionNew 1 e\", e);\n\n var layers = e.layers;\n layers.eachLayer((layer) => {\n //console.log(\"addRegionNew 2 layer\", layer);\n // console.log(\n // \"addRegionNew 3 layer.getLatLngs()[0]\",\n // layer.getLatLngs()[0]\n // );\n // console.log(\"addRegionNew 4 list = this.props.input\", this.props.input);\n\n const points = layer.getLatLngs()[0];\n\n const newRegionList = [...this.props.input.value, buildNewRegion(points)];\n this.props.input.onChange(newRegionList);\n });\n };\n\n deleteRegion = (e) => {\n //console.log(\"deleteRegion\", e);\n\n const { id } = e.props;\n this.props.input.onChange(regionListWithoutId(this.props.input.value, id));\n };\n\n deleteRegion_New = (e) => {\n console.log(\"deleteRegionNew\", e);\n\n var layers = e.layers;\n layers.eachLayer((layer) => {\n // console.log(\"deleteRegionNew 2 layer\", layer);\n // console.log(\n // \"deleteRegionNew 3 layer.getLatLngs()[0]\",\n // layer.getLatLngs()[0]\n // );\n // console.log(\n // \"deleteRegionNew 4 list = this.props.input\",\n // this.props.input\n // );\n\n const { id } = e.props;\n this.props.input.onChange(\n regionListWithoutId(this.props.input.value, id)\n );\n });\n };\n\n changeRegion = (e, layer) => {\n // console.log(\"changeRegion 1 e\", e);\n // console.log(\"changeRegion 2 layer\", layer);\n // console.log(\"changeRegion 3 layer.getLatLngs()[0]\", layer.getLatLngs()[0]);\n // console.log(\"changeRegion 4 list = this.props.input\", this.props.input);\n\n const points = layer.getLatLngs()[0];\n const { id } = e.props;\n let list = this.props.input.value;\n list = regionListWithoutId(list, id);\n list = [...list, buildNewRegion(points)];\n this.props.input.onChange(list);\n };\n\n changeRegion_New = (e) => {\n //console.log(\"changeRegion 1 e\", e);\n\n var layers = e.layers;\n layers.eachLayer((layer) => {\n // console.log(\"changeRegion 2 layer\", layer);\n // console.log(\n // \"changeRegion 3 layer.getLatLngs()[0]\",\n // layer.getLatLngs()[0]\n // );\n // console.log(\"changeRegion 4 list = this.props.input\", this.props.input);\n\n const points = layer.getLatLngs()[0];\n const { id } = e.props;\n let list = this.props.input.value;\n list = regionListWithoutId(list, id);\n list = [...list, buildNewRegion(points)];\n this.props.input.onChange(list);\n });\n };\n\n handleActivityStarted = (e) => {\n //console.log(\"isActivity started\", e, this.props);\n const { SetMapMoving } = this.props;\n this.setState({ editing: true });\n SetMapMoving(true);\n };\n\n handleActivityStopped = (e) => {\n //console.log(\"isActivity stopped\", e, this.props);\n const { SetMapMoving } = this.props;\n this.setState({ editing: false });\n SetMapMoving(false);\n };\n\n render() {\n const {\n mineLevelIdValue,\n width,\n height,\n backgroundColor = { r: 0, g: 0, b: 0, a: 0.5 },\n input: { value },\n } = this.props;\n\n if (!mineLevelIdValue) {\n return
Must select area
;\n }\n\n // polygon styling\n const fillColor = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b})`;\n const opacity = `${backgroundColor.a}`;\n\n return (\n \n \n \n \n \n \n \n {/* see - https://github.com/andrewdodd/react-leaflet-draw/blob/master/example-full/edit-control.js */}\n Wups
shapes cannot intersect\",\n },\n },\n polyline: false,\n },\n edit: {\n edit: {\n selectedPathOptions: {\n maintainColor: true,\n fillOpacity: 0.5,\n // fillColor: null\n },\n },\n poly: {\n allowIntersection: false,\n drawError: {\n color: \"fuchsia\",\n message:\n \"Wups shapes cannot intersect\",\n },\n },\n },\n position: \"topright\",\n }}\n >\n {value.map((region) => {\n const { id, points } = region;\n return (\n \n );\n })}\n \n {/* ******************************************* */}\n\n {/* #NOTE @13Jul21 - The following code section is the start of moving away\n from Andrew's fork of react-leaflet-draw. The *_New functions work\n exact for changeRegion() > e.props.\n React-leaflet-draw does not accommodate passing the child props back to the parent.\n accommodates this.\n The original reason for moving to generic react-leaflet-draw was to get access to \n onEditStart & onEditStop. However I found Andrew has included onActivityStarted & \n onActivityStopped as equivalents.\n This whole area should be restructured. \n See - https://stackoverflow.com/questions/63460655/edit-a-single-polygon-in-react-leaflet\n See - https://stackblitz.com/edit/react-sn5kcm?file=src%2FMap.js\n See - https://github.com/alex3165/react-leaflet-draw/blob/master/example/edit-control.js\n As an examples for consideration. \n //\n \n \n console.log(`editStart! :)`)}\n onEditStop={() => console.log(`editStop! :(`)}\n draw={{\n rectangle: {\n //shapeOptions: { color: \"green\" },\n showLength: false,\n metric: false,\n feet: false,\n showArea: false,\n },\n marker: false,\n circle: false,\n circlemarker: false,\n polygon: {\n // shapeOptions: { color: \"blue\" },\n allowIntersection: false,\n showLength: false,\n metric: false,\n feet: false,\n showArea: false,\n drawError: {\n color: \"#E1E100\",\n message:\n \"Wups shapes cannot intersect\",\n },\n },\n polyline: false,\n }}\n edit={{\n edit: {\n selectedPathOptions: {\n maintainColor: true,\n fillOpacity: 0.5,\n // fillColor: null\n },\n },\n poly: {\n allowIntersection: false,\n drawError: {\n color: \"fuchsia\",\n message:\n \"Wups shapes cannot intersect\",\n },\n },\n }}\n position={\"topright\"}\n />\n {value.map((region) => {\n const { id, points } = region;\n //console.log(\"regions\", region);\n return (\n \n );\n })}\n \n )} \n */}\n {/* ******************************************* */}\n \n \n \n \n );\n }\n}\n\nconst mapDispatchToProps = (dispatch, props) => ({\n SetMapMoving: (bool) => dispatch(SetMapMoving(bool)),\n});\n\nexport default connect(null, mapDispatchToProps)(CreateRegionsField);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport {\n Form,\n Container,\n Grid,\n Segment,\n Button,\n Header,\n Message,\n Icon,\n TextArea,\n Popup,\n} from \"semantic-ui-react\";\nimport { SketchPicker } from \"react-color\";\nimport reactCSS from \"reactcss\";\n\nimport ContainerDimensions from \"react-container-dimensions\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport _isEqual from \"lodash/isEqual\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\n\nimport { sanitizeRegionShape } from \"utils/RegionShape\";\nimport cuid from \"cuid\";\n\nimport ChooseMineLevelField from \"components/ChooseMineLevelField\";\n//import { MineLevelMapById } from \"components/Map/MineLevelMap\";\n//import { LayersControl } from \"react-leaflet\";\n//import { Polygon } from \"react-leaflet\";\n\nimport { renderField } from \"admin/form-field\";\n\n//import { EditControlFeatureGroup } from \"@andrewdodd/react-leaflet-draw\";\n\n//import { FeatureGroup } from \"react-leaflet\";\n//import { EditControl } from \"react-leaflet-draw\";\n\n//import CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroupGeoJson\";\n\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport {\n getAreaStatusesById,\n getAreaStatuses,\n} from \"components/WebWorker/reducer\";\n\nimport { getNamedAreaStatusesByAreaId } from \"components/WebWorker/reducer\";\n\n//import { geoFromSVGFile, geoFromSVGXML } from \"svg2geojson\";\nimport { geoFromSVGXML } from \"utils/svg2geojson/svg2geojson\";\n\nimport { transformGeoJsonUtmToPixels } from \"components/Map/util-geoJsonToPixels\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n//import { fileExists } from \"utils/fileExists\";\n\nimport { isMapMoving } from \"components/Map/reducer\";\n\nimport CreateRegionsField from \"admin/named-area-simple/CreateRegionsField\";\nimport { stringify } from \"querystring\";\n\nconst buildNewRegion = (points) => {\n const namedAreaTimestamp = new Date().getTime();\n\n return {\n id: namedAreaTimestamp, //cuid(),\n points: sanitizeRegionShape(points),\n };\n};\n\n// const regionListWithoutId = (list, id) =>\n// list.filter((region) => region.id !== id);\n\n// class _CreateRegionsField extends Component {\n// constructor(props) {\n// super(props);\n// this.state = { editing: false };\n// }\n\n// addRegion = (evt) => {\n// //console.log(\"addRegion\", evt);\n\n// const points = evt.layer.getLatLngs()[0];\n// // console.log(\"addRegion points\", points);\n// // console.log(\"addRegion points\", JSON.stringify(points));\n// // console.log(\"addRegion this.props\", this.props);\n\n// const newRegionList = [...this.props.input.value, buildNewRegion(points)];\n// this.props.input.onChange(newRegionList);\n// };\n\n// addRegion_New = (e) => {\n// console.log(\"addRegionNew 1 e\", e);\n\n// var layers = e.layers;\n// layers.eachLayer((layer) => {\n// console.log(\"addRegionNew 2 layer\", layer);\n// console.log(\n// \"addRegionNew 3 layer.getLatLngs()[0]\",\n// layer.getLatLngs()[0]\n// );\n// console.log(\"addRegionNew 4 list = this.props.input\", this.props.input);\n\n// const points = layer.getLatLngs()[0];\n\n// const newRegionList = [...this.props.input.value, buildNewRegion(points)];\n// this.props.input.onChange(newRegionList);\n// });\n// };\n\n// deleteRegion = (e) => {\n// //console.log(\"deleteRegion\", e);\n\n// const { id } = e.props;\n// this.props.input.onChange(regionListWithoutId(this.props.input.value, id));\n// };\n\n// deleteRegion_New = (e) => {\n// console.log(\"deleteRegionNew\", e);\n\n// var layers = e.layers;\n// layers.eachLayer((layer) => {\n// console.log(\"deleteRegionNew 2 layer\", layer);\n// console.log(\n// \"deleteRegionNew 3 layer.getLatLngs()[0]\",\n// layer.getLatLngs()[0]\n// );\n// console.log(\n// \"deleteRegionNew 4 list = this.props.input\",\n// this.props.input\n// );\n\n// const { id } = e.props;\n// this.props.input.onChange(\n// regionListWithoutId(this.props.input.value, id)\n// );\n// });\n// };\n\n// changeRegion = (e, layer) => {\n// // console.log(\"changeRegion 1 e\", e);\n// // console.log(\"changeRegion 2 layer\", layer);\n// // console.log(\"changeRegion 3 layer.getLatLngs()[0]\", layer.getLatLngs()[0]);\n// // console.log(\"changeRegion 4 list = this.props.input\", this.props.input);\n\n// const points = layer.getLatLngs()[0];\n// const { id } = e.props;\n// let list = this.props.input.value;\n// list = regionListWithoutId(list, id);\n// list = [...list, buildNewRegion(points)];\n// this.props.input.onChange(list);\n// };\n\n// changeRegion_New = (e) => {\n// console.log(\"changeRegion 1 e\", e);\n\n// var layers = e.layers;\n// layers.eachLayer((layer) => {\n// console.log(\"changeRegion 2 layer\", layer);\n// console.log(\n// \"changeRegion 3 layer.getLatLngs()[0]\",\n// layer.getLatLngs()[0]\n// );\n// console.log(\"changeRegion 4 list = this.props.input\", this.props.input);\n\n// const points = layer.getLatLngs()[0];\n// const { id } = e.props;\n// let list = this.props.input.value;\n// list = regionListWithoutId(list, id);\n// list = [...list, buildNewRegion(points)];\n// this.props.input.onChange(list);\n// });\n// };\n\n// handleActivityStarted = (e) => {\n// //console.log(\"started\", e);\n// const { flagStartedEditing } = this.props;\n// if (flagStartedEditing) {\n// //flagStartedEditing()\n// //flagStartedEditing={() => {this.setState({'editing': true})}}\n// this.setState({ editing: true });\n// this.props.SetMapMoving(true);\n// }\n// };\n\n// handleActivityStopped = (e) => {\n// //console.log(\"stopped\", e);\n// const { flagStoppedEditing } = this.props;\n// if (flagStoppedEditing) {\n// //flagStoppedEditing()\n// //flagStoppedEditing={() => {this.setState({'editing': false})}}\n// this.setState({ editing: false });\n// this.props.SetMapMoving(false);\n// }\n// };\n\n// render() {\n// const {\n// mineLevelIdValue,\n// width,\n// height,\n// input: { value },\n// } = this.props;\n\n// if (!mineLevelIdValue) {\n// return
Must select area
;\n// }\n\n// return (\n// \n// Math.floor(width), // \"100%\",\n// position: \"relative\",\n// zIndex: 0,\n// // #REVIEW #WIP #TODO - get background from mineLevel\n// //backgroundColor: `rgba(${this.state.backgroundColor.r}, ${this.state.backgroundColor.g}, ${this.state.backgroundColor.b}, ${this.state.backgroundColor.a})`,\n// backgroundColor: `rgba(255,255,255,1)`,\n// }}\n// //invaliddateSize={}\n// >\n// \n// \n// \n// \n// \n// {/* see - https://github.com/andrewdodd/react-leaflet-draw/blob/master/example-full/edit-control.js */}\n// Wups
shapes cannot intersect\",\n// },\n// },\n// polyline: false,\n// },\n// edit: {\n// edit: {\n// selectedPathOptions: {\n// maintainColor: true,\n// fillOpacity: 0.5,\n// // fillColor: null\n// },\n// },\n// poly: {\n// allowIntersection: false,\n// drawError: {\n// color: \"fuchsia\",\n// message:\n// \"Wups shapes cannot intersect\",\n// },\n// },\n// },\n// position: \"topright\",\n// }}\n// >\n// {value.map((region) => {\n// const { id, points } = region;\n// //console.log(\"regions\", region);\n// return (\n// \n// );\n// })}\n// \n// {/* ******************************************* */}\n\n// {/* #NOTE @13Jul21 - The following code section is the start of moving away\n// from Andrew's fork of react-leaflet-draw. The *_New functions work\n// exact for changeRegion() > e.props.\n// React-leaflet-draw does not accommodate passing the child props back to the parent.\n// accommodates this.\n// The original reason for moving to generic react-leaflet-draw was to get access to\n// onEditStart & onEditStop. However I found Andrew has included onActivityStarted &\n// onActivityStopped as equivalents.\n// This whole area should be restructured.\n// See - https://stackoverflow.com/questions/63460655/edit-a-single-polygon-in-react-leaflet\n// See - https://stackblitz.com/edit/react-sn5kcm?file=src%2FMap.js\n// See - https://github.com/alex3165/react-leaflet-draw/blob/master/example/edit-control.js\n// As an examples for consideration.\n// //\n\n// \n// console.log(`editStart! :)`)}\n// onEditStop={() => console.log(`editStop! :(`)}\n// draw={{\n// rectangle: {\n// //shapeOptions: { color: \"green\" },\n// showLength: false,\n// metric: false,\n// feet: false,\n// showArea: false,\n// },\n// marker: false,\n// circle: false,\n// circlemarker: false,\n// polygon: {\n// // shapeOptions: { color: \"blue\" },\n// allowIntersection: false,\n// showLength: false,\n// metric: false,\n// feet: false,\n// showArea: false,\n// drawError: {\n// color: \"#E1E100\",\n// message:\n// \"Wups shapes cannot intersect\",\n// },\n// },\n// polyline: false,\n// }}\n// edit={{\n// edit: {\n// selectedPathOptions: {\n// maintainColor: true,\n// fillOpacity: 0.5,\n// // fillColor: null\n// },\n// },\n// poly: {\n// allowIntersection: false,\n// drawError: {\n// color: \"fuchsia\",\n// message:\n// \"Wups shapes cannot intersect\",\n// },\n// },\n// }}\n// position={\"topright\"}\n// />\n// {value.map((region) => {\n// const { id, points } = region;\n// //console.log(\"regions\", region);\n// return (\n// \n// );\n// })}\n// \n// )}\n// */}\n// {/* ******************************************* */}\n// \n// \n// \n// \n// );\n// }\n// }\n\n// export const CreateRegionsField = connect(null, { SetMapMoving })(\n// _CreateRegionsField\n// );\n\nconst validate = (values) => {\n const { mineLevelId, areaName, regions } = values;\n\n const errors = {};\n\n if (!mineLevelId) {\n errors.mineLevelId = \"Required\";\n }\n if (!areaName) {\n errors.areaName = \"Required\";\n }\n\n if (_isEmpty(regions)) {\n errors.regions = \"Required\";\n }\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n if (type === \"noSpaces\") {\n return value.replace(\" \", \"_\");\n } else {\n return value;\n }\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst isNamedAreaNameOK = (value, allValues, props, name) => {\n const { id } = allValues;\n\n const { uniqueNamedAreaParentIds, strings } = props;\n\n const valueNoSpace = value.replace(\" \", \"_\");\n\n const notIncludingThisId = uniqueNamedAreaParentIds\n .filter((item) => !item.id.includes(id))\n .map((item) => item.parentName);\n\n //console.log(`notIncludingThisId `, notIncludingThisId);\n\n if (notIncludingThisId?.includes(valueNoSpace)) {\n return strings?.[\"This name has already been used\"];\n } else {\n return undefined;\n }\n};\n\nclass NamedAreaSimpleForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n importSvg: \"\",\n collapse: false,\n errorMessage: \"\",\n // color picker\n displayColorPicker: false,\n backgroundColor: {\n r: 0,\n g: 0,\n b: 0,\n a: 0.5,\n },\n };\n }\n\n componentDidMount() {\n const {\n initialValues: { backgroundColor },\n } = this.props;\n this.setState({ backgroundColor: backgroundColor });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { mineLevelIdValue, area } = this.props;\n\n // #NOTE\n // #WIP\n\n // This section has been commented out for the moment.\n // I want to check if the file exist before trying to load the mine level, however\n // this check `fileExists` appears to have the effect of clearing the browser memory cache(?) of the\n // image file. So after the check the file needs to be reloaded from disk cache.\n //\n // This needs to be analysed and a better method found to use globally.\n //\n // if (!_isEqual(mineLevelIdValue, prevProps.mineLevelIdValue)) {\n // console.log(`render check file exists!`);\n // if (mineLevelIdValue) {\n // // check there is a map image to load\n // const url = process.env.PUBLIC_URL + \"/areas/\" + area?.image_filename;\n // if (!fileExists(url)) {\n // this.setState({\n // errorMessage:\n // \"Area image file does not exist. Check Area settings.\",\n // });\n // }\n // }\n // }\n }\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n resetForm = (e) => {\n e.preventDefault();\n this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // https://github.com/Asymmetrik/ngx-leaflet/issues/88\n // unmount error - \"TypeError: Cannot read property 'off' of undefined\"\n\n // abort page changes\n //this.props.reset();\n this.props.onCancel();\n };\n\n submitMyForm = (values) => {\n //console.log(`form submitted: values`, values);\n\n // const { mineLevelId, areaName, regions, namedAreaParentName } = values;\n //const { transformPixelsToUtm } = this.props;\n\n // let newNamedAreas = [];\n\n // regions.forEach((region) => {\n // const { id, points } = region;\n\n // let shape = [];\n\n // points.forEach((point) => {\n // const objLatLng = transformPixelsToUtm.transform({\n // lat: point.lat,\n // lng: point.lng,\n // });\n\n // shape.push(Object.values(objLatLng).reverse()); // reverse lat / lng coords\n // });\n\n // shape.push(shape[0]); // append 1st point to end to close the shape\n\n // newNamedAreas.push({\n // id: `${mineLevelId}:${areaName}:${id}`,\n // name: `${id}`,\n // parent: `${mineLevelId}:${areaName}`,\n // parentName: namedAreaParentName,\n // area: mineLevelId,\n // shape: shape,\n // });\n // });\n\n //this.props.onSubmit(newNamedAreas);\n\n this.props.onSubmit(values);\n };\n\n requestDelete = (id) => {\n // `id` is the only prop\n // console.log(\"requestDelete\", id);\n // console.log(\"requestDelete\", this.props);\n\n const { change } = this.props;\n\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call change to populate the formValue `_action` at the beginning of the delete process.\n // The _action value is checked in the NavigationPromptModal, which does not display.\n change(\"_action\", \"delete\");\n\n this.props.onDelete(id);\n };\n\n importSvgCheck = (value) => {\n console.log(\"value\", value);\n\n this.setState({ importSvg: value });\n };\n\n importSvgSubmit = (e) => {\n e.preventDefault();\n\n let svg = this.state.importSvg;\n\n //console.log(\"sss svg\", svg);\n\n const { diagonalRefCoords, areaStatuses, mineLevelIdValue } = this.props;\n\n //console.log(\"diagonalRefCoords\", diagonalRefCoords);\n\n const { ref1, ref2, ref3, ref4 } = diagonalRefCoords;\n\n if (!svg.includes(\"\")) {\n svg = `\n \n \n \n \n \n \n \n \n \n \n `;\n }\n\n // ...processing SVG code as a string\n let importSvg = {};\n\n geoFromSVGXML(\n svg,\n (layer) => {\n importSvg = layer;\n },\n { area: mineLevelIdValue } // options // NOTE# - don't defined `{layers:true, tolerance:0.5}`\n );\n\n // scale\n // get common scaling from featureCollection\n const units = importSvg.units || \"m\"; // default to \"m\" metres 1:1\n let scale = 1;\n switch (units) {\n case \"m\":\n scale = 1;\n break;\n case \"cm\":\n scale = 100;\n break;\n case \"mm\":\n scale = 1000; // mm -> m\n break;\n case \"in\":\n scale = 39.3700787402; // in -> m\n break;\n default:\n break;\n }\n\n const transpose = false;\n\n const newGeo = transformGeoJsonUtmToPixels(\n importSvg,\n areaStatuses,\n scale,\n transpose\n );\n\n // add new regions to the form\n const currentRegions = this.props?.regions;\n\n let newRegions = [];\n\n if (!_isEmpty(newGeo)) {\n newGeo.features.forEach((feature) => {\n const {\n geometry: { coordinates },\n } = feature;\n\n const newRegion = coordinates[0].map((point) => {\n return { lat: point[0], lng: point[1] };\n });\n newRegions.push(buildNewRegion(newRegion));\n });\n\n const newRegionList = [...currentRegions, ...newRegions];\n this.props.change(\"regions\", newRegionList);\n }\n };\n\n handleColorClick = () => {\n this.setState({ displayColorPicker: !this.state.displayColorPicker });\n };\n\n handleColorClose = () => {\n this.setState({ displayColorPicker: false });\n };\n\n handleColorChange = (color) => {\n this.setState({ backgroundColor: color.rgb });\n this.props.change(\"backgroundColor\", color.rgb);\n console.log(\"fillColor\", color.rgb);\n };\n\n render() {\n const {\n header,\n handleSubmit,\n pristine,\n submitting,\n error,\n mineLevelIdValue,\n initialValues,\n regions,\n isActivity,\n strings,\n } = this.props;\n\n const { id, activeEvent, namedAreaSubType } = initialValues;\n\n const { backgroundColor } = this.state;\n\n // APP_TERMINOLOGY\n\n // APP_TERMINOLOGY\n let strNamedArea = strings?.[\"Polygon\"];\n let strNamedAreas = strings?.[\"Polygons\"];\n\n //console.log(`namedAreaSubType edit`, namedAreaSubType);\n\n switch (namedAreaSubType) {\n case \"tagzone\":\n strNamedArea = strings?.[\"Tag Zone\"];\n strNamedAreas = strings?.[\"Tag Zones\"];\n break;\n case \"forced\":\n strNamedArea = strings?.[\"Forced FireFly\"];\n strNamedAreas = strings?.[\"Forced FireFlys\"];\n break;\n case null:\n default:\n break;\n }\n\n const isActiveEvent = !_isEmpty(activeEvent);\n\n // #################################################\n\n // format of received event\n\n const test2 = {\n active: false,\n active_color: \"red\",\n active_state: \"on\",\n area: \"DMLZ_Extraction\",\n button_groups: { 0: -1 },\n id: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a:1625725335065\", // named area\n parent: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", // parent\n precanned: 0,\n priority: 2, //<--- points to button type\n timestamp: 1625728002755400,\n };\n\n // format for activate(operation)\n\n const testEvent = {\n active: true,\n active_color: \"red\",\n active_state: \"on\",\n alt: \"Level 1\",\n clickable: true,\n color: \"red\",\n default: true,\n group: 0,\n hint: \"Level 0\",\n icon: \"icon-earthquake123\",\n id: \"c9a0be7c-c4b3-45f8-a78f-21d739c2e22b\", // named area\n marker: \"RoundMarker\",\n named_area: \"DMLZ_Extraction:411b517a-a499-4ef9-a71b-30d857fa5e0a\", // parent\n off_time: 0,\n on_time: 0,\n priority: 2, //<--- points to button type\n state: \"on\",\n title: \"Seismic 1\",\n train: 0,\n type: \"SEISMIC1_EVENT\",\n };\n // #################################################\n\n const stylesColorPicker = reactCSS({\n default: {\n color: {\n width: \"36px\",\n height: \"14px\",\n borderRadius: \"2px\",\n background: `rgba(${this.state.backgroundColor.r}, ${this.state.backgroundColor.g}, ${this.state.backgroundColor.b}, ${this.state.backgroundColor.a})`,\n },\n group: {\n alignItems: \"center\",\n display: \"flex\",\n },\n label: {\n fontWeight: \"bold\",\n paddingRight: \"10px\",\n fontSize: \".92857143em\", //#NOTE #HACK - FFS why it is so hard to inherit font sizes??!\n },\n\n swatch: {\n padding: \"5px\",\n background: \"#fff\",\n borderRadius: \"1px\",\n boxShadow: \"0 0 0 1px rgba(0,0,0,.1)\",\n display: \"inline-block\",\n cursor: \"pointer\",\n },\n popover: {\n position: \"absolute\",\n zIndex: \"2\",\n },\n cover: {\n position: \"fixed\",\n top: \"0px\",\n right: \"0px\",\n bottom: \"0px\",\n left: \"0px\",\n },\n },\n });\n\n const isNewNamedArea = id === undefined;\n\n const areaNameChecks = isNewNamedArea\n ? [required, isNamedAreaNameOK]\n : [required];\n\n const isCollapse = this.state.collapse;\n\n const { errorMessage } = this.state;\n\n return (\n \n {/* {error &&
{error}
} */}\n
\n \n \n \n {isCollapse && (\n \n \n \n \n \n \n \n }\n />\n \n \n \n \n )}\n {!isCollapse && (\n <>\n \n \n \n \n
{header}
\n
\n \n \n \n \n }\n />\n \n
\n \n \n \n \n \n normalise(value, \"normalise\")\n }\n />\n \n \n
\n
\n \n {error && }\n {errorMessage && (\n \n \n \n \n Error\n {errorMessage}\n \n \n \n )}\n {isActiveEvent && (\n \n \n \n \n \n {strings?.[\"Polygon Active Event Message Header\"]}\n \n {strings?.[\"Polygon Active Event Message Content\"]}\n \n \n \n )}\n \n \n \n \n \n {strings?.[\"Polygon Info Message Header\"]}\n \n {strings?.[\"Polygon Info Message Content\"]}\n \n \n \n {false && (\n \n \n \n \n
Convert SVG Shape
\n
\n \n this.importSvgSubmit(e)}\n >\n Convert\n \n }\n />\n \n
\n \n \n \n ... shapes here to convert them to regions.\"\n style={{ minHeight: 300 }}\n onChange={(e, { value }) =>\n this.importSvgCheck(value)\n }\n />\n \n \n \n
\n
\n )}\n \n )}\n
\n \n \n \n \n \n {!isNewNamedArea && (\n \n \n {/* \n Delete\n */}\n \n )}\n \n \n \n \n \n \n this.resetForm(e)}\n >\n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n \n \n
{strings?.[\"Map\"]}
\n \n {({ width, height }) => (\n \n )}\n \n
\n
\n
\n
\n \n\n \n
\n );\n }\n}\n\nconst selector = formValueSelector(\"namedAreaSimpleForm\");\n\nNamedAreaSimpleForm = reduxForm({\n form: \"namedAreaSimpleForm\",\n //enableReinitialize: true,\n //keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(NamedAreaSimpleForm);\n\nconst mapStateToProps = (state, props) => {\n const mineLevelId = selector(state, \"mineLevelId\");\n\n const { namedAreaSubType } = props.initialValues;\n\n const allNamedAreaStatuses = getNamedAreaStatusesByAreaId(state, mineLevelId); // getAllNamedAreaStatuses(state);\n const uniqueNamedAreaParentIds = allNamedAreaStatuses\n .map((item) => {\n return {\n id: item.parent,\n parentName: item.parent_name,\n subType: item.sub_type,\n };\n }) // .parent\n .filter(\n (value, index, self) =>\n index ===\n self.findIndex(\n (t) => t.id === value.id && t.parentName === value.parentName\n )\n )\n .filter((item) => item.subType === namedAreaSubType);\n // .filter((value, index, self) => self.indexOf(value) === index);\n //.map((item) => item.split(\":\")[1]);\n\n //console.log(`uniqueNamedAreaParentIds`, uniqueNamedAreaParentIds);\n\n const area = getAreaStatusesById(state, mineLevelId);\n const areaStatuses = getAreaStatuses(state);\n\n const diagonalRefCoords = !_isEmpty(area?.ref_coord)\n ? {\n ref1: {\n image: area.ref_coord[0].image_xy,\n latLng: area.ref_coord[0].utm,\n },\n ref2: {\n image: area.ref_coord[1].image_xy,\n latLng: area.ref_coord[1].utm,\n },\n ref3: {\n image: area.ref_coord[2].image_xy,\n latLng: area.ref_coord[2].utm,\n },\n ref4: {\n image: area.ref_coord[3].image_xy,\n latLng: area.ref_coord[3].utm,\n },\n }\n : { ref1: [], ref2: [], ref3: [], ref4: [] };\n\n const transformPixelsToUtm = area?.transformPixelsToUtm;\n const transformUtmToPixels = area?.transformUtmToPixels;\n\n const regions = selector(state, \"regions\");\n\n return {\n namedAreaParentName: selector(state, \"namedAreaParentName\"),\n mineLevelIdValue: mineLevelId,\n transformPixelsToUtm,\n transformUtmToPixels,\n uniqueNamedAreaParentIds,\n //\n diagonalRefCoords,\n areaStatuses,\n //\n regions,\n area,\n //\n isActivity: isMapMoving(state),\n\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"onChange\", values);\n if (values.mineLevelId !== previousValues.mineLevelId) {\n const {\n change,\n initialValues: { mineLevelId, regions },\n } = props;\n if (values.mineLevelId === mineLevelId) {\n dispatch(change(\"regions\", regions));\n } else {\n dispatch(change(\"regions\", []));\n }\n }\n },\n };\n};\n\nexport default connect(mapStateToProps, null)(NamedAreaSimpleForm);\n","export function fetchTags() {\n return { type: \"TAGS_FETCH_REQUESTED\" };\n}\n\nexport const getTags = (data) => {\n return { type: \"GET_TAGS\", payload: data };\n};\n\nexport function fetchTagTrackingAreaStatuses(payload) {\n //console.log(`fetchTagTrackingAreaStatuses`, payload);\n return { type: \"TAGS_FETCH_AREA_STATUSES\", payload };\n}\n\nexport function assignUser(payload) {\n //console.log(`assignUser`, payload);\n return { type: \"TAGS_ASSIGN_USER\", payload };\n}\n\nexport function assignVehicle(payload) {\n //console.log(`assignVehicle`, payload);\n return { type: \"TAGS_ASSIGN_VEHICLE\", payload };\n}\n\nexport function unassignUser(payload) {\n //console.log(`unassignUser`, payload);\n return { type: \"TAGS_UNASSIGN_USER\", payload };\n}\n\nexport function unassignVehicle(payload) {\n //console.log(`unassignVehicle`, payload);\n return { type: \"TAGS_UNASSIGN_VEHICLE\", payload };\n}\n\n// user manage\n\nexport function addUpdateUser(payload) {\n //console.log(`addUpdateUser`, payload);\n return { type: \"TAGS_ADD_UPDATE_USER\", payload };\n}\n\nexport function addUpdateVehicle(payload) {\n //console.log(`addUpdateVehicle`, payload);\n return { type: \"TAGS_ADD_UPDATE_VEHICLE\", payload };\n}\n\nexport function deleteTagUserById(payload) {\n //console.log(`deleteTagUserById`, payload);\n return { type: \"TAGS_DELETE_USER_BY_ID\", payload };\n}\n\nexport function deleteTagVehicleById(payload) {\n //console.log(`deleteTagVehicleById`, payload);\n return { type: \"TAGS_DELETE_VEHICLE_BY_ID\", payload };\n}\n\nexport function updateTagZone(payload) {\n //console.log(`updateTagZone action`, payload);\n return { type: \"TAGS_UPDATE_TAG_ZONE\", payload };\n}\n\n// fetch all\n\nexport function fetchAllTagUsers() {\n //console.log(`fetchAllTagUsers`);\n return { type: \"TAGS_FETCH_ALL_USERS\" };\n}\n\nexport function fetchAllTagVehicles() {\n //console.log(`fetchAllTagVehicles`);\n return { type: \"TAGS_FETCH_ALL_VEHICLES\" };\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport { Container } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Grid from \"semantic-ui-react/dist/commonjs/collections/Grid\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nimport { saveNewNamedArea } from \"NamedAreas/actions\";\n\nimport NamedAreaSimpleForm from \"admin/named-area-simple/NamedAreaSimpleForm\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { SubmissionError } from \"redux-form\";\n\nimport { Dimmer, Loader } from \"semantic-ui-react\";\n\nimport { v4 as uuid } from \"uuid\";\n\nimport _isEqual from \"lodash/isEqual\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport { newNamedAreaTemplate } from \"admin/named-area-simple/NewNamedAreaTemplate\";\n\nimport { fetchNamedAreas, fetchNamedAreaEvents } from \"NamedAreas/actions\";\nimport { updateTagZone } from \"components/Tags/actions\";\n\nimport { isTagTracking } from \"components/ConfigJs\";\nimport { getUserSettings } from \"auth/reducer\";\n\nclass CreateNamedAreaSimple extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n isTagTracking: false,\n };\n }\n\n componentDidMount() {\n const {\n allAreas,\n //goto,\n namedAreaSubType,\n } = this.props;\n\n // If no areas data is loaded redirect to area list\n // this is typically when the the page is F5 reloaded.\n // Can't operate without area data.\n //\n\n // #REVIEW - disable this for Adding new Named Area.\n // See case for 1st installation there will be no\n // areas except for the defaultArea, but the defaultArea is excluded from State\n // see \" if (area !== \"defaultArea\") {\" ... src/components/WebWorker/reducer.js\n //\n //\n if (false) {\n const checkAllAreas = _isEmpty(allAreas);\n if (checkAllAreas) {\n this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n }\n }\n\n if (\n this.props.userSettings?.application?.includes(\"tagTracking\") ||\n isTagTracking()\n )\n this.setState({ isTagTracking: true });\n\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n return (\n !_isEqual(JSON.stringify(this.props), JSON.stringify(nextProps)) ||\n !_isEqual(this.state, nextState)\n );\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n // newNamedAreaTemplate = (id, name, parent, parentName, area, shape) => {\n // return {\n // id: id,\n // area: area,\n // name: name,\n // shape: shape,\n // type: \"Polygon\",\n // priority: 1,\n // parent: parent,\n // parent_name: parentName,\n // // #WIP #TODO - set a central location for dummy buttons - used in a few places\n // button: [\n // {\n // priority: 0,\n // type: \"SEISMIC0_EVENT\",\n // clickable: true,\n // icon: \"icon-earthquake0\",\n // color: \"green\",\n // hint: \"Level 0\",\n // title: \"Seismic 0\",\n // alt: \"Level 0\",\n // id: id,\n // named_area: parent,\n // group: 0,\n // default: true,\n // active: true,\n // column: 0,\n // state: \"on\",\n // active_color: \"green\",\n // active_state: \"on\",\n // on_time: 0,\n // off_time: 0,\n // train: 0,\n // marker: \"RoundMarker\",\n // },\n // ],\n // active_color: \"GREEN\",\n // active_state: \"ON\",\n // style:\n // '{\"stroke\":true,\"color\":\"hsl(137.508,50%,75%)\",\"weight\":1,\"opacity\":1,\"fill\":true,\"fillColor\":\"hsl(137.508,50%,75%)\",\"fillOpacity\":0.5,\"clickable\":true}',\n // };\n // };\n\n _preProcessValues = (values) => {\n const {\n mineLevelId,\n areaName,\n regions,\n namedAreaParentName,\n backgroundColor,\n } = values;\n\n const { allAreas } = this.props;\n const thisArea = allAreas.find((area) => area.id === mineLevelId);\n const transformPixelsToUtm = thisArea?.transformPixelsToUtm;\n\n let newNamedAreas = [];\n\n regions.forEach((region) => {\n const { id, points } = region;\n\n let shape = [];\n\n points.forEach((point) => {\n const objLatLng = transformPixelsToUtm.transform({\n lat: point.lat,\n lng: point.lng,\n });\n\n shape.push(Object.values(objLatLng).reverse()); // reverse lat / lng coords\n });\n\n shape.push(shape[0]); // append 1st point to end to close the shape\n\n // polygon styling\n const color = `rgb(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b})`;\n const fillColor = color;\n const opacity = `${backgroundColor.a}`;\n\n newNamedAreas.push({\n id: `${mineLevelId}:${areaName}:${id}`,\n name: `${id}`,\n parent: `${mineLevelId}:${areaName}`,\n parentName: namedAreaParentName,\n area: mineLevelId,\n shape: shape,\n style: `{\"stroke\":true,\"color\":\"${color}\",\"weight\":1,\"opacity\":1,\"fill\":true,\"fillColor\":\"${fillColor}\",\"fillOpacity\":${opacity},\"clickable\":true}`,\n });\n });\n\n return newNamedAreas;\n };\n\n submitMyForm = (values) => {\n //console.log(`submitMyForm values`, values);\n\n const { saveNewNamedArea, isNamedAreaActive, namedAreaSubType } =\n this.props;\n\n let promiseArray = [];\n values.forEach((value) => {\n const { id, name, parent, parentName, area, shape, style } = value;\n\n promiseArray.push(\n new Promise((resolve, reject) => {\n const newValues = newNamedAreaTemplate(\n id,\n name,\n parent,\n parentName,\n area,\n shape,\n \"green\",\n { active_state: \"on\" },\n namedAreaSubType,\n null,\n style\n );\n saveNewNamedArea({\n values: newValues,\n resolve,\n reject,\n });\n })\n );\n\n if (this.state.isTagTracking) {\n // tagTracking ...\n /// this sends an update message to tagTracking api\n // #REVIEW- WIP . Currently does not support \"NEW\"\n // promiseArray.push(\n // new Promise((resolve, reject) =>\n // updateTagZone({ values: { id: id }, resolve, reject })\n // )\n // );\n }\n });\n return Promise.all(promiseArray)\n .then((results) => {\n //console.log(\"saveNewNamedArea promise allSettled results\", results);\n results.forEach((result, idx) => {\n const { status } = result;\n switch (status) {\n case \"fulfilled\":\n const {\n value: { topic, token, status, message },\n } = result;\n\n // tagTracking - updateTagZone will respond with\n // e.g.\n // {\n // status: \"fulfilled\",\n // value: {\n // data: {\n // id: \"Area_Main:717d59d5-604f-4924-bb16-d69d9c48ba06:1639017750907\",\n // },\n // message: \"ok\",\n // status: \"success\",\n // },\n // };\n\n if (this.state.isTagTracking) {\n if (status && message) {\n if (message === \"success\") {\n // everything is OK .... ATM not check if things fail...\n }\n }\n }\n\n break;\n\n default:\n break;\n }\n });\n\n console.log(\"SUCCESS saveNewNamedArea\", results);\n })\n .then(() => {\n //this.onResetError();\n\n this.props.fetchNamedAreas();\n this.props.fetchNamedAreaEvents();\n this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n })\n .catch((error) => {\n console.log(`ERROR saveNewNamedArea error`, error);\n this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const {\n //isLoading, error,\n namedAreaSubType,\n strings,\n } = this.props;\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n // APP_TERMINOLOGY\n let strNamedArea = strings?.[\"Polygon\"];\n let strNamedAreas = strings?.[\"Polygons\"];\n\n switch (namedAreaSubType) {\n case \"tagzone\":\n strNamedArea = strings?.[\"Tag Zone\"];\n strNamedAreas = strings?.[\"Tag Zones\"];\n break;\n case \"forced\":\n strNamedArea = strings?.[\"Forced FireFly\"];\n strNamedAreas = strings?.[\"Forced FireFlys\"];\n break;\n case null:\n default:\n break;\n }\n\n return (\n
\n \n this.submitMyForm(this._preProcessValues(formValues))\n }\n />\n \n \n \n \n
{`${strings?.[\"Add\"]} - ${strNamedArea}`}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n this.submitMyForm(this._preProcessValues(values))\n }\n // #NOTE - disabled as this is fired as soon as submit,\n // *not* after successful completion of the Promise!!\n // onSubmitSuccess={(result, dispatch) => {\n // //console.log(`onSubmitSuccess ${result}`);\n // // wait for state change before redirecting page\n // this.setState(\n // {\n // submitted: true,\n // },\n // () => {\n // //this.onResetError();\n\n // console.log(`!!!!onSubmitSuccess`);\n // // this.props.fetchNamedAreas();\n // // this.props.fetchNamedAreaEvents();\n // // this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n // }\n // );\n // }}\n onCancel={() => {\n this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n }}\n strings={strings}\n />\n\n \n
\n
\n // <>\n // this.onResetError()}\n // errorMessage={errorMessage}\n // />\n // \n // Saving changes\n // \n // {\n // return new Promise((resolve, reject) => {\n // console.log(\"values\", values);\n // saveNewNamedArea({ values, resolve, reject });\n // }).catch((error) => {\n // console.log(`onSubmit ${error}`);\n // this.onSetError(\"failed\");\n // // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n // throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n // });\n // }}\n // onSubmitSuccess={(result, dispatch) => {\n // console.log(`onSubmitSuccess ${result}`);\n // this.onResetError();\n // dispatch(push(\"/admin/named-area\"));\n // }}\n // onSubmitFail={(errors) => {\n // console.log(`onSubmitFail ${errors}`);\n // }}\n // onCancel={() => {\n // this.props.goto(\"/admin/named-area\");\n // }}\n // />\n // \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const allAreas = getAllAreaStatuses(state);\n\n return {\n isNamedAreaActive: false,\n allAreas,\n userSettings: getUserSettings(state) || {},\n };\n};\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n saveNewNamedArea: (data) => dispatch(saveNewNamedArea(data)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n fetchNamedAreas: () => dispatch(fetchNamedAreas()),\n fetchNamedAreaEvents: () => dispatch(fetchNamedAreaEvents()),\n //\n updateTagZone: (data) => {\n dispatch(updateTagZone(data));\n },\n };\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(CreateNamedAreaSimple);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport { Container } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Grid from \"semantic-ui-react/dist/commonjs/collections/Grid\";\n\nimport _isEqual from \"lodash/isEqual\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { saveNewNamedArea, updateNamedArea } from \"NamedAreas/actions\";\n\nimport {\n getNamedAreaStatusesById,\n getAllNamedAreaStatuses,\n getNamedAreaStatusesByAreaId,\n getNamedAreaInfosByAreaId,\n getAreaStatusesById,\n getAllAreaStatuses,\n getNamedAreaEventsByParentId,\n} from \"components/WebWorker/reducer\";\n\nimport {\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n} from \"OperationalChanges/actions\";\n\nimport NamedAreaSimpleForm from \"admin/named-area-simple/NamedAreaSimpleForm\";\nimport { deleteNamedArea } from \"NamedAreas/actions\";\nimport { updateNamedAreaGroup } from \"NamedAreaGroups/actions\";\n\nimport { updateTagZone } from \"components/Tags/actions\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport { SubmissionError, startSubmit } from \"redux-form\";\n\nimport { Dimmer, Loader } from \"semantic-ui-react\";\nimport cuid from \"cuid\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport {\n fetchNamedAreas,\n fetchNamedAreaEvents,\n fetchNamedAreaTriggers,\n} from \"NamedAreas/actions\";\n\nimport { confirmTokenRxWithRetryAndTimeout } from \"utils/confirmTokenRxWithRetryAndTimeout\";\nimport * as Api from \"api/apiAck\";\n\nimport { isMqttNotApiPost, isTagTracking } from \"components/ConfigJs\";\nimport { getUserSettings } from \"auth/reducer\";\n\n// #WIP - make common object merge function\n//\n// see also `mergeSettings` which is the same\nconst MergeSettings = (obj1, obj2) => {\n if (obj2) {\n var obj3 = {};\n for (let attrname in obj1) {\n obj3[attrname] = obj1[attrname];\n }\n for (let attrname in obj2) {\n obj3[attrname] = obj2[attrname];\n }\n return obj3;\n } else {\n return obj1;\n }\n};\n\nclass EditNamedAreaSimple extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n isMqttNotApiPost: true,\n isTagTracking: false,\n };\n }\n\n componentDidMount() {\n const { allAreas, goto, namedAreaSubType, TurnOnOffPokeTheWorker } =\n this.props;\n\n // If no areas data is loaded redirect to area list\n // this is typically when the the page is F5 reloaded.\n // Can't operate without area data.\n //\n const checkDataOk = _isEmpty(allAreas);\n if (checkDataOk) {\n goto(`/admin/named-area/${namedAreaSubType}`);\n }\n\n // turn off data collection\n TurnOnOffPokeTheWorker(false);\n\n if (isMqttNotApiPost()) this.setState({ isMqttNotApiPost: true });\n\n if (\n this.props.userSettings?.application?.includes(\"tagTracking\") ||\n isTagTracking()\n )\n this.setState({ isTagTracking: true });\n }\n\n componentWillUnmount() {\n const { TurnOnOffPokeTheWorker } = this.props;\n // turn on data collection\n TurnOnOffPokeTheWorker(true);\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n return (\n !_isEqual(JSON.stringify(this.props), JSON.stringify(nextProps)) ||\n !_isEqual(this.state, nextState)\n );\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n // #NOTE - create a function\n // src/admin/named-area-group/NamedAreaGroupTableItems.js\n deleteItemByNamedAreaParentId = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n //console.log(`items`, items);\n //console.log(`items id`, id);\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n updateItemByNamedAreaParentId = (items, id, label) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and replace object by id\n\n //console.log(`items`, items);\n //console.log(`items id`, id);\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n } else {\n let tempItem = JSON.parse(JSON.stringify(item));\n tempItem.label = label;\n tempItem.namedArea.label = label;\n newSubSubItem[k] = tempItem;\n // console.log(\n // `updateItemByNamedAreaParentId item newSubSubItem[k]`,\n // newSubSubItem[k]\n // );\n }\n k = k + 1;\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n makeNewNamedAreaGroup = (area, parentId, action, data) => {\n // get current area info\n const {\n id,\n image_filename,\n image_info,\n slug,\n coordinatesUtm,\n ref_coord,\n floor,\n ceiling,\n default_color,\n default_state,\n namedAreaGroup,\n } = area;\n\n const cloneItems = !_isEmpty(namedAreaGroup)\n ? JSON.parse(JSON.stringify(namedAreaGroup))\n : [];\n\n let newItems = cloneItems;\n //console.log(`cloneItems`, cloneItems);\n\n switch (action) {\n case \"delete\":\n newItems = this.deleteItemByNamedAreaParentId(cloneItems, parentId);\n break;\n case \"update\":\n newItems = this.updateItemByNamedAreaParentId(\n cloneItems,\n parentId,\n data // for `update` data is the label string\n );\n break;\n default:\n break;\n }\n\n let bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n const firstPoint = bounds[0];\n bounds.push(firstPoint);\n\n // create new Area with updated namedAreaGroup\n const newArea = {\n id,\n image_filename,\n image_info: JSON.stringify(image_info),\n slug,\n bounds: bounds,\n ref_coord,\n floor,\n ceiling,\n default_color: default_color.toUpperCase(),\n default_state: default_state.toUpperCase(),\n named_area_group: JSON.stringify(newItems),\n };\n\n const newValues = { id: id, data: newArea };\n\n return newValues;\n };\n\n // #NOTE - create a function\n // see - src/admin/named-area-group/NamedAreaGroupEditPage.js\n\n old_newNamedAreaGroup = (\n allAreas,\n allNamedAreas,\n namedAreaId,\n action,\n data\n ) => {\n const namedArea = allNamedAreas.find(\n (namedArea) => namedArea.id === namedAreaId\n );\n\n const { area: areaId, parent: parentId } = namedArea;\n\n if (_isEmpty(areaId)) {\n return null;\n }\n\n const area = allAreas.find((area) => area.id === areaId);\n\n if (_isEmpty(area)) {\n return null;\n }\n\n // get current area info\n const {\n id,\n image_filename,\n image_info,\n slug,\n coordinatesUtm,\n ref_coord,\n floor,\n ceiling,\n default_color,\n default_state,\n namedAreaGroup,\n } = area;\n\n // update namedAreaGroup - delete current namedArea if exists\n if (_isEmpty(namedAreaGroup)) {\n return null;\n }\n\n const cloneItems = !_isEmpty(namedAreaGroup)\n ? JSON.parse(JSON.stringify(namedAreaGroup))\n : [];\n\n let newItems = cloneItems;\n\n //console.log(`cloneItems`, cloneItems);\n\n switch (action) {\n case \"delete\":\n newItems = this.deleteItemByNamedAreaParentId(cloneItems, parentId);\n break;\n case \"update\":\n newItems = this.updateItemByNamedAreaParentId(\n cloneItems,\n parentId,\n data // for `update` data is the label string\n );\n break;\n default:\n break;\n }\n\n let bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n const firstPoint = bounds[0];\n bounds.push(firstPoint);\n\n // create new Area with updated namedAreaGroup\n const newArea = {\n id,\n image_filename,\n image_info: JSON.stringify(image_info),\n slug,\n bounds: bounds,\n ref_coord,\n floor,\n ceiling,\n default_color: default_color.toUpperCase(),\n default_state: default_state.toUpperCase(),\n named_area_group: JSON.stringify(newItems),\n };\n\n const newValues = { id: id, data: newArea };\n\n return newValues;\n };\n\n _preProcessValues = (values) => {\n const {\n mineLevelId,\n areaName,\n regions,\n namedAreaParentName,\n backgroundColor,\n } = values;\n\n const { allAreas } = this.props;\n const thisArea = allAreas.find((area) => area.id === mineLevelId);\n const transformPixelsToUtm = thisArea?.transformPixelsToUtm;\n\n let newNamedAreas = [];\n\n regions.forEach((region) => {\n const { id, points } = region;\n\n let shape = [];\n\n points.forEach((point) => {\n const objLatLng = transformPixelsToUtm.transform({\n lat: point.lat,\n lng: point.lng,\n });\n\n shape.push(Object.values(objLatLng).reverse()); // reverse lat / lng coords\n });\n\n shape.push(shape[0]); // append 1st point to end to close the shape\n\n // polygon styling\n const color = `rgb(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b})`;\n const fillColor = color;\n const opacity = `${backgroundColor.a}`;\n\n newNamedAreas.push({\n id: `${mineLevelId}:${areaName}:${id}`,\n name: `${id}`,\n parent: `${mineLevelId}:${areaName}`,\n parentName: namedAreaParentName,\n area: mineLevelId,\n shape: shape,\n style: `{\"stroke\":true,\"color\":\"${color}\",\"weight\":1,\"opacity\":1,\"fill\":true,\"fillColor\":\"${fillColor}\",\"fillOpacity\":${opacity},\"clickable\":true}`,\n });\n });\n\n console.log(`_preProcessValues newNamedAreas`, newNamedAreas);\n\n return newNamedAreas;\n };\n\n submitMyForm = (values) => {\n console.log(\"updateNamedArea values\", values);\n\n const parentIds = values.map((value) => value.parent);\n let parentId = \"\";\n // check all the same parentIds\n if (parentIds.every((val, i, arr) => val === arr[0])) {\n if (parentIds.length) {\n parentId = parentIds[0];\n }\n }\n\n const {\n id,\n saveNewNamedArea,\n deleteNamedArea,\n updateNamedAreaGroup,\n namedAreasByParent,\n area,\n // to send new events\n activateEvent,\n activeNamedAreaEventButton,\n //\n fetchNamedAreas,\n fetchNamedAreaEvents,\n //\n namedAreaSubType,\n updateTagZone,\n } = this.props;\n\n // #NOTE -\n // The edit process for `NamedAreaSimpleForm` deletes the original shape\n // and creates a new shape.\n // Consequently need to :\n // 1 - find named areas (shapes/regions) for deletion\n // 2 - find named areas (shapes/regions) for addition\n // 3 - there is another case where attributes have changed requiring resending\n // the same data.\n // i.e. parentName has changed.\n //\n\n // find the original Ids\n const originalNamedAreaIds = namedAreasByParent.map((na) => na.id);\n\n // find the Ids of the updated data\n const updatedNamedAreaIds = values.map((na) => na.id);\n\n // create an array of deleted Ids\n const deletedNamedAreaIds = originalNamedAreaIds.filter(\n (e) => !updatedNamedAreaIds.includes(e)\n );\n\n console.log(\"SAVE deletedNamedAreaIds\", deletedNamedAreaIds);\n console.log(\"SAVE updatedNamedAreaIds\", updatedNamedAreaIds);\n\n // get data for the new namedAreas\n // * button array\n // * active_color\n // * active_state\n //\n // These are common to all areas for the same parent so\n // copy values from any i.e. the first\n // console.log(\"namedAreasByParent\", namedAreasByParent);\n const templateObj = namedAreasByParent[0];\n // console.log(\"templateObj\", templateObj);\n let buttons = [];\n let active_color = \"GREEN\";\n let active_state = \"ON\";\n let priority = 1;\n if (templateObj !== undefined) {\n buttons = templateObj.button;\n active_color = templateObj.active_color;\n active_state = templateObj.active_state;\n priority = templateObj.priority;\n }\n\n let promiseArray = [];\n let newParentName;\n\n updatedNamedAreaIds.forEach((namedAreaId) => {\n const value = values.find((value) => value.id === namedAreaId);\n const { id, parent, parentName } = value;\n\n let newValue = JSON.parse(JSON.stringify(value));\n\n // update properties\n newValue.parent_name = parentName;\n newValue.default_state = active_state;\n newValue.active_color = active_color;\n // newValue.style =\n // '{\"stroke\":true,\"color\":\"hsl(137.508,50%,75%)\",\"weight\":1,\"opacity\":1,\"fill\":true,\"fillColor\":\"hsl(137.508,50%,75%)\",\"fillOpacity\":0.5,\"clickable\":true}';\n newValue.type = \"Polygon\";\n newValue.sub_type = namedAreaSubType;\n newValue.priority = priority;\n\n // update button info\n let updateButtons = [];\n buttons.forEach((button, idx) => {\n // deep clone a copy of the button object before reassigning properties\n updateButtons[idx] = JSON.parse(JSON.stringify(button));\n // correct the id in the button object when updating\n updateButtons[idx].id = id;\n // correct the named_area\n updateButtons[idx].named_area = parent;\n });\n newValue.button = updateButtons;\n\n console.log(\"SAVING THIS NAMED AREA ID:\", namedAreaId);\n console.log(\"SAVING THIS NAMED AREA VALUES:\", newValue);\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n saveNewNamedArea({ values: newValue, resolve, reject })\n )\n );\n\n if (this.state.isTagTracking) {\n // tagTracking ...\n /// this sends an update message to tagTracking api\n promiseArray.push(\n new Promise((resolve, reject) =>\n updateTagZone({ values: { id: id }, resolve, reject })\n )\n );\n }\n\n // #NOTE - this will get overwritten with the same information\n // for all newNamedAreaIds. i.e. parentName is the same for all newNamedAreaIds\n newParentName = parentName;\n });\n\n // delete named areas as necessary\n deletedNamedAreaIds.forEach((id) => {\n console.log(\"DELETING THIS NAMED AREA ID:\", id);\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({\n values: { id: id },\n resolve,\n reject,\n })\n )\n );\n });\n\n // update namedAreaGroup with changes\n const newNamedAreaGroup = this.makeNewNamedAreaGroup(\n area,\n id,\n \"update\",\n newParentName\n );\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n updateNamedAreaGroup({\n values: newNamedAreaGroup,\n resolve,\n reject,\n })\n )\n );\n\n // #TODO - change .all to .allSettled\n // return Promise.all(promiseArray) //\n // .then((results) => {\n // console.log(\"saveNewNamedArea promise results \", results);\n // })\n return (\n Promise.allSettled(promiseArray)\n .then((results) => {\n // #TODO - check each promise to see if status/reason is OK and the action passed\n //\n //console.log(\"saveNewNamedArea promise allSettled results\", results);\n results.forEach((result, idx) => {\n // console.log(\n // \"saveNewNamedArea promise allSettled result\",\n // idx,\n // \" - \",\n // result\n // );\n const { status } = result;\n switch (status) {\n case \"fulfilled\":\n const {\n value: { topic, token, status, message },\n } = result;\n\n // tagTracking - updateTagZone will respond with\n // e.g.\n // {\n // status: \"fulfilled\",\n // value: {\n // data: {\n // id: \"Area_Main:717d59d5-604f-4924-bb16-d69d9c48ba06:1639017750907\",\n // },\n // message: \"ok\",\n // status: \"success\",\n // },\n // };\n\n if (this.state.isTagTracking) {\n if (status && message) {\n if (message === \"success\") {\n // everything is OK .... ATM not check if things fail...\n }\n }\n }\n\n // else ... saveNamedArea\n\n const topicArray = topic?.split(\"/\");\n const topicType = topicArray?.[0];\n const topicId = topicArray?.[1];\n const topicAction = topicArray?.[2];\n\n // e.g.\n // named_area/DMLZ_Extraction:4c891f20-de82-45f4-b7ef-b3bb2ed1c5f9:1626218801483/change\n if (topicType === \"named_area\" && topicAction === \"change\") {\n if (token !== undefined) {\n if (this.state.isMqttNotApiPost) {\n // wait for ack message with promise message timer\n // waits time is 1000 mS between retries\n\n // #TODO - put retries into config.js\n //\n\n const retries = 2;\n const checkToken = async (token) => {\n return await confirmTokenRxWithRetryAndTimeout(\n token,\n retries\n );\n };\n\n checkToken(token)\n .then((result) =>\n console.log(\n \"saveNewNamedArea checkToken found the Ack at index: \",\n result\n )\n ) // found matching ack\n .then(() => Api.removeAckToken(token)) // delete it\n //.then(() => Promise.resolve(\"ACK OK\"))\n .then(() => {\n if (updatedNamedAreaIds.length) {\n // console.log(\n // `xxxxxxxx checkToken activeNamedAreaEventButton`,\n // activeNamedAreaEventButton\n // );\n\n const operation = {\n ...activeNamedAreaEventButton,\n // overwrite these props ...\n id: topicId,\n named_area: parentId,\n };\n\n console.log(\n `NAMED AREA CHANGE ACK FOUND - SENDING EVENTS --> `,\n operation\n );\n\n activateEvent(operation);\n\n // setTimeout(() => {\n // // try fetch\n // // wait for 1st new named areas to propogate\n // //\n // // catch the ack\n // //\n // //fetchNamedAreas(); //#FETCHS\n // //fetchNamedAreaEvents(); // #FETCHS\n // // now wait for the fetch to resolve\n // // still wait 1000mS as well\n // setTimeout(() => {\n // console.log(\n // `SENDING send out events --> `,\n // operation\n // );\n // activateEvent(operation);\n // }, 1000);\n // }, 1000);\n\n // #BUG>!> BUTTON GROUP STATE IS NOT SET APPROPRIATELY\n //\n // ACK CHECKS?????\n // IMPLEMENT ACK CHECKING MORE WIDELY\n //\n\n // #NOTE - works OK under local testing.\n // Need to try production installation to see if this is a problem.\n }\n })\n .catch((error) =>\n console.log(\n \"saveNewNamedArea checkToken error\",\n error\n )\n );\n }\n // api POST - fulfilled = success\n else {\n if (updatedNamedAreaIds.length) {\n const operation = {\n ...activeNamedAreaEventButton,\n // overwrite these props ...\n id: topicId,\n named_area: parentId,\n };\n\n console.log(\n `NAMED AREA CHANGE ACK FOUND - SENDING EVENTS --> `,\n operation\n );\n\n activateEvent(operation);\n }\n }\n } else {\n console.log(\n `ERROR: saveNewNamedArea - token undefined`,\n result\n );\n }\n }\n break;\n case \" rejected\":\n const { reason } = result;\n console.log(\n \"saveNewNamedArea promise allSettled result rejected\",\n reason\n );\n break;\n\n default:\n break;\n }\n });\n })\n // .then(() => {\n // if (updatedNamedAreaIds.length) {\n // //\n // //\n // // #PROBLEM - I NEED TO GET WAIT FOR THE UPDATED POLYGONS TO COME BACK FROM THE SERVER.\n // // GIVEN POLL RATE COULD BE SECONDS, THIS IS A PROBLEM!\n // // FETCH?\n // // WAIT FOR ACK?\n\n // // #NOTE - only really need the named_area and priority properties anyway!!!!\n // // ....after all that trouble getting the button stuff together!\n // const operation = {\n // ...activeNamedAreaEventButton,\n // named_area: parentId,\n // };\n\n // setTimeout(() => {\n // // try fetch\n // // wait for 1st new named areas to propogate\n // //\n // // catch the ack\n // //\n // //fetchNamedAreas(); //#FETCHS\n // //fetchNamedAreaEvents(); // #FETCHS\n // // now wait for the fetch to resolve\n // // still wait 1000mS as well\n // setTimeout(() => {\n // console.log(`SENDING send out events --> `, operation);\n // //activateEvent(operation);\n // }, 1000);\n // }, 1000);\n\n // // #BUG>!> BUTTON GROUP STATE IS NOT SET APPROPRIATELY\n // //\n // // ACK CHECKS?????\n // // IMPLEMENT ACK CHECKING MORE WIDELY\n // //\n\n // // #NOTE - works OK under local testing.\n // // Need to try production installation to see if this is a problem.\n // }\n // })\n .then(() => {\n this.onResetError();\n this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n })\n .catch((error) => {\n console.log(\"onSubmit error\", error);\n this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n })\n );\n };\n\n render() {\n const {\n // id,\n // mineLevelId,\n //updateNamedArea,\n // saveNewNamedArea,\n deleteNamedArea,\n updateNamedAreaGroup,\n error,\n initialValues,\n isNamedAreaActive,\n namedAreasByParent,\n // namedAreaEvents,\n area,\n namedAreaSubType,\n strings,\n } = this.props;\n\n // APP_TERMINOLOGY\n let strNamedArea = strings?.[\"Polygon\"];\n let strNamedAreas = strings?.[\"Polygons\"];\n\n //console.log(`namedAreaSubType edit`, namedAreaSubType);\n\n switch (namedAreaSubType) {\n case \"tagzone\":\n strNamedArea = strings?.[\"Tag Zone\"];\n strNamedAreas = strings?.[\"Tag Zones\"];\n break;\n case \"forced\":\n strNamedArea = strings?.[\"Forced FireFly\"];\n strNamedAreas = strings?.[\"Forced FireFlys\"];\n break;\n case null:\n default:\n break;\n }\n\n const { errorMessage } = this.state;\n const openModal = errorMessage !== \"\";\n\n // #WIP - ATM don't allow reload, or direct link to a named-area page.....\n // Instead redirect to the controller list page and wait for named-area to list (with next message).\n\n if (error) {\n this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n return null;\n // return (\n // <>\n // \n // \n // \n // );\n }\n\n return (\n
\n \n this.submitMyForm(this._preProcessValues(formValues))\n }\n />\n \n \n \n \n
{`${strings?.[\"Edit\"]} - ${strNamedArea}`}
\n
\n \n \n \n
\n \n
\n {/* dummy row for spacing consistency */}\n \n this.submitMyForm(this._preProcessValues(values))\n }\n // #NOTE - disabled as this is fired as soon as submit,\n // *not* after successful completion of the Promise!!\n // onSubmitSuccess={(result, dispatch) => {\n // //console.log(`onSubmitSuccess ${result}`);\n // // wait for state change before redirecting page\n // this.setState(\n // {\n // submitted: true,\n // },\n // () => {\n // this.onResetError();\n // this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n // }\n // );\n // }}\n onSubmitFail={(errors) => {\n console.log(`onSubmitFail ${errors}`);\n }}\n onCancel={() => {\n this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n }}\n // deleting the whole named area\n onDelete={(id) => {\n //console.log(\"delete id\", id);\n\n // #NOTE - this works, but instead we are using _action = \"delete\" in the form as this\n // can be consistently used across many other pages.\n //\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call startSubmit at the beginning of the delete process.\n // This flips the submit flag. If the form is seem to be submitting\n // The NavigationPromptModal does not display.\n //this.props.startSubmit();\n\n const originalNamedAreaIds = namedAreasByParent.map(\n (na) => na.id\n );\n\n let promiseArray = [];\n\n originalNamedAreaIds.forEach((id) => {\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteNamedArea({\n values: { id: id },\n resolve,\n reject,\n })\n )\n );\n\n if (this.state.isTagTracking) {\n // tagTracking ...\n /// this sends an update message to tagTracking api\n // #REVIEW- WIP . Currently does not support \"DELETE\"\n // promiseArray.push(\n // new Promise((resolve, reject) =>\n // updateTagZone({ values: { id: id }, resolve, reject })\n // )\n // );\n }\n });\n\n const { namedAreaGroup } = area;\n // update namedAreaGroup with changes\n // ...if it there is something to update\n\n if (!_isEmpty(namedAreaGroup)) {\n const newNamedAreaGroup = this.makeNewNamedAreaGroup(\n area,\n id,\n \"delete\",\n null\n );\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n updateNamedAreaGroup({\n values: newNamedAreaGroup,\n resolve,\n reject,\n })\n )\n );\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"Deleting named areas\", results);\n })\n .then(\n () => {\n this.props.fetchNamedAreas();\n this.props.fetchNamedAreaEvents();\n this.props.goto(`/admin/named-area/${namedAreaSubType}`);\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n }}\n strings={strings}\n />\n \n
\n
\n );\n }\n}\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n deleteNamedArea: (id) => {\n dispatch(deleteNamedArea(id));\n },\n updateNamedAreaGroup: (data) => dispatch(updateNamedAreaGroup(data)),\n goto: (path) => dispatch(push(path)),\n saveNewNamedArea: (data) => dispatch(saveNewNamedArea(data)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n activateEvent: (operation) =>\n dispatch(activateNamedAreaEventSingle(operation)),\n fetchNamedAreas: () => dispatch(fetchNamedAreas()),\n fetchNamedAreaEvents: () => dispatch(fetchNamedAreaEvents()),\n startSubmit: () => {\n dispatch(startSubmit(\"namedAreaSimpleForm\"));\n },\n //\n updateTagZone: (data) => {\n dispatch(updateTagZone(data));\n },\n };\n};\n\nconst mapStateToProps = (state, props) => {\n const { match, namedAreaSubType } = props;\n\n const id = match.params.id;\n const nameArray = id.split(\":\");\n const mineLevelId = nameArray[0];\n\n // #REVIEW - this code is used in a few places\n let name;\n if (nameArray[1] === undefined) {\n // for edit form use namedArea name (i.e. not `Level Wide (${nameArray[0]})`)\n name = nameArray[0];\n } else {\n name = nameArray[1];\n }\n\n // for edit form named area\n const namedAreaIdValue = name;\n\n const allNamedAreas = getNamedAreaStatusesByAreaId(state, mineLevelId);\n const namedAreaParent = allNamedAreas?.find((na) => na.parent === id);\n\n const namedAreaParentName = namedAreaParent?.parent_name;\n\n // polygon style\n const namedAreaParentStyle = namedAreaParent?.style;\n\n // polygon styling\n //\n // The styling information is passed by a string.\n // Convert the string to an object.\n\n // obect template\n let backgroundObjTemplate = [\"r\", \"g\", \"b\", \"a\"];\n let rgbString = namedAreaParentStyle?.fillColor || \"rgb(0, 0, 0)\";\n let alpha = namedAreaParentStyle?.fillOpacity || 0.5;\n let colorArr = rgbString\n .slice(rgbString.indexOf(\"(\") + 1, rgbString.indexOf(\")\"))\n .split(\", \");\n let backgroundColor = {};\n // Insert the values into obj\n colorArr.forEach((k, i) => {\n backgroundColor[backgroundObjTemplate[i]] = Number(k);\n });\n backgroundColor.a = alpha;\n\n const allAreas = getAllAreaStatuses(state);\n\n const namedAreasByParent = allNamedAreas.filter((na) => na.parent === id);\n const area = getAreaStatusesById(state, mineLevelId);\n\n const transformUtmToPixels = area?.transformUtmToPixels;\n\n // console.log(\"id\", id);\n // console.log(\"name\", name);\n // console.log(\"mineLevelId\", mineLevelId);\n // console.log(\"allNamedAreas\", allNamedAreas);\n // console.log(\"namedAreasByParent\", namedAreasByParent);\n // console.log(\"name\", name);\n\n let regions = [];\n\n // #WIP #TODO #NOTE -\n // direct links to this page may not have the area loaded so\n // will not have transform and shapes will not show on initialValues\n // if undefined, need to pop error and suggest reload\n\n if (transformUtmToPixels !== undefined) {\n namedAreasByParent.forEach((namedArea) => {\n const { name, coordinatesUtm } = namedArea;\n\n // console.log(\n // \"sss intialValues regions c|| []\n let points = [];\n\n // #WIP #TODO #NOTE - `0` reference as do not support multipart objects - check!?\n coordinatesUtm[0].forEach((coord) => {\n const arrayLatLng = coord.slice();\n const objLatLng = transformUtmToPixels.transform({\n lat: arrayLatLng[0], // <-- **NOTE: lat & lng are NOT swapped! (compare with transformGeoJsonPixelsToUtm) **\n lng: arrayLatLng[1],\n });\n points.push(objLatLng);\n });\n regions.push({ id: name, points: points });\n });\n }\n\n const namedAreaEvent = getNamedAreaEventsByParentId(state, id) || [];\n //console.log(`xxxx namedAreaEvent`, namedAreaEvent);\n // check if there is an active event on the namedArea\n // just get the first available as they are all the same event characteristices\n // for a given parent\n const activeEvent = namedAreaEvent.find((event) => event.active === true);\n let activeNamedAreaEventButton = {};\n if (!_isEmpty(activeEvent)) {\n const { priority } = activeEvent;\n const templateNamedAreaParent = namedAreasByParent.find(\n (na) => na.parent === id\n );\n activeNamedAreaEventButton = templateNamedAreaParent?.button?.[priority];\n //console.log(`xxxx namedAreaEvent namedAreasByParent`, namedAreasByParent);\n //console.log(`xxxx namedAreaEvent eventButton`, activeNamedAreaEventButton);\n }\n\n let namedArea = {\n _action: \"\", // used to control dlg display\n id: id,\n mineLevelId: mineLevelId,\n areaName: name,\n regions: regions,\n namedAreaParentName: namedAreaParentName || \"unknown\",\n activeEvent,\n namedAreaSubType: namedAreaSubType,\n backgroundColor: backgroundColor,\n };\n\n // #WIP #TODO - stop changes while active event on namedArea\n const isNamedAreaActive = false;\n\n return {\n id,\n mineLevelId,\n error: namedArea === undefined ? \"Named area not found\" : null,\n initialValues: namedArea,\n isNamedAreaActive,\n namedAreasByParent,\n activeNamedAreaEventButton,\n\n //\n allAreas,\n allNamedAreas,\n area,\n //\n userSettings: getUserSettings(state) || {},\n };\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(EditNamedAreaSimple);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\n\nimport ListNamedAreaSimple from \"admin/named-area-simple/NamedAreaSimpleList\";\nimport CreateNamedAreaSimple from \"admin/named-area-simple/NamedAreaSimpleCreatePage\";\nimport EditNamedAreaSimple from \"admin/named-area-simple/NamedAreaSimpleEditPage\";\n\nimport { fetchNamedAreas } from \"NamedAreas/actions\";\n\nclass NamedAreaSimpleAdminPages extends Component {\n render() {\n const { match, namedAreaSubType, strings } = this.props;\n\n return (\n \n (\n \n )}\n />\n (\n \n )}\n />\n (\n \n )}\n />\n \n );\n }\n}\n\nexport default withRouter(\n connect(null, { fetchNamedAreas })(NamedAreaSimpleAdminPages)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { SetMapImage } from \"components/Settings/actions\";\nimport { getMapImages } from \"components/Settings/reducer\";\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\n\nfunction AreaImages({ ...props }) {\n const { areaIds, areaImageFileNames, mapImagesFromState, SetMapImage } =\n props;\n\n const mapImageIds = [...mapImagesFromState.map((img) => img.id)];\n\n const content = areaIds.map((areaId) => {\n //\n const imageFilename = areaImageFileNames.find?.(\n (item) => item.id === areaId\n )?.src;\n\n const imageSrc = process.env.PUBLIC_URL + \"/areas/\" + imageFilename;\n\n var xhr = new XMLHttpRequest();\n xhr.open(\"GET\", imageSrc);\n xhr.responseType = \"blob\";\n xhr.onload = response;\n xhr.send();\n\n function response(e) {\n // console.log(\n // `AreaImageImgBlob IMAGE LOADED: this.response`,\n // this.response\n // );\n let reader = new FileReader();\n reader.readAsDataURL(this.response);\n reader.onloadend = function () {\n let base64data = reader.result?.replace(\n /^data:image\\/(png|jpg);base64,/,\n \"\"\n );\n console.log(\n `AreaImageImgBlob IMAGE LOADED: blob ${imageSrc}`,\n base64data\n );\n SetMapImage({\n id: areaId,\n imageData: base64data,\n });\n };\n }\n\n return null;\n });\n\n return content;\n}\n\nconst mapStateToProps = (state, props) => {\n const areas = getAllAreaStatuses(state) || [];\n const areaIds = areas.map((area) => area?.id);\n const areaImageFileNames = areas.map((area) => {\n return { id: area.id, src: area.image_filename };\n });\n\n return {\n areaIds,\n areaImageFileNames,\n folderFilesList: getFolderFileNamesListById(state, \"areas\"),\n mapImagesFromState: getMapImages(state),\n };\n};\n\nexport default connect(mapStateToProps, { SetMapImage })(AreaImages);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nimport { fetchMineLevels, deleteArea } from \"MineLevels/actions\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { isBoomgateCrane, isAreaImageToState } from \"components/ConfigJs\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { fetchFolderFilesListByFolder } from \"components/Settings/actions\";\n\nimport AreaImages from \"components/AreaImages/AreaImageImgBlob\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ListMineLevels extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n area: \"\",\n active: \"\",\n order: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n\n // image update run one\n isAreaImage: false,\n\n // configJs settings\n isAreaImageToState: false,\n isBoomgateCrane: false,\n };\n }\n\n componentDidMount() {\n const {\n data,\n fetchMineLevels,\n fetchFolderFilesListByFolder,\n componentstate,\n } = this.props;\n\n // put configJs in state\n const areaImageToState = isAreaImageToState() || false;\n this.setState({ isAreaImageToState: areaImageToState });\n // railway_application\n const boomgateCrane = isBoomgateCrane() || false;\n this.setState({ isBoomgateCrane: boomgateCrane });\n\n // could have come here after editing area image so\n // fetch updated listing of the folder image list\n //\n fetchFolderFilesListByFolder(\"areas\"); // #FETCHS\n\n // if (_isEmpty(data)) {\n // // #FETCHS\n // fetchMineLevels(); // #FETCHS\n // fetchFolderFilesListByFolder(\"areas\"); // #FETCHS\n // }\n\n const filterInput = componentstate.get(\"filterInput\", \"areaList\");\n\n //console.log(\"filterInput componentDidMount\", filterInput);\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n\n // only run AreaImage check once at componentDidMount to load the images,\n // then this disables it.\n this.setState({ isAreaImage: false });\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"areaList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n }\n\n componentDidUpdate(prevProps, prevState) {\n //only run AreaImage check once when start, if not on mount then here\n if (this.state.isAreaImage) {\n this.setState({ isAreaImage: false });\n }\n\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n requestAction = (action) => {\n const { selections } = this.state;\n const { deleteArea, push, fetchMineLevels } = this.props;\n\n let promiseArray = [];\n\n for (var selection in selections) {\n //console.log(\"deleting Firefly ... \", selection);\n promiseArray.push(\n // eslint-disable-next-line no-loop-func\n new Promise((resolve, reject) => {\n deleteArea({ values: { id: selection }, resolve, reject });\n })\n );\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"DELETING AREA: \", results);\n })\n .then(\n () => {\n fetchMineLevels();\n push(\"/admin/area\");\n },\n (msg) => {\n console.log(\"delete failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, strings, allAreas } = this.props;\n const {\n column,\n data,\n direction,\n filterInput,\n isAreaImage,\n isAreaImageToState,\n } = this.state;\n\n // APP_TERMINOLOGY\n const strArea = strings?.[\"Area\"];\n const strAreas = strings?.[\"Areas\"];\n\n // railway_application\n const pageTitle = !isBoomgateCrane()\n ? strings?.[\"Areas\"]\n : strings?.[\"Map Image\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const areaFromDataById = (id) => allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let addButton;\n let enableButton;\n let disableButton;\n let deleteButton;\n let areaSelectedList;\n\n addButton = (\n \n \n \n {deleteButton}\n {/* \n {enableButton}\n \n {disableButton} */}\n \n \n
\n {viewablesPage.length} items displayed. {selectedCount}{\" \"}\n selected\n
\n \n {areaSelectedList}\n \n \n \n \n \n \n \n {/* */}\n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n {/* \n {strings?.[\"Active\"]}\n */}\n \n {strings?.[\"Order\"]}\n \n \n {strings?.[\"Area\"]}\n \n \n \n \n \n {_.map(\n viewablesPage,\n ({ id, areaLink, area, disableDelete, active, order }) => (\n \n \n this.handleSelect(id)}\n disabled={disableDelete}\n />\n \n {/* {active} */}\n {order}\n {areaLink}\n \n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n \n );\n }\n}\n\nconst _prepData = (elements) => {\n let filteredParents = [];\n\n elements.forEach(function (element, idx) {\n const {\n id,\n name,\n image_filename,\n floor,\n ceiling,\n default_color,\n default_state,\n active,\n order,\n } = element;\n\n if (!id?.includes(\"defaultArea\")) {\n filteredParents[idx] = {\n id: id,\n active: active ? \"true\" : \"false\",\n order: order?.toString(),\n area: name,\n areaLink: {name} ,\n disableDelete: false,\n };\n }\n });\n\n return filteredParents;\n};\n\nfunction mapStateToProps(state) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.namedAreas;\n const isLoading = false;\n const error = false;\n\n // exclude ALL_AREAS, LEVEL_WIDE\n const allAreas = getAllAreaStatuses(state).filter(\n (na) => na.type !== \"LEVEL_WIDE\" && na.type !== \"ALL_AREAS\"\n );\n\n const data = _prepData(allAreas);\n\n return {\n isLoading,\n error,\n data,\n allAreas,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n deleteArea,\n fetchMineLevels,\n push,\n fetchFolderFilesListByFolder,\n saveUserSettingsComponentState,\n })(ListMineLevels)\n);\n","import React, { Component } from \"react\";\nimport { Button, Label, Icon } from \"semantic-ui-react\";\n\nexport default class ImageUpload extends Component {\n _handleImageChange(e) {\n e.preventDefault();\n let reader = new FileReader();\n let file = e.target.files[0];\n\n reader.onloadend = () => {\n this.props.onFileChanged(file, reader.result);\n };\n reader.readAsDataURL(file);\n\n // Note - If you select the same file, the onChange event of input[type=file] will not fire.\n // This is commonly done with debug testing e.g. same extraction.png\n // This resets the input field so if you removed it you can re-add the same file.\n\n //e.target.value = \"\";\n }\n\n render() {\n const { strings } = this.props;\n\n return (\n // \n // \n // this._handleImageChange(e)}\n // />\n // \n <>\n this.input.click()}\n >\n \n \n \n\n (this.input = element)}\n hidden\n onChange={(e) => this._handleImageChange(e)}\n type=\"file\"\n accept=\"image/png, image/jpeg\"\n />\n \n );\n }\n}\n","import L from \"leaflet\";\n\n// loads image, writes to file with new filename stripping timecode\nexport const loadImgToFile = async (url, newFilename) => {\n //console.log(\"loadImgToFile url\", url);\n //console.log(\"loadImgToFile newFilename\", newFilename);\n return await fetch(url)\n .then((response) => {\n //console.log(\"loadImgToFile response\", response);\n if (response.ok) {\n //console.log(\"loadImgToFile response ok?\", response.ok);\n //console.log(\"loadImgToFile response blob\", response.clone().blob());\n // response.clone() b/c stream is locked on 2nd time through\n return response.clone().blob(); // response.blob(); //response.status; // response.json(); // #REVIEW - this returns SyntaxError: Unexpected token � in JSON at position 0\n } else {\n //console.log(\"Fetch \", url, \"failed. Response : \", response);\n throw response.status;\n }\n })\n //.then((r) => r.blob())\n .then(\n (blobFile) => new File([blobFile], newFilename, { type: \"image/png\" })\n )\n .catch((err) => {\n console.log(\"loadImgToFile err:\", err); // most likely 404\n throw err;\n });\n};\n\nexport async function loadImage(imageUrl) {\n //console.log(\"IMAGE LOADED: imageUrl\", imageUrl);\n\n let img;\n const imageLoadPromise = new Promise((resolve) => {\n img = new Image();\n img.onload = resolve;\n img.src = imageUrl;\n });\n\n await imageLoadPromise;\n //console.log(\"IMAGE LOADED:\", img);\n return img;\n}\n\nconst checkImage = (path) =>\n new Promise((resolve) => {\n const img = new Image();\n img.onload = () => resolve({ path, status: \"ok\" });\n img.onerror = () => resolve({ path, status: \"error\" });\n\n img.src = path;\n });\n\nexport const initialiseArea = async (initialValues) => {\n const { id, image_filename, ref_coord } = initialValues;\n\n const url = process.env.PUBLIC_URL + \"/areas/\" + image_filename;\n let width, height;\n let image = new Image();\n\n // console.log(\"initialValues\", initialValues);\n // console.log(\"image_filename\", image_filename);\n // console.log(\"url\", url);\n\n // get filename before date code\n const filenameArray = image_filename.split(\"-\");\n const newFilename = `${filenameArray[0]}.png`;\n\n let imageFile;\n\n const getImageFile = async (url, newFilename) => {\n return await fetch(url)\n .then((response) => {\n //console.log(\"getImageFile response\", response);\n if (response.ok) {\n return response.blob(); //status; // response.json(); // #REVIEW - this returns SyntaxError: Unexpected token � in JSON at position 0\n } else {\n console.log(response.status);\n return Promise.reject(response.status);\n }\n })\n //.then((r) => r.blob())\n .then(\n (blobFile) => new File([blobFile], newFilename, { type: \"image/png\" })\n )\n .catch((err) => {\n console.log(err); // most likely 404\n throw err;\n });\n };\n\n getImageFile(url, newFilename)\n .catch((err) => {\n throw err;\n })\n .then((result) => {\n imageFile = result;\n //console.log(\"getImageFile\", imageFile);\n })\n .catch((err) => {\n console.log(\"getImageFile error\", err);\n const url = process.env.PUBLIC_URL + \"/areas/default.png\";\n const bounds = L.latLngBounds([0, 0], [height, width]);\n this.setState({ contentLoading: false });\n this.setState({ errorMessage: err });\n });\n\n image.onload = () => {\n // `naturalWidth`/`naturalHeight` aren't supported on {\n return {\n easting: ref_coord[idx].utm[0],\n northing: ref_coord[idx].utm[1],\n zoneLetter: ref_coord[idx].utm_zone_letter,\n zoneNum: ref_coord[idx].utm_zone_number,\n lat: ref_coord[idx].image_xy[0],\n lng: ref_coord[idx].image_xy[1],\n };\n };\n\n const ref1 = refObject(0);\n const ref2 = refObject(1);\n const ref3 = refObject(2);\n const ref4 = refObject(3);\n\n // const imageRef1 = L.latLng({ lat: ref1.lat, lng: ref1.lng });\n const imageRef1 = L.latLng(ref1.lat, ref1.lng);\n const imageRef2 = L.latLng(ref2.lat, ref2.lng);\n const imageRef3 = L.latLng(ref3.lat, ref3.lng);\n const imageRef4 = L.latLng(ref4.lat, ref4.lng);\n\n const initialValues = {\n id: id,\n name: id,\n mapFile: imageFile,\n mapUrl: url,\n bounds: bounds,\n imageRef1: imageRef1,\n imageRef2: imageRef2,\n imageRef3: imageRef3,\n imageRef4: imageRef4,\n ref1: ref1,\n ref2: ref2,\n ref3: ref3,\n ref4: ref4,\n };\n\n return initialValues;\n };\n\n image.src = url; // triggers onload\n};\n","import React, { Component, useDebugValue } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Form,\n Container,\n Label,\n Header,\n Grid,\n Message,\n Segment,\n Table,\n Icon,\n Popup,\n Dimmer,\n Loader,\n Button,\n} from \"semantic-ui-react\";\nimport { SketchPicker } from \"react-color\";\nimport reactCSS from \"reactcss\";\n\nimport { renderSelect, renderRadio } from \"admin/form-field\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\nimport { push } from \"react-router-redux\";\n\nimport L, { bounds } from \"leaflet\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport _isEqual from \"lodash/isEqual\";\n\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport ImageUpload from \"admin/mine-level/ImageUpload\";\nimport MapWithImage from \"components/Map/MapWithImage\";\nimport MapMarker from \"components/ColorableMapMarker\";\nimport getSemanticColor from \"colorpalette\";\nimport { localPts } from \"components/Map/referencePoints\";\n\nimport { deleteMineLevel } from \"MineLevels/actions\";\nimport { renderField } from \"admin/form-field\";\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport FlashMessagesList from \"FlashMessages\";\nimport { reset } from \"testdouble\";\n\nimport { LeastSquaresApproximationFourPointsSixParametersTransformation } from \"projection\";\n\nimport {\n //initialiseArea, // #NOTE - attempt to make a common separate initial function. Abandoned.\n loadImage,\n loadImgToFile,\n} from \"./MineLevelInitialiseArea\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { TemplateDefaultArea } from \"components/ConfigJs\";\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\nimport { imageCheck } from \"utils/imageCheck\";\nimport { allowedLightColors as _allowedLightColors } from \"components/ConfigJs\";\n\nconst validate = (values) => {\n const required = [\n \"name\",\n \"active\",\n \"order\",\n \"defaultColor\",\n \"defaultState\",\n \"mapFile\",\n \"imageInfo.backgroundColor\",\n \"imageInfo\",\n \"ref1.easting\",\n \"ref1.northing\",\n \"ref1.zoneLetter\",\n \"ref1.zoneNum\",\n \"ref2.easting\",\n \"ref2.northing\",\n \"ref2.zoneLetter\",\n \"ref2.zoneNum\",\n \"ref3.easting\",\n \"ref3.northing\",\n \"ref3.zoneLetter\",\n \"ref3.zoneNum\",\n \"ref4.easting\",\n \"ref4.northing\",\n \"ref4.zoneLetter\",\n \"ref4.zoneNum\",\n ];\n\n const errors = {};\n\n required.forEach((r) => {\n if (!get(values, r)) {\n set(errors, r, \"Required\");\n }\n });\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n switch (type) {\n case \"name\":\n return value.replace(\" \", \"_\");\n case \"easting\":\n return (value > 0 && Number(value)) || \"\";\n case \"northing\":\n return (value > 0 && Number(value)) || \"\";\n case \"99\":\n return (value < 99 && value > 0 && Number(value)) || \"\";\n case \"char\":\n return (\n (value.match(/^[A-Za-z]+$/) &&\n value.toString().toUpperCase().slice(0, 1)) ||\n \"\"\n );\n default:\n return value;\n }\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst isAreaNameOK = (value, allValues, props, name) => {\n const { allAreaIds } = props;\n\n const valueNoSpace = value.replace(\" \", \"_\");\n if (allAreaIds.includes(valueNoSpace)) {\n return \"Area name has already been used\";\n } else {\n return undefined;\n }\n};\n\n// calculates the UTM region from the ref points and image\nconst calculateAreaRegion = (values) => {\n const {\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n } = values;\n\n let utmRef = [];\n utmRef.push({ lat: ref1?.easting, lng: ref1?.northing });\n utmRef.push({ lat: ref2?.easting, lng: ref2?.northing });\n utmRef.push({ lat: ref3?.easting, lng: ref3?.northing });\n utmRef.push({ lat: ref4?.easting, lng: ref4?.northing });\n\n let pixelRef = [];\n pixelRef.push({ lat: imageRef1?.lat, lng: imageRef1?.lng });\n pixelRef.push({ lat: imageRef2?.lat, lng: imageRef2?.lng });\n pixelRef.push({ lat: imageRef3?.lat, lng: imageRef3?.lng });\n pixelRef.push({ lat: imageRef4?.lat, lng: imageRef4?.lng });\n\n // the geometric coordinate to map pixel transformation\n const Transform = (localPts, standardPts) => {\n const LeastSq4Pt =\n LeastSquaresApproximationFourPointsSixParametersTransformation.fromPoints(\n localPts,\n standardPts\n );\n return LeastSq4Pt;\n };\n\n // update region bounds utm points\n const transform = Transform(utmRef, pixelRef); // convert utmRef -> pixelRef\n\n const {\n _northEast: { lat: height, lng: width },\n } = bounds;\n\n // area rectangle has four points\n const southWest = transform.transform({\n lat: 0,\n lng: 0,\n });\n const northEast = transform.transform({\n lat: height,\n lng: width,\n });\n const northWest = { lng: southWest.lng, lat: northEast.lat };\n const southEast = { lng: northEast.lng, lat: southWest.lat };\n\n let boundsArray = [southWest, northWest, northEast, southEast, southWest];\n boundsArray = boundsArray.map((bound) => Object.values(bound).reverse());\n\n // debug.....................\n // console.log(\"lll bounds\", bounds);\n // console.log(\"lll imgBounds\", boundsArray);\n // console.log(\"lll southWest\", Object.values(southWest).reverse());\n // console.log(\"lll northEast\", Object.values(northEast).reverse());\n // console.log(\"lll utmRef\", utmRef);\n // console.log(\"lll pixelRef\", pixelRef);\n\n return boundsArray;\n};\n\nconst initialiseValues = async (\n defaultColor,\n defaultState,\n imageInfo,\n defaultRefCoords,\n folderFilesList,\n active,\n order\n) => {\n // console.log(\n // \"initialiseValues defaultColor\",\n // defaultColor,\n // \"defaultState\",\n // defaultState,\n // \"imageInfo\",\n // imageInfo,\n // \"defaultRefCoords\",\n // defaultRefCoords,\n // \"folderFilesList\",\n // folderFilesList\n // );\n\n const newFilename = \"default.png\";\n\n const url = imageCheck(folderFilesList, newFilename, imageInfo);\n\n let imageFile;\n\n return new Promise((resolve, reject) => {\n loadImgToFile(url, newFilename)\n .catch((err) => {\n throw err;\n })\n .then((result) => {\n //console.log(\"initialiseValues loadImgToFile result\", result);\n imageFile = result;\n loadImage(url)\n .then((img) => {\n // console.log(\"loadImgToFile img\", img);\n // console.log(\n // `loadImgToFile img ${img.src} w: ${img.width} | h: ${img.height}`\n // );\n\n const imageSrc = img.src;\n const imageHeight = img.height;\n const imageWidth = img.width;\n\n //console.log(\"initialiseValues loadImgToFile imageFile\", imageFile);\n\n // change the filename by resaving image\n const blob = imageFile.slice(0, imageFile.size, \"image/png\");\n const filename = imageFile.name;\n let newFilename = filename; // filename.replace(\"-\", \"\"); // strip out all '-' as used to parse loaded files\n // newFilename = newFilename.replace(\n // \".png\",\n // `-[${img.width},${img.height}].png`\n // );\n const newFile = new File([blob], newFilename, {\n type: \"image/png\",\n });\n\n const newImageInfo = {\n width: imageWidth,\n height: imageHeight,\n backgroundColor: imageInfo.backgroundColor,\n };\n\n // console.log(\"initialValues newFilename\", newFilename);\n // console.log(\"initialValues newFile\", newFile);\n // console.log(\"initialValues defaultRefCoords\", defaultRefCoords);\n\n const bounds = L.latLngBounds([0, 0], [imageHeight, imageWidth]);\n const imageRef1 = bounds.getNorthWest();\n const imageRef2 = bounds.getNorthEast();\n const imageRef3 = bounds.getSouthEast();\n const imageRef4 = bounds.getSouthWest();\n\n const ref1 = defaultRefCoords.ref1;\n const ref2 = defaultRefCoords.ref2;\n const ref3 = defaultRefCoords.ref3;\n const ref4 = defaultRefCoords.ref4;\n\n const areaRegion = calculateAreaRegion({\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n });\n\n const values = {\n defaultColor: defaultColor,\n defaultState: defaultState,\n mapFile: newFile,\n imageInfo: newImageInfo,\n mapUrl: imageSrc,\n bounds: bounds,\n areaRegion: areaRegion,\n // reference to bottom left corner\n // image ref 1 is top left\n imageRef1: imageRef1,\n imageRef2: imageRef2,\n imageRef3: imageRef3,\n imageRef4: imageRef4,\n //\n ref1: ref1,\n ref2: ref2,\n ref3: ref3,\n ref4: ref4,\n //\n active: active,\n order: order,\n };\n //this.setState({ contentLoading: false });\n //console.log(\"initialValues values .......\", values);\n resolve(values);\n })\n .catch((err) => {\n console.error(`loadImage ${err}`);\n reject(err);\n //this.setState({ errorMessage: err });\n //this.setState({ contentLoading: false });\n });\n })\n // .then(\n // loadImage(url)\n // .then((img) => {\n // console.log(\"loadImgToFile img\", img);\n // console.log(\n // `loadImgToFile img ${img.src} w: ${img.width} | h: ${img.height}`\n // );\n\n // const imageSrc = img.src;\n // const imageHeight = img.height;\n // const imageWidth = img.width;\n\n // console.log(\"initialiseValues loadImgToFile imageFile\", imageFile);\n\n // // change the filename by resaving image\n // const blob = imageFile.slice(0, imageFile.size, \"image/png\");\n // const filename = imageFile.name;\n // let newFilename = filename.replace(\"-\", \"\"); // strip out all '-' as used to parse loaded files\n // newFilename = newFilename.replace(\n // \".png\",\n // `-[${img.width},${img.height}].png`\n // );\n // const newFile = new File([blob], newFilename, {\n // type: \"image/png\",\n // });\n\n // const newImageInfo = {\n // width: imageWidth,\n // height: imageHeight,\n // backgroundColor: imageInfo.backgroundColor,\n // };\n\n // console.log(\"initialValues newFilename\", newFilename);\n // console.log(\"initialValues newFile\", newFile);\n\n // const bounds = L.latLngBounds([0, 0], [imageHeight, imageWidth]);\n // const imageRef1 = bounds.getNorthWest();\n // const imageRef2 = bounds.getNorthEast();\n // const imageRef3 = bounds.getSouthEast();\n // const imageRef4 = bounds.getSouthWest();\n\n // const values = {\n // defaultColor: defaultColor,\n // defaultState: defaultState,\n // mapFile: newFile,\n // imageInfo: newImageInfo,\n // mapUrl: imageSrc,\n // bounds: bounds,\n // // reference to bottom left corner\n // // image ref 1 is top left\n // imageRef1: imageRef1,\n // imageRef2: imageRef2,\n // imageRef3: imageRef3,\n // imageRef4: imageRef4,\n // ref1: localPts()[0],\n // ref2: localPts()[1],\n // ref3: localPts()[2],\n // ref4: localPts()[3],\n // };\n // //this.setState({ contentLoading: false });\n // console.log(\"initialValues values .......\", values);\n // resolve(values);\n // })\n // .catch((err) => {\n // console.error(`loadImage ${err}`);\n // reject(err);\n // //this.setState({ errorMessage: err });\n // //this.setState({ contentLoading: false });\n // })\n // )\n .catch((err) => {\n console.log(\"getImageFile error\", err);\n\n // #NOTE - this should never happen because we've aleady checks the file exists\n // and loaded a default blob if not available.\n\n // load default image\n const url = process.env.PUBLIC_URL + \"/areas/default.png\";\n //this.setState({ errorMessage: err });\n return loadImgToFile(url, newFilename);\n });\n\n // loadImage(url)\n // .then((img) => {\n // console.log(`loadImage ${img.src} w: ${img.width} | h: ${img.height}`);\n\n // const height = img.height;\n // const width = img.width;\n\n // // change the filename by resaving image\n // const blob = file.slice(0, file.size, \"image/png\");\n // const filename = file.name;\n // let newFilename = filename.replace(\"-\", \"\"); // strip out all '-' as used to parse loaded files\n // newFilename = newFilename.replace(\n // \".png\",\n // `-[${img.width},${img.height}].png`\n // );\n // const newFile = new File([blob], newFilename, {\n // type: \"image/png\",\n // });\n\n // console.log(\"onMapChanged newFilename\", newFilename);\n // console.log(\"onMapChanged newFile\", newFile);\n\n // const bounds = L.latLngBounds([0, 0], [height, width]);\n // const imageRef1 = bounds.getNorthWest();\n // const imageRef2 = bounds.getNorthEast();\n // const imageRef3 = bounds.getSouthEast();\n // const imageRef4 = bounds.getSouthWest();\n\n // // update form props for new imageRefs\n // this.props.change(\"mapFile\", newFile);\n // this.props.change(\"imageRef1\", imageRef1);\n // this.props.change(\"imageRef2\", imageRef2);\n // this.props.change(\"imageRef3\", imageRef3);\n // this.props.change(\"imageRef4\", imageRef4);\n\n // this.setState({\n // mapFile: newFile,\n // mapUrl: url,\n // bounds: bounds,\n // // reference to bottom left corner\n // // image ref 1 is top left\n // imageRef1: imageRef1,\n // imageRef2: imageRef2,\n // imageRef3: imageRef3,\n // imageRef4: imageRef4,\n // });\n // console.log(\"onMapChanged bounds\", bounds);\n\n // this.setState({ contentLoading: false });\n // })\n // .catch((err) => console.error(`loadImage ${err}`));\n });\n};\n\nclass CreateMineLevelForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n contentLoading: true,\n errorMessage: \"\",\n id: props.id,\n name: \"\",\n defaultColor: \"green\",\n defaultState: \"on\",\n mapFile: \"\",\n imageInfo: {\n width: \"\",\n height: \"\",\n backgroundColor: { r: 255, g: 255, b: 255, a: 1 },\n },\n mapUrl: \"\",\n bounds: [],\n imageRef1: {},\n imageRef2: {},\n imageRef3: {},\n imageRef4: {},\n ref1: {},\n ref2: {},\n ref3: {},\n ref4: {},\n areaRegion: [],\n defaultRefCoords: {},\n // color picker\n displayColorPicker: false,\n backgroundColor: {\n r: 255,\n g: 255,\n b: 255,\n a: 1,\n },\n //\n initialValues: {\n name: \"\",\n defaultColor: \"green\",\n defaultState: \"on\",\n mapFile: \"\",\n imageInfo: {\n width: \"\",\n height: \"\",\n backgroundColor: { r: 255, g: 255, b: 255, a: 1 },\n },\n mapUrl: \"\",\n bounds: [],\n imageRef1: {},\n imageRef2: {},\n imageRef3: {},\n imageRef4: {},\n ref1: {},\n ref2: {},\n ref3: {},\n ref4: {},\n areaRegion: [],\n },\n //\n collapse: false,\n };\n }\n\n // #REVIEW -\n // Render issue - with each heartbeat the STATE updates which causes localPts to be updated and so resets the map state\n\n // This stops re-rendering the map unnecessarily\n // #WIP\n\n componentDidMount() {\n const { folderFilesList } = this.props;\n\n const initialValues = this.state.initialValues;\n const { defaultColor, defaultState, imageInfo, active, order } =\n initialValues;\n\n // set state for color picker\n if (imageInfo?.backgroundColor !== undefined) {\n this.setState({ backgroundColor: imageInfo.backgroundColor });\n }\n\n // get default reference coordinates for the form\n const templateDefaultArea = TemplateDefaultArea() || {};\n const templateDefaultAreaRefCoords = templateDefaultArea?.ref_coord;\n let defaultRefCoords;\n\n if (!_isEmpty(templateDefaultAreaRefCoords)) {\n const ref1 = {\n easting: templateDefaultAreaRefCoords[0].utm[0],\n northing: templateDefaultAreaRefCoords[0].utm[1],\n zoneLetter: templateDefaultAreaRefCoords[0].utm_zone_letter,\n zoneNum: templateDefaultAreaRefCoords[0].utm_zone_number,\n };\n const ref2 = {\n easting: templateDefaultAreaRefCoords[1].utm[0],\n northing: templateDefaultAreaRefCoords[1].utm[1],\n zoneLetter: templateDefaultAreaRefCoords[1].utm_zone_letter,\n zoneNum: templateDefaultAreaRefCoords[1].utm_zone_number,\n };\n const ref3 = {\n easting: templateDefaultAreaRefCoords[2].utm[0],\n northing: templateDefaultAreaRefCoords[2].utm[1],\n zoneLetter: templateDefaultAreaRefCoords[2].utm_zone_letter,\n zoneNum: templateDefaultAreaRefCoords[2].utm_zone_number,\n };\n const ref4 = {\n easting: templateDefaultAreaRefCoords[3].utm[0],\n northing: templateDefaultAreaRefCoords[3].utm[1],\n zoneLetter: templateDefaultAreaRefCoords[3].utm_zone_letter,\n zoneNum: templateDefaultAreaRefCoords[3].utm_zone_number,\n };\n\n defaultRefCoords = { ref1, ref2, ref3, ref4 };\n }\n\n this.setState({ defaultRefCoords: defaultRefCoords });\n\n initialiseValues(\n defaultColor,\n defaultState,\n imageInfo,\n defaultRefCoords,\n folderFilesList,\n active,\n order\n )\n .then((values) => {\n //console.log(\"componentDidMount initialiseValues .... \", values);\n this.setState({ ...values, initialValues: { ...values } });\n // initialize() is a prop provided by reduxForm, that can be used to fill up the form values.\n // Note - enableReinitialize: true,\n this.props.initialize(values);\n this.setState({ contentLoading: false });\n })\n .catch((err) => {\n //console.log(\"componentDidMount initialiseValues error\", err);\n this.setState({ errorMessage: err });\n this.setState({ contentLoading: false });\n });\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n const check =\n !_isEqual(this.props.formValues, nextProps.formValues) ||\n !_isEqual(this.state, nextState);\n\n return check;\n }\n\n svgMarkerIcon = (text, color) => {\n return (\n \n \n \n \n {text}\n \n \n );\n };\n\n onFieldChanged = () => {\n //console.log(\"lll FieldChanged!\");\n\n // update area region calculation\n const {\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n } = this.state;\n\n const areaRegion = calculateAreaRegion({\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n });\n\n //console.log(\"lll areaRegion\", areaRegion);\n this.props.change(\"areaRegion\", areaRegion);\n this.setState({ areaRegion: areaRegion });\n };\n\n createRefTable = () => {\n const colObjRef = [\"easting\", \"northing\", \"zoneLetter\", \"zoneNum\"];\n const colLabel = [\"easting\", \"northing\", \"zone letter\", \"zone number\"];\n const colType = [\"easting\", \"northing\", \"char\", \"99\"];\n const colFieldType = [\"number\", \"number\", \"text\", \"number\"];\n\n const rows = 4;\n const cols = 4; // 1st column is marker icon\n\n let table = [];\n\n // Outer loop to create parent\n for (let i = 0; i < rows; i++) {\n let children = [];\n //Inner loop to create children\n for (let j = 0; j < cols; j++) {\n children.push(\n \n console.log(\"Field value\", value)}\n onBlur={() => this.onFieldChanged()}\n normalize={(value) => normalise(value, colType[j])}\n type={colFieldType[j]}\n />\n \n );\n }\n //Create the parent and add the children\n table.push(\n \n \n
{this.svgMarkerIcon(i + 1, \"#2185D0\")}
\n
\n {children}\n
\n );\n }\n return table;\n };\n\n onMapChanged = (file, url) => {\n if (!file) {\n return;\n }\n\n // console.log(\"file\", file);\n // console.log(\"url\", url);\n\n this.setState({ contentLoading: true });\n\n loadImage(url)\n .then((img) => {\n //console.log(`loadImage ${img.src} w: ${img.width} | h: ${img.height}`);\n\n const src = img.src;\n const height = img.height;\n const width = img.width;\n\n // console.log(\"onMapChanged file\", file);\n // console.log(\"onMapChanged url\", url);\n\n // change the filename by resaving image\n const blob = file.slice(0, file.size, \"image/png\");\n const filename = file.name;\n let newFilename = filename; // filename.replace(\"-\", \"\"); // strip out all '-' as used to parse loaded files\n // newFilename = newFilename.replace(\n // \".png\",\n // `-[${img.width},${img.height}].png`\n // );\n const newFile = new File([blob], newFilename, {\n type: \"image/png\",\n });\n\n const imageInfo = {\n width: width,\n height: height,\n backgroundColor: this.state.backgroundColor,\n };\n\n // console.log(\"onMapChanged newFilename\", newFilename);\n // console.log(\"onMapChanged newFile\", newFile);\n\n const bounds = L.latLngBounds([0, 0], [height, width]);\n const imageRef1 = bounds.getNorthWest();\n const imageRef2 = bounds.getNorthEast();\n const imageRef3 = bounds.getSouthEast();\n const imageRef4 = bounds.getSouthWest();\n\n // update form props for new imageRefs\n this.props.change(\"mapFile\", newFile);\n this.props.change(\"imageInfo\", imageInfo);\n this.props.change(\"mapUrl\", src);\n\n this.props.change(\"imageRef1\", imageRef1);\n this.props.change(\"imageRef2\", imageRef2);\n this.props.change(\"imageRef3\", imageRef3);\n this.props.change(\"imageRef4\", imageRef4);\n\n this.setState({\n mapFile: newFile,\n imageInfo: imageInfo,\n mapUrl: src,\n bounds: bounds,\n // reference to bottom left corner\n // image ref 1 is top left\n imageRef1: imageRef1,\n imageRef2: imageRef2,\n imageRef3: imageRef3,\n imageRef4: imageRef4,\n });\n //console.log(\"onMapChanged bounds\", bounds);\n\n this.setState({ contentLoading: false });\n })\n .catch((err) => console.error(`loadImage ${err}`));\n\n // this.setState({ contentLoading: true });\n\n // // console.log(\"onMapChanged file\", file);\n // // console.log(\"onMapChanged url\", url);\n\n // // change the filename by resaving image\n // const blob = file.slice(0, file.size, \"image/png\");\n // const filename = file.name;\n // const newFilename = filename.replace(\"-\", \"\"); // strip out all '-' as used to parse loaded files\n // const newFile = new File([blob], `${newFilename}`, { type: \"image/png\" });\n\n // // console.log(\"onMapChanged newFilename\", newFilename);\n // // console.log(\"onMapChanged newFile\", newFile);\n\n // this.props.change(\"mapFile\", newFile);\n // var that = this;\n // var img = new Image();\n\n // img.onload = function () {\n // const { width, height } = this;\n // const bounds = L.latLngBounds([0, 0], [height, width]);\n // const imageRef1 = bounds.getNorthWest();\n // const imageRef2 = bounds.getNorthEast();\n // const imageRef3 = bounds.getSouthEast();\n // const imageRef4 = bounds.getSouthWest();\n\n // // update form props for new imageRefs\n // that.props.change(\"imageRef1\", imageRef1);\n // that.props.change(\"imageRef2\", imageRef2);\n // that.props.change(\"imageRef3\", imageRef3);\n // that.props.change(\"imageRef4\", imageRef4);\n\n // that.setState({\n // mapFile: newFile,\n // mapUrl: url,\n // bounds: bounds,\n // // reference to bottom left corner\n // // image ref 1 is top left\n // imageRef1: imageRef1,\n // imageRef2: imageRef2,\n // imageRef3: imageRef3,\n // imageRef4: imageRef4,\n // });\n // console.log(\"onMapChanged bounds\", bounds);\n\n // that.setState({ contentLoading: false });\n // };\n // img.src = url;\n };\n\n onDragEnded(id, newLocation) {\n if (this.state.bounds.contains(newLocation)) {\n this.props.change(id, newLocation);\n this.setState({ [id]: newLocation });\n\n // update area region calculation\n const {\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n } = this.state;\n\n const areaRegion = calculateAreaRegion({\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n });\n this.props.change(\"areaRegion\", areaRegion);\n this.setState({ areaRegion: areaRegion });\n } else {\n this.setState({ [id]: { ...this.state[id] } });\n }\n }\n\n makeOnDragEnd(id) {\n return ({ target }) => {\n this.onDragEnded(id, target.getLatLng());\n };\n }\n\n // #NOTE - this function it not called. Can not delete within a create form.\n requestDelete = (id) => {\n return null;\n };\n\n submitMyForm = (values) => {\n //console.log(`form submitted: values`, values);\n this.props.onSubmit(values);\n };\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n resetForm = (e) => {\n e.preventDefault();\n\n // const width = 15001; // default image dimmensions\n // const height = 10001;\n // const bounds = L.latLngBounds([0, 0], [height, width]);\n // let image = new Image(width, height);\n // // image.src = \"boo!\";\n\n // this.setState({\n // // default to empty image\n // mapFile: \"\",\n // mapUrl: image,\n // bounds: bounds,\n // imageRef1: bounds.getNorthWest(),\n // imageRef2: bounds.getNorthEast(),\n // imageRef3: bounds.getSouthEast(),\n // imageRef4: bounds.getSouthWest(),\n // });\n\n // const initialValues = {\n // name: \"\",\n // ref1: localPts()[0],\n // ref2: localPts()[1],\n // ref3: localPts()[2],\n // ref4: localPts()[3],\n // };\n\n const { initialValues, defaultRefCoords } = this.state;\n const { defaultColor, defaultState, imageInfo, active, order } =\n initialValues;\n const { folderFilesList } = this.props;\n\n initialiseValues(\n defaultColor,\n defaultState,\n imageInfo,\n defaultRefCoords,\n folderFilesList,\n active,\n order\n )\n .then((values) => {\n //console.log(\"initialValues\", values);\n this.setState({ ...values });\n // initialize() is a prop provided by reduxForm, that can be used to fill up the form values.\n // Note - enableReinitialize: true,\n this.props.initialize(values);\n this.setState({ contentLoading: false });\n this.setState(values);\n })\n .catch((err) => {\n this.setState({ errorMessage: err });\n this.setState({ contentLoading: false });\n });\n\n //console.log(\"setInitialValues\", setInitialValues);\n\n // initialize() is a prop provided by reduxForm, that can be used to fill up the form values.\n // Note - enableReinitialize: true,\n //this.props.initialize(setInitialValues);\n //this.props.reset();\n\n //this.setState(setInitialValues);\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // abort page changes\n this.props.onCancel();\n };\n\n handleColorClick = () => {\n this.setState({ displayColorPicker: !this.state.displayColorPicker });\n };\n\n handleColorClose = () => {\n this.setState({ displayColorPicker: false });\n };\n\n handleColorChange = (color) => {\n this.setState({ backgroundColor: color.rgb });\n this.props.change(\"backgroundColor\", color.rgb);\n\n let imageInfo = this.state.imageInfo;\n imageInfo.backgroundColor = color.rgb;\n this.props.change(\"imageInfo\", imageInfo);\n };\n\n handleOrderChange = (e, data) => {\n this.props.change(\"order\", data);\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n //reset,\n strings,\n allAreaIds,\n } = this.props;\n\n const {\n //id,\n //mapFile,\n mapUrl,\n bounds,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n } = this.state;\n\n //console.log(\"MineLevelCreateForm mapUrl, bounds,\", mapUrl, bounds);\n\n const stylesColorPicker = reactCSS({\n default: {\n color: {\n width: \"36px\",\n height: \"14px\",\n borderRadius: \"2px\",\n background: `rgba(${this.state.backgroundColor.r}, ${this.state.backgroundColor.g}, ${this.state.backgroundColor.b}, ${this.state.backgroundColor.a})`,\n },\n group: {\n alignItems: \"center\",\n display: \"flex\",\n },\n label: {\n fontWeight: \"bold\",\n paddingRight: \"10px\",\n fontSize: \".92857143em\", //#NOTE #HACK - FFS why it is so hard to inherit font sizes??!\n },\n\n swatch: {\n padding: \"5px\",\n background: \"#fff\",\n borderRadius: \"1px\",\n boxShadow: \"0 0 0 1px rgba(0,0,0,.1)\",\n display: \"inline-block\",\n cursor: \"pointer\",\n },\n popover: {\n position: \"absolute\",\n zIndex: \"2\",\n },\n cover: {\n position: \"fixed\",\n top: \"0px\",\n right: \"0px\",\n bottom: \"0px\",\n left: \"0px\",\n },\n },\n });\n\n const refLocationsComponent = (\n
\n \n {[\n [\"ref1point\", imageRef1, \"imageRef1\", \"blue\"],\n [\"ref2point\", imageRef2, \"imageRef2\", \"blue\"],\n [\"ref3point\", imageRef3, \"imageRef3\", \"blue\"],\n [\"ref4point\", imageRef4, \"imageRef4\", \"blue\"],\n ].map(([key, position, id, color], idx) => (\n \n

Reference {idx + 1}

\n

\n Pixel Coord: {parseInt(position.lat)},{parseInt(position.lng)}\n

\n \n ))}\n \n {/* Information confusing to user\n
Ref 1 Pixel: {JSON.stringify(imageRef1)}
\n
Ref 2 Pixel: {JSON.stringify(imageRef2)}
*/}\n\n {/* REVIEW - pads between image and save button - huge hack - fix the spacing */}\n
\n
\n );\n\n const allowedLightColors = _allowedLightColors();\n const orderOptions = [...allAreaIds, \"new\"]?.map((area, idx) => {\n return { key: idx + 1, value: idx + 1, text: idx + 1 };\n });\n\n const isCollapse = this.state.collapse;\n const { contentLoading } = this.state;\n\n if (contentLoading) {\n return (\n \n Loading data\n \n );\n } else {\n return (\n
\n \n \n \n \n
Area
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {/* ***************Create Form ************************ */}\n {error && (\n \n )}\n\n \n \n \n \n {isCollapse && (\n \n \n \n \n \n \n \n }\n />\n \n \n \n \n )}\n {!isCollapse && (\n <>\n \n \n \n \n
Add Area
\n
\n \n \n \n \n }\n />\n \n
\n \n \n \n normalise(value, \"name\")\n }\n />\n \n \n \n {/* \n \n */}\n \n \n \n \n
\n
\n {error && (\n \n )}\n\n \n
{strings?.[\"Light Settings\"]}
\n\n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n {strings?.[\"Area Message Header\"]}\n \n {strings?.[\"Area Message Content\"]}\n \n \n \n \n \n
\n\n \n \n \n \n \n
\n
\n \n \n
\n
\n
\n {this.state.displayColorPicker ? (\n
\n \n \n
\n ) : null}\n
\n
\n \n \n \n \n
\n
\n
\n \n
\n {strings?.[\"Map Reference Markers\"]}\n
\n \n \n \n \n \n {strings?.[\"Easting\"]}\n \n \n {strings?.[\"Northing\"]}\n \n \n {strings?.[\"Letter\"]}\n \n \n {strings?.[\"Number\"]}\n \n \n \n {this.createRefTable()}\n
\n
\n \n )}\n
\n \n \n \n \n {/* \n \n */}\n \n \n \n \n \n \n this.resetForm(e)}\n >\n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n \n
{strings?.[\"Map\"]}
\n {refLocationsComponent}\n
\n
\n
\n
\n \n\n \n
\n
\n );\n }\n }\n}\n\nconst selector = formValueSelector(\"createNewMineLevelForm\");\n\nCreateMineLevelForm = reduxForm({\n form: \"createNewMineLevelForm\",\n // Note - to reinitialize values in componentDidMount\n // Make sure you set the values of enableReinitialize & keepDirtyOnReinitialize to true\n // See - https://stackoverflow.com/questions/44273099/redux-form-initialization-with-props-initialize\n //enableReinitialize: true,\n //keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(CreateMineLevelForm);\n\nconst mapStateToProps = (state, props) => {\n //const id = props.id;\n\n // collect an array of existing area ids to validate against new area name\n const allAreaStatuses = getAllAreaStatuses(state);\n const allAreaIds = allAreaStatuses.map((item) => item.id);\n\n // Render issue - with each heartbeat the STATE updates which causes localPts to be updated and so resets the map state\n // See console.log below - note grab action is cancelled when the time changes.\n //console.log(\"ggg render issue ref1\", ref1, new Date(Date.now()));\n // See - shouldComponentUpdate\n\n return {\n mineLevelId: selector(state, \"id\"),\n allAreaIds,\n folderFilesList: getFolderFileNamesListById(state, \"areas\"),\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"reduxForm onChange values\", values);\n //const areaRegion = calculateAreaRegion(values);\n //console.log(\"lll areaRegion\", areaRegion);\n },\n reduxFormValues: getFormValues(\"createNewMineLevelForm\")(state), // #REVIEW - only used for debugging,\n };\n};\n\nCreateMineLevelForm = connect(mapStateToProps, { deleteMineLevel, push })(\n CreateMineLevelForm\n);\n\nexport default CreateMineLevelForm;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { saveNewMineLevel, fetchMineLevels } from \"MineLevels/actions\";\n\nimport CreateMineLevelForm from \"./MineLevelCreateForm\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nimport { fetchFolderFilesListByFolder } from \"components/Settings/actions\";\n\nimport { messageToken } from \"utils/messageToken\";\nimport { mqttPublish } from \"components/WebWorker/actions\";\n\nimport {\n SubmissionError,\n stopSubmit,\n startSubmit,\n //\n} from \"redux-form\";\n\nimport { Dimmer, Loader } from \"semantic-ui-react\";\n\nclass CreateMineLevel extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n\n componentDidMount() {\n const { allAreas, goto } = this.props;\n\n // If no areas data is loaded redirect to area list\n // this is typically when the the page is F5 reloaded.\n // Can't operate without area data.\n //\n\n // #REVIEW - disable this for Adding new Areas. In the case of 1st installation there will be no\n // areas except for the defaultArea, but the defaultArea is excluded from State\n // see \" if (area !== \"defaultArea\") {\" ... src/components/WebWorker/reducer.js\n //\n // This check is intended to prevent issues with slow load/accumulation of data (esp. over MQTT) when the\n // page is reloaded, however this may not be an issue if/when the area updates are done via POST.\n // e.g. schenario. Direct page load on 'http://localhost:3000/admin/area/new'\n\n //\n if (false) {\n console.log(\"componentDidMount checkDataOk allAreas\", allAreas);\n const checkDataOk = _isEmpty(allAreas);\n if (checkDataOk) {\n goto(\"/admin/area\");\n }\n }\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n const { mineLevel, goto } = this.props;\n\n // If no areas data is loaded redirect to area list\n // this is typically when the the page is F5 reloaded.\n // Can't operate without area data.\n //\n const checkDataOk = _isEmpty(mineLevel);\n if (checkDataOk) {\n goto(\"/admin/area\");\n }\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n submitMyForm = (values) => {\n //console.log(`submitMyForm values`, values);\n\n const {\n saveNewMineLevel,\n startSubmit,\n stopSubmit,\n fetchMineLevels,\n fetchFolderFilesListByFolder,\n } = this.props;\n\n // set namedAreaGroup to values\n // this is done outside of the form because namedAreaGroup is maintained elsewhere - see `src/admin/named-area-group/NamedAreaGroup.js`\n const newValues = { ...values, namedAreaGroup: JSON.stringify({}) };\n\n // #NOTE - submit is managed manually in this process.\n // Start and Stop submit is used.\n\n return new Promise((resolve, reject) => {\n startSubmit();\n saveNewMineLevel({ values: newValues, resolve, reject });\n })\n .then((result) => {\n console.log(`saveNewMineLevel onSubmit SUCESSFULL! `, result);\n stopSubmit({});\n this.setState(\n {\n submitted: true,\n },\n () => {\n console.log(\"CLEAR ALL SYSTEM EVENTS - system/event/clear\");\n // after namedAreaGroup has changed, clear the existing events.\n //\n // #WIP\n // - this needs to change to clear only defined AREAS\n // - change to API which can be resolved\n // -\n this.props.mqttPublish({\n topic: `system/event/clear`,\n qos: 0,\n message: {\n clear_events: true,\n token: messageToken(),\n },\n retained: false,\n });\n\n this.onResetError();\n // After saving the area return to control screen.\n // #NOTE - aside from a more logical UX, this has the additional benefit that\n // users return to area edit via the MineLevelList which updated the state,\n // especially the `folderFilesList` which takes time to update/return.\n //\n\n fetchFolderFilesListByFolder();\n fetchMineLevels();\n this.props.goto(\"/admin/area\");\n }\n );\n })\n .catch((error) => {\n console.log(`onSubmit failed `, error);\n this.onSetError(`${error}`);\n stopSubmit({});\n });\n };\n\n render() {\n const { error, submitting, strings } = this.props;\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n if (error) {\n return (\n <>\n \n \n );\n }\n\n return (\n <>\n this.onResetError()}\n errorMessage={errorMessage}\n />\n \n Saving changes\n \n this.submitMyForm(formValues)}\n />\n this.submitMyForm(values)}\n // #NOTE - onSubmitSuccess is not defined.\n // This is managed through submitMyForm.\n\n onSubmitFail={(errors) => {\n console.log(`onSubmitFail errors`, errors);\n }}\n onCancel={() => {\n this.props.goto(\"/admin/area\");\n }}\n strings={strings}\n />\n \n );\n }\n}\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n saveNewMineLevel: (data) => dispatch(saveNewMineLevel(data)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n stopSubmit: (errors) => {\n dispatch(stopSubmit(\"createNewMineLevelForm\", errors));\n },\n startSubmit: (errors) => {\n dispatch(startSubmit(\"createNewMineLevelForm\"));\n },\n fetchMineLevels: () => {\n dispatch(fetchMineLevels());\n },\n fetchFolderFilesListByFolder: () => {\n dispatch(fetchFolderFilesListByFolder());\n },\n mqttPublish: (msg) => dispatch(mqttPublish(msg)),\n };\n};\n\nfunction mapStateToProps(state, props) {\n const allAreas = getAllAreaStatuses(state);\n\n return {\n allAreas, // only used to check if content loaded\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(CreateMineLevel);\n","import React, { Component, useDebugValue } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Form,\n Container,\n Label,\n Header,\n Grid,\n Message,\n Segment,\n Table,\n Icon,\n Popup,\n Dimmer,\n Loader,\n Dropdown,\n Button,\n GridRow,\n GridColumn,\n} from \"semantic-ui-react\";\nimport { SketchPicker } from \"react-color\";\nimport reactCSS from \"reactcss\";\n\nimport { renderSelect, renderRadio } from \"admin/form-field\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport {\n Field,\n reduxForm,\n formValueSelector,\n SubmissionError,\n getFormValues,\n isDirty,\n} from \"redux-form\";\nimport { push } from \"react-router-redux\";\n\nimport L, { bounds } from \"leaflet\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport _isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\n\nimport ImageUpload from \"admin/mine-level/ImageUpload\";\n\nimport MapWithImage from \"components/Map/MapWithImage\";\nimport { MineLevelMapById } from \"components/Map/MineLevelMap\";\n\nimport MapMarker from \"components/ColorableMapMarker\";\nimport getSemanticColor from \"colorpalette\";\nimport { localPts } from \"components/Map/referencePoints\";\n\nimport { deleteMineLevel, fetchMineLevels } from \"MineLevels/actions\";\nimport { fetchFolderFilesListByFolder } from \"components/Settings/actions\";\n\nimport { renderField } from \"admin/form-field\";\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport FlashMessagesList from \"FlashMessages\";\nimport { reset } from \"testdouble\";\n\nimport { LeastSquaresApproximationFourPointsSixParametersTransformation } from \"projection\";\n\nimport {\n //initialiseArea, // #NOTE - attempt to make a common separate initial function. Abandoned.\n loadImage,\n loadImgToFile,\n} from \"admin/mine-level/MineLevelInitialiseArea\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\nimport { imageCheck } from \"utils/imageCheck\";\n\nimport {\n allowedLightColors as _allowedLightColors,\n allowedLightStates as _allowedLightStates,\n} from \"components/ConfigJs\";\n\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\nconst validate = (values) => {\n const required = [\n \"name\",\n \"active\",\n \"order\",\n \"defaultColor\",\n \"defaultState\",\n \"mapFile\",\n \"imageInfo.backgroundColor\",\n \"imageInfo\",\n \"ref1.easting\",\n \"ref1.northing\",\n \"ref1.zoneLetter\",\n \"ref1.zoneNum\",\n \"ref2.easting\",\n \"ref2.northing\",\n \"ref2.zoneLetter\",\n \"ref2.zoneNum\",\n \"ref3.easting\",\n \"ref3.northing\",\n \"ref3.zoneLetter\",\n \"ref3.zoneNum\",\n \"ref4.easting\",\n \"ref4.northing\",\n \"ref4.zoneLetter\",\n \"ref4.zoneNum\",\n ];\n\n const errors = {};\n\n required.forEach((r) => {\n if (!get(values, r)) {\n set(errors, r, \"Required\");\n }\n });\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n switch (type) {\n case \"easting\":\n return (value > 0 && Number(value)) || \"\";\n case \"northing\":\n return (value > 0 && Number(value)) || \"\";\n case \"99\":\n return (value < 99 && value > 0 && Number(value)) || \"\";\n case \"char\":\n return (\n (value.match(/^[A-Za-z]+$/) &&\n value.toString().toUpperCase().slice(0, 1)) ||\n \"\"\n );\n default:\n return value;\n }\n};\n\n// calculates the UTM region from the ref points and image\nconst calculateAreaRegion = (values) => {\n const {\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n } = values;\n\n let utmRef = [];\n utmRef.push({ lat: ref1?.easting, lng: ref1?.northing });\n utmRef.push({ lat: ref2?.easting, lng: ref2?.northing });\n utmRef.push({ lat: ref3?.easting, lng: ref3?.northing });\n utmRef.push({ lat: ref4?.easting, lng: ref4?.northing });\n\n let pixelRef = [];\n pixelRef.push({ lat: imageRef1?.lat, lng: imageRef1?.lng });\n pixelRef.push({ lat: imageRef2?.lat, lng: imageRef2?.lng });\n pixelRef.push({ lat: imageRef3?.lat, lng: imageRef3?.lng });\n pixelRef.push({ lat: imageRef4?.lat, lng: imageRef4?.lng });\n\n // the geometric coordinate to map pixel transformation\n const Transform = (localPts, standardPts) => {\n const LeastSq4Pt =\n LeastSquaresApproximationFourPointsSixParametersTransformation.fromPoints(\n localPts,\n standardPts\n );\n return LeastSq4Pt;\n };\n\n // update region bounds utm points\n const transform = Transform(utmRef, pixelRef); // convert utmRef -> pixelRef\n\n const {\n _northEast: { lat: height, lng: width },\n } = bounds;\n\n // area rectangle has four points\n const southWest = transform.transform({\n lat: 0,\n lng: 0,\n });\n const northEast = transform.transform({\n lat: height,\n lng: width,\n });\n const northWest = { lng: southWest.lng, lat: northEast.lat };\n const southEast = { lng: northEast.lng, lat: southWest.lat };\n\n let boundsArray = [southWest, northWest, northEast, southEast, southWest];\n boundsArray = boundsArray.map((bound) => Object.values(bound).reverse());\n\n // debug.....................\n // console.log(\"lll bounds\", bounds);\n // console.log(\"lll imgBounds\", boundsArray);\n // console.log(\"lll southWest\", Object.values(southWest).reverse());\n // console.log(\"lll northEast\", Object.values(northEast).reverse());\n // console.log(\"lll utmRef\", utmRef);\n // console.log(\"lll pixelRef\", pixelRef);\n\n return boundsArray;\n};\n\nconst prepValues = (\n img,\n imageInfo,\n defaultColor,\n defaultState,\n active,\n order\n) => {\n const { id, ref_coord, imageFile, url } = imageInfo;\n\n const imageSrc = img.src;\n const imageHeight = img.height;\n const imageWidth = img.width;\n const bounds = L.latLngBounds([0, 0], [imageHeight, imageWidth]);\n\n const refObject = (idx) => {\n return {\n easting: ref_coord[idx].utm[0],\n northing: ref_coord[idx].utm[1],\n zoneLetter: ref_coord[idx].utm_zone_letter,\n zoneNum: ref_coord[idx].utm_zone_number,\n lat: ref_coord[idx].image_xy[0],\n lng: ref_coord[idx].image_xy[1],\n };\n };\n const ref1 = refObject(0);\n const ref2 = refObject(1);\n const ref3 = refObject(2);\n const ref4 = refObject(3);\n\n // const imageRef1 = L.latLng({ lat: ref1.lat, lng: ref1.lng });\n const imageRef1 = L.latLng(ref1.lat, ref1.lng);\n const imageRef2 = L.latLng(ref2.lat, ref2.lng);\n const imageRef3 = L.latLng(ref3.lat, ref3.lng);\n const imageRef4 = L.latLng(ref4.lat, ref4.lng);\n\n const values = {\n id: id,\n name: id,\n active: active,\n order: order,\n defaultColor: defaultColor,\n defaultState: defaultState,\n mapFile: imageFile,\n imageInfo: imageInfo,\n mapUrl: imageSrc,\n bounds: bounds,\n imageRef1: imageRef1,\n imageRef2: imageRef2,\n imageRef3: imageRef3,\n imageRef4: imageRef4,\n ref1: ref1,\n ref2: ref2,\n ref3: ref3,\n ref4: ref4,\n areaRegion: [],\n };\n\n values.areaRegion = calculateAreaRegion(values);\n\n return values;\n};\n\nconst initialiseValues = async (\n id,\n imageInfo,\n image_filename,\n ref_coord,\n defaultColor,\n defaultState,\n folderFilesList,\n active,\n order\n) => {\n // get filename before date code\n const filenameArray = image_filename.split(\"-\");\n const newFilename = `${filenameArray[0]}.png`;\n\n // console.log(\n // `IMAGE> folderFilesList, image_filename, imageInfo`,\n // folderFilesList,\n // image_filename,\n // imageInfo\n // );\n\n const url = imageCheck(folderFilesList, image_filename, imageInfo);\n\n let newImageInfo = {};\n newImageInfo.id = id;\n newImageInfo.width = imageInfo?.width;\n newImageInfo.height = imageInfo?.height;\n newImageInfo.ref_coord = ref_coord;\n newImageInfo.url = url;\n\n // color picker\n newImageInfo.backgroundColor = imageInfo.backgroundColor;\n\n //console.log(`IMAGE> newImageInfo.url`, newImageInfo.url);\n\n return new Promise((resolve, reject) => {\n // let imageFile;\n\n loadImgToFile(url, newFilename)\n .catch((err) => {\n throw err;\n })\n .then((result) => {\n newImageInfo.imageFile = result;\n loadImage(url)\n .then((img) => {\n resolve({\n errorMessage: \"\",\n ...prepValues(\n img,\n newImageInfo,\n defaultColor,\n defaultState,\n active,\n order\n ),\n });\n })\n .catch((err) => {\n console.error(`initialiseValues loadImage ${err}`);\n reject(err);\n });\n })\n .catch((err) => {\n console.log(\"initialiseValues error\", err);\n\n // NOTE: the following code is a repetition of above to acommodate the situation where an image\n // can't be loaded off the server, and instead we load the default.png.\n // i.e. something has to load to resume population of all other parameters for the mine level.\n // Allows the user to change the image, delete the mine level or do something else....\n\n //# REVIEW - this is ugly ugly ugly but at the time I struggled to see an easier way?!!\n\n if (err === 404) {\n // load default image\n\n const newFilename = \"default.png\"; // default image fallback\n\n // ...old...\n // Directly load fixed size image\n //const url = process.env.PUBLIC_URL + \"/areas/\" + newFilename;\n\n // create a replacement image using known dimensions\n let canvas = document.createElement(\"canvas\");\n\n // set desired size of transparent image\n canvas.width = newImageInfo.width;\n canvas.height = newImageInfo.height;\n\n // extract as new image (data-uri)\n const url = canvas.toDataURL();\n newImageInfo.url = url;\n\n return loadImgToFile(url, newFilename)\n .catch((err) => {\n throw err;\n })\n .then((result) => {\n newImageInfo.imageFile = result;\n })\n .then(\n loadImage(url)\n .then((img) => {\n resolve({\n errorMessage:\n \"404. Failed to load area image. Displaying default blank image. Reload the page, check the server contents, or select (and save) a replacement image.\",\n ...prepValues(\n img,\n newImageInfo,\n defaultColor,\n defaultState\n ),\n });\n })\n .catch((err) => {\n console.log(`initialiseValues loadImage ${err}`);\n reject(err);\n })\n );\n } else {\n console.log(`initialiseValues ${err}`);\n reject(err);\n }\n });\n });\n};\n\nclass EditMineLevelForm extends Component {\n constructor(props) {\n super(props);\n this.state = {\n contentLoading: true,\n errorMessage: \"\",\n id: props.id,\n name: \"\",\n defaultColor: \"green\",\n defaultState: \"on\",\n mapFile: \"\",\n imageInfo: {\n width: \"\",\n height: \"\",\n backgroundColor: { r: 255, g: 255, b: 255, a: 1 },\n },\n mapUrl: \"\",\n bounds: [],\n imageRef1: {},\n imageRef2: {},\n imageRef3: {},\n imageRef4: {},\n ref1: {},\n ref2: {},\n ref3: {},\n ref4: {},\n areaRegion: [],\n // color picker\n displayColorPicker: false,\n backgroundColor: {\n r: 255,\n g: 255,\n b: 255,\n a: 1,\n },\n active: false,\n order: 0,\n //\n initialValues: {\n _action: \"\", // used to control dlg display\n name: \"\",\n defaultColor: \"green\",\n defaultState: \"on\",\n mapFile: \"\",\n backgroundColor: {\n r: 255,\n g: 255,\n b: 255,\n a: 1,\n },\n imageInfo: {\n width: \"\",\n height: \"\",\n backgroundColor: { r: 255, g: 255, b: 255, a: 1 },\n },\n mapUrl: \"\",\n bounds: [],\n imageRef1: {},\n imageRef2: {},\n imageRef3: {},\n imageRef4: {},\n ref1: {},\n ref2: {},\n ref3: {},\n ref4: {},\n areaRegion: [],\n active: true,\n order: 0,\n },\n //\n collapse: false,\n //\n testImageUrl: \"\",\n //\n submitted: false,\n };\n }\n\n componentDidMount() {\n const { theInitialValues, folderFilesList } = this.props;\n const {\n id,\n imageInfo,\n image_filename,\n ref_coord,\n defaultColor,\n defaultState,\n active,\n order,\n } = theInitialValues;\n\n // set state for color picker\n if (imageInfo?.backgroundColor !== undefined) {\n this.setState({ backgroundColor: imageInfo.backgroundColor });\n }\n\n // console.log(`IMAGE> --------------------`);\n // console.log(`IMAGE> newValues imageInfo`, imageInfo);\n // console.log(`IMAGE> newValues folderFilesList`, folderFilesList);\n // console.log(`IMAGE> newValues image_filename`, image_filename);\n\n initialiseValues(\n id,\n imageInfo,\n image_filename,\n ref_coord,\n defaultColor,\n defaultState,\n folderFilesList,\n active,\n order\n )\n .then((values) => {\n this.setState({ ...values, initialValues: { ...values } });\n // initialize() is a prop provided by reduxForm, that can be used to fill up the form values.\n // Note - enableReinitialize: true,\n\n // console.log(`this.props.initialize(values)`);\n // console.log(`props.initialize initialize values`, values);\n // console.log(`props.initialize initialize props`, this.props);\n\n this.props.initialize(values);\n this.props.reset();\n\n this.setState({ contentLoading: false });\n })\n .catch((err) => {\n this.setState({ errorMessage: err });\n this.setState({ contentLoading: false });\n });\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n const check =\n !_isEqual(this.props.formValues, nextProps.formValues) ||\n !_isEqual(this.state, nextState);\n\n return check;\n }\n\n svgMarkerIcon = (text, color) => {\n return (\n \n \n \n \n {text}\n \n \n );\n };\n\n onFieldChanged = () => {\n console.log(\"lll FieldChanged!\");\n // update area region calculation\n const {\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n } = this.state;\n\n const areaRegion = calculateAreaRegion({\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n });\n console.log(\"areaRegion\", areaRegion);\n this.props.change(\"areaRegion\", areaRegion);\n this.setState({ areaRegion: areaRegion });\n };\n\n createRefTable = () => {\n const colObjRef = [\"easting\", \"northing\", \"zoneLetter\", \"zoneNum\"];\n const colLabel = [\"easting\", \"northing\", \"zone letter\", \"zone number\"];\n const colType = [\"easting\", \"northing\", \"char\", \"99\"];\n const colFieldType = [\"number\", \"number\", \"text\", \"number\"];\n\n const rows = 4;\n const cols = 4; // 1st column is marker icon\n\n let table = [];\n\n // Outer loop to create parent\n for (let i = 0; i < rows; i++) {\n let children = [];\n //Inner loop to create children\n for (let j = 0; j < cols; j++) {\n children.push(\n \n console.log(\"Field value\", value)}\n onBlur={() => this.onFieldChanged()}\n normalize={(value) => normalise(value, colType[j])}\n type={colFieldType[j]}\n />\n \n );\n }\n //Create the parent and add the children\n table.push(\n \n \n
{this.svgMarkerIcon(i + 1, \"#2185D0\")}
\n
\n {children}\n
\n );\n }\n return table;\n };\n\n onMapChanged = (file, url) => {\n if (!file) {\n return;\n }\n // console.log(\"file\", file);\n // console.log(\"url\", url);\n\n const { bounds: currentBounds } = this.state;\n\n // console.log(\"onMapChanged currentBounds\", currentBounds);\n\n this.setState({ contentLoading: true });\n\n loadImage(url)\n .then((img) => {\n console.log(`LOADIMAGE ${img.src} `);\n console.log(`LOADIMAGE DIMMENSIONS W: ${img.width} | H: ${img.height}`);\n\n const src = img.src;\n const height = img.height;\n const width = img.width;\n\n // console.log(\"onMapChanged file\", file);\n // console.log(\"onMapChanged url\", url);\n\n // change the filename by resaving image\n const blob = file.slice(0, file.size, \"image/png\");\n const filename = file.name;\n let newFilename = filename.replace(\"-\", \"\"); // strip out all '-' as used to parse loaded files\n // newFilename = newFilename.replace(\n // \".png\",\n // `-[${img.width},${img.height}].png`\n // );\n\n const newFile = new File([blob], newFilename, {\n type: \"image/png\",\n });\n\n const imageInfo = {\n width: width,\n height: height,\n backgroundColor: this.state.backgroundColor,\n };\n\n // console.log(\"onMapChanged newFilename\", newFilename);\n // console.log(\"onMapChanged newFile\", newFile);\n // console.log(\"onMapChanged imageInfo\", imageInfo);\n\n const bounds = L.latLngBounds([0, 0], [height, width]);\n\n // console.log(\"onMapChanged bounds\", bounds);\n\n this.setState({\n mapFile: newFile,\n imageInfo: imageInfo,\n mapUrl: src,\n });\n\n this.props.change(\"mapFile\", newFile);\n this.props.change(\"imageInfo\", imageInfo);\n this.props.change(\"mapUrl\", src);\n\n if (!_isEqual(currentBounds, bounds)) {\n const imageRef1 = bounds.getNorthWest();\n const imageRef2 = bounds.getNorthEast();\n const imageRef3 = bounds.getSouthEast();\n const imageRef4 = bounds.getSouthWest();\n\n // console.log(\"onMapChanged imageRef1\", imageRef1);\n // console.log(\"onMapChanged imageRef2\", imageRef2);\n // console.log(\"onMapChanged imageRef3\", imageRef3);\n // console.log(\"onMapChanged imageRef4\", imageRef4);\n\n // update form props for new imageRefs\n this.props.change(\"imageRef1\", imageRef1);\n this.props.change(\"imageRef2\", imageRef2);\n this.props.change(\"imageRef3\", imageRef3);\n this.props.change(\"imageRef4\", imageRef4);\n\n this.setState({\n bounds: bounds,\n // reference to bottom left corner\n // image ref 1 is top left\n imageRef1: imageRef1,\n imageRef2: imageRef2,\n imageRef3: imageRef3,\n imageRef4: imageRef4,\n });\n }\n\n this.setState({ contentLoading: false });\n })\n .catch((err) => console.error(`loadImage ${err}`));\n\n // this.props.change(\"mapFile\", file);\n // var that = this;\n // var img = new Image();\n\n // img.onload = function () {\n // const { width, height } = this;\n // const bounds = L.latLngBounds([0, 0], [height, width]);\n // const imageRef1 = bounds.getNorthWest();\n // const imageRef2 = bounds.getNorthEast();\n // const imageRef3 = bounds.getSouthEast();\n // const imageRef4 = bounds.getSouthWest();\n\n // // update form props for new imageRefs\n // that.props.change(\"imageRef1\", imageRef1);\n // that.props.change(\"imageRef2\", imageRef2);\n // that.props.change(\"imageRef3\", imageRef3);\n // that.props.change(\"imageRef4\", imageRef4);\n\n // that.setState({\n // mapFile: file,\n // mapUrl: url,\n // bounds: bounds,\n // // reference to bottom left corner\n // // image ref 1 is top left\n // imageRef1: imageRef1,\n // imageRef2: imageRef2,\n // imageRef3: imageRef3,\n // imageRef4: imageRef4,\n // });\n // console.log(\"onMapChanged bounds\", bounds);\n\n // that.setState({ contentLoading: false });\n // };\n // img.src = url;\n };\n\n onDragEnded(id, newLocation) {\n if (this.state.bounds.contains(newLocation)) {\n this.props.change(id, newLocation);\n this.setState({ [id]: newLocation });\n\n // update area region calculation\n const {\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n } = this.state;\n\n const areaRegion = calculateAreaRegion({\n bounds,\n ref1,\n ref2,\n ref3,\n ref4,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n });\n\n // console.log(`change onChange areaRegion`, areaRegion);\n // console.log(`change onChange areaRegion this.props`, this.props);\n\n this.props.change(\"areaRegion\", areaRegion);\n this.setState({ areaRegion: areaRegion });\n } else {\n this.setState({ [id]: { ...this.state[id] } });\n }\n }\n\n makeOnDragEnd(id) {\n return ({ target }) => {\n this.onDragEnded(id, target.getLatLng());\n };\n }\n\n // requestDelete_reduxForm = (id) => {\n\n // const { handleSubmit, deleteMineLevel_reduxForm, push } = this.props;\n\n // // handle submit is necessary to trigger error catching\n // handleSubmit(() => {\n // return new Promise((resolve, reject) => {\n // deleteMineLevel_reduxForm({ values: { id }, resolve, reject });\n // })\n // .catch((error) => {\n // console.log(`onSubmit error`, error);\n // // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n // throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n // })\n // .then(\n // () => {\n // this.props.goto(\"/admin/area\");\n // },\n // (err) => {\n // throw err;\n // }\n // );\n // });\n // };\n\n requestDelete = (id) => {\n const {\n deleteMineLevel,\n goto,\n change,\n fetchMineLevels,\n fetchFolderFilesListByFolder,\n } = this.props;\n\n //console.log(`deleteFirefly requestDelete`, this.props);\n\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call change to populate the formValue `_action` at the beginning of the delete process.\n // The _action value is checked in the NavigationPromptModal, which does not display.\n change(\"_action\", \"delete\");\n\n return new Promise((resolve, reject) => {\n deleteMineLevel({ values: { id }, resolve, reject });\n }).then(\n () => {\n fetchFolderFilesListByFolder();\n fetchMineLevels();\n //console.log(\"SUCCESS deleteMineLevel area delete\");\n goto(\"/admin/area\");\n },\n (msg) => {\n console.log(\"AREA DELETE FAILED!\", msg); // #TODO probs should show this?\n }\n );\n };\n\n submitMyForm = (values) => {\n //console.log(`form submitted: values`, values);\n this.props.onSubmit(values);\n };\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n resetForm = (e) => {\n e.preventDefault();\n\n // initialize() is a prop provided by reduxForm, that can be used to fill up the form values.\n // Note - enableReinitialize: true,\n const initialValues = this.state.initialValues;\n\n // console.log(`resetForm this.props.initialize(initialValues)`);\n // console.log(\"resetForm initialValues props.initialize(\", initialValues);\n\n this.props.initialize(initialValues);\n this.setState(initialValues);\n\n // Note: use redux-form reset() but the form initial values do not include the reference points\n // this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // abort page changes\n this.props.onCancel();\n };\n\n onResetError = () => {\n //this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n handleColorClick = () => {\n this.setState({ displayColorPicker: !this.state.displayColorPicker });\n };\n\n handleColorClose = () => {\n this.setState({ displayColorPicker: false });\n };\n\n handleColorChange = (color) => {\n this.setState({ backgroundColor: color.rgb });\n this.props.change(\"backgroundColor\", color.rgb);\n\n let imageInfo = this.state.imageInfo;\n imageInfo.backgroundColor = color.rgb;\n this.props.change(\"imageInfo\", imageInfo);\n };\n\n handleDefaultColorChange = (e, data) => {\n // console.log(`handleDefaultColorChange`, data);\n if (data === \"off\") {\n this.props.change(\"defaultState\", \"off\");\n }\n };\n\n handleDefaultStateChange = (e, data) => {\n // console.log(`handleDefaultStateChange`, data);\n if (data === \"off\") {\n this.props.change(\"defaultColor\", \"off\");\n }\n };\n\n handleOrderChange = (e, data) => {\n this.props.change(\"order\", data);\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n //reset,\n //deleteMineLevel,\n strings,\n allAreaIds,\n } = this.props;\n\n // display section if STROBE, FORWARD, BACKWARDS\n const { isStateStrobe, isStateForwardBackward } = this.props;\n\n const {\n id,\n //mapFile,\n mapUrl,\n bounds,\n imageRef1,\n imageRef2,\n imageRef3,\n imageRef4,\n //submitted,\n } = this.state;\n\n const stylesColorPicker = reactCSS({\n default: {\n color: {\n width: \"36px\",\n height: \"14px\",\n borderRadius: \"2px\",\n background: `rgba(${this.state.backgroundColor.r}, ${this.state.backgroundColor.g}, ${this.state.backgroundColor.b}, ${this.state.backgroundColor.a})`,\n },\n group: {\n alignItems: \"center\",\n display: \"flex\",\n },\n label: {\n fontWeight: \"bold\",\n paddingRight: \"10px\",\n fontSize: \".92857143em\", //#NOTE #HACK - FFS why it is so hard to inherit font sizes??!\n },\n\n swatch: {\n padding: \"5px\",\n background: \"#fff\",\n borderRadius: \"1px\",\n boxShadow: \"0 0 0 1px rgba(0,0,0,.1)\",\n display: \"inline-block\",\n cursor: \"pointer\",\n },\n popover: {\n position: \"absolute\",\n zIndex: \"2\",\n },\n cover: {\n position: \"fixed\",\n top: \"0px\",\n right: \"0px\",\n bottom: \"0px\",\n left: \"0px\",\n },\n },\n });\n\n const refLocationsComponent = (\n
\n \n {[\n [\"ref1point\", imageRef1, \"imageRef1\", \"blue\"],\n [\"ref2point\", imageRef2, \"imageRef2\", \"blue\"],\n [\"ref3point\", imageRef3, \"imageRef3\", \"blue\"],\n [\"ref4point\", imageRef4, \"imageRef4\", \"blue\"],\n ].map(([key, position, id, color], idx) => (\n \n

Reference {idx + 1}

\n

\n Pixel Coord: {parseInt(position.lat)},{parseInt(position.lng)}\n

\n \n ))}\n \n {/* Information confusing to user\n
Ref 1 Pixel: {JSON.stringify(imageRef1)}
\n
Ref 2 Pixel: {JSON.stringify(imageRef2)}
*/}\n\n {/* REVIEW - pads between image and save button - huge hack - fix the spacing */}\n
\n
\n );\n\n const allowedLightColors = _allowedLightColors();\n const allowedLightStates = _allowedLightStates();\n const orderOptions = allAreaIds?.map((area, idx) => {\n return { key: idx + 1, value: idx + 1, text: idx + 1 };\n });\n\n const isCollapse = this.state.collapse;\n\n const { contentLoading } = this.state;\n\n const { errorMessage } = this.state;\n\n // #NOTE - disabled SubmissionModal\n // Cleanup should delete or enable this again\n\n const openModal = false; //errorMessage !== \"\";\n\n if (openModal) {\n return (\n this.onResetError()}\n errorMessage={errorMessage}\n />\n );\n } else if (contentLoading) {\n return (\n \n Loading data\n \n );\n } else {\n return (\n
\n \n \n \n \n
Area
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {/* ***************Edit Form ************************ */}\n {error && (\n \n )}\n\n \n \n \n \n {isCollapse && (\n \n \n \n \n \n \n \n }\n />\n \n \n \n \n )}\n {!isCollapse && (\n <>\n \n \n \n \n
\n {strings?.[\"Edit Area\"]}\n
\n
\n \n \n \n \n }\n />\n \n
\n \n \n \n \n \n \n {/* \n \n */}\n \n \n \n \n
\n
\n {errorMessage && (\n \n \n \n\n \n Error\n {errorMessage}\n \n \n \n )}\n \n
{strings?.[\"Light Settings\"]}
\n \n \n \n \n \n \n\n \n \n \n \n {/* {false && \n \n {isStateStrobe && (\n
\n \n normalise(value, \"off_time\")\n }\n component={renderField}\n />\n \n normalise(value, \"on_time\")\n }\n component={renderField}\n />\n
\n )}\n {isStateForwardBackward && (\n
\n \n normalise(value, \"train\")\n }\n component={renderField}\n />\n
\n )}\n
} */}\n \n \n \n \n \n {strings?.[\"Area Message Header\"]}\n \n {strings?.[\"Area Message Content\"]}\n \n \n \n
\n
\n
\n \n
{strings?.[\"Map Settings\"]}
\n \n \n \n \n
\n
\n \n \n
\n
\n
\n {this.state.displayColorPicker ? (\n
\n \n \n
\n ) : null}\n
\n
\n \n \n \n \n
\n
\n
\n \n
\n {strings?.[\"Map Reference Markers\"]}\n
\n\n \n \n \n \n \n {strings?.[\"Easting\"]}\n \n \n {strings?.[\"Northing\"]}\n \n \n {strings?.[\"Letter\"]}\n \n \n {strings?.[\"Number\"]}\n \n \n \n {this.createRefTable()}\n
\n
\n \n )}\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n this.resetForm(e)}\n >\n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n\n \n
{strings?.[\"Map\"]}
\n {refLocationsComponent}\n
\n
\n
\n
\n \n \n
\n
\n );\n }\n }\n}\n\nconst selector = formValueSelector(\"editMineLevelForm\");\n\nEditMineLevelForm = reduxForm({\n form: \"editNewMineLevelForm\",\n // Note - to reinitialize values in componentDidMount\n // Make sure you set the values of enableReinitialize & keepDirtyOnReinitialize to true\n // See - https://stackoverflow.com/questions/44273099/redux-form-initialization-with-props-initialize\n\n // #NOTE\n // @17Jun21 - disabled the following lines because caused immediate reinitialisation of the form, but there is\n // a problem with the initial state so it loaded a blank form.\n //\n // The reprecussions are that the form now loads as a dirty form - why?\n //\n\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(EditMineLevelForm);\n\nconst mapStateToProps = (state, props) => {\n const id = props.id;\n\n // collect an array of existing area ids to validate against new area name\n const allAreaStatuses = getAllAreaStatuses(state);\n const allAreaIds = allAreaStatuses.map((item) => item.id);\n\n // Render issue - with each heartbeat the STATE updates which causes localPts to be updated and so resets the map state\n // See console.log below - note grab action is cancelled when the time changes.\n //console.log(\"ggg render issue ref1\", ref1, new Date(Date.now()));\n // See - shouldComponentUpdate\n\n const stateValue = selector(state, \"defaultState\");\n const isStateStrobe = [\"strobe\", \"forward\", \"backward\"].includes(stateValue);\n const isStateForwardBackward = [\"forward\", \"backward\"].includes(stateValue);\n\n return {\n id,\n allAreaIds,\n folderFilesList: getFolderFileNamesListById(state, \"areas\"),\n isStateStrobe,\n isStateForwardBackward,\n //shouldError: () => isDirty(\"editNewMineLevelForm\")(state),\n formValues: getFormValues(\"editNewMineLevelForm\")(state),\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"onChange reduxForm previousValues\", previousValues);\n //console.log(\"onChange reduxForm newValues\", values);\n //console.log(\"onChange reduxForm props\", props);\n //const areaRegion = calculateAreaRegion(values);\n //console.log(\"onChange areaRegion\", areaRegion);\n },\n };\n};\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n deleteMineLevel: (data) => dispatch(deleteMineLevel(data)),\n fetchMineLevels: () => {\n dispatch(fetchMineLevels());\n },\n fetchFolderFilesListByFolder: () => {\n dispatch(fetchFolderFilesListByFolder());\n },\n };\n};\n\nEditMineLevelForm = connect(\n mapStateToProps,\n mapDispatchToProps\n)(EditMineLevelForm);\n\nexport default EditMineLevelForm;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\n\nimport {\n SubmissionError,\n //\n getFormValues,\n getFormInitialValues,\n getFormSyncErrors,\n getFormMeta,\n getFormAsyncErrors,\n getFormSyncWarnings,\n getFormSubmitErrors,\n getFormError,\n getFormNames,\n isDirty,\n isPristine,\n isValid,\n isInvalid,\n isSubmitting,\n hasSubmitSucceeded,\n hasSubmitFailed,\n stopSubmit,\n startSubmit,\n} from \"redux-form\";\n\nimport { Container, Dimmer, Loader, Message } from \"semantic-ui-react\";\nimport { min } from \"date-fns\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { getAreaById, getAllAreaStatuses } from \"components/WebWorker/reducer\";\n\n//import CreateMineLevelForm from \"./MineLevelCreateForm\";\nimport EditMineLevelForm from \"./MineLevelEditForm\";\n\nimport SubmissionModal from \"admin/SubmissionModal\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { saveNewMineLevel, fetchMineLevels } from \"MineLevels/actions\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { fetchFolderFilesListByFolder } from \"components/Settings/actions\";\n\nimport { messageToken } from \"utils/messageToken\";\nimport { mqttPublish } from \"components/WebWorker/actions\";\n\nclass EditMineLevel extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n\n componentDidMount() {\n const { mineLevel, goto } = this.props;\n\n // If no areas data is loaded redirect to area list\n // this is typically when the the page is F5 reloaded.\n // Can't operate without area data.\n //\n const checkDataOk = _isEmpty(mineLevel);\n if (checkDataOk) {\n goto(\"/admin/area\");\n }\n\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n //this.props.fetchFolderFilesListByFolder(\"areas\");\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n submitMyForm = (values) => {\n //console.log(`submitMyForm values`, values);\n\n const {\n namedAreaGroup,\n saveNewMineLevel,\n stopSubmit,\n startSubmit,\n fetchMineLevels,\n fetchFolderFilesListByFolder,\n } = this.props;\n\n // restore namedAreaGroup to values\n // this is done outside of the form because namedAreaGroup is maintained elsewhere - see `src/admin/named-area-group/NamedAreaGroup.js`\n const newValues = {\n ...values,\n namedAreaGroup: JSON.stringify(namedAreaGroup),\n };\n\n // #NOTE - submit is managed manually in this process.\n // Start and Stop submit is used.\n\n return new Promise((resolve, reject) => {\n startSubmit();\n saveNewMineLevel({ values: newValues, resolve, reject });\n })\n .then((result) => {\n console.log(`saveNewMineLevel onSubmit SUCESSFULL! `, result);\n stopSubmit({});\n this.setState(\n {\n submitted: true,\n },\n () => {\n console.log(\"CLEAR ALL SYSTEM EVENTS - system/event/clear\");\n // after namedAreaGroup has changed, clear the existing events.\n //\n // #WIP\n // - this needs to change to clear only defined AREAS\n // - change to API which can be resolved\n // -\n this.props.mqttPublish({\n topic: `system/event/clear`,\n qos: 0,\n message: {\n clear_events: true,\n token: messageToken(),\n },\n retained: false,\n });\n\n this.onResetError();\n // After saving the area return to control screen.\n // #NOTE - aside from a more logical UX, this has the additional benefit that\n // users return to area edit via the MineLevelList which updated the state,\n // especially the `folderFilesList` which takes time to update/return.\n //\n fetchFolderFilesListByFolder();\n fetchMineLevels();\n\n this.props.goto(\"/admin/area\");\n }\n );\n })\n .catch((error) => {\n console.log(`onSubmit failed `, error);\n this.onSetError(`${error}`);\n stopSubmit({});\n });\n };\n\n render() {\n const {\n id,\n namedAreaGroup,\n saveNewMineLevel,\n updateMineLevel,\n error,\n initialValues,\n submitting,\n strings,\n } = this.props;\n\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n if (error) {\n return (\n <>\n \n \n \n );\n }\n\n return (\n <>\n this.onResetError()}\n errorMessage={errorMessage}\n />\n \n Saving changes\n \n this.submitMyForm(formValues)}\n />\n {\n // this.submitMyForm(values);\n // console.log(`onSubmit out`);\n // }}\n\n onSubmit={(values) => {\n this.submitMyForm(values);\n }}\n // #NOTE - onSubmitSuccess is not defined.\n // This is managed through submitMyForm.\n\n onSubmitFail={(errors, dispatch, submitError, props) => {\n console.log(`onSubmitFail errors`, errors);\n //console.log(`onSubmitFail submitError`, submitError);\n //console.log(`onSubmitFail props`, props);\n }}\n onCancel={() => {\n this.props.goto(\"/admin/area\");\n }}\n strings={strings}\n />\n \n );\n }\n}\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n saveNewMineLevel: (data) => dispatch(saveNewMineLevel(data)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n stopSubmit: (errors) => {\n dispatch(stopSubmit(\"editMineLevelForm\", errors));\n },\n startSubmit: () => {\n dispatch(startSubmit(\"editMineLevelForm\"));\n },\n fetchMineLevels: () => {\n dispatch(fetchMineLevels());\n },\n fetchFolderFilesListByFolder: () => {\n dispatch(fetchFolderFilesListByFolder());\n },\n mqttPublish: (msg) => dispatch(mqttPublish(msg)),\n };\n};\n\n//export default connect(null, { updateMineLevel })(EditMineLevel);\n\nfunction mapStateToProps(state, props) {\n const match = props.match;\n const id = match.params.id;\n\n const mineLevel = getAreaById(state, id); // getMineLevelById(state, id);\n\n //console.log(\"xxx mineLevel\", mineLevel);\n\n // set default case if mineLevel is undefined.\n // This can happen when returning from a deleting mine level action\n let imageInfo = {\n width: \"\",\n height: \"\",\n backgroundColor: { r: 255, g: 255, b: 255, a: 1 },\n };\n let image_filename = \"\";\n let ref_coord = {};\n let defaultColor = \"green\"; // #REVIEW #TODO - move default setups to get from server/application state\n let defaultState = \"on\";\n let namedAreaGroup = {};\n let order = 0;\n let active = true;\n\n // Note - forcing default if objects undefined is repetitive.\n // remove when have `settings `\n\n //console.log(`mineLevel imageInfo`, mineLevel);\n\n if (mineLevel !== undefined) {\n imageInfo = mineLevel.image_info || imageInfo;\n image_filename = mineLevel.image_filename || image_filename;\n ref_coord = mineLevel.ref_coord || ref_coord;\n defaultColor = mineLevel.default_color || defaultColor;\n defaultState = mineLevel.default_state || defaultState;\n namedAreaGroup = mineLevel.namedAreaGroup || namedAreaGroup;\n order = mineLevel.order || order;\n active = mineLevel.active;\n }\n\n const initialValues = {\n id,\n imageInfo,\n image_filename,\n ref_coord,\n defaultColor,\n defaultState,\n order,\n active,\n };\n\n return {\n id,\n error: mineLevel === undefined ? \"Area not found\" : null,\n initialValues: initialValues, // props passed to redux-form loads these as (predictably), initial values\n namedAreaGroup,\n //\n mineLevel, // only used to check if content loaded\n\n //\n //values: getFormValues(\"editMineLevelForm\")(state),\n //initialValues: getFormInitialValues(\"editMineLevelForm\")(state),\n //formSyncErrors: getFormSyncErrors(\"editMineLevelForm\")(state),\n //fields: getFormMeta(\"editMineLevelForm\")(state),\n //formAsyncErrors: getFormAsyncErrors(\"editMineLevelForm\")(state),\n //syncWarnings: getFormSyncWarnings(\"editMineLevelForm\")(state),\n //submitErrors: getFormSubmitErrors(\"editMineLevelForm\")(state),\n //formError: getFormError(\"editMineLevelForm\")(state),\n //names: getFormNames()(state),\n //dirty: isDirty(\"editMineLevelForm\")(state),\n //pristine: isPristine(\"editMineLevelForm\")(state),\n //valid: isValid(\"editMineLevelForm\")(state),\n //invalid: isInvalid(\"editMineLevelForm\")(state),\n submitting: isSubmitting(\"editMineLevelForm\")(state),\n //submitSucceeded: hasSubmitSucceeded(\"editMineLevelForm\")(state),\n //submitFailed: hasSubmitFailed(\"editMineLevelForm\")(state),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(EditMineLevel);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\n\nimport ListMineLevels from \"admin/mine-level/MineLevelList\";\nimport CreateMineLevel from \"admin/mine-level/MineLevelCreatePage\";\nimport EditMineLevel from \"admin/mine-level/MineLevelEditPage\";\nimport { fetchMineLevels } from \"MineLevels/actions\";\n\nclass MineLevelAdminPages extends Component {\n componentDidMount() {\n // const { fetchMineLevels } = this.props;\n // // #FETCHS\n // fetchMineLevels(); // #FETCHS\n }\n\n render() {\n const { match, strings } = this.props;\n return (\n \n }\n />\n }\n />\n }\n />\n \n );\n }\n}\n\nexport default withRouter(\n connect(null, { fetchMineLevels })(MineLevelAdminPages)\n);\n","import React from \"react\";\n\nimport { Form, Grid, Image, Segment, Header } from \"semantic-ui-react\";\nimport { Field } from \"redux-form\";\nimport { renderField } from \"admin/form-field\";\nimport { Link } from \"react-router-dom\";\n\nexport const tagTrackingUserDetailsCardPersonnel = (\n urlImage,\n tagUserId,\n disabled,\n showDetails\n) => {\n // if the card is 'disabled' it has been 'assigned'\n const cardTitle = showDetails ? (disabled ? (\n \n {`Personnel Assigned`}{\" \"}\n \n ) : (\n \"Details\"\n )) : (\"Details are not accessible.\");\n\n return (\n \n \n \n \n
{cardTitle}
\n
\n
\n {showDetails && (\n \n \n \n \n \n \n \n \n \n {/* */}\n \n )}\n
\n
\n );\n};\n","import React from \"react\";\n\nimport { Form, Grid, Image, Segment, Header } from \"semantic-ui-react\";\nimport { Field } from \"redux-form\";\nimport { renderField } from \"admin/form-field\";\nimport { Link } from \"react-router-dom\";\nimport { minValueEqual, maxValueEqual } from \"utils/normalise\";\n\n// range limits\nconst minValueEqual0 = minValueEqual(0); // ? \"out of range\" : undefined;\nconst maxValueEqual25 = maxValueEqual(25); // #NOTE - arbitrary value\n\n// do not check for 0 as falsy\nconst required = (value) => (value !== \"\" ? undefined : \"Required\");\nconst validate = (values) => {\n const errors = {};\n return errors;\n};\n\nexport const tagTrackingUserDetailsCardVehicle = (\n urlImage,\n tagUserId,\n disabled\n) => {\n // if the card is 'disabled' it has been 'assigned'\n const cardTitle = disabled ? (\n \n {`Vehicle Assigned`}{\" \"}\n \n ) : (\n \"Details\"\n );\n\n return (\n \n \n \n \n
{cardTitle}
\n
\n
\n \n \n \n \n \n \n \n (value !== \"\" ? parseInt(value) : \"\")}\n className={disabled ? \"disabled-form-field\" : null}\n disabled={disabled}\n />\n \n \n \n
\n
\n );\n};\n","import Immutable from \"seamless-immutable\";\n\nimport {\n transformGeoJsonUtmToPixels,\n transformGeoJsonUtmToPixelsByChangeList,\n} from \"components/Map/util-geoJsonToPixels\";\n\nconst initialState = Immutable({\n tagsObject: {},\n areaStatuses: {},\n tagCoordinates: {},\n //\n // tag users\n tagPersonnel: [],\n tagVehicles: [],\n});\n\nconst makeGeoJson = (object) => {\n return { type: \"FeatureCollection\", features: Object.values(object) };\n};\n\nfunction updateTagObjectStatus(tagsObject, newData, status) {\n //console.log(`DEBUG - updateTagObjectStatus`, newData);\n\n let newTagObjects = { ...tagsObject };\n let newTagObject = newTagObjects[newData.id];\n if (newTagObject) {\n newTagObject = {\n ...newTagObject,\n status: status,\n last_updated: newData.reported_ts,\n };\n newTagObjects[newData.id] = newTagObject;\n }\n return newTagObjects || {};\n}\n\nfunction updateTagCoordStatus(tagsCoords, newData, status) {\n //console.log(`DEBUG - updateTagCoordStatus`, newData);\n\n let newTagCoords = { ...tagsCoords };\n let newTagCoord = newTagCoords[newData.id];\n if (newTagCoord) {\n newTagCoord = {\n ...newTagCoord,\n };\n newTagCoord.properties.status = status;\n newTagCoord.properties.last_updated = newData.reported_ts;\n newTagCoords[newData.id] = newTagCoord;\n }\n return newTagCoords || {};\n}\n\nfunction updateTagsObject(tagsObject, newData, status) {\n // console.log(\"updateTagsObject tagsObject\", tagsObject);\n // console.log(\"updateTagsObject newData\", newData);\n\n let newTagsObject = { ...tagsObject }; // clone it\n let newTagObject = newTagsObject[newData.id]; // create a keyed object\n\n // tag already exists...update it\n if (newTagObject) {\n newTagObject = {\n ...newTagObject,\n\n coord: newData.coord_to,\n locations: newData.locations_to,\n status: status,\n last_updated: newData.reported_ts,\n };\n } // new tag ... make new\n else {\n newTagObject = {\n id: newData.id,\n mac: newData.mac,\n calculated_rssi: newData.calculated_rssi,\n coord: newData.coord_to,\n locations: newData.locations_to,\n status: status,\n last_updated: newData.reported_ts,\n //\n tag_id: 1,\n type: \"unknown\",\n user_info: null,\n vehicle_info: null,\n };\n }\n newTagsObject[newData.id] = newTagObject;\n return newTagsObject;\n}\n\nfunction makeTagCoordFeature(newTag) {\n\n const {\n id,\n mac,\n coord,\n calculated_rssi,\n last_updated,\n locations,\n tagId,\n tagUserId,\n tagUserType,\n userInfo,\n vehicleInfo,\n zones,\n status,\n area,\n } = newTag;\n\n // default startup coordinate\n let tempCoords = Object.values({\n x: 0,\n y: 0,\n });\n\n if (coord) {\n tempCoords = Object.values(coord);\n }\n\n const newTagFeature = {\n id: id,\n type: \"Feature\",\n geometry: { type: \"Point\", coordinates: tempCoords },\n properties: {\n id: id,\n area,\n zone: zones,\n\n calculated_rssi,\n last_updated,\n locations,\n tagId,\n mac,\n tagUserId,\n tagUserType,\n userInfo,\n vehicleInfo,\n\n easting: coord?.x,\n northing: coord?.y,\n utm_zone_number: 0,\n utm_zone_letter: \"\",\n z: 0,\n\n status: status,\n },\n };\n\n return newTagFeature;\n}\n\nexport default function reduce(state = initialState, action = {}) {\n const newState = { ...state };\n const { type, payload } = action;\n\n switch (type) {\n // sends a copy of the areaStatuses to tags to allow it to do transforms on coordinates\n // for update messages\n //\n case \"TAGS_FETCH_AREA_STATUSES\":\n // console.log(\n // `fetchTagTrackingAreaStatuses TAGS_UPDATE_AREA_STATUSES`,\n // payload\n // );\n\n // convert to keyed object\n let newAreaStatuses = {};\n payload.forEach((area) => (newAreaStatuses[area.id] = area));\n\n newState.areaStatuses = newAreaStatuses;\n\n // console.log(\n // `############### TAGS_FETCH_AREA_STATUSES newAreaStatuses`,\n // newAreaStatuses\n // );\n\n return newState;\n\n case \"TAGS_FETCH_SUCCEEDED\":\n // fetches original state of the tags via api/areas/current\n // Subsequent updates are via websocket connection\n\n console.log(`tagTracking TAGS_FETCH_SUCCEEDED payload`, payload);\n\n // if there are no tags it returns 'null'\n const tags = payload.map((tag) => {\n let tagUserType = \"unknown\";\n let tagUserId = 0;\n if (tag?.vehicle) {\n tagUserId = tag.vehicle.id;\n tagUserType = \"vehicle\";\n }\n // #NOTE - can't be both so default to personnel if exists\n if (tag?.user) {\n tagUserId = tag.user.id;\n tagUserType = \"personnel\";\n }\n\n const {\n id,\n coord,\n calculated_rssi,\n last_updated,\n locations,\n tag_id: tagId,\n user: userInfo,\n vehicle: vehicleInfo,\n zones,\n status,\n } = tag;\n\n // #WIP - leave this first code in place for the moment...?\n\n // #Note - Area is derived from the locations, rather than Zone so tags\n // plot even if they are not in a zone\n // There must be a FF to know the location.\n // Support tag locations in multiple Areas.\n // this is possible if a controller is setup with a different Area\n // with firefly in multiple area detecting a common tag\n let derivedAreas = locations.map(\n (location) => location.split(\":\")?.[0]\n );\n\n return {\n id,\n mac: id, // set mac to rx ID\n coord,\n calculated_rssi,\n last_updated,\n locations,\n tagId,\n tagUserId,\n userInfo,\n vehicleInfo,\n tagUserType,\n zones: [...new Set(zones)], // unique zone names\n status: status,\n area: [...new Set(derivedAreas)], // unique areas\n };\n });\n\n // convert tag into indexed object\n // this is easier to update TAG_UPDATE as just target object key\n //\n // #NOTE - the tag id is a combination of area and tag mac b/c\n // tags could appear in multiple areas\n //\n let tagsObject = {};\n tags.forEach((tag) => {\n const { area: areas, zones } = tag;\n areas.forEach((area) => {\n // define new id based on area and mac\n const newTagId = `${area}~${tag.id}`;\n // filter out zones not in the derived area\n const newZones = zones.filter((zone) => zone.area === area);\n\n tagsObject[newTagId] = {\n ...tag,\n id: newTagId,\n area: area,\n zones: newZones,\n };\n });\n });\n\n // console.log(\n // \"tagTracking - TAGS_FETCH_SUCCEEDED tags\",\n // tags,\n // tagsObject,\n // new Date().getTime()\n // );\n\n newState.tagsObject = tagsObject || {};\n\n // ====================================================\n\n let newTagFeatures = {};\n // setup coordinate geoJson\n for (const key in tagsObject) {\n const tag = tagsObject[key];\n\n // #REVIEW - protects against undefined tag for key.\n // This occassionaly happens - WHY?\n //\n if (tag) {\n newTagFeatures[tag.id] = makeTagCoordFeature(tag);\n }\n }\n\n //console.log(`############### newTagFeatures`, newTagFeatures);\n\n const newTagCoordinatesToTransform = {\n type: \"FeatureCollection\",\n features: Object.values(newTagFeatures),\n };\n\n const tempTransformedCoords = transformGeoJsonUtmToPixels(\n newTagCoordinatesToTransform,\n newState.areaStatuses,\n 1,\n false\n );\n\n // save transformed geoJson as a keyed object\n let newTagCoordinates = {};\n const tempTransformedCoordsFeatures = tempTransformedCoords.features;\n tempTransformedCoordsFeatures.forEach(\n (tag) => (newTagCoordinates[tag.id] = tag)\n );\n\n newState.tagCoordinates = newTagCoordinates;\n\n return newState;\n // \"TAG_UPDATE\"\n case \"TAG_UPDATE\":\n // tag updates via websocket connection\n // TAG_UPDATE with one of the following INITIAL, LOST, CHANGE, UNKNOWN\n // ZONE_UPDATE with one of the following CHANGE\n\n console.log(\"tagTracking - TAG_UPDATE tags\", payload);\n\n const { type } = payload;\n\n switch (type) {\n case \"INITIAL\":\n console.log(\"tagTracking - TAG_UPDATE INITIAL tags\", payload);\n // cater for new tag inserted into the system\n // update 'defaultTagObject'\n\n // split tag CHANGE message for different AREAs into separate 'payloads'\n const INITIAL_locations_to = payload.locations_to || [];\n let INITIAL_derivedAreas = INITIAL_locations_to.map(\n (location) => location.split(\":\")?.[0]\n );\n INITIAL_derivedAreas = [...new Set(INITIAL_derivedAreas)];\n\n let newInitialPayload = [];\n INITIAL_derivedAreas.forEach((area) => {\n // define new id based on area and mac\n const newTagId = `${area}~${payload.mac}`;\n // filter out zones not in the derived area\n const newZones = payload.zones?.filter?.(\n (zone) => zone.area === area\n );\n\n newInitialPayload.push({\n ...payload,\n id: newTagId,\n area: area,\n zones: newZones,\n });\n });\n\n console.log(\n \"tagTracking - TAG_UPDATE INITIAL newInitialPayload\",\n newInitialPayload\n );\n\n newInitialPayload.forEach((payload) => {\n const newInitialTagsObject = updateTagsObject(\n newState.tagsObject,\n payload,\n \"initial\"\n );\n\n //#WIP - split to multiple areas\n\n newState.tagsObject = newInitialTagsObject;\n\n let newInitialTagCoordinates = { ...newState.tagCoordinates };\n newInitialTagCoordinates[payload.id] = makeTagCoordFeature(\n newInitialTagsObject[payload.id]\n );\n\n // convert previous and current to feature collections\n const newInitialTagCoordinatesToTransform =\n transformGeoJsonUtmToPixelsByChangeList(\n newState.tagCoordinates, // feature object\n makeGeoJson(newInitialTagCoordinates), // geoJson object\n [payload.id],\n newState.areaStatuses\n );\n\n // save transformed geoJson as a keyed object\n let initialChangedTagCoordinates = {};\n const newInitialTagCoordinatesToTransformFeatures =\n newInitialTagCoordinatesToTransform.features;\n newInitialTagCoordinatesToTransformFeatures.forEach(\n (tag) => (initialChangedTagCoordinates[tag.id] = tag)\n );\n\n newState.tagCoordinates = initialChangedTagCoordinates || {};\n });\n\n console.log(\n \"tagTracking - TAG_UPDATE INITIAL newState.tagCoordinates\",\n newState.tagCoordinates\n );\n\n break;\n case \"LOST\":\n console.log(\"tagTracking - TAG_UPDATE LOST tags\", payload);\n\n // split tag CHANGE message for different AREAs into separate 'payloads'\n const LOST_locations_to = payload.locations_to || [];\n let LOST_derivedAreas = LOST_locations_to.map(\n (location) => location.split(\":\")?.[0]\n );\n LOST_derivedAreas = [...new Set(LOST_derivedAreas)];\n\n let newLostPayload = [];\n LOST_derivedAreas.forEach((area) => {\n // define new id based on area and mac\n const newTagId = `${area}~${payload.mac}`;\n // filter out zones not in the derived area\n const newZones = payload.zones?.filter?.(\n (zone) => zone.area === area\n );\n\n newLostPayload.push({\n ...payload,\n id: newTagId,\n area: area,\n zones: newZones,\n });\n });\n\n console.log(\n \"tagTracking - TAG_UPDATE LOST newLostPayload\",\n newLostPayload\n );\n\n newLostPayload.forEach((payload) => {\n newState.tagsObject = updateTagObjectStatus(\n newState.tagsObject,\n payload,\n \"lost\"\n );\n\n newState.tagCoordinates = updateTagCoordStatus(\n newState.tagCoordinates,\n payload,\n \"lost\"\n );\n });\n\n break;\n case \"CHANGE\":\n console.log(\"tagTracking - TAG_UPDATE CHANGE tags\", payload);\n\n // split tag CHANGE message for different AREAs into separate 'payloads'\n const CHANGE_locations_to = payload.locations_to || [];\n let CHANGE_derivedAreas = CHANGE_locations_to.map(\n (location) => location.split(\":\")?.[0]\n );\n CHANGE_derivedAreas = [...new Set(CHANGE_derivedAreas)];\n\n let newChangePayload = [];\n CHANGE_derivedAreas.forEach((area) => {\n // define new id based on area and mac\n const newTagId = `${area}~${payload.mac}`;\n // filter out zones not in the derived area\n const newZones = payload.zones?.filter?.(\n (zone) => zone.area === area\n );\n\n newChangePayload.push({\n ...payload,\n id: newTagId,\n area: area,\n zones: newZones,\n });\n });\n\n // console.log(\n // \"tagTracking - TAG_UPDATE CHANGE newChangePayload\",\n // newChangePayload\n // );\n\n newChangePayload.forEach((payload) => {\n const newChangeTagsObject = updateTagsObject(\n newState.tagsObject,\n payload,\n \"change\"\n );\n\n newState.tagsObject = newChangeTagsObject;\n\n let newTagCoordinates = { ...newState.tagCoordinates };\n\n let newTagCoordinate = newTagCoordinates[payload.id];\n if (newTagCoordinate) {\n newTagCoordinate = {\n ...newTagCoordinate,\n };\n console.log(\n \"tagTracking - TAG_UPDATE CHANGE newTagCoordinate\",\n newTagCoordinate\n );\n\n newTagCoordinate.geometry.coordinates = Object.values(\n payload.coord_to\n );\n\n // newTagCoordinate.geometry.coordinates = Object.values({\n // x: 736749.684764485,\n // y: 9549616.990156105,\n // }); //Object.values(coord_to);\n newTagCoordinate.properties.northing = payload.coord_to.x;\n newTagCoordinate.properties.easting = payload.coord_to.y;\n\n newTagCoordinate.properties.locations = payload.locations_to;\n newTagCoordinate.properties.last_updated = payload.reported_ts;\n newTagCoordinates[payload.id] = newTagCoordinate;\n }\n\n // convert previous and current to feature collections\n const tagCoordinatesToTransform =\n transformGeoJsonUtmToPixelsByChangeList(\n newState.tagCoordinates, // feature object\n makeGeoJson(newTagCoordinates), // geoJson object\n [payload.id],\n newState.areaStatuses\n );\n\n // save transformed geoJson as a keyed object\n let changedTagCoordinates = {};\n const tagCoordinatesToTransformFeatures =\n tagCoordinatesToTransform.features;\n tagCoordinatesToTransformFeatures.forEach(\n (tag) => (changedTagCoordinates[tag.id] = tag)\n );\n\n newState.tagCoordinates = changedTagCoordinates || {};\n });\n\n console.log(\n \"tagTracking - TAG_UPDATE CHANGE newState.tagCoordinates\",\n newState.tagCoordinates\n );\n\n break;\n case \"UNKNOWN\":\n break;\n default:\n break;\n }\n\n return newState;\n\n case \"ZONE_UPDATE\":\n console.log(`tagTracking - TAG_UPDATE ZONE_UPDATE payload`, payload);\n\n //{\"mac\":\"ac:23:3f:63:37:43\",\n //\"zones\":[{\"id\":\"Area_Main:e12dbf83-d6ae-49d6-972c-5d3dc4d7876b:1639025597226\",\n //\"area\":\"Area_Main\",\"name\":\"Left\"}],\n // \"reported_ts\":\"2021-12-10T14:00:42.466719583+11:00\"}\n\n // split tag CHANGE message for different AREAs into separate 'payloads'\n const ZONE_UPDATE_locations_to = payload.locations_to || [];\n let ZONE_UPDATE_derivedAreas = ZONE_UPDATE_locations_to.map(\n (location) => location.split(\":\")?.[0]\n );\n ZONE_UPDATE_derivedAreas = [...new Set(ZONE_UPDATE_derivedAreas)];\n\n let newZoneUpdatePayload = [];\n ZONE_UPDATE_derivedAreas.forEach((area) => {\n // define new id based on area and mac\n const newTagId = `${area}~${payload.mac}`;\n // filter out zones not in the derived area\n const newZones = payload.zones?.filter?.((zone) => zone.area === area);\n\n newZoneUpdatePayload.push({\n ...payload,\n id: newTagId,\n area: area,\n zones: newZones,\n });\n });\n\n // console.log(\n // \"tagTracking - TAG_UPDATE CHANGE newChangePayload\",\n // newChangePayload\n // );\n\n newZoneUpdatePayload.forEach((payload) => {\n let newTagsObjectZones = { ...newState.tagsObject };\n let newTagsObjectZone = newTagsObjectZones[payload.id];\n if (newTagsObjectZone) {\n newTagsObjectZone = {\n ...newTagsObjectZone,\n status: \"zone change\",\n zones: payload.zones,\n last_updated: payload.reported_ts,\n };\n newTagsObjectZones[payload.id] = newTagsObjectZone;\n }\n\n newState.tagsObject = newTagsObjectZones || {};\n\n let newTagCoordZones = { ...newState.tagCoordinates };\n let newTagCoordZone = newTagCoordZones[payload.id];\n if (newTagCoordZone) {\n newTagsObjectZone = {\n ...newTagCoordZone,\n };\n newTagsObjectZone.properties.zones = payload.zones;\n newTagsObjectZone.properties.status = \"zone change\";\n newTagsObjectZone.properties.last_updated = payload.reported_ts;\n newTagCoordZones[payload.id] = newTagCoordZone;\n }\n\n newState.tagCoordinates = newTagCoordZones || {};\n });\n\n console.log(\n \"tagTracking - TAG_UPDATE ZONE_UPDATE newState.tagCoordinates\",\n newState.tagCoordinates\n );\n\n return newState;\n\n case \"TAGS_FETCH_ALL_USERS_SUCCEEDED\":\n console.log(`TAGS_FETCH_ALL_USERS_SUCCEEDED`, payload);\n\n // get tags assigned to this tag type\n const tagPersonnelAssignedTags = getTagsAssignedByTagType(\n newState.tagsObject,\n \"personnel\"\n );\n\n // loop the payload the updated the users with the assigned tags\n let tagPersonnel = [];\n tagPersonnel = payload?.map((user) => {\n const assignedTags = tagPersonnelAssignedTags?.filter(\n (tag) => tag.userInfo.id === user.id\n );\n return { ...user, assigned: assignedTags };\n });\n\n //console.log(`TAGS_FETCH_ALL_USERS_SUCCEEDED `, payload, tagPersonnel);\n\n newState.tagPersonnel = tagPersonnel;\n return newState;\n\n case \"TAGS_FETCH_ALL_VEHICLES_SUCCEEDED\":\n console.log(`TAGS_FETCH_ALL_VEHICLES_SUCCEEDED `, payload);\n\n // get tags assigned to this tag type\n const tagVehicleAssignedTags = getTagsAssignedByTagType(\n newState.tagsObject,\n \"vehicle\"\n );\n\n // loop the payload the updated the users with the assigned tags\n let tagVehicles = [];\n tagVehicles = payload?.map((user) => {\n const assignedTags = tagVehicleAssignedTags?.filter(\n (tag) => tag.vehicleInfo.id === user.id\n );\n return { ...user, assigned: assignedTags };\n });\n\n //console.log(`TAGS_FETCH_ALL_VEHICLES_SUCCEEDED `, payload, tagVehicles);\n\n newState.tagVehicles = tagVehicles;\n return newState;\n\n case \"RESET\":\n console.log(\"RESET! - Tags!\");\n return state;\n default:\n return state;\n }\n}\n\nfunction getTagsAssignedByTagType(tagObjects, tagType) {\n return Object.values(tagObjects)?.filter(\n (tag) => tag.tagUserType === tagType\n );\n}\n\nfunction stableOrder(order, items) {\n return Immutable(order.map((k) => items[k]));\n}\n\nexport const getAllTags = (state) => {\n const data = state.tags.tagsObject;\n const keys = Object.keys(data).sort();\n return stableOrder(keys, data);\n};\n\nexport const getAllTagCoordinates = (state) => {\n const data = state.tags.tagCoordinates;\n const keys = Object.keys(data).sort();\n return stableOrder(keys, data);\n};\n\nexport const getTagById = (state, id) => {\n const tags = getAllTags(state, id);\n const result = tags.find((tag) => tag.id === id);\n return result;\n};\n\nexport const getTagPersonnel = (state) => {\n return state.tags.tagPersonnel;\n};\n\nexport const getTagPersonnelById = (state, id) => {\n const data = getTagPersonnel(state, id);\n const result = data.find((tag) => tag.id === id);\n return result;\n};\n\nexport const getTagVehicles = (state) => {\n return state.tags.tagVehicles;\n};\n\nexport const getTagVehicleById = (state, id) => {\n const data = getTagVehicles(state, id);\n const result = data.find((tag) => tag.id === id);\n return result;\n};\n\n// [{ id, type, }]\n// id - for linking to tag records\n// type - to display icons\n//\nexport const getFireflyByTagByPriority = (state, id, priority) => {\n const tagById = getTagById(state, id);\n const result = tagById?.fireflies?.find((ff) => ff.priority === 1);\n return result;\n};\n\nexport const getAllFireflyTagsByPriority = (state, priority) => {\n const allTags = getAllTags(state);\n let fireflyTags = {};\n allTags.forEach((tag) => {\n const fireflyByPriority = getFireflyByTagByPriority(\n state,\n tag.id,\n priority\n );\n const { firefly: fireflyId } = fireflyByPriority;\n\n if (fireflyTags[fireflyId] === undefined) fireflyTags[fireflyId] = [];\n\n const { id, type, userInfo, vehicleInfo } = tag;\n\n let tagEntry = \"?\";\n switch (type) {\n case \"personnel\":\n const { firstname, lastname } = userInfo;\n tagEntry = `${firstname} ${lastname}`;\n break;\n case \"vehicle\":\n const { name, type } = vehicleInfo;\n tagEntry = `${name}`;\n break;\n\n default:\n break;\n }\n\n fireflyTags[fireflyId].push({ id: id, type: type, name: tagEntry });\n });\n\n return fireflyTags;\n};\n\nexport const getTagTrackingFFCoordinatesByTagType = (state, tagType) => {\n //const geoJson = tagTrackingCoordinates;\n const ffCoords = state.webWorker?.general?.fireflyCoordinates || [];\n // deepclone\n const geoJson = JSON.parse(JSON.stringify(ffCoords));\n\n const fireflyTagsByPriority = getAllFireflyTagsByPriority(state, 1);\n\n let newTags = [];\n\n for (const tagsKey in fireflyTagsByPriority) {\n if (tagType === \"all\") {\n newTags[tagsKey] = fireflyTagsByPriority[tagsKey];\n } else {\n newTags[tagsKey] = fireflyTagsByPriority[tagsKey].filter(\n (tag) => tag.type === tagType\n );\n }\n }\n\n //console.log(`xxx fireflyTagsByPriority`, newTags);\n\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n filteredgeojson.features = [];\n\n if (geoJson?.features !== undefined) {\n // create a new feature and properties specifically for tagTracking position markers\n geoJson.features.forEach((feature) => {\n if (newTags?.[feature.id]?.length > 0) {\n const {\n id,\n type,\n geometry,\n properties: {\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_letter,\n utm_zone_number,\n z,\n timestamp, // <---THIS SHOULD BE TAG TIMESTAMP?\n },\n } = feature;\n const newProperties = {\n id,\n area,\n location,\n position,\n easting,\n northing,\n utm_zone_letter,\n utm_zone_number,\n z,\n //\n timestamp,\n //\n tagTracking: newTags[id], // <<--- {}\n tagType: tagType,\n };\n const newFeature = {\n type: type,\n geometry: geometry,\n properties: newProperties,\n };\n\n filteredgeojson.features.push(newFeature);\n }\n });\n } else {\n filteredgeojson.features = [];\n }\n //console.log(`xxxxx filteredgeojson`, filteredgeojson);\n\n return filteredgeojson;\n};\n\nexport const getTagTrackingFFCoordinatesByAreaId = (state, id) => {\n //const geoJson = tagTrackingCoordinates;\n const geoJson = getTagTrackingFFCoordinatesByTagType(state, \"all\");\n\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.area.id === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getTagTrackingFFCoordinatesByAreaIdByTagType = (\n state,\n id,\n type\n) => {\n //const geoJson = tagTrackingCoordinates;\n const geoJson = getTagTrackingFFCoordinatesByTagType(state, type);\n\n //console.log(`tagTrack geoJson`, geoJson);\n\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.area === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\n// ----------------------------------------------------------------\n// tags not based on FF coordinates\nexport const getAllTagTrackingGeoJson = (state) => {\n return makeGeoJson(state.tags.tagCoordinates);\n};\n\nexport const getTagTrackingCoordinatesByAreaId = (state, id) => {\n const geoJson = getAllTagTrackingGeoJson(state);\n\n //console.log(`getTagTrackingCoordinatesByAreaId`, geoJson);\n //console.log(`getTagTrackingCoordinatesByAreaId id`, id);\n\n let filteredgeojson = {};\n filteredgeojson.type = \"FeatureCollection\";\n if (geoJson?.features !== undefined) {\n filteredgeojson.features = geoJson.features.filter(\n (item) => item.properties.area === id\n );\n } else {\n filteredgeojson.features = [];\n }\n return filteredgeojson;\n};\n\nexport const getTagIdsByAreaId = (state, id) => {\n //console.log(`getTagIdsByAreaId getAllTags`, getAllTags(state));\n\n return getAllTags(state)\n .filter((tag) => tag.area === id)\n .map((tag) => tag.id);\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { withRouter, Prompt } from \"react-router\";\n\nimport { push } from \"react-router-redux\";\nimport {\n Form,\n Container,\n Button,\n Popup,\n Icon,\n Segment,\n Header,\n Message,\n Grid,\n Tab,\n Divider,\n Image,\n Table,\n} from \"semantic-ui-react\";\n\nimport AsyncSelect from 'react-select/async';\n\nimport _ from \"lodash\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\nimport { LayersControl } from \"react-leaflet\";\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroupGeoJson\";\nimport { renderField, renderTextArea, renderSelect } from \"admin/form-field\";\nimport { SaveButton } from \"admin/SaveButton\";\nimport isEqual from \"lodash/isEqual\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { tagTrackingUserDetailsCardPersonnel } from \"admin/tag-tracking/TagTrackingUserDetailsCardPersonnel\";\nimport { tagTrackingUserDetailsCardVehicle } from \"admin/tag-tracking/TagTrackingUserDetailsCardVehicle\";\nimport { getTagPersonnel, getTagVehicles } from \"components/Tags/reducer\";\n\nimport { getAllAreasButtonState } from \"../../components/WebWorker/reducer\";\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst tagTypeOptions = [\n {\n key: \"personnel\",\n text: \"Personnel\",\n value: \"personnel\",\n },\n {\n key: \"vehicle\",\n text: \"Vehicle\",\n value: \"vehicle\",\n },\n];\n\n// function MapPositioningDisplay({ mineLevelId, children }) {\n// if (!mineLevelId) {\n// return
No mine level selected
;\n// }\n// return (\n// \n// {children}\n// \n// );\n// }\n\nclass TagTrackingDetailsForm extends Component {\n constructor(props) {\n super(props);\n this.state = {\n collapse: false,\n errorMessage: \"\",\n isAssigned: true,\n };\n }\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n componentDidMount() {\n this.setState({ isAssigned: this.props.initialValues?.tagUserId > 0 });\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (\n prevState.tagUserId !== undefined &&\n prevState.tagUserId !== this.props.formValues.tagUserId &&\n this.props.initialValues?.tagUserId > 0\n ) {\n this.setState({ assigned: this.props.formValues.tagUserId });\n }\n }\n\n componentWillUnmount() {\n //console.log(` componentWillUnmount`);\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n // only re-render if the firefly object has changed.\n // This stops re-rendering the map unnecessarily\n\n return (\n !isEqual(this.props.fireflyId, nextProps.fireflyId) ||\n !isEqual(this.props.fireflyNote, nextProps.fireflyNote) ||\n !isEqual(this.props.position, nextProps.position) ||\n !isEqual(this.state.collapse, nextState.collapse) ||\n !isEqual(this.state.errorMessage, nextState.errorMessage) ||\n !isEqual(this.state.tagType, nextState.tagType) ||\n !isEqual(this.props.formValues, nextProps.formValues) ||\n !isEqual(this.props.pristine, nextProps.pristine)\n );\n }\n\n submitMyForm = (values) => {\n // const { saveTagTrackingSettings, fetchTags } = this.props;\n // return new Promise((resolve, reject) => {\n // saveTagTrackingSettings({ values: values, resolve, reject });\n // }).then(() => {\n // // wait for state change before redirecting page\n // this.setState(\n // {\n // submitted: true,\n // },\n // () => {\n // fetchTags(); // #FETCHS\n // this.props.push(`/status/tag/`);\n // }\n // );\n // });\n\n this.props.onSubmit(values);\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n this.props.push(\"/status/tag/\");\n };\n\n requestUnassign = (id) => {\n const { change, tagUserType } = this.props;\n\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call change to populate the formValue `_action` at the beginning of the delete process.\n // The _action value is checked in the NavigationPromptModal, which does not display.\n //change(\"_action\", \"delete\"); // 'delete' is an accepted string to bypass the check\n \n this.props.onUnassign({ id, tagUserType });\n\n this.props.change(\"tagUserId\", 0);\n this.setState({ isAssigned: false }); \n };\n\n onResetError = () => {\n const { push, submitting, submitSucceeded } = this.props;\n\n this.setState({ errorMessage: \"\" });\n\n // if we've just submit the form -> leave\n if (submitting || submitSucceeded) {\n push(\"/\");\n }\n };\n\n onChangeSelectUserType = (evt, data) => {\n //console.log(`onChangeSelectUserType`, data);\n\n this.props.change(\"tagUserType\", data);\n };\n\n onChangeSelectUser = (evt, data) => {\n //console.log(`onChangeSelectUser`, data);\n\n // key = 0 is default \"No .... defined\" entry\n if (data > 0) {\n this.props.change(\"tagUserId\", data);\n this.props.change(\"_action\", \"assign\");\n }\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n error,\n reset,\n //\n id,\n tagUserId,\n tagUserType,\n allowToShowDetails,\n formValues,\n tagPersonnelSelectOptions,\n tagVehicleSelectOptions,\n strings,\n } = this.props;\n\n const { collapse: isCollapse, isAssigned } = this.state;\n\n const imageFilenameUnknown = \"tag-unknown.png\";\n const imageFilenameUser = \"avatar-construction.png\";\n const imageFilenameVehicle = \"avatar-dump-truck.png\";\n\n const urlImageUnknown =\n process.env.PUBLIC_URL + \"/images/\" + imageFilenameUnknown;\n const urlImagePersonnel =\n process.env.PUBLIC_URL + \"/images/\" + imageFilenameUser;\n const urlImageVehicle =\n process.env.PUBLIC_URL + \"/images/\" + imageFilenameVehicle;\n\n // const panes = [\n // {\n // menuItem: \"Position\",\n // render: () => (\n // \n // \n // \n // {fireflyId}\n // \n // \n // \n // \n // \n // \n // \n // \n // ),\n // },\n // {\n // menuItem: \"Latest Report\",\n // render: () => (\n // {/* */}\n // ),\n // },\n // ];\n\n //console.log(`xxxxxxxxxxxx formValues`, formValues);\n //console.log(`xxxxxxxxxxxx id`, id);\n\n const tagUserOptions = (tagUserType) => {\n switch (tagUserType) {\n case \"personnel\":\n return tagPersonnelSelectOptions;\n case \"vehicle\":\n return tagVehicleSelectOptions;\n default:\n break;\n }\n };\n\n const tagUserImage = (tagUserType) => {\n switch (tagUserType) {\n case \"personnel\":\n return urlImagePersonnel;\n case \"vehicle\":\n return urlImageVehicle;\n default:\n return urlImageUnknown;\n }\n };\n\n const tagId = formValues?.tagId; // #NOTE - need to pass the integer Id for the tag for unassign (not the mac)\n\n const loadUserOptions = async searchText => {\n return new Promise((resolve, reject) => {\n const options = tagUserOptions(tagUserType);\n const filtered = options.filter((o) => o.text.toLowerCase().includes(searchText.toLowerCase())); \n resolve(filtered);\n });\n };\n\n const onUserSelect = option => {\n if (option !== undefined) {\n this.onChangeSelectUser(null, option.key)\n }\n }\n \n return (\n <>\n \n {error &&
{error}
}\n
\n \n \n \n {isCollapse && (\n \n \n \n \n \n \n \n }\n />\n \n \n \n \n )}\n {!isCollapse && (\n <>\n \n \n \n \n
{\"Tag\"}
\n
\n \n \n \n \n }\n />\n \n
\n
\n
\n\n {false && (\n \n \n \n )}\n \n )}\n\n {/* \n \n \n \n Reset\n \n */}\n
\n\n \n \n \n \n \n {isAssigned && (\n this.requestUnassign(tagId)}\n id={id}\n color=\"orange\"\n >\n {strings?.[\"Unassign\"]}\n \n }\n />\n )}\n \n \n \n \n \n \n \n \n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n\n {/* */}\n \n
\n
\n
\n \n
\n \n );\n }\n}\n\nconst selector = formValueSelector(\"tagTrackingDetailsForm\");\n\nTagTrackingDetailsForm = reduxForm({\n form: \"tagTrackingDetailsForm\",\n enableReinitialize: false,\n keepDirtyOnReinitialize: false,\n touchOnChange: true,\n})(TagTrackingDetailsForm);\n\nconst mapStateToProps = (state, props) => {\n const tagPersonnel = getTagPersonnel(state);\n\n let tagPersonnelSelectOptions = tagPersonnel?.map((item) => {\n const { id, firstname, lastname } = item;\n return { key: id, text: `${firstname} ${lastname}`, value: id };\n });\n\n if (!tagPersonnelSelectOptions.length)\n tagPersonnelSelectOptions = [\n { key: 0, text: `No personnel defined.`, value: 0 },\n ];\n\n const tagVehicles = getTagVehicles(state);\n let tagVehicleSelectOptions = tagVehicles?.map((item) => {\n const { id, name, type } = item;\n return { key: id, text: `${name} - ${type}`, value: id };\n });\n\n if (!tagVehicleSelectOptions.length)\n tagVehicleSelectOptions = [\n { key: 0, text: `No vehicles defined.`, value: 0 },\n ];\n\n const allowToShowDetails = getAllAreasButtonState(state) !== 0 ? true : false;\n\n return {\n tagUserType: selector(state, \"tagUserType\"),\n tagPersonnelSelectOptions: tagPersonnelSelectOptions,\n tagVehicleSelectOptions: tagVehicleSelectOptions,\n allowToShowDetails,\n\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"xxxxxxxxxxx onChange values\", values);\n //console.log(\"xxxxxxxxxxx onChange props\", props);\n },\n formValues: getFormValues(\"tagTrackingDetailsForm\")(state), // #REVIEW - only used for debugging,\n };\n};\n\nTagTrackingDetailsForm = withRouter(\n connect(mapStateToProps, { push })(TagTrackingDetailsForm)\n);\n\nexport default TagTrackingDetailsForm;\n","import React, { PureComponent } from \"react\";\nimport { push } from \"react-router-redux\";\n\nimport { Container, Header, Grid } from \"semantic-ui-react\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { connect } from \"react-redux\";\n\nimport TagTrackingDetailsForm from \"admin/tag-tracking/TagTrackingDetailsForm\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport { getTagById } from \"components/Tags/reducer\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport {\n assignUser,\n assignVehicle,\n unassignUser,\n unassignVehicle,\n fetchTags,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n} from \"components/Tags/actions\";\n\nclass TagTrackingEditPage extends PureComponent {\n constructor(props) {\n super(props);\n this.state = {\n submitted: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n console.log(`TagTrackingEditPage - componentDidMount`);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n assignVehicle = (values) => {\n return new Promise((resolve, reject) => {\n this.props.assignVehicle({\n values,\n resolve,\n reject,\n });\n });\n };\n\n unassignVehicle = (values) => {\n return new Promise((resolve, reject) => {\n this.props.unassignVehicle({\n values,\n resolve,\n reject,\n });\n });\n };\n\n assignPersonnel = (values) => {\n return new Promise((resolve, reject) => {\n this.props.assignUser({\n values,\n resolve,\n reject,\n });\n });\n };\n\n unassignPersonnel = (values) => {\n return new Promise((resolve, reject) => {\n this.props.unassignUser({\n values,\n resolve,\n reject,\n });\n });\n };\n\n submitMyForm = (values) => {\n //console.log(`TagTrackingDetails values`, values);\n\n const { _action, tagId, tagUserType, id, tagUserId } = values;\n\n let promiseArray = [];\n\n switch (_action) {\n case \"assign\":\n switch (tagUserType) {\n case \"personnel\":\n promiseArray.push(\n this.assignPersonnel({ id: tagId, user_id: tagUserId })\n );\n break;\n case \"vehicle\":\n promiseArray.push(\n this.assignVehicle({ id: tagId, vehicle_id: tagUserId })\n );\n break;\n default:\n break;\n }\n\n break;\n\n default:\n break;\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"UPDATING TAG DETAILS\", results);\n })\n .then(\n () => {\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n this.props.fetchTags(); // #FETCHS\n this.props.fetchAllTagUsers();\n this.props.fetchAllTagVehicles();\n this.props.push(`/status/tag/`); \n }\n );\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n unassignId = async ({id, tagUserType }) => {\n //console.log(`unassignId id`, id);\n\n let promiseArray = [];\n\n switch (tagUserType) {\n case \"personnel\":\n promiseArray.push(this.unassignPersonnel({ id }));\n break;\n case \"vehicle\":\n promiseArray.push(this.unassignVehicle({ id }));\n break;\n default:\n break;\n }\n\n try {\n const results = await Promise.all(promiseArray); \n console.log(\"SUCCESS TagTrackingEditPage unassignTag\", results); this.props.fetchTags(); \n } catch (error) {\n console.log(`ERROR TagTrackingEditPage unassignTag error`, error);\n } \n };\n\n render() {\n const { id, mac, error, push, tagData, strings } = this.props;\n const { submitted } = this.state;\n\n if (error) {\n return (\n <>\n \n \n \n );\n }\n\n // in development page reload will initially have no tagData\n // so return null until componentDidUpdate ...\n if (!tagData) return null;\n\n const {\n calculated_rssi,\n coord,\n last_updated,\n locations,\n tagId,\n tagUserId,\n tagUserType,\n } = tagData;\n\n let tagUserData = {};\n\n switch (tagUserType) {\n case \"personnel\":\n tagUserData = tagData?.userInfo;\n break;\n case \"vehicle\":\n tagUserData = tagData?.vehicleInfo;\n break;\n default:\n break;\n }\n\n return (\n
\n this.submitMyForm(formValues)}\n />\n \n \n \n \n
Tag Details
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n //this.submitMyForm(this._preProcessValues(values))\n this.submitMyForm(values)\n }\n onCancel={() => {\n push(`/status/tag`);\n }}\n onUnassign={(values) => this.unassignId(values)}\n strings={strings}\n />\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const match = props.match;\n const id = match.params.id;\n // derive mac from id. Format is `id~mac`\n const mac = id?.split?.(\"~\")?.[1] || \"\";\n\n return {\n id,\n mac,\n error: \"\", //firefly ? undefined : \"No Firefly for id\",\n tagData: getTagById(state, id),\n };\n};\n\nexport default connect(mapStateToProps, {\n push,\n TurnOnOffPokeTheWorker,\n assignUser,\n assignVehicle,\n unassignUser,\n unassignVehicle,\n fetchTags,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n})(TagTrackingEditPage);\n","export function LogIt(thingsLogged) {\n // console.log(\"LOG_IT - thingsLogged - \", thingsLogged);\n return { type: \"LOG_IT\", payload: thingsLogged };\n}\n\nexport function ClearLog() {\n //console.log(\"LOG_IT action- ClearLog\");\n return { type: \"CLEAR_LOG\" };\n}\n","import React, { Component } from \"react\";\nimport { push } from \"react-router-redux\";\n\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Popup,\n Icon,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport GenericButton from \"admin/GenericButton\";\n\nimport { DateTime } from \"luxon\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { ClearLog } from \"components/Logger/actions\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { getAllAreasButtonState } from \"../../components/WebWorker/reducer\";\n\n// tag specific operations\n//\n\nimport {\n getAllTags,\n getAllTagCoordinates,\n getTagPersonnel,\n getTagVehicles,\n} from \"components/Tags/reducer\";\n\nimport {\n fetchTags,\n unassignUser,\n unassignVehicle,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n} from \"components/Tags/actions\";\n\nimport { fetchAllUsers } from \"components/UserAdmin/actions\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass TagTrackingList extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search id: \"\",\n mac: \"\",\n firefly: \"\",\n rssi: \"\",\n name: \"\",\n vehicle: \"\",\n tagZone: \"\",\n area: \"\",\n tagUserType: \"\",\n status: \"\",\n tagEntry: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"tagsList\"\n );\n\n //console.log(\"filterInput componentDidMount\", filterInput);\n\n if (!_.isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"tagsList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase().includes(match[key].toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n if (!item.disableUnassign) newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n fetchStuff = () => {\n this.props.fetchAllUsers();\n this.props.fetchTags();\n this.props.fetchAllTagUsers();\n this.props.fetchAllTagVehicles();\n };\n\n unassignVehicle = (values) => {\n return new Promise((resolve, reject) => {\n this.props.unassignVehicle({\n values,\n resolve,\n reject,\n });\n });\n };\n\n unassignPersonnel = (values) => {\n return new Promise((resolve, reject) => {\n this.props.unassignUser({\n values,\n resolve,\n reject,\n });\n });\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n\n const { data } = this.props;\n\n let promiseArray = [];\n\n if (action === \"unassign\") {\n for (var key in selections) {\n const selection = key; // mac address\n\n const tagSelection = data?.find((tag) => tag.id === selection);\n const { tagId, tagUserType } = tagSelection;\n\n console.log(`unassign`, tagSelection);\n\n switch (tagUserType) {\n case \"personnel\":\n promiseArray.push(this.unassignPersonnel({ id: tagId }));\n break;\n case \"vehicle\":\n promiseArray.push(this.unassignVehicle({ id: tagId }));\n break;\n\n default:\n break;\n }\n }\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\" .... processed unassign tags\", results);\n })\n .then(\n () => {\n this.props.fetchTags();\n this.props.fetchAllTagUsers();\n this.props.fetchAllTagVehicles();\n this.props.push(`/status/tag`);\n },\n (errorMsg) => {\n console.log(\"action failed\", errorMsg); // #TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n const includeTitles = this.props.includeTitles === \"true\";\n const title = includeTitles ? (\n
{strings?.[\"Tags\"]}
\n ) : (\n
\n );\n\n // APP_TERMINOLOGY\n let strTag = strings?.[\"Tag\"];\n let strTags = strings?.[\"Tags\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n // if enough faults display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const tagUserFromDataById = (id) => allData.find((item) => item.id == id); // falsey\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let unassignButton;\n let tagSelectedList;\n if (selectedCount > 0) {\n let tagNames = [];\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (tagUserFromDataById(key) !== undefined) {\n let tagName = tagUserFromDataById(key).id;\n tagNames.push(tagName);\n }\n }\n tagNames.sort(sortAlphaNum);\n tagNames = tagNames.join(\", \"); // separate by commas\n\n unassignButton = (\n this.requestAction(\"unassign\")}\n />\n );\n\n tagSelectedList = (\n \n \n {strings.formatString(strings?.[`{list_items} selected...`], {\n list_items: strTags,\n })}\n \n {tagNames}\n \n );\n }\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n return (\n
\n \n \n \n \n
{title}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n
\n this.fetchStuff()}\n >\n {itemsCount}\n \n }\n />\n
\n
\n \n \n {!areAnySelected && (\n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n )}\n \n \n {selectedCount} selected\n \n \n {unassignButton}\n
\n
\n \n {strings.formatString(\n strings?.[`{list_length} items displayed`],\n {\n list_length: viewablesPage.length,\n }\n )}\n \n
\n \n {tagSelectedList}\n \n\n \n \n \n \n \n \n \n \n \n {/* \n \n \n \n \n */}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strings?.[\"Tag User\"]}\n \n {/* \n Name\n \n \n Vehicle\n */}\n \n {strings?.[\"Type\"]}\n \n \n {strings?.[\"MAC\"]}\n \n \n {strings?.[\"Zones\"]}\n \n \n {strings?.[\"FireFly\"]}\n \n \n {strings?.[\"RSSI\"]}\n \n \n {strings?.[\"Areas\"]}\n \n \n {strings?.[\"Status\"]}\n \n \n {strings?.[\"Latest Report\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n mac,\n firefly,\n rssi,\n name,\n vehicle,\n tagZone,\n area,\n tagLink,\n tagUserType,\n lastStatusReport,\n disableUnassign,\n status,\n }) => (\n \n \n this.handleSelect(id)}\n disabled={disableUnassign}\n />\n \n {tagLink}\n {/* {name}\n {vehicle} */}\n {tagUserType}\n {mac}\n {tagZone}\n {firefly}\n {rssi}\n {area}\n {status}\n {lastStatusReport}\n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements, coords, tagUsers) => {\n let filteredElements = [];\n\n const { personnel, vehicles, allowToShowDetails } = tagUsers;\n\n // console.log(\n // `tagTracking elements, personnel, vehicles`,\n // elements,\n // personnel,\n // vehicles\n // );\n\n // only need a subset of data\n elements.forEach(function (element, idx) {\n const {\n id,\n mac,\n calculated_rssi: rssi,\n tagId,\n tagUserId,\n tagUserType,\n last_updated: lastUpdated,\n locations,\n area = \"?\",\n zones: tagZones = [\"?\"],\n status,\n } = element;\n\n // #DEBUG - for debugging coordinate points\n // let coordInfo = ``;\n // const coord = coords?.find((coord) => coord.id === id);\n // if (coord) {\n // //console.log(`uuu coords[id]`, coord);\n // const {\n // geometry: { coordinates },\n // properties: { easting, northing },\n // } = coord;\n // coordInfo = `[${northing},${easting}]: [${coordinates.join(\", \")}]`;\n // }\n\n // is it a user _OR_ a vehicle\n let tagEntry = \"?\";\n switch (tagUserType) {\n case \"personnel\":\n if (allowToShowDetails) {\n const tagInfoPersonnel = personnel?.find(\n (info) => info.id === tagUserId\n ) || { firstname: \"\", lastname: \"\" };\n const { firstname, lastname } = tagInfoPersonnel;\n tagEntry = `${firstname} ${lastname}`;\n } else {\n tagEntry = `?`;\n }\n break;\n\n case \"vehicle\":\n const tagInfoVehicle = vehicles?.find((info) => info.id === tagUserId);\n const { name, type } = tagInfoVehicle || { name: \"\", type: \"\" };\n tagEntry = `${name} - ${type}`;\n break;\n\n case \"unknown\":\n tagEntry = `?`; \n break;\n\n default:\n break;\n }\n\n // disable unassign if not yet assigned\n let disableUnassign = tagEntry === \"?\";\n\n // break down lastStatusReport as it may not be defined in object\n let lastStatusReport = \"-\";\n if (lastUpdated) {\n // see - https://moment.github.io/luxon/#/formatting?id=toformat\n lastStatusReport = DateTime.fromISO(lastUpdated).toFormat(\"FF\");\n }\n\n // tagZones\n // e.g. [{id: 'Area_Main:e12dbf83-d6ae-49d6-972c-5d3dc4d7876b:1639025597226', area: 'Area_Main', name: 'Left'}...]\n const tagZone = tagZones?.map((zone) => `${zone.name}`);\n\n // compose new data set\n filteredElements[idx] = {\n id: id,\n mac: mac,\n tagId: tagId,\n disableUnassign: disableUnassign,\n tagLink: {tagEntry} ,\n tagEntry: tagEntry,\n firefly: locations.join(\", \"),\n rssi: rssi.toString(),\n name: tagEntry,\n vehicle: tagEntry,\n tagUserType: tagUserType === \"unknown\" ? \"?\" : tagUserType,\n tagZone: tagZone?.length ? tagZone.join(\", \") : \"?\",\n area: area,\n lastStatusReport,\n status: status?.toUpperCase(),\n };\n });\n\n //console.log(`TagTrackingList filteredElements`, filteredElements);\n\n return filteredElements;\n};\n\nfunction mapStateToProps(state) {\n const tagData = getAllTags(state);\n const tagCoordinates = getAllTagCoordinates(state);\n const tagPersonnel = getTagPersonnel(state);\n const tagVehicles = getTagVehicles(state);\n const allowToShowDetails = getAllAreasButtonState(state) !== 0 ? true : false;\n const data = _prepData(tagData, tagCoordinates, {\n personnel: tagPersonnel,\n vehicles: tagVehicles,\n allowToShowDetails\n });\n\n return {\n data,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n push,\n ClearLog,\n fetchTags,\n fetchAllUsers,\n //\n fetchAllTagUsers,\n fetchAllTagVehicles,\n unassignUser,\n unassignVehicle,\n saveUserSettingsComponentState,\n })(TagTrackingList)\n);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\nimport { fetchFireflys } from \"UPSPanelControllers/actions\";\n\nimport TagTrackingEditPage from \"admin/tag-tracking/TagTrackingEditPage\";\nimport TagTrackingList from \"admin/tag-tracking/TagTrackingList\";\n\nclass TagTrackingAdminPages extends Component {\n render() {\n const { match, strings } = this.props;\n\n return (\n \n (\n \n )}\n />\n (\n \n )}\n />\n \n );\n }\n}\n\nexport default withRouter(\n connect(null, { fetchFireflys })(TagTrackingAdminPages)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport {\n getTagPersonnel,\n getTagVehicles,\n getTagsAssignedByTagUserType,\n} from \"components/Tags/reducer\";\n\nimport {\n deleteTagUserById,\n deleteTagVehicleById,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n} from \"components/Tags/actions\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass TagTrackingUserList extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n tagUser: \"\",\n tagId: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n // const { fetchNamedAreas } = this.props;\n\n // // #FETCHS\n // fetchNamedAreas();// #FETCHS\n\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"tagUsersList\"\n );\n\n //console.log(\"filterInput componentDidMount\", filterInput);\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"tagUsersList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column: rxColumn, direction } = this.state;\n\n // if undefined, default sort to 'tagUser'\n let column = rxColumn; // ? rxColumn : \"tagUser\";\n\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n deleteTagUserById = (values) => {\n return new Promise((resolve, reject) => {\n this.props.deleteTagUserById({\n values,\n resolve,\n reject,\n });\n });\n };\n\n deleteTagVehicleById = (values) => {\n return new Promise((resolve, reject) => {\n this.props.deleteTagVehicleById({\n values,\n resolve,\n reject,\n });\n });\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n\n const { push, tagUserType } = this.props;\n\n let promiseArray = [];\n\n if (action === \"delete\") {\n for (var key in selections) {\n const selection = key;\n\n switch (tagUserType) {\n case \"personnel\":\n promiseArray.push(\n this.deleteTagUserById({ id: Number(selection) })\n );\n break;\n case \"vehicle\":\n promiseArray.push(\n this.deleteTagVehicleById({ id: Number(selection) })\n );\n break;\n\n default:\n break;\n }\n }\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\" .... processed users\", results);\n })\n .then(\n () => {\n this.props.fetchAllTagUsers();\n this.props.fetchAllTagVehicles();\n push(`/status/taguser/${tagUserType}`);\n },\n (errorMsg) => {\n console.log(\"action failed\", errorMsg); // #TODO probs should show this?\n }\n );\n };\n\n render() {\n const {\n isLoading,\n error,\n tagUserType,\n //includeTitles\n strings,\n } = this.props;\n\n // APP_TERMINOLOGY\n let strTagUser = strings?.[\"User\"];\n let strTagUsers = strings?.[\"Users\"];\n\n switch (tagUserType) {\n case \"personnel\":\n strTagUser = strings?.[\"Personnel\"];\n strTagUsers = strings?.[\"Personnel\"];\n break;\n case \"vehicle\":\n strTagUser = strings?.[\"Vehicle\"];\n strTagUsers = strings?.[\"Vehicles\"];\n break;\n case null:\n default:\n break;\n }\n\n const { column, data, direction, filterInput } = this.state;\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const tagUserFromDataById = (id) => allData.find((item) => item.id == id); // falsey\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let enableButton;\n let disableButton;\n let deleteButton;\n let copyButton;\n let tagUserSelectedList;\n if (selectedCount > 0) {\n let tagUserNames = [];\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (tagUserFromDataById(key) !== undefined) {\n let tagUserName = tagUserFromDataById(key).tagUser;\n tagUserNames.push(tagUserName);\n }\n }\n tagUserNames.sort(sortAlphaNum);\n tagUserNames = tagUserNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")}\n strings={strings}\n />\n );\n\n copyButton = (\n this.requestAction(\"copy\")}\n />\n );\n\n tagUserSelectedList = (\n \n \n {strings.formatString(strings?.[`{list_items} selected...`], {\n list_items: strTagUsers,\n })}\n \n\n {tagUserNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
\n {strings?.[\"Tag\"]} {strTagUsers}\n
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n \n \n {deleteButton}\n \n
\n \n {strings.formatString(\n strings?.[`{list_length} items displayed`],\n {\n list_length: viewablesPage.length,\n }\n )}\n \n \n {tagUserSelectedList}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strTagUser}\n \n \n {strings?.[\"Assigned Tags\"]}\n \n \n \n \n \n {_.map(viewablesPage, ({ id, tagUserLink, tagId }) => (\n \n \n this.handleSelect(id)}\n />\n \n {tagUserLink}\n {tagId || \"-\"}\n \n \n ))}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements, tagUserType) => {\n let filteredElements = [];\n elements.forEach(function (element, idx) {\n const { id, assigned } = element;\n\n // tags assigned\n const tagsAssigned = assigned.map((tag) => tag.id)?.join(\", \");\n\n let tagUser = \"?\";\n switch (tagUserType) {\n case \"personnel\":\n const { firstname, lastname } = element;\n tagUser = `${firstname} ${lastname}`;\n break;\n case \"vehicle\":\n const { name, type } = element;\n tagUser = `${name} - ${type}`;\n break;\n\n default:\n break;\n }\n\n filteredElements[idx] = {\n id: id,\n tagUser,\n active: true, // active,\n tagUserLink: {tagUser},\n tagId: tagsAssigned,\n };\n });\n\n return filteredElements;\n};\n\nconst mapStateToProps = (state, props) => {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n const isLoading = false;\n const error = false;\n\n const { tagUserType } = props;\n\n let userData;\n switch (tagUserType) {\n case \"personnel\":\n userData = getTagPersonnel(state);\n break;\n case \"vehicle\":\n userData = getTagVehicles(state);\n break;\n\n default:\n break;\n }\n\n const data = _prepData(userData, tagUserType);\n\n return {\n isLoading,\n error,\n data,\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n push,\n deleteTagUserById,\n deleteTagVehicleById,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n saveUserSettingsComponentState,\n })(TagTrackingUserList)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Form,\n Container,\n Grid,\n Segment,\n Button,\n Header,\n Message,\n Icon,\n TextArea,\n Popup,\n Image,\n Table,\n} from \"semantic-ui-react\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport _isEqual from \"lodash/isEqual\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { tagTrackingUserDetailsCardPersonnel } from \"admin/tag-tracking/TagTrackingUserDetailsCardPersonnel\";\nimport { tagTrackingUserDetailsCardVehicle } from \"admin/tag-tracking/TagTrackingUserDetailsCardVehicle\";\n\nconst validate = (values) => {\n const { mineLevelId, areaName, regions } = values;\n\n const errors = {};\n\n if (!mineLevelId) {\n errors.mineLevelId = \"Required\";\n }\n if (!areaName) {\n errors.areaName = \"Required\";\n }\n\n if (_isEmpty(regions)) {\n errors.regions = \"Required\";\n }\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n if (type === \"noSpaces\") {\n return value.replace(\" \", \"_\");\n } else {\n return value;\n }\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst isTagUserNameOK = (value, allValues, props, name) => {\n const { id } = allValues;\n\n const { uniqueNamedAreaParentIds } = props;\n\n const valueNoSpace = value.replace(\" \", \"_\");\n\n const notIncludingThisId = uniqueNamedAreaParentIds\n .filter((item) => !item.id.includes(id))\n .map((item) => item.parentName);\n\n if (notIncludingThisId?.includes(valueNoSpace)) {\n return \"This name has already been used\";\n } else {\n return undefined;\n }\n};\n\nclass TagTrackingUserForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n importSvg: \"\",\n collapse: false,\n errorMessage: \"\",\n };\n }\n\n componentDidUpdate(prevProps, prevState) {\n //\n }\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n resetForm = (e) => {\n e.preventDefault();\n this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // https://github.com/Asymmetrik/ngx-leaflet/issues/88\n // unmount error - \"TypeError: Cannot read property 'off' of undefined\"\n\n // abort page changes\n //this.props.reset();\n this.props.onCancel();\n };\n\n submitMyForm = (values) => {\n //console.log(`form submitted: values`, values);\n\n this.props.onSubmit(values);\n };\n\n requestDelete = (id) => {\n const { change, tagUserType } = this.props;\n\n //console.log(`requestDelete`, id, tagUserType);\n\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call change to populate the formValue `_action` at the beginning of the delete process.\n // The _action value is checked in the NavigationPromptModal, which does not display.\n change(\"_action\", \"delete\");\n this.props.onDelete({ id, tagUserType });\n };\n\n render() {\n const {\n header,\n handleSubmit,\n pristine,\n submitting,\n error,\n //mineLevelIdValue,\n initialValues,\n //regions,\n //isActivity,\n tagUserType,\n id,\n formType,\n //formValues,\n strings,\n } = this.props;\n\n // APP_TERMINOLOGY\n let strTagUser = \"User\";\n let strTagUsers = \"Users\";\n\n switch (tagUserType) {\n case \"personnel\":\n strTagUser = \"Personnel\";\n strTagUsers = \"Personnel\";\n break;\n case \"vehicle\":\n strTagUser = \"Vehicle\";\n strTagUsers = \"Vehicles\";\n break;\n case null:\n default:\n break;\n }\n\n const areaNameChecks =\n formType === \"new\" ? [required, isTagUserNameOK] : [required];\n\n const {\n collapse: isCollapse,\n submitted,\n modalMessage,\n errorMessage,\n } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n //console.log(`xxxxxxxxxxx formValues formValues`, formValues);\n //console.log(`xxxxxxxxxxx formValues pristine`, pristine);\n //console.log(`xxxxxxxxxxx formValues this.props`, this.props);\n\n const imageFilenameUser = \"avatar-construction.png\";\n const imageFilenameVehicle = \"avatar-dump-truck.png\";\n\n let urlImage = process.env.PUBLIC_URL + \"/images/\" + imageFilenameUser;\n switch (tagUserType) {\n case \"personnel\":\n urlImage = process.env.PUBLIC_URL + \"/images/\" + imageFilenameUser;\n break;\n case \"vehicle\":\n urlImage = process.env.PUBLIC_URL + \"/images/\" + imageFilenameVehicle;\n break;\n default:\n break;\n }\n\n // only show unique tag data\n // ...this deals with assignedTags possibly being in multiple Areas\n // The tag information is the same for each Area, so\n // return only the first record found for each tag.\n //\n const assignedTags = initialValues?.tagUserData?.assigned || [];\n let uniqueTagIds = assignedTags?.map((tag) => tag.mac);\n uniqueTagIds = [...new Set(uniqueTagIds)]; // unique tag mac\n // returns the 1st record found or [{}]\n const uniqueAssignedTags = [\n assignedTags.find((tag) => uniqueTagIds.includes(tag.mac)) || {},\n ];\n\n return (\n \n {/* {error &&
{error}
} */}\n
\n \n \n \n {isCollapse && (\n \n \n \n \n \n \n \n }\n />\n \n \n \n \n )}\n {!isCollapse && (\n <>\n \n \n \n \n
{header}
\n
\n \n \n \n \n }\n />\n \n
\n \n \n {tagUserType === \"personnel\" &&\n tagTrackingUserDetailsCardPersonnel(\n urlImage,\n false,\n false,\n true\n )}\n\n {tagUserType === \"vehicle\" &&\n tagTrackingUserDetailsCardVehicle(\n urlImage,\n false,\n false,\n true\n )}\n \n \n
\n
\n {error && }\n {errorMessage && (\n \n \n \n \n Error\n {errorMessage}\n \n \n \n )}\n \n )}\n
\n \n \n \n \n \n {formType === \"edit\" && (\n \n \n {/* \n Delete\n */}\n \n )}\n \n \n \n \n \n \n this.resetForm(e)}\n >\n Reset\n \n \n this.cancelForm(e)}\n >\n Cancel\n \n \n \n \n \n \n \n {formType === \"edit\" && (\n \n
Assigned Tags
\n \n \n \n Tag MAC\n RSSI\n Locations\n \n \n \n {uniqueAssignedTags?.map((tag, idx) => {\n const { id, mac, locations, calculated_rssi } = tag;\n return (\n \n \n {mac} \n \n {calculated_rssi}\n {locations?.join(\", \")}\n \n );\n })}\n \n
\n
\n )}\n
\n
\n
\n
\n\n \n
\n );\n }\n}\n\nTagTrackingUserForm = reduxForm({\n form: \"tagTrackingUserForm\",\n //enableReinitialize: true,\n //keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(TagTrackingUserForm);\n\nconst mapStateToProps = (state, props) => {\n const { id, tagUserType, formType } = props;\n\n return {\n tagUserType,\n formValues: getFormValues(\"tagTrackingUserForm\")(state), // #REVIEW - only used for debugging,\n // onChange: (values, dispatch, props, previousValues) => {\n // console.log(\"onChange\", values);\n // if (values.mineLevelId !== previousValues.mineLevelId) {\n // const {\n // change,\n // initialValues: { mineLevelId, regions },\n // } = props;\n // }\n // },\n };\n};\n\nexport default connect(mapStateToProps, null)(TagTrackingUserForm);\n","import React, { Component } from \"react\";\nimport { push } from \"react-router-redux\";\nimport { Container, Header, Grid, Message } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport { connect } from \"react-redux\";\nimport TagTrackingUserForm from \"admin/tag-tracking/TagTrackingUserForm\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { getTagPersonnel, getTagVehicles } from \"components/Tags/reducer\";\nimport { SubmissionError } from \"redux-form\";\nimport {\n addUpdateUser,\n addUpdateVehicle,\n deleteTagUserById,\n deleteTagVehicleById,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n} from \"components/Tags/actions\";\n\nclass TagTrackingUserEditPage extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n saveAddUpdateUser = (values) => {\n return new Promise((resolve, reject) => {\n this.props.addUpdateUser({\n values,\n resolve,\n reject,\n });\n });\n };\n\n saveAddUpdateVehicle = (values) => {\n return new Promise((resolve, reject) => {\n this.props.addUpdateVehicle({\n values,\n resolve,\n reject,\n });\n });\n };\n\n deleteTagUserById = (values) => {\n return new Promise((resolve, reject) => {\n this.props.deleteTagUserById({\n values,\n resolve,\n reject,\n });\n });\n };\n\n deleteTagVehicleById = (values) => {\n return new Promise((resolve, reject) => {\n this.props.deleteTagVehicleById({\n values,\n resolve,\n reject,\n });\n });\n };\n\n submitMyForm = (values) => {\n //console.log(`submitMyForm values`, values);\n\n const { _action, tagUserData, tagUserType } = values;\n const { id } = tagUserData;\n\n let promiseArray = [];\n\n switch (_action) {\n case \"edit\":\n switch (tagUserType) {\n case \"personnel\":\n const { firstname, lastname } = tagUserData;\n promiseArray.push(\n this.saveAddUpdateUser({ id, firstname, lastname })\n );\n break;\n case \"vehicle\":\n const { name, type } = tagUserData;\n promiseArray.push(this.saveAddUpdateVehicle({ id, name, type }));\n break;\n\n default:\n break;\n }\n\n break;\n default:\n break;\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"SUCCESS TagTrackingUserEditPage Submit\", results);\n })\n .then(() => {\n this.props.fetchAllTagUsers();\n this.props.fetchAllTagVehicles();\n this.props.push(`/status/taguser/${tagUserType}`);\n })\n .catch((error) => {\n console.log(`ERROR addUpdateUser error`, error);\n //this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n //throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n deleteId = ({ id, tagUserType }) => {\n console.log(`deleteId id`, id);\n\n let promiseArray = [];\n\n switch (tagUserType) {\n case \"personnel\":\n promiseArray.push(this.deleteTagUserById({ id }));\n break;\n case \"vehicle\":\n promiseArray.push(this.deleteTagVehicleById({ id }));\n break;\n\n default:\n break;\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"SUCCESS TagTrackingUserEditPage deleteTag\", results);\n })\n .then(() => {\n this.props.fetchAllTagUsers();\n this.props.fetchAllTagVehicles();\n this.props.push(`/status/taguser/${tagUserType}`);\n })\n .catch((error) => {\n console.log(\n `ERROR TagTrackingUserEditPage deleteTagUserById error`,\n error\n );\n //this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n //throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const { id, error, tagUserType, tagUsers, tagVehicles, push, strings } =\n this.props;\n\n // APP_TERMINOLOGY\n let strTagUser = \"User\";\n let strTagUsers = \"Users\";\n\n switch (tagUserType) {\n case \"personnel\":\n strTagUser = \"Personnel\";\n strTagUsers = \"Personnel\";\n break;\n case \"vehicle\":\n strTagUser = \"Vehicle\";\n strTagUsers = \"Vehicles\";\n break;\n case null:\n default:\n break;\n }\n\n // #WIP - ATM don't allow reload, or direct link to a firefly page.....\n // Instead redirect to the controller list page and wait for firefly to list (with next message).\n\n if (error) {\n push(`/status/taguser/${tagUserType}`);\n return null;\n // return (\n // <>\n // \n // \n // \n // );\n }\n\n let tagUserData;\n switch (tagUserType) {\n case \"personnel\":\n tagUserData = tagUsers?.find((user) => user.id == id) || {}; // id is string or integer\n\n // temporary until nickname is setup (note - cloned above to be mutable)\n tagUserData.nick = `${\n tagUserData?.firstname\n }${tagUserData?.lastname?.charAt(0)}`;\n break;\n case \"vehicle\":\n tagUserData = tagVehicles?.find((vehicle) => vehicle.id == id) || {}; // id is string or integer\n console.log(`tagUserData`, tagUserData);\n break;\n default:\n break;\n }\n\n return (\n
\n \n \n \n \n
Tag User Details
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n this.submitMyForm(values)}\n onCancel={() => {\n push(`/status/taguser/${tagUserType}`);\n }}\n onDelete={(values) => this.deleteId(values)}\n strings={strings}\n />\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const match = props.match;\n const id = match.params.id;\n return {\n id,\n error: \"\",\n tagUsers: getTagPersonnel(state),\n tagVehicles: getTagVehicles(state),\n };\n};\n\nexport default connect(mapStateToProps, {\n push,\n TurnOnOffPokeTheWorker,\n addUpdateUser,\n addUpdateVehicle,\n deleteTagUserById,\n deleteTagVehicleById,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n})(TagTrackingUserEditPage);\n","import React, { Component } from \"react\";\nimport { push } from \"react-router-redux\";\nimport { Container, Header, Grid, Message } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport { connect } from \"react-redux\";\nimport TagTrackingUserForm from \"admin/tag-tracking/TagTrackingUserForm\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\nimport { SubmissionError } from \"redux-form\";\nimport {\n addUpdateUser,\n addUpdateVehicle,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n} from \"components/Tags/actions\";\n\nimport {\n saveAddUpdateUser,\n saveAddUpdateVehicle,\n} from \"admin/tag-tracking/TagTrackingPageUtils\";\n\nclass TagTrackingUserCreatePage extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n saveAddUpdateUser = (values) => {\n return new Promise((resolve, reject) => {\n this.props.addUpdateUser({\n values,\n resolve,\n reject,\n });\n });\n };\n\n saveAddUpdateVehicle = (values) => {\n return new Promise((resolve, reject) => {\n this.props.addUpdateVehicle({\n values,\n resolve,\n reject,\n });\n });\n };\n\n submitMyForm = (values) => {\n //console.log(`submitMyForm values`, values);\n\n const { _action, tagUserData, tagUserType } = values;\n\n const id = null; // no 'id' for create/add user\n\n let promiseArray = [];\n\n switch (_action) {\n case \"add\":\n switch (tagUserType) {\n case \"personnel\":\n const { firstname, lastname } = tagUserData;\n promiseArray.push(\n this.saveAddUpdateUser({ id, firstname, lastname })\n );\n break;\n case \"vehicle\":\n const { name, type } = tagUserData;\n promiseArray.push(this.saveAddUpdateVehicle({ id, name, type }));\n break;\n\n default:\n break;\n }\n\n break;\n default:\n break;\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"SUCCESS TagTrackingUserCreatePage\", results);\n })\n .then(() => {\n this.props.fetchAllTagUsers();\n this.props.fetchAllTagVehicles();\n this.props.push(`/status/taguser/${tagUserType}`);\n })\n .catch((error) => {\n console.log(`ERROR addUpdateUser error`, error);\n //this.onSetError(\"failed\");\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n //throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const { id, error, tagUserType, push, tagUsers, tagVehicles, strings } =\n this.props;\n\n // APP_TERMINOLOGY\n let strTagUser = \"User\";\n let strTagUsers = \"Users\";\n\n switch (tagUserType) {\n case \"personnel\":\n strTagUser = \"Personnel\";\n strTagUsers = \"Personnel\";\n break;\n case \"vehicle\":\n strTagUser = \"Vehicle\";\n strTagUsers = \"Vehicles\";\n break;\n case null:\n default:\n break;\n }\n\n // #WIP - ATM don't allow reload, or direct link to a firefly page.....\n // Instead redirect to the controller list page and wait for firefly to list (with next message).\n\n if (error) {\n push(\"/status/tag\");\n return null;\n // return (\n // <>\n // \n // \n // \n // );\n }\n\n // default settings\n\n let tagUserData;\n switch (tagUserType) {\n case \"personnel\":\n tagUserData = { nick: \"\", firstname: \"\", lastname: \"\" };\n break;\n case \"vehicle\":\n tagUserData = { type: \"\", id: \"\" };\n break;\n default:\n break;\n }\n\n return (\n
\n \n this.submitMyForm(this._preProcessValues(formValues))\n }\n />\n \n \n \n \n
{`Add ${strTagUser}`}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n this.submitMyForm(values)}\n onCancel={() => {\n push(`/status/taguser/${tagUserType}`);\n }}\n />\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const match = props.match;\n const id = match.params.id;\n\n return {\n id,\n error: \"\",\n };\n};\n\nexport default connect(mapStateToProps, {\n push,\n TurnOnOffPokeTheWorker,\n addUpdateUser,\n addUpdateVehicle,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n})(TagTrackingUserCreatePage);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\nimport { fetchFireflys } from \"UPSPanelControllers/actions\";\n\nimport TagTrackingUserList from \"admin/tag-tracking/TagTrackingUserList\";\nimport EditTagTrackingUser from \"admin/tag-tracking/TagTrackingUserEditPage\";\nimport CreateTagTrackingUser from \"admin/tag-tracking/TagTrackingUserCreatePage\";\n\nclass TagTrackingUserAdminPages extends Component {\n render() {\n const { match, tagUserType, strings } = this.props;\n\n return (\n \n (\n \n )}\n />\n (\n \n )}\n />\n (\n \n )}\n />\n \n );\n }\n}\n\nexport default withRouter(\n connect(null, { fetchFireflys })(TagTrackingUserAdminPages)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Header,\n Grid,\n Table,\n Container,\n Input,\n Pagination,\n Dropdown,\n Icon,\n Segment,\n Button,\n Checkbox,\n Radio,\n Popup,\n Message,\n Tab,\n Form,\n} from \"semantic-ui-react\";\n\nimport { renderField } from \"admin/form-field\";\n\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport GenericButton from \"admin/GenericButton\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n//import { StatusEnum } from \"utils/StatusEnum\";\n\nimport { Download } from \"components/Download/index.js\";\n\nimport { fetchNamedAreaExtTriggerEventInfo } from \"NamedAreas/actions\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nconst validate = (values) => {\n const { mineLevelId, areaName, regions } = values;\n\n const errors = {};\n\n if (!mineLevelId) {\n errors.mineLevelId = \"Required\";\n }\n if (!areaName) {\n errors.areaName = \"Required\";\n }\n\n if (_isEmpty(regions)) {\n errors.regions = \"Required\";\n }\n\n return errors;\n};\n\nconst displayOptions = [\n {\n key: \"all\",\n text: \"Show All\",\n value: \"all\",\n },\n {\n key: \"ok\",\n text: \"OK\",\n value: \"ok\",\n },\n {\n key: \"commissioned\",\n text: \"New\",\n value: \"commissioned\",\n },\n // {\n // key: \"conflict\",\n // text: \"Position Conflict\",\n // value: \"conflict\",\n // },\n // {\n // key: \"moved\",\n // text: \"Position Moved\",\n // value: \"moved\",\n // },\n {\n key: \"shifted\",\n text: \"Position Shifted\",\n value: \"shifted\",\n },\n {\n key: \"timeout\",\n text: \"Timeout\",\n value: \"timeout\",\n },\n {\n key: \"old\",\n text: \"No Status Report\",\n value: \"old\",\n },\n];\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ExternalTriggerEditForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n id: { string: \"\", include: true },\n active: { string: \"\", include: true },\n area: { string: \"\", include: true },\n group: { string: \"\", include: true },\n level: { string: \"\", include: true },\n polygon: { string: \"\", include: true },\n source: { string: \"\", include: true },\n reason: { string: \"\", include: true },\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox delete selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n // default for radio button group\n statusGroup: \"all\",\n //\n // tab info\n activeIndex: 0,\n };\n }\n\n componentDidMount() {\n const {\n data,\n //fetchUPSs,\n //fetchFireflys,\n componentstate,\n } = this.props;\n\n const filterInput = componentstate.get(\n \"filterInput\",\n \"externalTriggerList\"\n );\n\n if (!_isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n\n // reset the radio button states\n //\n const filterInputStatusString = filterInput?.status?.string;\n\n switch (filterInputStatusString) {\n case \"\":\n this.setState({ statusGroup: \"all\" });\n break;\n case \"ok\":\n this.setState({ statusGroup: \"ok\" });\n break;\n case \"Notcommissioned\":\n this.setState({ statusGroup: \"commissioned\" });\n break;\n case \"sameposition.Statusreportmissing\":\n this.setState({ statusGroup: \"conflict\" });\n break;\n case \"Reportedtopologychanged\":\n this.setState({ statusGroup: \"moved\" });\n break;\n case \"Shifted\":\n this.setState({ statusGroup: \"shifted\" });\n break;\n case \"Nostatusreport\":\n this.setState({ statusGroup: \"old\" });\n break;\n case \"Timeout\":\n this.setState({ statusGroup: \"timeout\" });\n break;\n default:\n break;\n }\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"externalTriggerList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n const checkItemString = item[key]?.toLowerCase()?.replace(/\\s/g, \"\"); // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n const checkMatchString = match[key]?.string?.toLowerCase();\n const checkIncludes =\n checkMatchString !== \"\" // remove item which don't match, but exclude \"\" empty case\n ? match[key].include && checkItemString.includes(checkMatchString) //'.include' = true for include, = false for exclude\n : true;\n\n checkMatch = checkMatch && checkIncludes;\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n\n return;\n }\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n // handleFilterStatusChange = ({ checked, value }) => { // <<--- for radio buttons\n handleFilterStatusChange = (e, data) => {\n this.setState({ statusGroup: data.value });\n\n let search = \"\";\n\n switch (data.value) {\n case \"ok\":\n search = \"ok\";\n break;\n case \"commissioned\":\n search = \"Not commissioned\";\n break;\n case \"conflict\":\n search = \"same position. Status report missing\";\n break;\n case \"moved\":\n search = \"Reported topology changed\";\n break;\n case \"shifted\":\n search = \"Shifted\";\n break;\n case \"old\":\n search = \"No status report\";\n break;\n case \"timeout\":\n search = \"Timeout\";\n break;\n case \"all\":\n default:\n search = \"\";\n break;\n }\n this.setFilterState({ name: \"status\", value: search }, true);\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n this.setFilterState(target, true);\n };\n\n setFilterState = ({ name, value }, include) => {\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n // update match value with most recent filter entry\n match[name].string = value.replace(/\\s/g, \"\");\n match[name].include = include;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (e, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState(\n (prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n }\n //() => console.log(\"xxx this.state.selections\", this.state.selections)\n );\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n if (\n true\n // #WIP - left in place, may be useful\n // item.statusValue !== StatusEnum.NOT_COMMISSIONED ||\n // this.props.isDeleteFireflyNotCommissioned // && item.statusValue !== StatusEnum.OK\n ) {\n newSelections[item.id] = true;\n }\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n resetForm = (e) => {\n e.preventDefault();\n this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // https://github.com/Asymmetrik/ngx-leaflet/issues/88\n // unmount error - \"TypeError: Cannot read property 'off' of undefined\"\n\n // abort page changes\n //this.props.reset();\n this.props.onCancel();\n };\n\n submitMyForm = (values) => {\n //console.log(`LocalisationEditForm submitted: values`, values);\n\n this.props.onSubmit(values);\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n const { push } = this.props;\n\n let promiseArray = [];\n\n // if (action === \"update\") {\n // this.props.fetchNamedAreaExtTriggerEventInfo();\n // }\n\n if (action === \"delete\") {\n }\n\n if (action === \"copy\") {\n }\n };\n\n handleTabChange = (e, { activeIndex, panes }) => {\n // #WIP - debugging reset to latest tab\n\n const area = panes?.[activeIndex]?.menuItem;\n console.log(\"kkkkkkkkkk tab handleTabChange \", area, panes, activeIndex);\n this.setState({ activeIndex });\n };\n\n render() {\n // form props\n const { handleSubmit, pristine, submitting, initialValues } = this.props;\n\n const { isLoading, error, levels, strings } = this.props;\n const {\n column,\n data: rxData,\n direction,\n filterInput,\n activeIndex,\n } = this.state;\n\n // filter data based on the tabs selected i.e. activeIndex\n const selectedArea = levels?.[activeIndex]?.id;\n const data = rxData?.filter?.((item) => item.area === selectedArea);\n\n // APP_TERMINOLOGY\n let strExternalTrigger = strings?.[\"External Trigger\"];\n let strExternalTriggers = strings?.[\"External Triggers\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Total of {itemsCount} items.{\" \"}\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const externalTriggerFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let updateButton;\n let enableButton;\n let disableButton;\n let deleteButton;\n let copyButton;\n let externalTriggerSelectedList;\n\n updateButton = (\n this.props.fetchNamedAreaExtTriggerEventInfo()}\n size=\"large\"\n >\n {strings?.[\"Update\"]}\n \n }\n />\n );\n\n if (selectedCount > 0) {\n updateButton = null; // disable update button if items selected\n\n let externalTriggerNames = [];\n\n for (var key in selections) {\n if (externalTriggerFromDataById(key) !== undefined) {\n let externalTriggerName = externalTriggerFromDataById(key)?.id; // #WIP - what should this be???\n\n externalTriggerNames.push(externalTriggerName);\n }\n }\n externalTriggerNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n externalTriggerNames = externalTriggerNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n size=\"large\"\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n size=\"large\"\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")}\n strings={strings}\n size=\"large\"\n />\n );\n\n copyButton = (\n this.requestAction(\"copy\")}\n size=\"large\"\n />\n );\n\n externalTriggerSelectedList = (\n \n {`${strExternalTriggers} selected ...`} \n {externalTriggerNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n <>\n \n \n \n {!areAnySelected && (\n <>\n {updateButton}\n\n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n \n )}\n \n \n \n \n {false && copyButton}\n {false && }\n {false && deleteButton}\n {false && }\n {enableButton}\n \n {disableButton}\n \n \n \n {viewablesPage.length} items displayed. {selectedCount} selected\n \n {false && (\n \n \n \n this.resetForm(e)}\n size=\"large\"\n >\n Reset\n \n \n this.cancelForm(e)}\n size=\"large\"\n >\n Cancel\n \n \n )}\n {/*
\n \n
*/}\n
\n {externalTriggerSelectedList}\n
\n {levels.length === 0 && (\n \n )}\n {levels.length > 0 && (\n {\n // data filter to level\n //const levelData = data.filter(item => item.area === level.id) || {};\n return {\n menuItem: level.name,\n render: () => (\n \n \n \n \n {/* \n \n */}\n {/* \n \n */}\n \n \n \n \n \n \n {/* \n \n */}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* \n this.handleFilterStatusChange(data)}\n />\n */}\n \n \n {/* \n \n this.handleSelectAll(viewablesPage)\n }\n />\n */}\n {/* \n {strings?.[\"Disabled\"]}\n */}\n \n {strings?.[\"External Trigger ID\"]}\n \n \n {strings?.[\"Active\"]}\n \n {/* \n {strings?.[\"Area\"]}\n */}\n \n {strings?.[\"Group\"]}\n \n \n {strings?.[\"Level\"]}\n \n \n {strings?.[\"Polygon\"]}\n \n \n {strings?.[\"Event Source\"]}\n \n \n {strings?.[\"Note\"]}\n \n \n {strings?.[\"Latest Report\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n active,\n area,\n group,\n level,\n polygon,\n source,\n reason,\n lastStatusReport,\n style,\n disable,\n }) => (\n \n {/* \n this.handleSelect(id)}\n // disabled={disableDelete}\n />\n */}\n {/* {disable || \"-\"} */}\n \n {id}\n {/* */}\n \n {active || \"-\"}\n {/* {area || \"-\"} */}\n {group || \"-\"}\n {level || \"-\"}\n {polygon || \"-\"}\n {source || \"-\"}\n {reason || \"-\"}\n \n {lastStatusReport || \"-\"}\n \n \n )\n )}\n \n \n
\n {pagination}\n
\n ),\n };\n })}\n />\n )}\n \n \n \n );\n }\n}\n\nExternalTriggerEditForm = reduxForm({\n form: \"externalTriggerEditForm\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(ExternalTriggerEditForm);\n\nconst mapStateToProps = (state, props) => {\n return {\n formValues: getFormValues(\"externalTriggerEditForm\")(state), // #REVIEW - only used for debugging,\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"externalTriggerEditForm onChange values\", values);\n },\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n fetchNamedAreaExtTriggerEventInfo,\n saveUserSettingsComponentState,\n })(ExternalTriggerEditForm)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push as goto } from \"react-router-redux\";\n\nimport { Container, Header, Grid } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\n\n//import { v4 as uuid } from \"uuid\";\n\n//import SubmissionModal from \"admin/SubmissionModal\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n//import DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\n//import { SubmissionError, isSubmitting, hasSubmitSucceeded } from \"redux-form\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport { formatRelative, parseISO } from \"date-fns\";\nimport { formatDateRelativeNow, minutesAgo } from \"utils/format-date\";\n\nimport {\n getAllAreaStatuses,\n getAllNamedAreaEvents,\n getNamedAreasInfoInNamedAreaGroupByAreaId,\n getNamedAreaExtTriggerEventInfo,\n} from \"components/WebWorker/reducer\";\n\nimport ExternalTriggerEditForm from \"admin/event-external-trigger/ExternalTriggerEditForm\";\nimport { isKthBitSet } from \"utils/bit-operations\";\n\nimport { fetchNamedAreaExtTriggerEventInfo } from \"NamedAreas/actions\";\nimport hash from \"object-hash\";\n\nclass ExternalTriggerEditPage extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n initialValues: {},\n submitted: false,\n saveSuccess: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n this.props.fetchNamedAreaExtTriggerEventInfo();\n }\n\n componentDidUpdate() {\n //this.props.fetchNamedAreaExtTriggerEventInfo();\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n\n const { submitting, submitSucceeded } = this.props;\n\n this.setState({ errorMessage: \"\" });\n\n // if we've just submit the form -> leave\n if (submitting || submitSucceeded) {\n goto(\"/\");\n }\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n submitMyForm = (values) => {\n const { changeLocalisation, reset, localisation } = this.props;\n const { id: language, fieldData } = values;\n\n let localisations = [];\n\n // ...............................\n\n const newValues = { id: language, localisations };\n\n return new Promise((resolve, reject) => {\n //changeLocalisation({ values: newValues, resolve, reject });\n }).then(() => {\n //this.props.fetchLocalisation();\n this.props.goto(\"/tools/localisation\");\n // #TODO\n // Should wait for change to propogate then reset() to return to new intialValues\n //reset();\n });\n };\n\n render() {\n const { id, strings, goto, data, levels } = this.props;\n\n // APP_TERMINOLOGY\n let strExternalTrigger = strings?.[\"External Trigger\"];\n let strExternalTriggers = strings?.[\"External Triggers\"];\n\n // fieldData is a keyed object\n let fieldData = {};\n data.forEach((element) => {\n fieldData[element.id] = { ...element };\n });\n\n const initialValues = {\n _action: \"edit\", // used to control dlg display\n id: id,\n fieldData: fieldData, // fieldData,\n };\n\n return (\n
\n this.submitMyForm(formValues)}\n />\n \n \n \n \n
{strings?.[\"External Trigger Events\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n this.submitMyForm(values)}\n onCancel={() => {\n goto(`/external-trigger-event`);\n }}\n strings={strings}\n />\n \n
\n
\n );\n }\n}\n\nconst _prepData = (elements) => {\n let filteredElements = [];\n\n //console.log(\"xxx elements\", elements);\n\n elements.forEach(function (element, idx) {\n const {\n id,\n active,\n area,\n buttonCustomLabel,\n buttonLabel,\n groupLabel: group,\n levelLabel: level,\n parent,\n permission,\n priority,\n origin,\n operator,\n reason,\n disable,\n timestamp,\n } = element;\n\n // console.log(\"xxx element\", element);\n\n let lastStatusReport = \"-\";\n if (timestamp !== null && timestamp !== undefined) {\n // format - previous used in tableformatters.js\n lastStatusReport = formatRelative(timestamp, new Date(), {\n includeSeconds: true,\n });\n }\n\n let style = null;\n // change row if active\n\n if (active) style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n\n // set style of disabled events\n if (disable === true) {\n style = { backgroundColor: \"rgb(242, 113, 28, 60%)\" };\n }\n\n // compose new data set\n filteredElements[idx] = {\n id: id, // `${parent}:${priority}`,\n active: active ? \"ACTIVE\" : \"INACTIVE\",\n area,\n group,\n level,\n polygon: buttonCustomLabel !== \"\" ? buttonCustomLabel : buttonLabel,\n source: `${origin} - ${operator}`,\n reason,\n lastStatusReport: lastStatusReport,\n style,\n disable: disable ? \"DISABLED\" : \"ENABLED\",\n };\n });\n\n return filteredElements;\n};\n\nfunction mapStateToProps(state, props) {\n const allAreas = getAllAreaStatuses(state);\n\n let levels = [];\n let rawData = [];\n\n // #NOTE - this is the old process to generate levels and data\n // This works but has been replaced by API call to get /ext_trigger_event_info\n //\n if (false) {\n // accumulate array of area ids called \"levels\" - old school!\n let namedAreasInNamedAreaGroupsByArea = [];\n\n allAreas.forEach((area) => {\n const { id } = area;\n const namedAreaInfoByArea = getNamedAreasInfoInNamedAreaGroupByAreaId(\n state,\n id\n );\n\n namedAreasInNamedAreaGroupsByArea.push({\n area: id,\n namedArea: namedAreaInfoByArea,\n });\n levels.push({ id: id, name: id });\n });\n\n const allNamedAreaEvents = getAllNamedAreaEvents(state);\n\n let rawData = [];\n namedAreasInNamedAreaGroupsByArea.forEach((a) => {\n const { area, namedArea } = a;\n namedArea.forEach((na) => {\n // only list if permission bit 1 is set i.e. enabled for External_Trigger_Event\n const isExternalTriggerEvent = isKthBitSet(na.permission, 1);\n\n if (isExternalTriggerEvent) {\n // could be multiple events (per parent polygon)\n const events = allNamedAreaEvents.filter(\n (event) =>\n event.parent === na.parent && event.priority === na.priority\n );\n\n // if there is an event, all child events should have the same info\n // so just use the state of the 1st found. WE call this the templateEvent\n let active = false;\n let origin = \"\";\n let operator = \"\";\n let reason = \"WIP\";\n\n if (events.length > 0) {\n const templateEvent = events[0];\n active = templateEvent.active;\n origin = templateEvent.origin;\n operator = templateEvent.operator;\n }\n\n rawData.push({\n area,\n events,\n active,\n origin,\n operator,\n reason,\n ...na,\n });\n }\n });\n });\n }\n\n // create level information\n allAreas.forEach((area) => {\n const { id } = area;\n levels.push({ id: id, name: id });\n });\n\n // external trigger event info via API /get_all_ext_trigger_event_info\n\n const namedAreaExtTriggerEventInfo = getNamedAreaExtTriggerEventInfo(state);\n\n rawData = namedAreaExtTriggerEventInfo;\n\n const data = _prepData(rawData);\n\n return {\n data,\n levels,\n };\n}\n\nexport default connect(mapStateToProps, {\n TurnOnOffPokeTheWorker,\n goto,\n fetchNamedAreaExtTriggerEventInfo,\n})(ExternalTriggerEditPage);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Icon,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport {\n getAllAreaStatuses,\n getScheduledEventJobInfo,\n} from \"components/WebWorker/reducer\";\n\nimport { saveNewNamedArea, deleteNamedArea } from \"NamedAreas/actions\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { updateNamedAreaGroup } from \"NamedAreaGroups/actions\";\nimport { v4 as uuid } from \"uuid\";\nimport { fetchScheduledEventJobs } from \"NamedAreas/actions\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\nimport { formatRelative, parseISO } from \"date-fns\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n// ScheduledEventListEditPage\nclass ScheduledEventList extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n namedArea: \"\",\n area: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n this.props.fetchScheduledEventJobs();\n\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"scheduledEventJobList\"\n );\n\n //console.log(\"filterInput componentDidMount\", filterInput);\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"scheduledEventJobList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column: rxColumn, direction } = this.state;\n\n // if undefined, default sort to 'namedArea'\n let column = rxColumn ? rxColumn : \"namedArea\";\n\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n // #NOTE - create a function\n // src/admin/named-area-group/NamedAreaGroupTableItems.js\n deleteItemByNamedAreaParentId = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n // #NOTE - create a function\n // see - src/admin/named-area-group/NamedAreaGroupEditPage.js\n\n // newNamedAreaGroup = (allAreas, allNamedAreas, namedAreaId) => {\n // const namedArea = allNamedAreas.find(\n // (namedArea) => namedArea.id === namedAreaId\n // );\n // const { area: areaId, parent: parentId } = namedArea;\n\n // if (_isEmpty(areaId)) {\n // return null;\n // }\n\n // const area = allAreas.find((area) => area.id === areaId);\n\n // if (_isEmpty(area)) {\n // return null;\n // }\n\n // // get current area info\n // const {\n // id,\n // image_filename,\n // image_info,\n // slug,\n // coordinatesUtm,\n // ref_coord,\n // floor,\n // ceiling,\n // default_color,\n // default_state,\n // namedAreaGroup,\n // } = area;\n\n // // update namedAreaGroup - delete current namedArea if exists\n // if (_isEmpty(namedAreaGroup)) {\n // return null;\n // }\n\n // const cloneItems = !_isEmpty(namedAreaGroup)\n // ? JSON.parse(JSON.stringify(namedAreaGroup))\n // : [];\n\n // const newItems = this.deleteItemByNamedAreaParentId(cloneItems, parentId);\n\n // let bounds = JSON.parse(JSON.stringify(coordinatesUtm[0])); // #NOTE - area is a single polygon (not multi)\n // const firstPoint = bounds[0];\n // bounds.push(firstPoint);\n\n // // create new Area with updated namedAreaGroup\n // const newArea = {\n // id,\n // image_filename,\n // image_info: JSON.stringify(image_info),\n // slug,\n // bounds: bounds,\n // ref_coord,\n // floor,\n // ceiling,\n // default_color: default_color.toUpperCase(),\n // default_state: default_state.toUpperCase(),\n // named_area_group: JSON.stringify(newItems),\n // };\n\n // const newValues = { id: id, data: newArea };\n\n // return newValues;\n // };\n\n requestAction = (action) => {\n const { selections } = this.state;\n const {\n allNamedAreas,\n allAreas,\n deleteNamedArea,\n saveNewNamedArea,\n updateNamedAreaGroup,\n push,\n namedAreaSubType,\n } = this.props;\n\n let promiseArray = [];\n\n if (action === \"delete\") {\n let namedAreas = [];\n for (var key in selections) {\n const selection = key;\n // allNamedAreas.forEach((namedArea, idx) => {\n // const { id, parent } = namedArea;\n // // selections are parents, so match whole parent. eg.\"DMLZ_Extraction:1234\" in \"DMLZ_Extraction:1234:1604620816915\"\n // if (parent === selection) {\n // namedAreas.push(id);\n // }\n // });\n }\n\n // namedAreas.forEach((namedAreaId) => {\n // promiseArray.push(\n // new Promise((resolve, reject) =>\n // deleteNamedArea({ values: { id: namedAreaId }, resolve, reject })\n // )\n // );\n\n // const newNamedAreaGroup = this.newNamedAreaGroup(\n // allAreas,\n // allNamedAreas,\n // namedAreaId\n // );\n\n // // null returned if the namedArea group is empty\n // if (newNamedAreaGroup !== null) {\n // // in loop because could be named area from different areas\n // promiseArray.push(\n // new Promise((resolve, reject) =>\n // updateNamedAreaGroup({\n // values: newNamedAreaGroup,\n // resolve,\n // reject,\n // })\n // )\n // );\n // }\n // });\n }\n\n if (action === \"copy\") {\n // for (var key in selections) {\n // const namedAreaParentId = key;\n // const newNamedAreaParent = uuid();\n // allNamedAreas.forEach((namedArea, idx) => {\n // const { id, parent } = namedArea;\n // if (parent === namedAreaParentId) {\n // // console.log(`xxxx -------------`);\n // // console.log(`xxxx namedArea.id`, namedArea.id);\n // // console.log(`xxxx -------------`);\n // const newNamedAreaName = new Date().getTime();\n // let newNamedArea = JSON.parse(JSON.stringify(namedArea));\n // newNamedArea.id = `${namedArea.area}:${newNamedAreaParent}:${newNamedAreaName}`;\n // newNamedArea.parent = `${namedArea.area}:${newNamedAreaParent}`;\n // newNamedArea.parent_name = `${namedArea.parent_name} (copy)`;\n // newNamedArea.name = `${newNamedAreaName}`;\n // newNamedArea.style = JSON.stringify(namedArea.style);\n // newNamedArea.type = \"Polygon\";\n // newNamedArea.sub_type = namedAreaSubType;\n // // append 1st point to close loop\n // const lengthCoord = namedArea.coordinatesUtm[0].length;\n // newNamedArea.shape = [...namedArea.coordinatesUtm[0]];\n // newNamedArea.shape[lengthCoord] = namedArea.coordinatesUtm[0][0];\n // // update button\n // namedArea.button.forEach((butt, idx) => {\n // newNamedArea.button[idx].id = newNamedArea.id;\n // newNamedArea.button[idx].named_area = newNamedArea.parent;\n // });\n // // delete unnecessary objects\n // const { Firefly_List, coordinatesUtm, ...copyNamedArea } =\n // newNamedArea;\n // // console.log(`xxxx originalNamedArea`, namedArea);\n // // console.log(`xxxx copyNamedArea`, copyNamedArea);\n // promiseArray.push(\n // new Promise((resolve, reject) =>\n // saveNewNamedArea({ values: copyNamedArea, resolve, reject })\n // )\n // );\n // }\n // });\n // }\n }\n // return Promise.all(promiseArray)\n // .then((results) => {\n // console.log(\" .... processed named areas.\", results);\n // })\n // .then(\n // () => {\n // push(`/admin/named-area/${namedAreaSubType}`);\n // },\n // (errorMsg) => {\n // console.log(\"action failed\", errorMsg); // #TODO probs should show this?\n // }\n // );\n };\n\n render() {\n const { isLoading, error, namedAreaSubType, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // APP_TERMINOLOGY\n let strScheduledEventJob = strings?.[\"Scheduled Job\"];\n let strScheduledEventJobs = strings?.[\"Scheduled Jobs\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const namedAreaFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let enableButton;\n let disableButton;\n let deleteButton;\n let copyButton;\n let namedAreaSelectedList;\n if (selectedCount > 0) {\n let namedAreaNames = [];\n //console.log(\"data\", data);\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (namedAreaFromDataById(key) !== undefined) {\n let namedAreaName = namedAreaFromDataById(key).namedArea;\n\n // namedAreaName = namedAreaName.substring(\n // 0,\n // namedAreaName.indexOf(\" (\")\n // ); // strip off the trailing ip\n namedAreaNames.push(namedAreaName);\n }\n }\n namedAreaNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n namedAreaNames = namedAreaNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n size=\"large\"\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n size=\"large\"\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")}\n strings={strings}\n size=\"large\"\n />\n );\n\n copyButton = (\n this.requestAction(\"copy\")}\n size=\"large\"\n />\n );\n\n namedAreaSelectedList = (\n \n {`${strScheduledEventJob} selected ...`} \n {namedAreaNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{strScheduledEventJob}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n {namedAreaSubType !== \"forced\" && (\n \n \n \n )}\n {!areAnySelected && (\n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n )}\n \n \n {selectedCount} selected\n \n \n \n {namedAreaSubType !== \"forced\" && }\n {namedAreaSubType !== \"forced\" && copyButton}\n {namedAreaSubType !== \"forced\" && }\n {deleteButton}\n {/* {enableButton}\n \n {disableButton} */}\n \n
\n
\n {viewablesPage.length} items displayed.\n
\n \n {namedAreaSelectedList}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strScheduledEventJob}\n \n \n {strings?.[\"Area\"]}\n \n \n \n \n \n {_.map(viewablesPage, ({ id, namedAreaLink, area }) => (\n \n \n this.handleSelect(id)}\n />\n \n {namedAreaLink}\n {area || \"-\"}\n \n \n ))}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements) => {\n let filteredElements = [];\n\n elements.forEach(function (element, idx) {\n const {\n active,\n area,\n buttonCustomLabel,\n buttonLabel,\n groupLabel: group,\n levelLabel: level,\n parent,\n permission,\n priority,\n origin,\n operator,\n reason,\n disable,\n } = element;\n\n const timestamp = undefined;\n\n let lastStatusReport = \"WIP\"; // #WIP get the time the event was triggered\n if (timestamp !== null && timestamp !== undefined) {\n // format - previous used in tableformatters.js\n lastStatusReport = formatRelative(parseISO(timestamp), new Date(), {\n includeSeconds: true,\n });\n }\n\n let style = null;\n // change row if active\n\n if (active) style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n\n // set style of disabled events\n if (disable === true) {\n style = { backgroundColor: \"rgb(242, 113, 28, 60%)\" };\n }\n\n // compose new data set\n filteredElements[idx] = {\n id: `${parent}:${priority}`,\n active: active ? \"ACTIVE\" : \"INACTIVE\",\n area,\n group,\n level,\n polygon: buttonCustomLabel !== \"\" ? buttonCustomLabel : buttonLabel,\n source: operator,\n reason,\n lastStatusReport: lastStatusReport,\n style,\n disable: disable ? \"DISABLED\" : \"ENABLED\",\n };\n });\n\n return filteredElements;\n};\n\nconst mapStateToProps = (state, props) => {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.namedAreas;\n const isLoading = false;\n const error = false;\n\n const allAreas = getAllAreaStatuses(state);\n\n let levels = [];\n let rawData = [];\n\n const scheduledEventJobInfo = getScheduledEventJobInfo(state);\n\n console.log(\"xxx scheduledEventJobInfo\", scheduledEventJobInfo);\n\n rawData = scheduledEventJobInfo.filter((job) => job.active !== false);\n\n const data = _prepData(rawData);\n\n return {\n isLoading,\n error,\n data,\n allNamedAreas: {},\n allAreas,\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n deleteNamedArea,\n updateNamedAreaGroup,\n push,\n fetchScheduledEventJobs,\n saveNewNamedArea,\n saveUserSettingsComponentState,\n })(ScheduledEventList)\n);\n","import { strings } from \"components/App/localisation\";\n\nexport const optionsMonths = [\n {\n value: \"*\",\n text: strings?.[\"month\"],\n key: \"every_month\",\n },\n {\n value: 1,\n text: strings?.[\"january\"],\n key: \"january\",\n },\n {\n value: 2,\n text: strings?.[\"february\"],\n key: \"february\",\n },\n { value: 3, text: strings?.[\"march\"], key: \"march\" },\n { value: 4, text: strings?.[\"april\"], key: \"april\" },\n { value: 5, text: strings?.[\"may\"], key: \"may\" },\n { value: 6, text: strings?.[\"june\"], key: \"june\" },\n { value: 7, text: strings?.[\"july\"], key: \"july\" },\n { value: 8, text: strings?.[\"august\"], key: \"august\" },\n { value: 9, text: strings?.[\"september\"], key: \"september\" },\n { value: 10, text: strings?.[\"october\"], key: \"october\" },\n { value: 11, text: strings?.[\"november\"], key: \"novemeber\" },\n { value: 12, text: strings?.[\"december\"], key: \"december\" },\n];\n\nexport function optionsDays() {\n let days = [\n {\n value: \"*\",\n text: strings?.[\"day\"],\n key: \"every_day\",\n },\n ];\n\n for (let index = 1; index < 32; index++) {\n days.push({\n value: index,\n text:\n index == 1 ? `${strings?.[\"day\"]}` : `${index} ${strings?.[\"days\"]}`,\n key: `day_${index}`,\n });\n }\n\n return days;\n}\n\nexport const optionsDayOfWeek = [\n { value: \"*\", text: strings?.[\"any day\"], key: \"every_*\" },\n { value: 0, text: strings?.[\"any day\"], key: \"every_dayWeek\" },\n { value: 1, text: strings?.[\"monday\"], key: \"monday\" },\n { value: 2, text: strings?.[\"tuesday\"], key: \"tuesday\" },\n { value: 3, text: strings?.[\"wednesday\"], key: \"wednesday\" },\n { value: 4, text: strings?.[\"thursday\"], key: \"thursday\" },\n { value: 5, text: strings?.[\"friday\"], key: \"friday\" },\n { value: 6, text: strings?.[\"saturday\"], key: \"saturday\" },\n { value: 7, text: strings?.[\"sunday\"], key: \"sunday\" },\n];\n\nexport function optionsHours() {\n let hours = [\n // {\n // value: 0,\n // text: strings?.[\"hour\"],\n // key: \"every\",\n // },\n ];\n\n for (let index = 0; index < 24; index++) {\n hours.push({\n value: index,\n text: index < 10 ? `0${index}:..` : `${index}:..`,\n key: `hour_${index}`,\n });\n }\n\n return hours;\n}\n\nexport function optionsMinutes() {\n let minutes = [\n // {\n // value: 0,\n // text: strings?.[\"minute\"],\n // key: \"every\",\n // },\n ];\n\n for (let index = 0; index < 60; index++) {\n minutes.push({\n value: index,\n text: index < 10 ? `..:0${index}` : `..:${index}`,\n key: `minute_${index}`,\n });\n }\n\n return minutes;\n}\n\n// yes, yes this be a general function which passes the # of items - get to it ;)\n\nexport function options60mins() {\n let value = [];\n\n for (let index = 2; index < 60; index++) {\n value.push({\n value: index,\n text:\n index == 1\n ? `${strings?.[\"minute\"]}`\n : `${index} ${strings?.[\"minutes\"]}`,\n key: index,\n });\n }\n\n return value;\n}\n\nexport function options24hours() {\n let value = [];\n\n for (let index = 1; index < 24; index++) {\n value.push({\n value: index,\n text:\n index == 1 ? `${strings?.[\"hour\"]}` : `${index} ${strings?.[\"hours\"]}`,\n key: index,\n });\n }\n\n return value;\n}\n\nexport function options12months() {\n let value = [];\n\n for (let index = 1; index < 13; index++) {\n value.push({\n value: index,\n text:\n index == 1\n ? `${strings?.[\"month\"]}`\n : `${index} ${strings?.[\"months\"]}`,\n key: index,\n });\n }\n\n return value;\n}\n\nexport const optionsDuration = [\n //{ value: \"second\", text: strings?.[\"seconds\"], key: \"second\" }, // #Note - only support min of 1 min ON/OFF\n { value: \"minute\", text: strings?.[\"minutes\"], key: \"minute\" },\n { value: \"hour\", text: strings?.[\"hours\"], key: \"hour\" },\n];\n","// * * * * * *\n// ┬ ┬ ┬ ┬ ┬ ┬\n// │ │ │ │ │ |\n// │ │ │ │ │ └ day of week (0 - 7, 1L - 7L) (0 or 7 is Sun)\n// │ │ │ │ └───── month (1 - 12)\n// │ │ │ └────────── day of month (1 - 31, L)\n// │ │ └─────────────── hour (0 - 23)\n// │ └──────────────────── minute (0 - 59)\n// └───────────────────────── second (0 - 59, optional)\n\n// see - https://github.com/harrisiirak/cron-parser\n// see - 7 segment fork - https://www.npmjs.com/package/@chuxingpay/cron-parser\nimport { parseExpression, fieldsToExpression } from \"cron-parser\";\n\n// see - https://github.com/GuillaumeRochat/cron-validator\n// npm i cron-validator\nimport { isValidCron } from \"cron-validator\";\n\n// see - https://github.com/Airfooox/cron-validate\n// npm install -S cron-validate\nimport cron from \"cron-validate\";\n\nconst dateToCron = (date) => {\n const second = date.getSeconds();\n const minute = date.getMinutes();\n const hour = date.getHours();\n const dayOfMonth = date.getDate();\n const month = date.getMonth() + 1;\n const dayOfWeek = date.getDay();\n\n return `${second} ${minute} ${hour} ${dayOfMonth} ${month} ${dayOfWeek}`;\n};\n\n// #NOTE - order of this object is *important* as the values make up the cron expression\nconst DEFAULT_CRON = {\n second: 0,\n minute: 0,\n hour: 0,\n dayOfMonth: 1,\n month: \"*\",\n dayOfWeek: \"*\",\n year: \"*\",\n};\n\n// enable debug messages\nconst DEBUG = !true;\n\nexport const convertFieldsToCronExpression = (values) => {\n DEBUG && console.log(\"xxx convertCron values\", values);\n\n //let cron = Object.values(DEFAULT_CRON);\n let cronObj = { ...DEFAULT_CRON };\n\n [\n \"year\",\n \"dayOfWeek\",\n \"month\",\n \"dayOfMonth\",\n \"hour\",\n \"minute\",\n \"second\",\n ].forEach((field) => {\n const everyString = values?.[field]?.every === true ? \"*/\" : \"\";\n\n if (values?.[field]) {\n // isNaN(Number(values?.[field]?.value))\n DEBUG && console.log(\"xxx convertCron field\", field);\n DEBUG && console.log(\"xxx convertCron values?.[field]\", values?.[field]);\n DEBUG &&\n console.log(\"xxx convertCron value value \", values?.[field]?.value);\n DEBUG &&\n console.log(\n \"xxx convertCron value isNaN(value) \",\n isNaN(values?.[field]?.value)\n );\n\n if (values?.[field]?.value !== 0) {\n if (everyString) {\n if (values?.[field]?.value !== \"*\") {\n // #Note - special case exclude every \"*/\" from minutes\n // i.e. \"*/59\" === every 59min, is same as \"59\" === every 59th minute\n //if (field === \"minute\") {\n // cronObj[field] = `${values?.[field]?.value}`;\n //} else {\n cronObj[field] = `${everyString}${values?.[field]?.value}`;\n //}\n }\n } else {\n cronObj[field] = values?.[field]?.value;\n }\n }\n DEBUG && console.log(\"xxx convertCron cronObj field\", cronObj, field);\n }\n });\n\n // make sure the order is correct!!!!!\n const cronString = `${cronObj.second} ${cronObj.minute} ${cronObj.hour} ${cronObj.dayOfMonth} ${cronObj.month} ${cronObj.dayOfWeek} ${cronObj.year}`;\n DEBUG && console.log(\"xxx convertCron cronString\", cronString);\n\n // 'isValidCron' does not support years --- :(\n const cronStringNoYear = `${cronObj.second} ${cronObj.minute} ${cronObj.hour} ${cronObj.dayOfMonth} ${cronObj.month} ${cronObj.dayOfWeek}`;\n const isCronOK = isValidCron(cronStringNoYear, { seconds: true });\n\n console.log(\"CRON CHECK FAILED isValidCron CRON : \", cronString);\n\n if (isCronOK) {\n const cronResult = cron(cronString, {\n override: {\n useSeconds: true,\n useYears: true,\n },\n });\n\n if (cronResult.isValid()) {\n const validValue = cronResult.getValue();\n\n // The valid value is a object containing all cron fields\n DEBUG && console.log(\"xxx convertCron cronResult validValue\", validValue);\n\n // maintenance - convert object keys for validValue\n // start\n const start = {\n year: validValue.years,\n dayOfWeek: validValue.daysOfWeek,\n month: validValue.months,\n dayOfMonth: validValue.daysOfMonth,\n hour: validValue.hours,\n minute: validValue.minutes,\n second: validValue.seconds,\n };\n\n let stop = { ...start };\n\n // #REVIEW - exclude years until needed in future\n const { year, ...stopNoYear } = stop;\n\n // stop = start + duration\n // convert cron to a time\n // time + duration\n //\n DEBUG &&\n console.log(\n \"xxx convertCron dur startParse\",\n Object.values(stopNoYear)?.join(\" \")\n );\n\n const cronStartStringNoYear = `${start.second} ${start.minute} ${start.hour} ${start.dayOfMonth} ${start.month} ${start.dayOfWeek}`;\n\n const startParse = parseExpression(cronStartStringNoYear);\n DEBUG && console.log(\"xxx convertCron startParse\", startParse);\n\n const nextStartParse = startParse.next().toString();\n\n DEBUG &&\n console.log(\"xxx convertCron dur startParse nextCron\", nextStartParse);\n\n //const dateText = nextCron; // \"2017-05-09T01:30:00.123Z\";\n // convert next Cron event to a date\n let date = new Date(nextStartParse);\n\n // convert the date back to a cron\n const cronNextStart = dateToCron(date);\n\n DEBUG &&\n console.log(\n \"xxx convertCron dur dateToCron cronNextStart\",\n cronNextStart\n );\n\n const duration = values?.duration || {};\n\n DEBUG && console.log(\"xxx convertCron duration value\", duration);\n\n let durationSecs = 0;\n if (!isNaN(Number(duration?.value))) {\n switch (duration?.unit) {\n case \"hour\":\n durationSecs = duration.value * 3600;\n break;\n case \"minute\":\n durationSecs = duration.value * 60;\n break;\n case \"second\":\n durationSecs = duration.value;\n break;\n default:\n break;\n }\n }\n\n // add duration to the date\n date.setSeconds(date.getSeconds() + durationSecs);\n\n // convert the date back to a cron\n const cronDuration = dateToCron(date);\n\n //console.log(\"xxx 123 dur dateToCron cronDuration\", cronDuration); //30 5 9 5 2\n\n const durationParse = parseExpression(cronDuration);\n DEBUG && console.log(\"xxx convertCron startParse\", startParse);\n\n const nextDurationParse = durationParse.next().toString();\n DEBUG &&\n console.log(\n \"xxx convertCron dur durationParse nextCron\",\n nextDurationParse\n );\n\n DEBUG && console.log(\"xxx convertCron dur ---- DIFFERENCE-------\");\n\n const arrayStart = cronNextStart.split(\" \");\n const arrayDuration = cronDuration.split(\" \");\n\n DEBUG &&\n console.log(\n \"xxx convertCron dur ---- DIFFERENCE------- arrayStart\",\n arrayStart\n );\n DEBUG &&\n console.log(\n \"xxx convertCron dur ---- DIFFERENCE------- arrayDuration\",\n arrayDuration\n );\n\n let diff = {\n second: 0,\n minute: 0,\n hour: 0,\n dayOfMonth: 0,\n month: 0,\n dayOfWeek: 0,\n };\n\n // return `${second} ${minute} ${hour} ${dayOfMonth} ${month} ${dayOfWeek}`;\n\n [\"second\", \"minute\", \"hour\", \"dayOfMonth\", \"month\", \"dayOfMonth\"].map(\n (period, idx) => {\n diff[period] = Number(arrayDuration[idx]) - Number(arrayStart[idx]);\n }\n );\n\n DEBUG &&\n console.log(\"xxx convertCron dur ---------------------diff \", diff);\n DEBUG && console.log(\"xxx convertCron dur ---------------------\");\n\n const startString = `${start.second} ${start.minute} ${start.hour} ${start.dayOfMonth} ${start.month} ${start.dayOfWeek}`;\n\n DEBUG && console.log(\"xxx convertCron dur stop \", stop);\n\n // #TODO - MAKE THIS A FUNCTION!!!!!!!!!!!!!!!!\n\n if (diff.dayOfMonth !== 0) {\n if (!isNaN(Number(start.dayOfMonth))) {\n stop.dayOfMonth = Number(start.dayOfMonth) + diff.dayOfMonth;\n } else if (start.dayOfMonth?.includes(\"*\")) {\n const arrayCron = [...start.dayOfMonth];\n DEBUG && console.log(\"xxx convertCron dur arrayCron \", arrayCron);\n }\n }\n\n if (diff.hour !== 0) {\n if (!isNaN(Number(start.hour))) {\n stop.hour = Number(start.hour) + diff.hour;\n } else if (start.hour?.includes(\"*\")) {\n //const arrayCron = [...start.hour];\n const arrayCron = start.hour.split(\"/\");\n\n DEBUG && console.log(\"xxx convertCron dur arrayCron \", arrayCron);\n DEBUG && console.log(\"xxx convertCron diff\", diff);\n DEBUG &&\n console.log(\"xxx convertCron dur diff.hour >= 0 \", diff.hour >= 0);\n\n if (diff.hour >= 0) {\n stop.hour = `${diff.hour}-23/${Number(arrayCron[1])}`;\n }\n // -ve\n else {\n let stopExp = `${23 + diff.minute}-23/${Number(arrayCron[1])}`;\n if (stopExp === \"0-23/23\") {\n stopExp = \"0\";\n } else {\n stop.minute = `${23 + diff.minute}-23/${Number(arrayCron[1])}`;\n }\n }\n }\n }\n\n if (diff.minute !== 0) {\n if (!isNaN(Number(start.minute))) {\n stop.minute = Number(start.minute) + diff.minute;\n } else if (start.minute?.includes(\"*\")) {\n const arrayCron = start.minute.split(\"/\");\n //stop.minute = `*/${Number(arrayCron[1]) + diff.minute}`;\n\n DEBUG && console.log(\"xxx convertCron diff\", diff);\n DEBUG && console.log(\"xxx convertCron dur arrayCron \", arrayCron);\n DEBUG &&\n console.log(\n \"xxx convertCron dur diff.minute >= 0 \",\n diff.minute >= 0\n );\n\n if (diff.minute >= 0) {\n stop.minute = `${diff.minute}-59/${Number(arrayCron[1])}`;\n }\n // -ve\n else {\n let stopExp = `${59 + diff.minute}-59/${Number(arrayCron[1])}`;\n if (stopExp === \"0-59/59\") {\n stopExp = \"0\";\n } else {\n stop.minute = `${59 + diff.minute}-59/${Number(arrayCron[1])}`;\n }\n }\n }\n }\n\n if (diff.second !== 0) stop.second = Number(stop.second) + diff.second;\n\n const stopString = `${stop.second} ${stop.minute} ${stop.hour} ${stop.dayOfMonth} ${stop.month} ${stop.dayOfWeek}`;\n\n DEBUG && console.log(\"xxx convertCron dur startString \", startString);\n DEBUG && console.log(\"xxx convertCron dur stopString \", stopString);\n DEBUG && console.log(\"xxx convertCron dur ------------------------ \");\n\n return { start: startString, stop: stopString };\n } else {\n const errorValue = cronResult.getError();\n\n // The error value contains an array of strings, which represent the cron validation errors.\n console.log(\"CRON RESULT ERROR \", errorValue); // string[] of error messages\n\n // 1...6 is meaningless but lets me quickly notice a failure\n return { start: \"1 2 3 4 5 6\", stop: \"1 2 3 4 5 6\" };\n }\n } else {\n // 1...6 is meaningless but lets me quickly notice a failure\n return { start: \"6 5 4 3 2 1\", stop: \"6 5 4 3 2 1\" };\n }\n};\n\n// #WIP - planned funtion\nexport const convertCronExpressionToFields = (cron) => {\n let cronString = \"* * * * * * *\";\n\n return cronString;\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Form,\n Container,\n Grid,\n Segment,\n Button,\n Header,\n Icon,\n Popup,\n Dropdown,\n Table,\n Tab,\n Input,\n TabPane,\n} from \"semantic-ui-react\";\n\nimport SemanticDatepicker from \"react-semantic-ui-datepickers\";\nimport \"react-semantic-ui-datepickers/dist/react-semantic-ui-datepickers.css\";\n\nimport {\n renderInput,\n renderSelect,\n renderField,\n renderRadio,\n renderCheckbox,\n renderTextArea,\n} from \"admin/form-field\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\n\n// see - https://www.npmjs.com/package/react-timezone-select\nimport TimezoneSelect from \"react-timezone-select\";\n\n// see - https://www.npmjs.com/package/cronstrue\nimport cronstrue from \"cronstrue/i18n\";\n\n// see - 7 segment fork - https://www.npmjs.com/package/@chuxingpay/cron-parser\nimport { parseExpression, fieldsToExpression } from \"cron-parser\";\n\nimport ChooseMineLevelField from \"components/ChooseMineLevelField\";\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport {\n getAreaStatusesById,\n getNamedAreasInfoInNamedAreaGroupByAreaId,\n} from \"components/WebWorker/reducer\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport {\n optionsMonths,\n optionsDays,\n optionsDayOfWeek,\n optionsHours,\n optionsMinutes,\n optionsDuration,\n options60mins,\n options24hours,\n options12months,\n} from \"admin/event-scheduled/ScheduleEventFormOptions\";\nimport { convertFieldsToCronExpression } from \"admin/event-scheduled/ScheduledEventCronUtils\";\nimport { DEFAULT_CRON_EXPRESSION } from \"utils/DEFAULTS\";\nimport { minValueEqual, maxValueEqual } from \"utils/normalise\";\nimport { isKthBitSet } from \"utils/bit-operations\";\nimport NumberInput from \"semantic-ui-react-numberinput\";\n\n// range limits\nconst minValueEqual0 = minValueEqual(0);\nconst maxValueEqual15 = maxValueEqual(15);\n\nconst validate = (values) => {\n const { mineLevelId } = values;\n\n const errors = {};\n\n if (!mineLevelId) {\n errors.mineLevelId = \"Required\";\n }\n\n //console.log(\"xxx validate\", errors);\n\n return errors;\n};\n\nconst normalise = (value, type) => {\n if (type === \"noSpaces\") {\n return value.replace(\" \", \"_\");\n } else {\n return value;\n }\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst isScheduledEventNameOK = (value, allValues, props, name) => {\n const { id } = allValues;\n\n const { strings } = props;\n\n if (false) {\n return strings?.[\"This name has already been used\"];\n } else {\n return undefined;\n }\n};\n\n// DEBUG\nconst DEBUG_HIDDEN = { display: \"none\" }; // null\n\nclass ScheduledEventForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n currentTimezone: \"\",\n selectedTimezone: \"\",\n //\n date: \"\",\n time: \"\",\n dateTime: \"\",\n datesRange: \"\",\n\n dateStart: \"\",\n dateStop: \"\",\n\n //\n disableDay: false,\n //\n cronValue: DEFAULT_CRON_EXPRESSION,\n //\n isAddEvent: true,\n events: [],\n //\n valueBitRegister: \"0\",\n valueDuration: \"1\",\n };\n }\n\n componentDidMount() {\n const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n this.setState({\n selectedTimezone: currentTimezone,\n currentTimezone,\n });\n //\n\n // console.log(\n // \"xxx componentDidMount initialValues.events\",\n // this.props.initialValues.events\n // );\n\n // initialise events - these are managed in local state\n this.setState({ events: this.props.initialValues.events });\n }\n\n resetForm = (e) => {\n e.preventDefault();\n\n this.props.reset();\n // initialise events - these are managed in local state\n this.setState({ events: this.props.initialValues.events });\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // https://github.com/Asymmetrik/ngx-leaflet/issues/88\n // unmount error - \"TypeError: Cannot read property 'off' of undefined\"\n\n // abort page changes\n //this.props.reset();\n this.props.onCancel();\n };\n\n submitMyForm = (values) => {\n const { reduxFormValues } = this.props;\n\n //console.log(\"xxx submitMyForm values\", values);\n\n const { events } = this.state;\n this.props.onSubmit({ ...reduxFormValues, events });\n };\n\n requestDelete = (id) => {\n const { change } = this.props;\n // #NOTE -\n // This is a fudge to stop the navigation prompt modal dlg.\n // Call change to populate the formValue `_action` at the beginning of the delete process.\n // The _action value is checked in the NavigationPromptModal, which does not display.\n change(\"_action\", \"delete\");\n\n this.props.onDelete(id);\n };\n\n setSelectedTimezone = (selectedTimezone) => {\n //console.log(\"xxx setSelectedTimezone\", selectedTimezone);\n\n this.setState({ selectedTimezone });\n };\n\n callback = (cronValue) => {\n //console.log(\"xxx cronValue\", cronValue);\n };\n\n handleSelectMonth = () => {};\n handleCheckEveryMonth = (e, data) => {\n if (data) {\n this.props.change(\"month.value\", 1);\n } else {\n this.props.change(\"month.value\", \"*\");\n }\n };\n handleSelectDay = () => {};\n handleCheckEveryDay = (e, data) => {\n if (data) {\n this.props.change(\"dayOfMonth.value\", 1);\n } else {\n this.props.change(\"dayOfMonth.value\", \"*\");\n }\n };\n handleSelectDayOfWeek = (e, data) => {\n if (data > 0) {\n this.setState({ disableDay: true }, () => {\n this.props.change(\"dayOfMonth.every\", false);\n this.props.change(\"dayOfMonth.value\", \"*\");\n });\n } else {\n this.setState({ disableDay: false });\n }\n };\n\n handleCheckEveryHour = (e, data) => {\n // if (data) {\n // // checked\n // this.props.change(\"hour.value\", 1);\n // }\n // //unchecked\n // else {\n // this.props.change(\"hour.value\", 1);\n // }\n };\n\n handleCheckEveryMinute = (e, data) => {\n //console.log(\"xxx handleCheckEveryMinute\", data);\n\n if (data === true) {\n // checked\n this.props.change(\"minute.value\", 2);\n\n this.props.change(\"duration.value\", 1);\n this.setState({ valueDuration: \"1\" });\n //this.props.change(\"duration.unit\", \"minute\");\n }\n // uncheck\n else {\n this.props.change(\"minute.value\", 0);\n\n this.props.change(\"duration.value\", 1);\n this.setState({ valueDuration: \"1\" });\n }\n };\n\n handleSelectGroup = (e, data) => {\n //console.log(\"xxx handleSelectGroup data\", data);\n\n this.setState({ isAddEvent: true });\n this.props.change(\"namedAreaGroupOption.level\", \"none\");\n this.props.change(\"namedAreaGroupOption.polygon\", \"none\");\n };\n\n handleSelectLevel = (e, data) => {\n //console.log(\"xxx handleSelectLevel data\", data);\n\n this.setState({ isAddEvent: true });\n //this.props.change(\"namedAreaGroupOption.polygon\", \"none\");\n };\n\n handleSelectPolygon = (e, data) => {\n //console.log(\"xxx handleSelectPolygon data\", data);\n\n this.setState({ isAddEvent: false });\n };\n\n onClickAddEvent = (e, data) => {\n //console.log(\"xxx onClickAddEvent data\", data);\n\n const {\n reduxFormValues: {\n namedAreaGroupOption: { polygonId },\n },\n namedAreaGroupInfo,\n } = this.props;\n\n // console.log(\"xxx onClickAddEvent reduxFormValues\", reduxFormValues);\n // console.log(\"xxx onClickAddEvent namedAreaGroupInfo\", namedAreaGroupInfo);\n\n let newEvents = [...this.state.events];\n\n const eventInfo = newEvents.find((event) => event.polygonId === polygonId);\n if (!eventInfo) {\n const test = namedAreaGroupInfo?.filter((i) => i.polygonId !== polygonId);\n\n //console.log(\"xxx onClickAddEvent test\", polygonId, test);\n\n const nagInfo = namedAreaGroupInfo?.find(\n (i) => i.polygonId === polygonId\n );\n //console.log(\"xxx onClickAddEvent nagInfo\", nagInfo);\n\n if (nagInfo) {\n newEvents.push(nagInfo);\n this.setState({ events: newEvents }, () => {\n this.props.change(\"events\", newEvents);\n });\n }\n }\n };\n\n // see - https://github.com/arfedulov/semantic-ui-calendar-react\n handleChange = (event, { name, value }) => {\n //console.log(\"xxx name, value\", name, value);\n\n if (this.state.hasOwnProperty(name)) {\n this.setState({ [name]: value });\n }\n\n switch (name) {\n case \"dateStart\":\n this.props.change(\"start.date\", value);\n break;\n case \"dateStop\":\n this.props.change(\"stop.date\", value);\n break;\n default:\n break;\n }\n };\n\n handleUserRelayChange = (e, data) => {\n //console.log(\"xxx handleUserRelayChange \", data);\n\n const { value, polygonId } = data;\n\n let newEvents = [...this.state.events];\n\n // copy event & update it\n let currentEvent = {\n ...newEvents.find((event) => event.polygonId === polygonId),\n };\n currentEvent.userRelay = Number(value);\n\n // filter event\n newEvents = newEvents.filter((event) => event.polygonId !== polygonId);\n\n // add back the update event\n newEvents.push(currentEvent);\n this.setState({ events: newEvents });\n };\n\n handleTrashClick = (e, data) => {\n //console.log(\"xxx handleTrashClick data\", data);\n\n let newEvents = [...this.state.events];\n newEvents = newEvents.filter((event) => event.polygonId !== data.id);\n\n this.setState({ events: newEvents }, () =>\n this.props.change(\"events\", newEvents)\n );\n };\n\n handleChangeStepperBitRegister = (value) => {\n this.setState({ valueBitRegister: value });\n };\n\n handleChangeDuration = (value) => {\n this.setState({ valueDuration: value });\n this.props.change(\"duration.value\", Number(value));\n };\n\n // if duration units change reset the value -> 0\n handleSelectDurationUnit = () => {\n this.setState({ valueDuration: \"1\" });\n this.props.change(\"duration.value\", Number(1));\n };\n\n render() {\n const {\n header,\n handleSubmit,\n pristine,\n submitting,\n error,\n initialValues,\n strings,\n reduxFormValues,\n cronStartExpression,\n cronStopExpression,\n userLanguage,\n everyDay,\n everyHour,\n everyMinute,\n id,\n } = this.props;\n\n // APP_TERMINOLOGY\n let strScheduledEvent = strings?.[\"Scheduled Job\"];\n let strScheduledEvents = strings?.[\"Scheduled Jobs\"];\n\n const isNewScheduledEvent = id === \"undefined\";\n\n const { errorMessage } = this.state;\n\n //console.log(\"xxx this.props\", this.props);\n // console.log(\"xxx initialValues\", initialValues);\n // console.log(\"xxx initialValues\", initialValues);\n //console.log(\"xxx reduxFormValues\", reduxFormValues);\n // console.log(\"xxx cronStartExpression\", cronStartExpression);\n // console.log(\"xxx cronStopExpression\", cronStopExpression);\n\n // see - https://github.com/bradymholt/cRonstrue/tree/master/src/i18n/locales\n // for a list of supported locales\n // userLanguage will be e.g. \"es-419\" so strip off the locale\n let cronstrueLocale = \"en\";\n const userLocale = userLanguage?.split(\"-\")?.[0] || \"en\";\n if (userLocale) cronstrueLocale = userLocale;\n //console.log(\"xxx cronstrueLocale\", cronstrueLocale);\n\n // #NOTE - restrict the minimum event period to 1 minutes ON-OFF.\n // i.e. minimum event period is 1min // #TODO - make this an option??????\n // This allows sufficient time for the ON event to activate and propogate around the system\n // in a slow network sitation before the OFF activation is sent.\n //\n // So cases:\n // - if every 2 minute is selected fix the duration option to 1min\n // - if every 3 min then duration options: 1,2\n // - if every 4 min then duration options: 1,2,3\n\n const durationInputMax = () => {\n let max = 1;\n const unit = this.props?.reduxFormValues?.duration?.unit;\n const valueMin = this.props?.reduxFormValues?.minute?.value;\n const everyMin = this.props?.reduxFormValues?.minute?.every;\n\n switch (unit) {\n case \"hour\":\n max = 23;\n break;\n case \"minute\":\n if (!everyMin) {\n max = 59;\n } else if (valueMin > 2) {\n max = valueMin - 1;\n }\n break;\n\n default:\n break;\n }\n return max;\n };\n\n let optionsFilteredDuration = [...optionsDuration];\n\n if (everyHour)\n optionsFilteredDuration = optionsFilteredDuration?.filter(\n (opt) => opt.value !== \"hour\"\n );\n\n let optionsFilteredDayOfMonth = [...optionsDays()];\n if (everyDay) {\n optionsFilteredDayOfMonth = optionsFilteredDayOfMonth?.filter(\n (opt) => opt.value !== \"*\"\n );\n }\n\n const eventsTableNoneContent = (\n \n {strings?.[\"Add a Polygon\"]}\n {/* */}\n \n \n \n \n \n );\n\n const eventsTableContent = (event) => {\n const {\n polygonId,\n groupLabel,\n levelLabel,\n buttonLabel,\n buttonCustomLabel,\n userRelay,\n } = event;\n\n // #TODO - change to stepper!!!!!!!!!!1\n //https://github.com/pksilen/semantic-ui-react-numberinput\n\n const userRelayContent = (event) => {\n return (\n <>\n {/* (value !== \"\" ? Number(value) : \"\")}\n /> */}\n \n \n );\n };\n\n return (\n \n {/* {polygonId} */}\n {groupLabel}\n {levelLabel}\n {`${buttonLabel} (${buttonCustomLabel})`}\n {userRelayContent(event)}\n \n \n \n \n );\n };\n\n const nextCronTableContent = (startExp, stopExp, userLanguage) => {\n const start = parseExpression(startExp);\n const stop = parseExpression(stopExp);\n\n const rows = [1, 2, 3];\n const dateFormat = {\n weekday: \"short\",\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: false,\n };\n\n const content = [];\n\n rows.forEach((row) => {\n const startDate = new Date(start.next().toString()).toLocaleString(\n userLanguage,\n dateFormat\n );\n\n const stopDate = new Date(stop.next().toString()).toLocaleString(\n userLanguage,\n dateFormat\n );\n\n content.push(\n \n {row}\n {startDate}\n {stopDate}\n \n );\n });\n\n return content;\n };\n\n return (\n \n
\n \n \n \n \n \n \n \n {!isNewScheduledEvent && (\n \n \n {/* \n Delete\n */}\n \n )}\n \n \n \n \n \n \n this.resetForm(e)}\n >\n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n \n \n \n \n \n
{header}
\n
\n
\n \n \n normalise(value, \"normalise\")}\n />\n \n \n \n \n
\n {\n // #NOTE - (for future development) - there is not absolute time entry (all times are relative to the server time) so no need to set a timezone for entry\n false && (\n \n
\n \n {strings?.[\"timezone\"]}\n \n
\n \n
\n
\n
\n )\n }\n {\n // NOTE - (for future development) - for addition of absolute start/stop times.\n false && (\n \n \n \n \n \n \n \n
\n \n
\n\n \n \n
\n
\n
\n
\n )\n }\n \n \n \n \n \n \n
\n \n
\n \n \n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n \n \n
\n \n
\n
\n
\n
\n
\n {false && (\n \n \n \n \n \n \n
\n \n
\n \n \n
\n
\n
\n
\n )}\n \n \n \n \n \n \n
\n \n
\n \n \n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n \n \n
\n
\n
\n
\n {\n // NOTE - (for future development) - for addition of absolute start/stop times.\n // #TODO - if this is developed need to accommodate locale for month format etc\n false && (\n \n \n \n \n \n \n \n
\n \n
\n \n \n
\n
\n
\n
\n )\n }\n \n \n \n \n \n \n {/* */}\n \n \n \n \n \n \n \n
\n \n \n \n \n \n
\n {strings?.[\"Schedule\"]}\n
\n \n \n
\n \n {strings?.[\"Activate\"]}\n
\n
\n {cronstrue?.toString(\n cronStartExpression,\n {\n locale: cronstrueLocale,\n use24HourTimeFormat: true,\n }\n )}\n
\n
\n \n normalise(value, \"normalise\")\n }\n disabled\n />\n
\n
\n \n
\n \n {strings?.[\"Deactivate\"]}\n
\n
\n {cronstrue?.toString(cronStopExpression, {\n locale: cronstrueLocale,\n use24HourTimeFormat: true,\n })}\n
\n
\n \n normalise(value, \"normalise\")\n }\n disabled\n />\n
\n
\n
\n \n \n \n \n \n CRON\n \n \n {cronStartExpression}\n \n \n {cronStopExpression}\n \n \n \n \n {strings?.[\"Next\"]}\n \n \n {strings?.[\"Activate\"]}\n \n \n {strings?.[\"Deactivate\"]}\n \n \n \n {nextCronTableContent(\n cronStartExpression,\n cronStopExpression,\n userLanguage\n )}\n \n
\n
\n
\n
\n \n {false && (\n // #REVIEW #TODO - left here as an example of using the job schedule to do other things\n \n
\n {strings?.[\"System Message\"]}\n
\n {\n // data filter to level\n //const levelData = data.filter(item => item.area === level.id) || {};\n return {\n menuItem: level.name,\n render: () => (\n \n {strings?.[\"FUTURE_FEATURE\"]}\n \n ),\n };\n })}\n />\n
\n )}\n \n
\n {strings?.[\"Lighting Event\"]}\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n \n
\n
\n \n
\n
\n \n
\n
\n \n
\n
\n \n
\n \n {strings?.[\"Add\"]}\n \n }\n />\n \n
\n \n \n \n \n \n {/* \n {strings?.[\"ID\"]}\n */}\n \n {strings?.[\"Group\"]}\n \n \n {strings?.[\"Level\"]}\n \n \n {strings?.[\"Polygon\"]}\n \n \n {strings?.[\"User Relay\"]}\n \n \n \n \n \n \n {this.state?.events?.length < 1\n ? eventsTableNoneContent\n : this.state?.events?.map?.((event) =>\n eventsTableContent(event)\n )}\n \n
\n
\n \n
\n
\n \n \n \n \n \n \n \n \n \n
\n\n \n
\n );\n }\n}\n\nconst selector = formValueSelector(\"scheduledEventForm\");\n\nScheduledEventForm = reduxForm({\n form: \"scheduledEventForm\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(ScheduledEventForm);\n\nconst getGroupOptions = (nagInfo, areaId, strings) => {\n let options = [];\n\n if (areaId === undefined) {\n options.push({\n key: \"none\",\n text: strings?.[\"Choose an Area\"],\n value: \"none\",\n });\n return options;\n }\n\n if (nagInfo.length < 1) {\n options.push({\n key: \"none\",\n text: strings?.[\"No Groups defined\"],\n value: \"none\",\n });\n return options;\n }\n\n nagInfo.forEach((info, idx) => {\n const isKeyExists = options?.some(\n (option) => option.value === info.groupLabel\n );\n //console.log(\"xxx isKeyExists info\", info);\n //console.log(\"xxx isKeyExists\", isKeyExists);\n if (\n !isKeyExists\n // stop duplicate keys\n ) {\n options.push({ key: idx, text: info.groupLabel, value: info.groupLabel });\n }\n });\n return options;\n};\n\nconst getLevelOptions = (nagInfo, groupOption, strings) => {\n let options = [];\n\n if (groupOption === \"none\") {\n options.push({\n key: \"none\",\n text: strings?.[\"Choose a Group\"],\n value: \"none\",\n });\n return options;\n }\n\n if (nagInfo.length < 1) {\n options.push({\n key: \"none\",\n text: strings?.[\"No Levels defined\"],\n value: \"none\",\n });\n return options;\n }\n\n nagInfo.forEach((info, idx) => {\n if (info.groupLabel === groupOption) {\n const isKeyExists = options?.some(\n (option) => option.value === info.levelLabel\n );\n\n if (\n // stop duplicate keys\n !isKeyExists\n ) {\n options.push({\n key: idx,\n text: info.levelLabel,\n value: info.levelLabel,\n });\n }\n }\n });\n return options;\n};\n\nconst getPolygonOptions = (\n nagInfo,\n groupOption,\n levelOption,\n events,\n strings\n) => {\n let options = [];\n\n if (levelOption === \"none\") {\n options.push({\n key: \"none\",\n text: strings?.[\"Choose a Level\"],\n value: \"none\",\n });\n return options;\n }\n\n if (nagInfo.length < 1) {\n options.push({\n key: \"none\",\n text: strings?.[\"No Polygons defined\"],\n value: \"none\",\n });\n return options;\n }\n\n nagInfo.forEach((info, idx) => {\n //console.log(\"xxx getPolygonOptions info\", info);\n //console.log(\"xxx getPolygonOptions groupOption\", groupOption);\n //console.log(\"xxx getPolygonOptions levelOption\", levelOption);\n //console.log(\"xxx getPolygonOptions events\", events);\n //console.log(\"xxx getPolygonOptions info.polygonId\", info.polygonId);\n\n const isAlreadySelected = events?.some(\n (event) => event.polygonId === info.polygonId\n );\n\n //console.log(\"xxx getPolygonOptions isAlreadySelected\", isAlreadySelected);\n //console.log(\"xxx getPolygonOptions ------------------\");\n\n if (\n info.levelLabel === levelOption &&\n info.groupLabel === groupOption &&\n !isAlreadySelected\n ) {\n const text = `${info.buttonLabel} ${\n info.buttonCustomLabel !== \"\" ? `(${info.buttonCustomLabel})` : \"\"\n }`;\n options.push({\n key: idx,\n text,\n value: info.polygonId,\n });\n }\n });\n return options;\n};\n\nconst mapStateToProps = (state, props) => {\n const mineLevelId = selector(state, \"mineLevelId\");\n const area = getAreaStatusesById(state, mineLevelId);\n\n // #NOTE #REVIEW - this is used to create the selector options for the polygon with [x] Scheduled Event checked (i.e. permission bit 2 = true in namedAreaGroup)\n // This `getNamedAreasInfoInNamedAreaGroupByAreaId` is very similar to the golang func() `Get_Named_Areas_Info_In_Named_Area_Group` since the later was\n // created to support the trigger event mqtt information messages 'ext_trigger/+/info'. This could be cleaned up to have one source of information.\n //\n const namedAreaGroupInfo = getNamedAreasInfoInNamedAreaGroupByAreaId(\n state,\n mineLevelId\n );\n\n // filter info based on settings.permission kthbit 2 is set for 'scheduled_event'\n const newNamedAreaGroupInfo = namedAreaGroupInfo.filter((info) =>\n isKthBitSet(info.permission, 2)\n );\n\n const groupOptions = getGroupOptions(\n newNamedAreaGroupInfo,\n mineLevelId,\n props.strings\n );\n\n const levelOptions = getLevelOptions(\n newNamedAreaGroupInfo,\n selector(state, \"namedAreaGroupOption.group\"),\n props.strings\n );\n\n const polygonOptions = getPolygonOptions(\n newNamedAreaGroupInfo,\n selector(state, \"namedAreaGroupOption.group\"),\n selector(state, \"namedAreaGroupOption.level\"),\n selector(state, \"events\"),\n props.strings\n );\n\n // console.log(\"xxx mineLevelId\", mineLevelId);\n // console.log(\"xxx namedAreaGroupInfo\", namedAreaGroupInfo);\n // console.log(\"xxx newNamedAreaGroupInfo\", newNamedAreaGroupInfo);\n // console.log(\"xxx groupOptions\", groupOptions);\n // console.log(\"xxx levelOptions\", levelOptions);\n // console.log(\"xxx polygonOptions\", polygonOptions);\n\n return {\n id: props?.id || \"undefined\",\n mineLevelId,\n area,\n cronStartExpression:\n selector(state, \"cron.start\") || DEFAULT_CRON_EXPRESSION,\n cronStopExpression: selector(state, \"cron.stop\") || DEFAULT_CRON_EXPRESSION,\n\n everyMonth: selector(state, \"month.every\"),\n everyDay: selector(state, \"dayOfMonth.every\"),\n everyHour: selector(state, \"hour.every\"),\n everyMinute: selector(state, \"minute.every\"),\n durationUnit: selector(state, \"duration.unit\"),\n // selector options\n groupOptions,\n levelOptions,\n polygonOptions,\n namedAreaGroupInfo,\n //\n events: selector(state, \"events\"),\n\n reduxFormValues: getFormValues(\"scheduledEventForm\")(state),\n onChange: (values, dispatch, props, previousValues) => {\n const { change } = props;\n\n //console.log(\"xxx onChange values\", values);\n //console.log(\"xxx onChange props.reduxFormValues\", props.reduxFormValues);\n const newCron = convertFieldsToCronExpression(props.reduxFormValues);\n\n dispatch(change(\"cron.start\", newCron.start));\n dispatch(change(\"cron.stop\", newCron.stop));\n },\n };\n};\n\nexport default connect(mapStateToProps, null)(ScheduledEventForm);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Container } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Grid from \"semantic-ui-react/dist/commonjs/collections/Grid\";\n\nimport ScheduledEventSimpleForm from \"admin/event-scheduled/ScheduledEventForm\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport {\n fetchNamedAreaScheduledEventInfo,\n saveNewScheduledEvent,\n} from \"NamedAreas/actions\";\nimport { getUserData } from \"auth/reducer\";\nimport {\n DEFAULT_CRON_EXPRESSION,\n DEFAULT_CRON_EXPRESSION_STOP,\n} from \"utils/DEFAULTS\";\nimport { v4 as uuid } from \"uuid\";\n\nclass ScheduledEventCreatePage extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n this.props.fetchNamedAreaScheduledEventInfo();\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n _preProcessValues = (values) => {\n //console.log(\"xxx values\", values);\n const {\n //\n } = values;\n\n return values;\n };\n\n submitMyForm = (values) => {\n const { saveNewScheduledEvent } = this.props;\n\n //console.log(\"xxx saveNewScheduledEvent submitMyForm values\", values);\n\n const id = uuid(); // see - src/admin/named-area-simple/NamedAreaSimpleCreatePage.js, also see for copy()\n const password = uuid(); // not supported ATM\n\n const {\n name,\n disable,\n cron,\n mineLevelId: area_id,\n note,\n duration,\n events,\n } = values;\n\n // #NOTE - events are in the form ............\n // e.g.\n // const events = [\n // {\n // polygon_id: uuid(),\n // user_relay: 1,\n // },\n // // {\n // // polygon_id: uuid(),\n // // user_relay: 3,\n // // },\n // // {\n // // polygon_id: uuid(),\n // // user_relay: 5,\n // // },\n // ];\n\n const newEvents = events.map((event) => {\n return { polygon_id: event.polygonId, user_relay: event.userRelay };\n });\n\n const cron_active_duration = `${duration.value}:${duration.unit}`;\n const info = JSON.stringify(values);\n\n const newValues = {\n id,\n name,\n cron,\n area_id,\n disable,\n events: newEvents,\n note,\n password,\n cron_active_duration,\n info,\n };\n\n //console.log(\"xxx save newValues\", newValues);\n\n return new Promise((resolve, reject) => {\n saveNewScheduledEvent({\n values: newValues,\n resolve,\n reject,\n });\n }).then(() => {\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n const { fetchNamedAreaScheduledEventInfo } = this.props;\n fetchNamedAreaScheduledEventInfo(); // #FETCHS\n\n this.props.goto(`/admin/scheduled-job`);\n }\n );\n });\n };\n\n render() {\n const {\n //isLoading, error,\n strings,\n userLanguage,\n } = this.props;\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n // APP_TERMINOLOGY\n let strScheduledEvent = strings?.[\"Scheduled Job\"];\n let strScheduledEvents = strings?.[\"Scheduled Jobs\"];\n\n return (\n
\n \n this.submitMyForm(this._preProcessValues(formValues))\n }\n />\n \n \n \n \n
{strings?.[\"Add Scheduled Job\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n this.submitMyForm(this._preProcessValues(values))\n }\n onCancel={() => {\n this.props.goto(`/admin/scheduled-job`);\n }}\n strings={strings}\n userLanguage={userLanguage}\n />\n\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n return {\n userLanguage: getUserData(state)?.language || \"en-US\",\n };\n};\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n fetchNamedAreaScheduledEventInfo: () =>\n dispatch(fetchNamedAreaScheduledEventInfo()),\n saveNewScheduledEvent: (data) => dispatch(saveNewScheduledEvent(data)),\n //\n };\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(ScheduledEventCreatePage);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Container } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Grid from \"semantic-ui-react/dist/commonjs/collections/Grid\";\n\nimport ScheduledEventSimpleForm from \"admin/event-scheduled/ScheduledEventForm\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { getScheduledEventJobInfo } from \"components/WebWorker/reducer\";\nimport {\n fetchNamedAreaScheduledEventInfo,\n saveNewScheduledEvent,\n deleteScheduledEventJob,\n} from \"NamedAreas/actions\";\nimport { getUserData } from \"auth/reducer\";\nimport { v4 as uuid } from \"uuid\";\n\nclass ScheduledEventEdtPage extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n submitted: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n this.props.fetchNamedAreaScheduledEventInfo();\n\n console.log(\n \"xxx componentDidMount src/admin/event-scheduled/ScheduledEventEditPage.js\"\n );\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n this.setState({ errorMessage: \"\" });\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n _preProcessValues = (values) => {\n const {\n //\n } = values;\n\n return values;\n };\n\n submitMyForm = (values) => {\n const { saveNewScheduledEvent } = this.props;\n\n console.log(\"xxx saveNewScheduledEvent submitMyForm values\", values);\n\n const id = this.props.id;\n const password = uuid(); // not supported ATM\n\n const {\n name,\n disable,\n cron,\n mineLevelId: area_id,\n note,\n duration,\n events,\n } = values;\n\n // #NOTE - events are in the form ............\n // e.g.\n // const events = [\n // {\n // polygon_id: uuid(),\n // user_relay: 1,\n // },\n // // {\n // // polygon_id: uuid(),\n // // user_relay: 3,\n // // },\n // // {\n // // polygon_id: uuid(),\n // // user_relay: 5,\n // // },\n // ];\n\n const newEvents = events.map((event) => {\n return { polygon_id: event.polygonId, user_relay: event.userRelay };\n });\n\n const cron_active_duration = `${duration.value}:${duration.unit}`;\n const info = JSON.stringify(values);\n\n const newValues = {\n id,\n name,\n cron,\n area_id,\n disable,\n events: newEvents,\n note,\n password,\n cron_active_duration,\n info,\n };\n\n //console.log(\"xxx save newValues\", newValues);\n\n return new Promise((resolve, reject) => {\n saveNewScheduledEvent({\n values: newValues,\n resolve,\n reject,\n });\n }).then(() => {\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n const { fetchNamedAreaScheduledEventInfo } = this.props;\n fetchNamedAreaScheduledEventInfo(); // #FETCHS\n\n this.props.goto(`/admin/scheduled-job`);\n }\n );\n });\n };\n\n render() {\n const {\n //isLoading, error,\n id,\n formValues,\n strings,\n userLanguage,\n } = this.props;\n const { errorMessage } = this.state;\n\n const openModal = errorMessage !== \"\";\n\n // APP_TERMINOLOGY\n let strScheduledEvent = strings?.[\"Scheduled Job\"];\n let strScheduledEvents = strings?.[\"Scheduled Jobs\"];\n\n return (\n
\n \n this.submitMyForm(this._preProcessValues(formValues))\n }\n />\n \n \n \n \n
{strings?.[\"Edit Scheduled Job\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n this.submitMyForm(this._preProcessValues(values))\n }\n onCancel={() => {\n this.props.goto(`/admin/scheduled-job`);\n }}\n onDelete={(id) => {\n let promiseArray = [];\n promiseArray.push(\n new Promise((resolve, reject) =>\n this.props.deleteScheduledEventJob({\n values: { id },\n resolve,\n reject,\n })\n )\n );\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"Deleting scheduled job\", results);\n })\n .then(\n () => {\n this.props.fetchNamedAreaScheduledEventInfo();\n this.props.goto(`/admin/scheduled-job/`);\n },\n (msg) => {\n console.log(\"action failed\", msg); // TODO probs should show this?\n }\n );\n }}\n strings={strings}\n userLanguage={userLanguage}\n />\n\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const match = props.match;\n const id = match.params.id;\n\n console.log(\"xxx editpage id\", id);\n\n const scheduledEventJobInfo = getScheduledEventJobInfo(state) || {};\n\n console.log(\"xxx editpage scheduledEventJobInfo\", scheduledEventJobInfo);\n\n const eventJob =\n scheduledEventJobInfo.filter((info) => info.eventJobId === id)?.[0] || {};\n\n let formValues = {};\n if (eventJob.info) {\n formValues = JSON.parse(eventJob.info);\n }\n\n console.log(\"xxx editpage eventJob\", eventJob);\n console.log(\"xxx editpage eventJob formValues\", formValues);\n\n return {\n id,\n formValues,\n userLanguage: getUserData(state)?.language || \"en-US\",\n };\n};\n\n// when props.redirect is called, dispatch the push method\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n goto: (path) => dispatch(push(path)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n fetchNamedAreaScheduledEventInfo: () =>\n dispatch(fetchNamedAreaScheduledEventInfo()),\n saveNewScheduledEvent: (data) => dispatch(saveNewScheduledEvent(data)),\n deleteScheduledEventJob: (data) => dispatch(deleteScheduledEventJob(data)),\n };\n};\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(ScheduledEventEdtPage);\n","import React, { Component } from \"react\";\nimport \"admin/event-scheduled/ScheduledEvent.css\";\n\nimport { connect } from \"react-redux\";\nimport { push as goto } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n Popup,\n Tab,\n} from \"semantic-ui-react\";\nimport _isEqual from \"lodash/isEqual\";\n\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { format } from \"date-fns\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport {\n fetchScheduledEventJobs,\n deleteScheduledEventJob,\n saveNewScheduledEvent,\n} from \"NamedAreas/actions\";\nimport hash from \"object-hash\";\nimport { toWebColor } from \"utils/toWebColor\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\nimport {\n getAllAreaStatuses,\n getScheduledEventJobInfo,\n} from \"components/WebWorker/reducer\";\nimport { formatRelative, parseISO } from \"date-fns\";\n// see - https://www.npmjs.com/package/cronstrue\nimport cronstrue from \"cronstrue/i18n\";\nimport { getUserData } from \"auth/reducer\";\nimport { v4 as uuid } from \"uuid\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ScheduledEventListAllJobs extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n disable: \"\",\n name: \"\",\n active: \"\",\n cronExpression: \"\",\n timestamp: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n\n //\n periodSelection: \"24hrs\",\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n this.props.fetchScheduledEventJobs();\n\n // #TODO - DO THIS EVERYWHERE!!!!!!!!!!!! - MAKE A FUNCTION!\n // make sure only current filter settings are updated\n const newFilterInput = this.props.componentstate.get(\n \"filterInput\",\n \"eventJobList\"\n );\n\n let filterInput = { ...this.state.filterInput };\n\n for (const key in filterInput) {\n if (Object.hasOwnProperty.call(filterInput, key)) {\n filterInput[key] = newFilterInput?.[key] || \"\";\n }\n }\n\n if (!_isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"eventJobList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n //console.log(`xxx item[key]`, item[key]);\n //console.log(`xxx match[key]`, match[key]);\n\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n requestAction = (action) => {\n const { selections } = this.state;\n const {\n deleteScheduledEventJob,\n saveNewScheduledEvent,\n onlyActiveJobs,\n strings,\n } = this.props;\n\n let promiseArray = [];\n\n if (action === \"delete\") {\n //console.log(\"xxx action delete selections\", selections);\n\n for (var key in selections) {\n const selection = key;\n\n //console.log(\"xxx action delete key\", key);\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteScheduledEventJob({\n values: { id: selection },\n resolve,\n reject,\n })\n )\n );\n }\n }\n\n if (action === \"copy\") {\n console.log(\"xxx copy selections\", selections);\n\n for (var key in selections) {\n const selection = key;\n\n const jobTemplate =\n onlyActiveJobs?.find((job, idx) => job.eventJobId === selection) ||\n {};\n\n const values = JSON.parse(jobTemplate.info);\n\n // set new eventJobId for jobTemplate\n const id = uuid(); // see - src/admin/named-area-simple/NamedAreaSimpleCreatePage.js, also see for copy()\n const password = uuid(); // not supported ATM\n\n const {\n name,\n disable,\n cron,\n mineLevelId: area_id,\n note,\n duration,\n events,\n } = values;\n\n const newEvents = events.map((event) => {\n return { polygon_id: event.polygonId, user_relay: event.userRelay };\n });\n\n const cron_active_duration = `${duration.value}:${duration.unit}`;\n\n const copyString = `(${strings?.[\"copy\"]})`;\n const newName = `${name} ${copyString}`;\n const info = JSON.stringify({\n ...values,\n name: newName,\n });\n\n const newValues = {\n id,\n name: newName,\n cron,\n area_id,\n disable,\n events: newEvents,\n note,\n password,\n cron_active_duration,\n info,\n };\n\n //console.log(\"xxx copy newValues\", newValues);\n\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveNewScheduledEvent({\n values: newValues,\n resolve,\n reject,\n });\n })\n );\n }\n }\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\" .... processed Scheduled Jobs selections.\", results);\n })\n .then(\n () => {\n this.props.fetchScheduledEventJobs();\n this.props.goto(`/admin/scheduled-job/`);\n },\n (errorMsg) => {\n console.log(\"action failed\", errorMsg); // #TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, levels, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // APP_TERMINOLOGY\n let strEventJob = strings?.[\"Scheduled Job\"];\n let strEventJobs = strings?.[\"Scheduled Jobs\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const eventJobFromDataById = (id) => allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let addButton;\n let updateButton;\n let enableButton;\n let disableButton;\n let deleteButton;\n let copyButton;\n let eventJobSelectedList;\n\n addButton = (\n \n \n }\n />\n );\n\n if (selectedCount > 0) {\n let eventJobNames = [];\n\n for (var key in selections) {\n if (eventJobFromDataById(key) !== undefined) {\n let eventJobName = eventJobFromDataById(key).name;\n eventJobNames.push(eventJobName);\n }\n }\n eventJobNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n eventJobNames = eventJobNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n size=\"large\"\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n size=\"large\"\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")}\n strings={strings}\n />\n );\n\n copyButton = (\n this.requestAction(\"copy\")}\n size=\"large\"\n />\n );\n\n eventJobSelectedList = (\n \n {`${strEventJob} selected ...`} \n {eventJobNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{strings?.[\"Scheduled Jobs\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n {!areAnySelected && (\n <>\n \n {addButton}\n \n {updateButton}\n \n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n \n )}\n \n \n \n \n {copyButton}\n {}\n {deleteButton}\n {false && }\n {false && enableButton}\n {false && }\n {false && disableButton}\n \n
\n \n {viewablesPage.length} items displayed. {selectedCount} selected\n \n \n {eventJobSelectedList}\n \n {levels.length === 0 && (\n \n )}\n {levels.length > 0 && (\n {\n // data filter to level\n //const levelData = data.filter(item => item.area === level.id) || {};\n return {\n menuItem: level.name,\n render: () => (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* \n \n */}\n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)\n }\n />\n \n \n {strings?.[\"Disabled\"]}\n \n \n {strings?.[\"Name\"]}\n \n \n {strings?.[\"Start\"]}\n \n \n {strings?.[\"State\"]}\n \n\n \n {strings?.[\"Duration\"]}\n \n {/* \n {strings?.[\"Active\"]}\n */}\n \n {strings?.[\"Note\"]}\n \n \n {strings?.[\"Created\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n disable,\n nameLink,\n active,\n cronExpression,\n duration,\n jobCreated,\n note,\n style,\n jobState,\n jobStateClass,\n }) => (\n \n \n this.handleSelect(id)}\n />\n \n {disable}\n \n {nameLink}\n \n \n {cronExpression}\n \n \n {jobState}\n \n \n {duration}\n \n {/* {active} */}\n {note}\n \n {jobCreated}\n \n \n )\n )}\n \n \n
\n {pagination}\n
\n ),\n };\n })}\n />\n )}\n \n \n \n );\n }\n}\n\nconst _prepData = ({ elements, strings, userLanguage }) => {\n let filteredElements = [];\n\n elements.forEach(function (element, idx) {\n const {\n active,\n activeJob,\n area,\n cron,\n cronActiveDuration,\n cronId,\n disable,\n eventJobId,\n name,\n note,\n password,\n timestamp,\n userRelay,\n } = element;\n\n console.log(\"xxx _prepData element\", element);\n\n let jobCreated = \"-\";\n if (timestamp !== null && timestamp !== undefined) {\n // format - previous used in tableformatters.js\n jobCreated = formatRelative(timestamp * 1000, new Date(), {\n includeSeconds: true,\n });\n }\n\n let style = null;\n\n // change row if active\n //if (!active) style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n\n // set style of disabled jobs\n if (disable === true) {\n style = {\n // backgroundColor: \"rgb(239, 239, 239, 0.3)\", // turn red-ish?\n //color: \"rgb(0, 0, 0, 0.3)\", // make the test \"grey\"\n };\n }\n\n // see - https://github.com/bradymholt/cRonstrue/tree/master/src/i18n/locales\n // for a list of supported locales\n // userLanguage will be e.g. \"es-419\" so strip off the locale\n let cronstrueLocale = \"en\";\n const userLocale = userLanguage?.split(\"-\")?.[0] || \"en\";\n if (userLocale) cronstrueLocale = userLocale;\n\n const cronExpression = cronstrue?.toString(cron, {\n locale: cronstrueLocale,\n use24HourTimeFormat: true,\n });\n const duration = cronActiveDuration?.split(\":\")?.join(\" \")?.toString();\n\n // display state of job\n // - QUEUED\n // - RUNNING...\n //\n let jobState = strings?.[\"QUEUED\"];\n let jobStateClass = null;\n if (activeJob && !disable) {\n jobState = `${strings?.[\"RUNNING\"]}...`;\n jobStateClass = \"flashing jobStateBg\";\n }\n\n // compose new data set\n filteredElements[idx] = {\n id: eventJobId,\n active: active ? strings?.[\"ACTIVE\"] : strings?.[\"INACTIVE\"],\n name,\n nameLink: (\n {name} \n ),\n cronExpression,\n duration,\n area,\n note,\n jobCreated,\n style,\n disable: disable ? strings?.[\"DISABLED\"] : strings?.[\"ENABLED\"],\n jobState,\n jobStateClass,\n timestamp: `${timestamp}`,\n };\n });\n\n return filteredElements;\n};\n\nfunction mapStateToProps(state, props) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.eventJobs;\n const isLoading = false;\n const error = false;\n\n const allAreas = getAllAreaStatuses(state);\n\n let levels = [];\n let onlyActiveJobs = [];\n\n // create level information\n allAreas.forEach((area) => {\n const { id } = area;\n levels.push({ id: id, name: id });\n });\n\n const scheduledEventJobInfo = getScheduledEventJobInfo(state);\n\n //console.log(\"xxx scheduledEventJobInfo\", scheduledEventJobInfo);\n\n onlyActiveJobs = scheduledEventJobInfo.filter((job) => job.active !== false);\n\n // only return one of each Even Job Id\n const uniqueKeys = [...new Set(onlyActiveJobs.map((job) => job.eventJobId))];\n\n // 'getScheduledEventJobInfo' returns a line item for every cron job so filter\n // this to show unique job #s.\n let firstJobInOnlyActiveJobs = [];\n uniqueKeys.map((key) => {\n const first = onlyActiveJobs?.filter(\n (data) => data.eventJobId === key\n )?.[0];\n firstJobInOnlyActiveJobs.push(first);\n });\n\n //console.log(\"xxx onlyActiveJobs\", onlyActiveJobs);\n //console.log(\"xxx onlyActiveJobs unique\", firstJobInOnlyActiveJobs);\n\n const data = _prepData({\n elements: firstJobInOnlyActiveJobs,\n strings: props.strings,\n userLanguage: getUserData(state)?.language || \"en-US\",\n });\n\n //console.log(\"xxx data\", data);\n //console.log(\"xxx data levels\", levels);\n\n return {\n isLoading,\n error,\n data,\n levels,\n onlyActiveJobs,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n TurnOnOffPokeTheWorker,\n goto,\n fetchScheduledEventJobs,\n saveUserSettingsComponentState,\n deleteScheduledEventJob,\n saveNewScheduledEvent,\n })(ScheduledEventListAllJobs)\n);\n","import Immutable from \"seamless-immutable\";\nimport isEmpty from \"lodash/isEmpty\";\n\nconst initialState = Immutable({\n eventLog: {},\n});\n\nexport default function reduce(state = initialState, action = {}) {\n const newState = { ...state };\n const { type, payload } = action;\n\n switch (type) {\n case \"EVENT_LOG_FETCH_SUCCEEDED\":\n case \"EVENT_LOG_PERIOD_FETCH_SUCCEEDED\":\n const { list } = payload;\n\n // message is saved as a string.\n const newList = list.map((item) => {\n return {\n ...JSON.parse(item?.message),\n ts_string: item?.timestring,\n ts_sec: item?.timestamp_sec,\n ts_msec: item?.timestamp_msec,\n };\n });\n\n newState.eventLog = newList;\n return newState;\n\n case \"RESET\":\n console.log(\"RESET! - Event Log\");\n return state;\n default:\n return state;\n }\n}\n\nfunction stableOrder(order, items) {\n return Immutable(order.map((k) => items[k]));\n}\n\nconst allEventLog = (state) => {\n const byId = state.eventLog.eventLog;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getEventLog = (state) => allEventLog(state);\n\n// export const old_getEventLog = (state) => {\n// const eventLog = allEventLog(state);\n\n// let newEventLog = [];\n\n// eventLog.forEach((e) => {\n// newEventLog.push({\n// active: e.active,\n// area: e.area,\n// groupLabel: e.group_label,\n// levelLabel: e.level_label,\n// buttonLabel: e.button_label,\n// buttonCustomLabel: e.button_custom_label,\n// parent: e.parent,\n// priority: e.priority,\n// permission: e.permission,\n// reason: e.reason,\n// origin: e.origin,\n// operator: e.operator,\n// secureKey: e.secure_key,\n// timestamp: e.ts,\n// });\n// });\n\n// return newEventLog;\n// };\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push as goto } from \"react-router-redux\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n Popup,\n} from \"semantic-ui-react\";\nimport _isEqual from \"lodash/isEqual\";\n\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\nimport { format } from \"date-fns\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { fetchEventLogPeriod } from \"components/EventLog/actions\";\nimport { getEventLog } from \"components/EventLog/reducer\";\nimport hash from \"object-hash\";\nimport { toWebColor } from \"utils/toWebColor\";\nimport { formatDate } from \"utils/format-date\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nimport { CSVLink } from \"react-csv\";\n\n// XLSL 'react-export-excel' IMPLEMENTATION\n// click button to download report\n// uses https://www.npmjs.com/package/react-export-excel\n// see ex - https://github.com/rdcalle/react-export-excel/blob/HEAD/examples/with_custom_download_element.md\nimport ReactExport from \"react-export-excel\";\nconst ExcelFile = ReactExport.ExcelFile;\nconst ExcelSheet = ReactExport.ExcelFile.ExcelSheet;\nconst ExcelColumn = ReactExport.ExcelFile.ExcelColumn;\n\nclass Download extends React.Component {\n render() {\n const { data, buttonStyle } = this.props;\n\n const filename = `iot_event_log_${formatDate(\n new Date(Date.now()),\n \"dd-MMM-yy-HH-mm-ss\"\n )}`;\n\n return (\n \n \n \n }\n />\n }\n >\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n }\n}\n\nconst downloadHeaders = [\n { label: \"Polygon ID\", key: \"id\" },\n { label: \"Polygon Parent\", key: \"parentName\" },\n { label: \"Priority\", key: \"priority\" },\n { label: \"Active\", key: \"active\" },\n { label: \"Active Color\", key: \"activeColor\" },\n { label: \"Active State\", key: \"activeState\" },\n { label: \"Active State Info\", key: \"activeStateInfo\" },\n { label: \"Active Range\", key: \"range\" },\n { label: \"Relay Event Active\", key: \"relayEventActive\" },\n { label: \"FireFlys\", key: \"fireflyList\" },\n { label: \"Polygon Coords\", key: \"strShape\" },\n { label: \"Operator\", key: \"operator\" },\n { label: \"Origin\", key: \"origin\" },\n { label: \"Time\", key: \"timestamp\" },\n { label: \"Timestamp\", key: \"ts\" },\n { label: \"Note\", key: \"note\" },\n];\n\nconst periodOptions = (strings) => {\n return [\n {\n key: 0,\n text: strings?.[\"24 Hours\"],\n value: \"24hrs\",\n },\n {\n key: 1,\n text: strings?.[\"7 Days\"],\n value: \"7days\",\n },\n {\n key: 2,\n text: strings?.[\"30 Days\"],\n value: \"30days\",\n },\n {\n key: 3,\n text: strings?.[\"All\"],\n value: \"all\",\n },\n ];\n};\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass EventLogListAllEvents extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search id: \"\",\n active: \"\",\n priority: \"\",\n activeColor: \"\",\n activeState: \"\",\n button: \"\",\n relayEventActive: \"\",\n origin: \"\",\n operator: \"\",\n disable: \"\",\n timestamp: \"\",\n note: \"\",\n parentName: \"\",\n //periodSelection: \"24hrs\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n\n //\n periodSelection: \"24hrs\",\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n this.props.fetchEventLogPeriod({ period: \"24hrs\" });\n\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"eventLogList\"\n );\n\n if (!_isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n\n // const filterPeriodSelection = filterInput?.periodSelection;\n\n // switch (filterPeriodSelection) {\n // case \"\":\n // this.setState({ periodSelection: \"24hrs\" });\n // break;\n // case \"24hrs\":\n // this.setState({ periodSelection: \"24hrs\" });\n // break;\n // case \"7days\":\n // this.setState({ periodSelection: \"7days\" });\n // break;\n // case \"30days\":\n // this.setState({ periodSelection: \"30days\" });\n // break;\n // case \"all\":\n // this.setState({ periodSelection: \"all\" });\n // break;\n // default:\n // break;\n // }\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"eventLogList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n //console.log(`xxx item[key]`, item[key]);\n //console.log(`xxx match[key]`, match[key]);\n\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n // #NOTE - create a function\n // src/admin/named-area-group/NamedAreaGroupTableItems.js\n deleteItemByNamedAreaParentId = (items, id) => {\n // object structure is three levels deep\n // all id are unique\n // loop over all levels and return !== id\n\n let newItems = [];\n\n let i = 0;\n // groups\n items.forEach((item) => {\n // levels - subItems\n let newSubItem = [];\n let j = 0;\n item.subItems.forEach((item) => {\n // named areas - subSubItems\n let newSubSubItem = [];\n let k = 0;\n item.subItems.forEach((item) => {\n if (item.namedArea.id !== id) {\n newSubSubItem[k] = item;\n k = k + 1;\n }\n });\n newSubItem[j] = item;\n newSubItem[j].subItems = newSubSubItem;\n j = j + 1;\n });\n newItems[i] = item;\n newItems[i].subItems = newSubItem;\n i = i + 1;\n });\n\n return newItems;\n };\n\n handleFilterPeriodSelectorChange = (e, data) => {\n this.setState({ periodSelection: data.value });\n this.props.fetchEventLogPeriod({ period: data.value });\n };\n\n render() {\n const { isLoading, error, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // APP_TERMINOLOGY\n let strEventLog = strings?.[\"Event Log\"];\n let strEventLogs = strings?.[\"Event Log\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const namedAreaFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let updateButton;\n let periodSelector;\n let enableButton;\n let disableButton;\n let deleteButton;\n let namedAreaSelectedList;\n\n updateButton = (\n \n this.props.fetchEventLogPeriod({\n period: this.state.periodSelection,\n })\n }\n size=\"large\"\n >\n {strings?.[\"Update\"]}\n \n }\n />\n );\n\n periodSelector = (\n this.handleFilterStatusChange(data)}\n />\n );\n\n if (selectedCount > 0) {\n let namedAreaNames = [];\n //console.log(\"data\", data);\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (namedAreaFromDataById(key) !== undefined) {\n let namedAreaName = namedAreaFromDataById(key).namedArea;\n\n // namedAreaName = namedAreaName.substring(\n // 0,\n // namedAreaName.indexOf(\" (\")\n // ); // strip off the trailing ip\n namedAreaNames.push(namedAreaName);\n }\n }\n namedAreaNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n namedAreaNames = namedAreaNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")} />\n );\n\n namedAreaSelectedList = (\n
\n {`${strEventLog} selected ...`} \n {namedAreaNames}\n
\n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n
\n \n \n \n \n
{strings?.[\"Event Log\"]}
{\" \"}\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n
\n {updateButton}\n {\n // #WIP - disabled the period selector as too much data is\n // being returns and the page lags.\n // Also the download report does not work reliably (hangs) for\n // large data sets.\n\n false && periodSelector\n }\n
\n {false && !areAnySelected && (\n Select items in the table below to apply an action.\n )}\n \n \n {selectedCount} selected\n \n \n \n {deleteButton}\n {/* \n {enableButton}\n \n {disableButton} */}\n \n
\n
\n {viewablesPage.length} items displayed.\n {/* */}\n \n \n \n \n }\n />\n \n
\n \n {namedAreaSelectedList}\n \n \n \n \n {/* \n \n */}\n {/* \n \n */}\n \n {/* */}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* */}\n {/* */}\n {/* */}\n \n {/* */}\n \n \n \n \n \n \n \n \n \n \n \n \n {/* \n this.handleSelectAll(viewablesPage)}\n />\n */}\n {/* \n Disabled\n */}\n \n {strings?.[\"Time\"]}\n \n \n {strings?.[\"Event/Shape ID\"]}\n \n \n {strings?.[\"Polygon\"]}\n \n \n {strings?.[\"Active\"]}\n \n \n {strings?.[\"Priority\"]}\n \n \n {strings?.[\"Active Color\"]}\n \n \n {strings?.[\"Active State\"]}\n \n {/* \n {strings?.[\"State Info ( On | Off | Train)\"]}\n */}\n {/* \n {strings?.[\"Range (Start -> End)\"]}\n */}\n {/* \n {strings?.[\"Button Info\"]}\n */}\n \n {strings?.[\"Relay Event Active\"]}\n \n \n {strings?.[\"Origin\"]}\n \n \n {strings?.[\"Operator\"]}\n \n \n {strings?.[\"Note\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n active,\n priority,\n activeColor,\n activeState,\n button,\n relayEventActive,\n activeStateInfo,\n range,\n origin,\n operator,\n disable,\n style,\n timestamp,\n note,\n parentName,\n strShape,\n fireflyList,\n }) => (\n \n {/* \n this.handleSelect(id)}\n />\n */}\n {/* {disable} */}\n {timestamp}\n \n
\n }\n content={`${strings?.[\"FireFlys\"]} -> ${fireflyList}`}\n on=\"hover\"\n />\n }\n content={`${strings?.[\"Polygon Coords\"]} -> ${strShape}`}\n on=\"hover\"\n />\n {id}\n
\n
\n {parentName}\n {active}\n {priority}\n {activeColor}\n {activeState}\n {/* {activeStateInfo} */}\n {/* {range} */}\n {/* {button} */}\n {relayEventActive}\n {origin}\n {operator}\n {note}\n
\n )\n )}\n \n
\n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = ({ elements: rxElements, strings }) => {\n let filtered = [];\n\n const elements = [...rxElements].sort((a, b) =>\n b.ts_string > a.ts_string ? 1 : -1\n );\n\n elements.forEach(function (element, idx) {\n const {\n id,\n active,\n active_color,\n active_state,\n priority,\n button_groups,\n relay_event_active,\n //relay_event_inactive,\n on_time,\n off_time,\n train,\n start,\n end,\n origin,\n operator,\n disable,\n note,\n password,\n parent_name,\n shape,\n firefly_list,\n //\n // log times\n ts_string,\n ts_sec,\n ts_msec, //\n } = element;\n\n let strTimestamp = \"-\";\n if (ts_string !== undefined) {\n strTimestamp = format(new Date(ts_sec), \"yyyy-MMM-dd hh:mm:ss a\");\n strTimestamp = `${strTimestamp} : ${Math.floor(ts_msec / 1000)}mS`;\n }\n\n let style = null;\n // set style of disabled events\n if (active === true) {\n style = { color: toWebColor(active_color) };\n }\n\n // make shape readable\n let strShape = [];\n\n if (shape !== null) {\n shape.forEach((s) => {\n strShape.push(`[${s.toString()}]`);\n });\n strShape = strShape.join(\",\");\n } else {\n strShape.push(strings?.[\"Not Applicable\"]);\n }\n\n // make firefly_list readable\n let fireflyList = strings?.[\"Not Applicable\"];\n if (firefly_list !== \"\") fireflyList = firefly_list;\n\n filtered[idx] = {\n id,\n active: active ? strings?.[\"ACTIVE\"] : strings?.[\"INACTIVE\"],\n activeColor: active_color,\n activeState: active_state,\n activeStateInfo: `${on_time || \"-\"} | ${off_time || \"-\"} | ${\n train || \"-\"\n }`,\n range: `${start | \"-\"} -> ${end | \"-\"}`,\n priority: `${priority}`,\n button: JSON.stringify(button_groups),\n relayEventActive: `${relay_event_active || \"-\"}`,\n //relay_event_inactive, // #NOTE - not supported ATM\n origin: origin,\n operator: operator,\n disable: `${disable}`,\n note,\n password,\n style,\n timestamp: strTimestamp,\n ts: ts_string,\n parentName: parent_name,\n strShape,\n fireflyList,\n };\n });\n\n return filtered;\n};\n\nfunction mapStateToProps(state, props) {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n //const { isLoading, error } = state.namedAreas;\n const isLoading = false;\n const error = false;\n\n const allNamedAreaEvents = getEventLog(state);\n\n //console.log(\"xxx getEventLog\", allNamedAreaEvents);\n\n const data = _prepData({\n elements: allNamedAreaEvents,\n strings: props.strings,\n });\n\n return {\n isLoading,\n error,\n data,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n TurnOnOffPokeTheWorker,\n goto,\n fetchEventLogPeriod,\n saveUserSettingsComponentState,\n })(EventLogListAllEvents)\n);\n","export const fetchEventLog = () => {\n return { type: \"EVENT_LOG_FETCH_REQUESTED\" };\n};\n\nexport const fetchEventLogPeriod = (data) => {\n return { type: \"EVENT_LOG_PERIOD_FETCH_REQUESTED\", payload: data };\n};\n\nexport const deleteEventLog = (data) => {\n console.log(\"EVENT_LOG_DELETE_REQUESTED\", data);\n return { type: \"EVENT_LOG_DELETE_REQUESTED\", payload: data };\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Header,\n Grid,\n Table,\n Container,\n Input,\n Pagination,\n Dropdown,\n Icon,\n Segment,\n Button,\n Checkbox,\n Radio,\n Popup,\n Message,\n Tab,\n Form,\n} from \"semantic-ui-react\";\n\nimport { renderField } from \"admin/form-field\";\n\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport GenericButton from \"admin/GenericButton\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n//import { StatusEnum } from \"utils/StatusEnum\";\n\nimport { Download } from \"components/Download/index.js\";\n\nimport { fetchNamedAreaScheduledEventInfo } from \"NamedAreas/actions\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nconst validate = (values) => {\n const { mineLevelId, areaName, regions } = values;\n\n const errors = {};\n\n if (!mineLevelId) {\n errors.mineLevelId = \"Required\";\n }\n if (!areaName) {\n errors.areaName = \"Required\";\n }\n\n if (_isEmpty(regions)) {\n errors.regions = \"Required\";\n }\n\n return errors;\n};\n\nconst displayOptions = [\n {\n key: \"all\",\n text: \"Show All\",\n value: \"all\",\n },\n {\n key: \"ok\",\n text: \"OK\",\n value: \"ok\",\n },\n {\n key: \"commissioned\",\n text: \"New\",\n value: \"commissioned\",\n },\n // {\n // key: \"conflict\",\n // text: \"Position Conflict\",\n // value: \"conflict\",\n // },\n // {\n // key: \"moved\",\n // text: \"Position Moved\",\n // value: \"moved\",\n // },\n {\n key: \"shifted\",\n text: \"Position Shifted\",\n value: \"shifted\",\n },\n {\n key: \"timeout\",\n text: \"Timeout\",\n value: \"timeout\",\n },\n {\n key: \"old\",\n text: \"No Status Report\",\n value: \"old\",\n },\n];\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ScheduledEventListEditForm extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n id: { string: \"\", include: true },\n active: { string: \"\", include: true },\n area: { string: \"\", include: true },\n group: { string: \"\", include: true },\n level: { string: \"\", include: true },\n polygon: { string: \"\", include: true },\n source: { string: \"\", include: true },\n reason: { string: \"\", include: true },\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox delete selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n // default for radio button group\n statusGroup: \"all\",\n //\n // tab info\n activeIndex: 0,\n };\n }\n\n componentDidMount() {\n const {\n data,\n //fetchUPSs,\n //fetchFireflys,\n componentstate,\n } = this.props;\n\n const filterInput = componentstate.get(\"filterInput\", \"scheduledEventList\");\n\n if (!_isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n\n // reset the radio button states\n //\n const filterInputStatusString = filterInput?.status?.string;\n\n switch (filterInputStatusString) {\n case \"\":\n this.setState({ statusGroup: \"all\" });\n break;\n case \"ok\":\n this.setState({ statusGroup: \"ok\" });\n break;\n case \"Notcommissioned\":\n this.setState({ statusGroup: \"commissioned\" });\n break;\n case \"sameposition.Statusreportmissing\":\n this.setState({ statusGroup: \"conflict\" });\n break;\n case \"Reportedtopologychanged\":\n this.setState({ statusGroup: \"moved\" });\n break;\n case \"Shifted\":\n this.setState({ statusGroup: \"shifted\" });\n break;\n case \"Nostatusreport\":\n this.setState({ statusGroup: \"old\" });\n break;\n case \"Timeout\":\n this.setState({ statusGroup: \"timeout\" });\n break;\n default:\n break;\n }\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"scheduledEventList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n const checkItemString = item[key]?.toLowerCase()?.replace(/\\s/g, \"\"); // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n const checkMatchString = match[key]?.string?.toLowerCase();\n const checkIncludes =\n checkMatchString !== \"\" // remove item which don't match, but exclude \"\" empty case\n ? match[key].include && checkItemString.includes(checkMatchString) //'.include' = true for include, = false for exclude\n : true;\n\n checkMatch = checkMatch && checkIncludes;\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n\n return;\n }\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n // handleFilterStatusChange = ({ checked, value }) => { // <<--- for radio buttons\n handleFilterStatusChange = (e, data) => {\n this.setState({ statusGroup: data.value });\n\n let search = \"\";\n\n switch (data.value) {\n case \"ok\":\n search = \"ok\";\n break;\n case \"commissioned\":\n search = \"Not commissioned\";\n break;\n case \"conflict\":\n search = \"same position. Status report missing\";\n break;\n case \"moved\":\n search = \"Reported topology changed\";\n break;\n case \"shifted\":\n search = \"Shifted\";\n break;\n case \"old\":\n search = \"No status report\";\n break;\n case \"timeout\":\n search = \"Timeout\";\n break;\n case \"all\":\n default:\n search = \"\";\n break;\n }\n this.setFilterState({ name: \"status\", value: search }, true);\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n this.setFilterState(target, true);\n };\n\n setFilterState = ({ name, value }, include) => {\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // strip white spaces from value to e.g. \"UPS02\" = \"UPS 02\"\n // update match value with most recent filter entry\n match[name].string = value.replace(/\\s/g, \"\");\n match[name].include = include;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (e, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState(\n (prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n }\n //() => console.log(\"xxx this.state.selections\", this.state.selections)\n );\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n if (\n true\n // #WIP - left in place, may be useful\n // item.statusValue !== StatusEnum.NOT_COMMISSIONED ||\n // this.props.isDeleteFireflyNotCommissioned // && item.statusValue !== StatusEnum.OK\n ) {\n newSelections[item.id] = true;\n }\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n resetForm = (e) => {\n e.preventDefault();\n this.props.reset();\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n // https://github.com/Asymmetrik/ngx-leaflet/issues/88\n // unmount error - \"TypeError: Cannot read property 'off' of undefined\"\n\n // abort page changes\n //this.props.reset();\n this.props.onCancel();\n };\n\n submitMyForm = (values) => {\n //console.log(`LocalisationEditForm submitted: values`, values);\n\n this.props.onSubmit(values);\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n const { push } = this.props;\n\n let promiseArray = [];\n\n // if (action === \"update\") {\n // this.props.fetchNamedAreaExtTriggerEventInfo();\n // }\n\n if (action === \"delete\") {\n }\n\n if (action === \"copy\") {\n }\n };\n\n handleTabChange = (e, { activeIndex, panes }) => {\n // #WIP - debugging reset to latest tab\n\n const area = panes?.[activeIndex]?.menuItem;\n //console.log(\"kkkkkkkkkk tab handleTabChange \", area, panes, activeIndex);\n this.setState({ activeIndex });\n };\n\n render() {\n // form props\n const { handleSubmit, pristine, submitting, initialValues } = this.props;\n\n const { isLoading, error, levels, strings } = this.props;\n const {\n column,\n data: rxData,\n direction,\n filterInput,\n activeIndex,\n } = this.state;\n\n // filter data based on the tabs selected i.e. activeIndex\n const selectedArea = levels?.[activeIndex]?.id;\n const data = rxData?.filter?.((item) => item.area === selectedArea);\n\n // APP_TERMINOLOGY\n let strScheduledEvent = strings?.[\"Scheduled Job\"];\n let strScheduledEvents = strings?.[\"Scheduled Jobs\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Total of {itemsCount} items.{\" \"}\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const scheduledEventFromDataById = (id) =>\n allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let updateButton;\n let enableButton;\n let disableButton;\n let deleteButton;\n let copyButton;\n let scheduledEventSelectedList;\n\n updateButton = (\n this.props.fetchNamedAreaScheduledEventInfo()}\n size=\"large\"\n >\n {strings?.[\"Update\"]}\n \n }\n />\n );\n\n if (selectedCount > 0) {\n updateButton = null; // disable update button if items selected\n\n let scheduledEventNames = [];\n\n for (var key in selections) {\n if (scheduledEventFromDataById(key) !== undefined) {\n let scheduledEventName = scheduledEventFromDataById(key)?.id; // #WIP - what should this be???\n\n scheduledEventNames.push(scheduledEventName);\n }\n }\n scheduledEventNames.sort(sortAlphaNum); // sort by name i.e. by panel locations description\n scheduledEventNames = scheduledEventNames.join(\", \"); // separate by commas\n\n enableButton = (\n this.requestAction(\"enable\")}\n size=\"large\"\n />\n );\n disableButton = (\n this.requestAction(\"disable\")}\n size=\"large\"\n />\n );\n deleteButton = (\n this.requestAction(\"delete\")}\n strings={strings}\n size=\"large\"\n />\n );\n\n copyButton = (\n this.requestAction(\"copy\")}\n size=\"large\"\n />\n );\n\n scheduledEventSelectedList = (\n \n {`${strScheduledEvents} selected ...`} \n {scheduledEventNames}\n \n );\n }\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n return (\n <>\n \n \n \n {!areAnySelected && (\n <>\n
{updateButton}
\n\n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n \n )}\n \n \n \n \n {copyButton}\n {}\n {deleteButton}\n {false && }\n {false && enableButton}\n {false && }\n {false && disableButton}\n \n \n \n {viewablesPage.length} items displayed. {selectedCount} selected\n \n {false && (\n \n \n \n this.resetForm(e)}\n size=\"large\"\n >\n Reset\n \n \n this.cancelForm(e)}\n size=\"large\"\n >\n Cancel\n \n \n )}\n {/*
\n \n
*/}\n
\n {scheduledEventSelectedList}\n
\n {levels.length === 0 && (\n \n )}\n {levels.length > 0 && (\n {\n // data filter to level\n //const levelData = data.filter(item => item.area === level.id) || {};\n return {\n menuItem: level.name,\n render: () => (\n \n \n \n \n {/* \n \n */}\n {/* \n \n */}\n \n \n \n \n \n \n {/* \n \n */}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* \n this.handleFilterStatusChange(data)}\n />\n */}\n \n \n {/* \n \n this.handleSelectAll(viewablesPage)\n }\n />\n */}\n {/* \n {strings?.[\"Disabled\"]}\n */}\n \n {strings?.[\"Polygon ID\"]}\n \n \n {strings?.[\"Active\"]}\n \n {/* \n {strings?.[\"Area\"]}\n */}\n \n {strings?.[\"Group\"]}\n \n \n {strings?.[\"Level\"]}\n \n \n {strings?.[\"Polygon\"]}\n \n \n {strings?.[\"Event Source\"]}\n \n \n {strings?.[\"Note\"]}\n \n \n {strings?.[\"Latest Report\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n active,\n area,\n group,\n level,\n polygon,\n source,\n sourceId,\n reason,\n lastStatusReport,\n style,\n disable,\n }) => (\n \n {/* \n this.handleSelect(id)}\n // disabled={disableDelete}\n />\n */}\n {/* {disable || \"-\"} */}\n \n {id}\n {/* */}\n \n {active || \"-\"}\n {/* {area || \"-\"} */}\n {group || \"-\"}\n {level || \"-\"}\n {polygon || \"-\"}\n \n {(\n \n {source}\n \n ) || \"-\"}\n \n {reason || \"-\"}\n \n {lastStatusReport || \"-\"}\n \n \n )\n )}\n \n \n
\n {pagination}\n
\n ),\n };\n })}\n />\n )}\n \n \n \n );\n }\n}\n\nScheduledEventListEditForm = reduxForm({\n form: \"scheduledEventListEditForm\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(ScheduledEventListEditForm);\n\nconst mapStateToProps = (state, props) => {\n return {\n formValues: getFormValues(\"scheduledEventListEditForm\")(state), // #REVIEW - only used for debugging,\n onChange: (values, dispatch, props, previousValues) => {\n console.log(\"scheduledEventListEditForm onChange values\", values);\n },\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n fetchNamedAreaScheduledEventInfo,\n saveUserSettingsComponentState,\n })(ScheduledEventListEditForm)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push as goto } from \"react-router-redux\";\n\nimport { Container, Header, Grid } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\n\n//import { v4 as uuid } from \"uuid\";\n\n//import SubmissionModal from \"admin/SubmissionModal\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n//import DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\n//import { SubmissionError, isSubmitting, hasSubmitSucceeded } from \"redux-form\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport { formatRelative, parseISO } from \"date-fns\";\nimport { formatDateRelativeNow, minutesAgo } from \"utils/format-date\";\n\nimport {\n getAllAreaStatuses,\n getAllNamedAreaEvents,\n getNamedAreasInfoInNamedAreaGroupByAreaId,\n getNamedAreaScheduledEventInfo,\n} from \"components/WebWorker/reducer\";\n\nimport ScheduledEventListEditForm from \"admin/event-scheduled/ScheduledEventListEditForm\";\nimport { isKthBitSet } from \"utils/bit-operations\";\n\nimport { fetchNamedAreaScheduledEventInfo } from \"NamedAreas/actions\";\nimport hash from \"object-hash\";\n\nclass ScheduledEventListEditPage extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n errorMessage: \"\",\n initialValues: {},\n submitted: false,\n saveSuccess: false,\n };\n }\n\n componentDidMount() {\n console.log(\n \"xxx componentDidMount src/admin/event-scheduled/ScheduledEventListEditPage.js\"\n );\n\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n this.props.fetchNamedAreaScheduledEventInfo();\n }\n\n componentDidUpdate() {\n //this.props.fetchNamedAreaScheduledEventInfo();\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n onResetError = () => {\n // console.log(\n // \"onResetError this.state.errorMessage\",\n // this.state.errorMessage\n // );\n\n const { submitting, submitSucceeded } = this.props;\n\n this.setState({ errorMessage: \"\" });\n\n // if we've just submit the form -> leave\n if (submitting || submitSucceeded) {\n goto(\"/\");\n }\n };\n\n onSetError = (err) => {\n // console.log(\"onSetError\", err);\n this.setState({ errorMessage: err });\n };\n\n submitMyForm = (values) => {\n const { changeLocalisation, reset, localisation } = this.props;\n const { id: language, fieldData } = values;\n\n let localisations = [];\n\n // ...............................\n\n const newValues = { id: language, localisations };\n\n return new Promise((resolve, reject) => {\n //changeLocalisation({ values: newValues, resolve, reject });\n }).then(() => {\n //this.props.fetchLocalisation();\n this.props.goto(\"/tools/localisation\");\n // #TODO\n // Should wait for change to propogate then reset() to return to new intialValues\n //reset();\n });\n };\n\n render() {\n const { id, strings, goto, data, levels } = this.props;\n\n // APP_TERMINOLOGY\n let strExternalTrigger = strings?.[\"Scheduled Events\"];\n let strExternalTriggers = strings?.[\"Scheduled Event\"];\n\n // fieldData is a keyed object\n let fieldData = {};\n data.forEach((element) => {\n fieldData[element.id] = { ...element };\n });\n\n const initialValues = {\n _action: \"edit\", // used to control dlg display\n id: id,\n fieldData: fieldData, // fieldData,\n };\n\n return (\n
\n this.submitMyForm(formValues)}\n />\n \n \n \n \n
{strings?.[\"Scheduled Events\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n this.submitMyForm(values)}\n onCancel={() => {\n goto(`/admin/scheduled-job`);\n }}\n strings={strings}\n />\n \n
\n
\n );\n }\n}\n\nconst _prepData = (elements, strings) => {\n let filteredElements = [];\n\n //console.log(\"xxx elements\", elements);\n\n elements.forEach(function (element, idx) {\n const {\n id,\n active,\n area,\n buttonCustomLabel,\n buttonLabel,\n groupLabel: group,\n levelLabel: level,\n parent,\n permission,\n priority,\n origin,\n operator,\n reason,\n disable,\n timestamp,\n } = element;\n\n // console.log(\"xxx element\", element);\n\n let lastStatusReport = \"-\";\n if (timestamp !== null && timestamp !== undefined) {\n // format - previous used in tableformatters.js\n lastStatusReport = formatRelative(timestamp, new Date(), {\n includeSeconds: true,\n });\n }\n\n let style = null;\n // change row if active\n\n if (active) style = { backgroundColor: \"rgb(219, 40, 40, 15%)\" };\n\n // set style of disabled events\n if (disable === true) {\n style = { backgroundColor: \"rgb(242, 113, 28, 60%)\" };\n }\n\n // areaLink: {name} ,\n\n let sourceName = strings?.[\"unknown\"];\n let sourceId = \"\";\n let source = \"\";\n //let sourceLink = \"\"; //
HI!
;\n\n switch (origin) {\n case \"scheduled_event\":\n const operatorArray = operator?.split(\":\");\n sourceName = operatorArray?.[1] || strings?.[\"unknown\"];\n sourceId = operatorArray?.[0] || \"\";\n source = `${strings?.[\"Job\"]}: ${sourceName}`;\n break;\n default:\n break;\n }\n\n // compose new data set\n filteredElements[idx] = {\n id, //`${parent}:${priority}`,\n active: active ? \"ACTIVE\" : \"INACTIVE\",\n area,\n group,\n level,\n polygon: buttonCustomLabel !== \"\" ? buttonCustomLabel : buttonLabel,\n source,\n sourceId,\n reason,\n lastStatusReport,\n style,\n disable: disable ? \"DISABLED\" : \"ENABLED\",\n };\n });\n\n return filteredElements;\n};\n\nfunction mapStateToProps(state, props) {\n const allAreas = getAllAreaStatuses(state);\n\n let levels = [];\n let rawData = [];\n\n // create level information\n allAreas.forEach((area) => {\n const { id } = area;\n levels.push({ id: id, name: id });\n });\n\n // scheduled event event info via API /get_all_scheduled_event_info\n const scheduledEventInfo = getNamedAreaScheduledEventInfo(state);\n\n //console.log(\"xxx scheduledEventInfo\", scheduledEventInfo);\n\n rawData = scheduledEventInfo; //.filter((event) => event.active !== false);\n\n const data = _prepData(rawData, props.strings);\n\n //console.log(\"xxx scheduledEventInfo data\", data);\n\n return {\n data,\n levels,\n };\n}\n\nexport default connect(mapStateToProps, {\n TurnOnOffPokeTheWorker,\n goto,\n fetchNamedAreaScheduledEventInfo,\n})(ScheduledEventListEditPage);\n","import React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\n\nimport { connect } from \"react-redux\";\nimport { withRouter } from \"react-router\";\n\nimport ExternalTriggerEditPage from \"admin/event-external-trigger/ExternalTriggerEditPage\";\n\nimport ScheduledEventList from \"admin/event-scheduled/ScheduledEventList\";\nimport ScheduledEventCreatePage from \"admin/event-scheduled/ScheduledEventCreatePage\";\nimport ScheduledEventEditPage from \"admin/event-scheduled/ScheduledEventEditPage\";\n\nimport ScheduledEventListAllJobs from \"admin/event-scheduled/ScheduledEventListAllJobs\";\n\nimport EventLogListAllEvents from \"admin/event-log/EventLogListAllEvents\";\n\nimport ScheduledEventListEditPage from \"admin/event-scheduled/ScheduledEventListEditPage\";\n\nclass EventAdminPages extends Component {\n render() {\n const { match, strings } = this.props;\n\n //console.log(\"xxx match\", match);\n\n return (\n \n (\n \n )}\n />\n (\n \n )}\n />\n (\n \n )}\n />\n\n (\n \n )}\n />\n (\n \n )}\n />\n (\n \n )}\n />\n \n );\n }\n}\n\nexport default withRouter(connect(null)(EventAdminPages));\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Container, Header, Grid } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\n\nclass LogPage extends Component {\n render() {\n const { strings } = this.props;\n\n return (\n
\n \n \n \n \n
{strings?.[\"System Log\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n
\n
\n );\n }\n}\n\nexport default connect(null)(LogPage);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n//import { Link } from \"react-router-dom\";\n\nclass FailPage extends Component {\n render() {\n const { strings } = this.props;\n return (\n
\n

{strings?.[\"Fault Log\"]}

\n \n
\n );\n }\n}\n\nexport default connect(null)(FailPage);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\nimport { Button, Icon, Popup } from \"semantic-ui-react\";\nimport { capitalize } from \"utils/format-text\";\nimport { LogIt } from \"components/Logger/actions\";\nimport {\n isConfigJs,\n faultFlash,\n faultMessageBannerDisplay,\n faultMessageBannerText,\n} from \"components/ConfigJs\";\n\nimport {\n addWarningFlashMessageIdColor,\n removeFlashMessage,\n clearFlashMessages,\n SetMessageBanner,\n} from \"FlashMessages/actions\";\n\n//import { SetMessageBanner } from \"components/AlarmButton/actions\";\n\nimport { getLatestFaultTs, getMqttMsg } from \"../WebWorker/reducer\";\n\nimport cuid from \"cuid\";\n\n// https://blog.lftechnology.com/using-svg-icons-components-in-react-44fbe8e5f91\n// import { ReactComponent as Icon} from './icon.svg';\n// \n// https://github.com/Semantic-Org/Semantic-UI-React/issues/931#issuecomment-263643210\n\nexport class AlarmButton extends Component {\n constructor(props) {\n super(props);\n this.state = {};\n }\n\n componentDidMount() {\n // not in use - yet?\n }\n\n componentDidUpdate(prevProps, prevState) {\n // set a message banner if necessary ...\n this.setFaultMessageBanner(prevProps);\n }\n\n clickAction = (e) => {\n const { faultType, faultAction, mqttFaultTs } = this.props;\n\n this.props.LogIt(\"FAULTS_BUTTON_PRESSED > \" + faultType);\n\n // for page reset button action\n if (faultAction === \"reset\") {\n // clear the alarm by setting the pageTS = mqttTS\n // i.e. PageFaultTs[faultType] = mqttFaultTs[faultType]\n // when button pushed, update state.alarmButton.faultLatestTs\n // via DISPATCH\n let tmpObj = {}; // make temporary object\n tmpObj.faultType = faultType;\n tmpObj.faultMaxFaultTs = mqttFaultTs[faultType];\n this.props.SetLatestFaultTs(tmpObj);\n\n // clear any MessageList banner which may be displayed\n this.clearFaultMessageBanner(faultType);\n }\n };\n\n clearFaultMessageBanner = (faultType) => {\n // this.props.clearFlashMessages(); // clear off previous messages\n\n // get the id for the flash message\n const bannerId = this.faultMessageBannerId(faultType);\n if (bannerId) {\n this.props.removeFlashMessage(bannerId);\n //#REVIEW - make this a function..........\n // delete this banner message from state\n let tmpObj = {};\n tmpObj.faultType = faultType;\n tmpObj.display = false;\n tmpObj.id = \"\";\n\n this.props.SetMessageBanner(tmpObj);\n }\n };\n\n faultMessageBannerId = (faultType) => {\n // check if a message of this type exists\n\n // get the id for the flash message\n const messageBanners = this.props.messageBanners; // from redux state\n return messageBanners[faultType].id;\n };\n\n // determined highest fault level for the current faultType\n getHighestFaultLevel = (faultType) => {\n // get all faults reported\n let faults = this.props.mqttMsg;\n\n // filter out only faultType\n faults = faults.filter((item) => item.type === faultType);\n\n // reduces to set with highest fault level\n // probably > 1 fault\n faults.reduce = (prev, current) => {\n return prev.fault_level > current.fault_level ? prev : current;\n };\n\n // just need one - first one will do\n return faults[0].fault_level;\n };\n\n // set the color for the message banner\n // setColorMessageBanner = (faultType) => {\n // const highestFaultLevel = this.getHighestFaultLevel(faultType);\n\n // switch (highestFaultLevel) {\n // case 3:\n // return \"red\";\n // case 2:\n // return \"pink\";\n // case 1:\n // return \"brown\";\n // default:\n // return \"brown\";\n // }\n // };\n\n setFaultMessageBanner = (prevProps) => {\n const { faultType, faultAction, pageFaultTs, mqttFaultTs } = this.props;\n // show 'alarm' state on button if *not* reset button\n if (faultAction !== \"reset\") {\n // if there are no mqttFaults, but there were (i.e. banner is being displayed), clear the banner.\n // This automatically clears the message banner if faults have been rectified\n if (\n prevProps.mqttFaultTs[faultType] >= mqttFaultTs[faultType] &&\n mqttFaultTs[faultType] === 0\n ) {\n this.clearFaultMessageBanner(faultType);\n }\n // if the current page faults timestamp (TS) is less than mqtt TS\n else if (pageFaultTs[faultType] < mqttFaultTs[faultType]) {\n // check if there is config for button styling\n if (isConfigJs() && faultMessageBannerDisplay()) {\n const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n const messageBanners = this.props.messageBanners; // from redux state\n const bannerDisplayed = messageBanners[faultType].display; // deconstruct to a simpler obj\n\n // if this fault type allows message banner display (in config)\n // and there hasn't been a message banner displayed previously\n if (isMessageBannerForFaultType[faultType] && !bannerDisplayed) {\n // create a unique ID for the banner\n const id = cuid();\n\n // display a new banner\n this.displayErrors(id, faultType);\n\n // record the update state of banner including the id (needed to delete this particular banner)\n let tmpObj = {};\n tmpObj.faultType = faultType;\n tmpObj.display = true;\n tmpObj.id = id;\n\n this.props.SetMessageBanner(tmpObj);\n }\n }\n }\n }\n };\n\n // get the text for the fault message banner from config.js or set default\n getFaultMessageBannerText = (faultType) => {\n let header;\n let message;\n let color;\n\n if (isConfigJs() && faultMessageBannerText()) {\n const messageBannerText = faultMessageBannerText(); // from config.js file\n header = messageBannerText[faultType].header;\n message = messageBannerText[faultType].message;\n color = messageBannerText[faultType].color;\n } else {\n // default messages if config.js object is stuffed\n switch (faultType) {\n case \"firefly\":\n header = \"FireFly Fault\";\n message =\n \"FireFly fault reported. Please address this fault immediately.\";\n color = \"red\";\n break;\n case \"battery\":\n header = \"Battery Fault\";\n message =\n \"Controller battery fault reported. Please address this fault immediately.\";\n color = \"red\";\n break;\n case \"network\":\n header = \"Network Fault\";\n message =\n \"Network fault reported. Please address this fault immediately.\";\n color = \"red\";\n break;\n case \"controller\":\n header = \"Controller Status Issue\";\n message =\n \"Controller Status Change reported. Please review this immediately.\";\n color = \"red\";\n break;\n case \"statusChecks\":\n header = \"Status Check Report\";\n message =\n \"Diagnostics have recommended actions to correct issues. Please review this immediately.\";\n color = \"red\";\n break;\n default:\n break;\n }\n }\n\n return { header, message, color };\n };\n\n // loads header and message to display on control screen page\n // depending on significance of the error\n // All cases go to the Browser Logger page\n //\n displayErrors(id, faultType) {\n const { header, message, color } =\n this.getFaultMessageBannerText(faultType);\n\n // set color from highest fault_level for the faultType\n // const color = this.setColorMessageBanner(faultType);\n\n this.props.addWarningFlashMessageIdColor(\n id,\n color,\n header,\n message || \"Unknown problem\"\n );\n //console.log(\"displayErrors - \" + header + \"-\" + message);\n }\n\n getButtonStyle = () => {\n // possible button colours\n // [\"red\",\"orange\",\"orange\",\"olive\",\"green\",\"teal\",\"blue\",\"violet\",\"purple\",\"pink\",\"brown\",\"grey\",\"black\",\"facebook\",\"google plus\",\"instagram\",\"linkedin\",\"twitter\",\"vk\",\"youtube\"].\n\n const { faultType, faultAction, pageFaultTs, mqttFaultTs } = this.props;\n // show 'alarm' state on button if *not* reset button\n if (faultAction !== \"reset\") {\n // and the current page faults timestamp (TS) is less than mqtt TS\n if (pageFaultTs[faultType] < mqttFaultTs[faultType]) {\n // check if there is config for button styling\n if (isConfigJs() && faultFlash()) {\n const buttonFlash = faultFlash();\n if (buttonFlash[faultType]) {\n // refer to custom.css for style class\n return \"red flash-button\";\n }\n }\n return \"red\";\n } else {\n return \"\";\n }\n }\n };\n\n getButtonClass = () => {\n return \"flash-button\";\n };\n\n // #WIP\n // custom icons\n // const iconTest={{ className: '/images/firefly.png' }};\n // https://github.com/Semantic-Org/Semantic-UI-React/issues/931#issuecomment-263643210\n\n getButtonIcon = () => {\n const { faultType, faultAction } = this.props;\n\n // button for reset has 'repeat' icon\n if (faultAction === \"reset\") return \"alarm mute\";\n\n // otherwise set by type\n switch (faultType) {\n case \"firefly\":\n return \"lightbulb\";\n case \"battery\":\n return \"battery half\";\n case \"network\":\n return \"sitemap\";\n case \"controller\":\n return \"hdd outline\";\n case \"statusChecks\":\n return \"lightbulb outline\";\n case \"external\":\n return \"level down alternate\";\n default:\n return \"lightbulb\";\n }\n };\n\n getButtonIconRotate = () => {\n const { faultType } = this.props;\n\n // otherwise set by type\n switch (faultType) {\n case \"external\":\n return \"\"; //\"counterclockwise\"; // #NOTE - subsequently changed from `reply` to `level down alternate`\n default:\n return \"\";\n }\n };\n\n getButtonLink = () => {\n const { faultType, faultAction } = this.props;\n\n // button for reset does not link to another page!\n if (faultAction === \"reset\") return `#`;\n\n switch (faultType) {\n case \"firefly\":\n return `/status/faults/${faultType}`;\n case \"battery\":\n return `/status/faults/${faultType}`;\n case \"network\":\n return `/status/faults/${faultType}`;\n case \"controller\":\n return `/status/faults/${faultType}`;\n case \"statusChecks\":\n return `/status/firefly`;\n case \"external\":\n return `/status/firefly`;\n default:\n return `#`;\n }\n };\n\n getButtonTooltip = () => {\n const { faultType, faultAction, strings } = this.props;\n\n // button for reset is different\n if (faultAction === \"reset\")\n return `Clear ${capitalize(faultType)} alarm and row highlight`;\n\n switch (faultType) {\n case \"firefly\":\n //return `View ${capitalize(faultType)} faults`;\n return strings?.formatString(strings?.[\"View {fault_type} faults\"], {\n fault_type: capitalize(faultType),\n });\n case \"battery\":\n //return `View FF controller ${capitalize(faultType)} faults`;\n return strings?.formatString(\n strings?.[\"View FireFly controller {fault_type} faults\"],\n { fault_type: capitalize(faultType) }\n );\n case \"network\":\n // return `View ${capitalize(faultType)} faults`;\n return strings?.formatString(strings?.[\"View {fault_type} faults\"], {\n fault_type: capitalize(faultType),\n });\n case \"controller\":\n return strings?.[\"View Controller Reports\"];\n case \"statusChecks\":\n return strings?.[\"View FireFly Status\"];\n case \"external\":\n return strings?.[\"View External Source Events\"];\n default:\n return ``;\n }\n };\n\n render() {\n const buttonSize = this.props?.size || \"large\";\n return (\n // note - button spacing in header defined at\n // src/components/Header/index.js\n \n \n {/* */}\n \n {/* */}\n \n }\n />\n \n );\n }\n}\n\nfunction mapStateToProps(state) {\n const { latestFaultTs: pageFaultTs } = state.alarmButton;\n\n // see - src/components/Header/index.js\n // switch between\n // \n //\n // const { latestFaultTs: mqttFaultTs } = state.mqtt;\n // \n //const { latestFaultTs: mqttFaultTs } = state.webWorker;\n const mqttFaultTs = getLatestFaultTs(state); // state.webWorker;\n const { messageBanners } = state.alarmButton;\n\n // need fault message to determine highest fault level for a given faultType\n // const { mqttMsg } = state.webWorker;\n const mqttMsg = getMqttMsg(state);\n\n return {\n messageBanners,\n pageFaultTs,\n mqttFaultTs,\n mqttMsg,\n };\n}\n\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n SetLatestFaultTs: (latestFaultTs) => {\n dispatch({ type: `SET_LATEST_FAULT_TS`, payload: latestFaultTs });\n },\n clearFlashMessages: () => {\n dispatch(clearFlashMessages());\n },\n removeFlashMessage: (id) => {\n dispatch(removeFlashMessage(id));\n },\n addWarningFlashMessageIdColor: (id, color, header, message) => {\n dispatch(addWarningFlashMessageIdColor(id, color, header, message));\n },\n SetMessageBanner: (messageState) => {\n dispatch(SetMessageBanner(messageState));\n },\n LogIt: (thingsLogged) => {\n dispatch(LogIt(thingsLogged));\n },\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(AlarmButton);\n","//https://stackoverflow.com/questions/847185/convert-a-unix-timestamp-to-time-in-javascript\nexport const timeConverter = UNIX_timestamp => {\n var a = new Date(UNIX_timestamp * 1000);\n var months = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\"\n ];\n var year = a.getFullYear();\n var month = months[a.getMonth()];\n var date = a.getDate();\n var hour = a.getHours();\n var min = a.getMinutes() < 10 ? \"0\" + a.getMinutes() : a.getMinutes();\n var sec = a.getSeconds() < 10 ? \"0\" + a.getSeconds() : a.getSeconds();\n var time =\n date + \" \" + month + \" \" + year + \" \" + hour + \":\" + min + \":\" + sec;\n return time;\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { getMqttMsg } from \"components/WebWorker/reducer.js\";\n\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Icon,\n Popup,\n Label,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport UPSLink from \"admin/ups/UPSLink\";\nimport FireflyLink from \"admin/firefly/FireflyLink\";\n\nimport AlarmButton from \"components/AlarmButton\";\nimport { timeConverter } from \"utils/format-time\";\nimport { capitalize } from \"utils/format-text\";\nimport { formatDate } from \"utils/format-date\";\n\nimport lodashSortBy from \"lodash/sortBy\";\nimport { formatRelative, parseISO } from \"date-fns\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\n// XLSL 'react-export-excel' IMPLEMENTATION\n// click button to download report\n// uses https://www.npmjs.com/package/react-export-excel\n// see ex - https://github.com/rdcalle/react-export-excel/blob/HEAD/examples/with_custom_download_element.md\nimport ReactExport from \"react-export-excel\";\nconst ExcelFile = ReactExport.ExcelFile;\nconst ExcelSheet = ReactExport.ExcelFile.ExcelSheet;\nconst ExcelColumn = ReactExport.ExcelFile.ExcelColumn;\n\nclass Download extends React.Component {\n render() {\n const { data, faultType } = this.props;\n\n const filename = `${capitalize(faultType)}_fault_status_report_${formatDate(\n new Date(Date.now()),\n \"dd-MMM-yy-HH-mm-ss\"\n )}`;\n\n return (\n \n \n \n }\n />\n }\n >\n \n \n \n \n \n \n \n \n \n \n \n \n );\n }\n}\n\nclass FaultList extends Component {\n constructor(props) {\n super(props);\n const downloadData = [];\n const mqttMsgDefault = [\n {\n type: \"\",\n id: \"\",\n name: \"\",\n position: 0,\n description: \"\",\n active: true,\n fault_level: 0,\n area: \"\",\n location: [\"\"],\n ip: \"\",\n ts: 0,\n fault_ts: 0,\n },\n ];\n this.state = {\n downloadData,\n mqttMsgDefault,\n // initialise data list sort columns\n column: null,\n data: props.data.filter((item) => item.type === props.faultType),\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // type: \"\",\n // id: \"\",\n name: \"\",\n description: \"\",\n // fault_level: \"\",\n area: \"\",\n location: \"\",\n // position: \"\",\n // ip: \"\",\n // ts: \"\",\n // fault_ts: \"\",\n // controller: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n };\n }\n\n componentDidMount() {\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n `${this.props.faultType}FaultList`\n );\n\n // console.log(\n // \"filterInput componentDidMount \",\n // `${this.props.faultType}FaultList`,\n // filterInput\n // );\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: `${this.props.faultType}FaultList`,\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { pageFaultTs, faultType, data: allFaultData } = this.props;\n const { filterInput: match } = this.state;\n\n // #REVIEW - this is a fudge because faultType is passed through as a prop but data is rendered\n // via redux mapstatetoprop which does not have access to faultType.\n // Probably should setup a HOC(?) for this but fudged it instead\n\n const data = allFaultData.filter((item) => item.type === faultType);\n\n // also filter prevProps.data -> prevProps\n const prevPropsData = prevProps.data.filter(\n (item) => item.type === faultType\n );\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(data) !== JSON.stringify(prevPropsData) // if original props data changes\n ) {\n let newData = data;\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n // add icon to 'new' faults\n newData = newData.map((item) => {\n if (item.fault_ts > pageFaultTs[faultType]) {\n return { ...item, icon: \"warning\" };\n } else {\n return { ...item, icon: \"\" };\n }\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n render() {\n const { faultType, pageTitle, strings } = this.props;\n\n const { isLoading, error } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n // if enough faults display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n return (\n
\n \n \n \n \n
{pageTitle}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n
\n \n \n \n
\n {/* label and button *will not* go to same height as depends on font sizes. \n Fudge by vertical centering the button and label in same div. */}\n
\n \n {itemsCount}\n \n }\n />\n \n
\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {strings?.[\"ID\"]}\n \n \n {strings?.[\"Device\"]}\n \n \n {strings?.[\"Fault\"]}\n \n\n \n {strings?.[\"Fault Level\"]}\n \n \n {strings?.[\"Area\"]}\n \n \n {strings?.[\"Location\"]}\n \n \n {strings?.[\"Position\"]}\n \n \n {strings?.[\"Controller URL\"]}\n \n \n {strings?.[\"Fault Time\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n idLink,\n name,\n description,\n descriptionLink,\n fault_level,\n area,\n location,\n position,\n ip,\n fault_tsReadable,\n icon,\n }) => (\n \n \n \n \n {idLink}\n {name}\n {descriptionLink}\n {fault_level}\n {area}\n {location}\n {position}\n {ip}\n {fault_tsReadable}\n \n )\n )}\n \n \n
\n {pagination}\n \n
\n
\n );\n }\n}\n\nconst _prepData = (elements) => {\n // filter out only faultType\n // const faultType = \"firefly\";\n // const elements = mqttMsg.filter((item) => item.type === faultType);\n\n let filteredElements = [];\n\n // only need a subset of data\n elements.forEach(function (element, idx) {\n const {\n type,\n subtype,\n id,\n name,\n description,\n fault_level,\n area,\n location,\n position,\n ip,\n ts,\n fault_ts,\n } = element;\n\n // change fault level from int to descriptor\n const faultLevelDescriptions = {\n 1: \"Low\",\n 2: \"Medium\",\n 3: \"High\",\n };\n let faultLevel = fault_level;\n if (Number.isInteger(fault_level)) {\n if (fault_level >= 1 && fault_level <= 3) {\n faultLevel = faultLevelDescriptions[fault_level];\n }\n }\n\n let ipLink = \"-\";\n if (!_isEmpty(ip)) {\n ipLink = ipLink ? (\n \n {ip}\n \n ) : (\n \"-\"\n );\n }\n\n // #NOTE - special parse of `altered` description\n let descriptionLink = description;\n if (type === \"firefly\" && subtype === \"device_change\") {\n console.log(`description`, description);\n\n // e.g. \"Device 'c4:4f:33:23:b2:d5' has changed Controller '4c:3f:d3:3b:62:14'\"\n const matches = description?.match(\n /\\b(?:Device|Controller|has|changed)\\b/g\n );\n if (matches?.length > 3) {\n let ipArray = description.match(/\\S+|'[^']+'/g);\n\n //console.log(\"ipArray\", ipArray);\n\n const fireflyMac = ipArray[1].replaceAll(\"'\", \"\");\n const controllerMac = ipArray[5].replaceAll(\"'\", \"\");\n descriptionLink = (\n
\n FF device ({fireflyMac}) has changed controller ID -{\" \"}\n {controllerMac}\n
\n );\n }\n }\n\n // compose new data set\n filteredElements[idx] = {\n // area: \"DMLZ_Extraction\",\n // description: \"Network failed : Could not Ping FireFly Controller\",\n // fault_level: 3,\n // fault_ts: 1591338973,\n // id: \"74:e1:82:91:60:c5\",\n // ip: \"10.208.26.143\",\n // location: \"P5, P6, P7, P8\",\n // name: \"UPS 14\",\n // position: 0,\n // ts: 1591342458,\n // type: \"network\",\n type: type,\n id: id,\n idLink:\n type === \"firefly\" ? (\n {id}\n ) : (\n {id}\n ),\n name: name,\n description: description,\n descriptionLink: descriptionLink,\n fault_level: faultLevel,\n area: area,\n location: location === undefined ? \"-\" : location.toString(),\n position: position === 0 ? \"-\" : `${position}`, // force to String\n ip: ipLink,\n ts: ts,\n fault_tsReadable: fault_ts > 0 ? timeConverter(fault_ts) : \"-\",\n fault_ts: fault_ts,\n icon: \"\",\n };\n });\n\n return filteredElements;\n};\n\nconst mapStateToProps = (state, props) => {\n // see - src/components/Header/index.js\n // switch between\n // \n //\n // const { mqtt } = state;\n // const { mqttMsg } = mqtt;\n // \n //const { mqttMsg } = state.webWorker;\n const mqttMsg = getMqttMsg(state);\n const data = _prepData(mqttMsg);\n\n // fault timestamp states for page and mqtt message\n const { latestFaultTs: pageFaultTs } = state.alarmButton;\n\n return {\n mqttMsg,\n pageFaultTs,\n data,\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, { saveUserSettingsComponentState })(FaultList)\n);\n","import Immutable from \"seamless-immutable\";\n\nimport { allowedLanguages as _allowedLanguages } from \"components/ConfigJs\";\n\nconst initialState = Immutable({\n localisation: {},\n});\n\nexport default function reduce(state = initialState, action = {}) {\n const newState = { ...state };\n const { type, payload } = action;\n\n switch (type) {\n case \"LOCALISATION_FETCH_SUCCEEDED\":\n const {\n localisation: { list },\n } = payload;\n\n console.log(\"LOCALISATION_FETCH_SUCCEEDED\", list);\n newState.localisation = list;\n return newState;\n\n case \"RESET\":\n console.log(\"RESET! - Localisation\");\n return state;\n default:\n return state;\n }\n}\n\nfunction stableOrder(order, items) {\n return Immutable(order.map((k) => items[k]));\n}\nexport const getLocalisation = (state) => {\n const byId = state.localisation.localisation;\n const keys = Object.keys(byId).sort();\n return stableOrder(keys, byId);\n};\n\nexport const getLocalisationByApplicationId = (state, id) => {\n const allTerms = getLocalisation(state).filter(\n (local) => local.application === \"default\"\n );\n return allTerms;\n};\n\nexport const getLocalisationByComponentId = (state, id) => {\n const allTerms = getLocalisationByApplicationId(state, id).filter(\n (local) => local.component === id\n );\n\n //console.log(\"getLocalisationByComponentId allTerms\", allTerms);\n\n const uniqueLanguages = allTerms\n .map((item) => item.language)\n .filter((value, index, self) => self.indexOf(value) === index);\n\n // put english en-US first in array\n const sortUniqueLanguages = [\n ...uniqueLanguages.filter((item) => item === \"en-US\"),\n ...uniqueLanguages.filter((item) => item !== \"en-US\"),\n ];\n\n //console.log(\"getLocalisationByComponentId sortUniqueLanguages\", allTerms);\n\n let result = {};\n sortUniqueLanguages.forEach((language) => {\n const byLanguage = allTerms.filter((term) => term.language === language);\n let terms = {};\n byLanguage.forEach((term) => {\n terms[term.reference] = term.term;\n });\n result[language] = terms;\n });\n\n //console.log(\"getLocalisationByComponentId result\", result);\n\n return result;\n};\n","import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\n\nimport { connect } from \"react-redux\";\n\nimport { Form, Grid, Icon } from \"semantic-ui-react\";\n\nimport isEmpty from \"lodash/isEmpty\";\nimport { login } from \"auth/actions\";\n\nimport { LogIt } from \"components/Logger/actions\";\n//import { findLocalIp } from \"utils/findLocalIp\";\n\nimport LocalizedStrings from \"react-localization\";\nimport { getLocalisation } from \"components/Localisation/reducer\";\n\nfunction validateInput(data) {\n let errors = {};\n\n if (isEmpty(data.email)) {\n errors.email = \"This field is required\";\n }\n if (isEmpty(data.password)) {\n errors.password = \"This field is required\";\n }\n return { errors, isValid: isEmpty(errors) };\n}\n\nclass LoginForm extends Component {\n static propTypes = {\n children: PropTypes.node,\n className: PropTypes.string,\n };\n\n constructor(props) {\n super(props);\n this.state = {\n username: \"\",\n email: \"\",\n password: \"\",\n fieldErrors: {},\n hidden: true,\n capsLockOn: false,\n };\n }\n\n componentDidMount() {\n if (this.props.password) {\n this.setState({ password: this.props.password });\n }\n }\n\n onSubmit = (e) => {\n e.preventDefault();\n if (this.isValid()) {\n this.setState({ fieldErrors: {} });\n this.props.login(this.state);\n this.props.LogIt(\"LOG_IN > Username: \" + this.state.username);\n }\n };\n\n isValid = () => {\n const { errors, isValid } = validateInput(this.state);\n this.setState({ fieldErrors: errors });\n return isValid;\n };\n\n onChange = (e) => {\n this.setState({ [e.target.name]: e.target.value });\n };\n\n toggleShow = (state) => {\n this.setState({ hidden: !this.state.hidden });\n };\n\n onKeyDown = (keyEvent) => {\n if (keyEvent.getModifierState(\"CapsLock\")) {\n this.setState({ capsLockOn: true });\n } else {\n this.setState({ capsLockOn: false });\n }\n };\n\n render() {\n const { isLoading } = this.props;\n const { username, email, password, fieldErrors, capsLockOn } = this.state;\n\n return (\n
\n \n \n }\n />\n \n \n {capsLockOn && CAPS}\n \n \n Login\n \n \n \n \n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const localisations = getLocalisation(state);\n\n //console.log(\"localisation\", localisations);\n\n return {\n isLoading: state.auth.isLoading,\n };\n}\n\nexport default connect(mapStateToProps, { login, LogIt })(LoginForm);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Icon,\n Popup,\n Label,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport UPSLink from \"../../admin/ups/UPSLink\";\nimport FireflyLink from \"../../admin/firefly/FireflyLink\";\n\nimport AlarmButton from \"components/AlarmButton\";\nimport { timeConverter } from \"../../utils/format-time\";\nimport { capitalize } from \"../../utils/format-text\";\n\nimport { formatDate } from \"utils/format-date\";\n\nimport lodashSortBy from \"lodash/sortBy\";\nimport { formatRelative, parseISO } from \"date-fns\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { ClearLog } from \"components/Logger/actions\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\n// XLSL 'react-export-excel' IMPLEMENTATION\n// click button to download report\n// uses https://www.npmjs.com/package/react-export-excel\n// see ex - https://github.com/rdcalle/react-export-excel/blob/HEAD/examples/with_custom_download_element.md\nimport ReactExport from \"react-export-excel\";\nconst ExcelFile = ReactExport.ExcelFile;\nconst ExcelSheet = ReactExport.ExcelFile.ExcelSheet;\nconst ExcelColumn = ReactExport.ExcelFile.ExcelColumn;\n\nclass Download extends React.Component {\n render() {\n const { data } = this.props;\n const filename = `Browser_log_report_${formatDate(\n new Date(Date.now()),\n \"dd-MMM-yy-HH-mm-ss\"\n )}`;\n\n return (\n \n \n \n }\n />\n }\n >\n \n \n \n \n \n );\n }\n}\n\nclass Logger extends Component {\n constructor(props) {\n super(props);\n const downloadData = [];\n this.state = {\n downloadData,\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n time: \"\",\n description: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n };\n }\n\n componentDidMount() {\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"browserlogList\"\n );\n\n //console.log(\"filterInput componentDidMount\", filterInput);\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"browserlogList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n render() {\n const { strings } = this.props;\n\n const includeTitles = this.props.includeTitles === \"true\";\n const title = includeTitles ? (\n
{strings?.[\"Browser Log\"]}
\n ) : (\n
\n );\n\n const { isLoading, error } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n // if enough faults display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n return (\n
\n \n \n \n \n
{title}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n
\n \n \n \n
\n {/* label and button *will not* go to same height as depends on font sizes. \n Fudge by vertical centering the button and label in same div. */}\n
\n \n {itemsCount}\n \n }\n />\n
\n
\n\n \n \n \n \n {/* */}\n \n \n \n \n \n \n \n {strings?.[\"Time\"]}\n \n \n {strings?.[\"Logged\"]}\n \n \n \n \n {_.map(viewablesPage, ({ time, description }, idx) => (\n \n {time}\n {description}\n \n ))}\n \n \n
\n {pagination}\n \n
\n
\n );\n }\n}\n\nconst _prepData = (elements) => {\n let filteredElements = [];\n\n // only need a subset of data\n elements.forEach(function (element, idx) {\n const { ts, description } = element;\n\n // compose new data set\n filteredElements[idx] = {\n time: ts > 0 ? timeConverter(ts) : \"-\",\n description: description,\n };\n });\n\n return filteredElements;\n};\n\nfunction mapStateToProps(state) {\n const { logOfThingsLogged } = state.logger;\n\n const data = _prepData(logOfThingsLogged);\n\n return {\n data,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, { ClearLog, saveUserSettingsComponentState })(Logger)\n);\n","import React from \"react\";\n\nimport { Header, Card, Divider, Message } from \"semantic-ui-react\";\n\nimport LoginForm from \"components/LoginForm\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport Logger from \"components/Logger\";\n\nconst HomePage = () => (\n \n \n \n \n LOGIN\n \n \n {/* #REVIEW - disable logger from admin login - questionable of its usefulless */}\n {/* \n */}\n \n \n);\n\nexport default HomePage;\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport Dropdown from 'semantic-ui-react/dist/commonjs/modules/Dropdown'\nimport { Link } from 'react-router-dom'\nimport toSlug from 'utils/toSlug'\n\nfunction MineLevelMenuItem ({ level }) {\n const { name } = level\n const slug = toSlug(name)\n return (\n \n \n \n New seismic overlay\n \n \n Seismic history\n \n \n Operational status\n \n \n \n )\n}\n\nMineLevelMenuItem.defaultProps = {}\n\nMineLevelMenuItem.propTypes = {\n level: PropTypes.object.isRequired\n}\n\nexport default MineLevelMenuItem\n","import React, { Component } from 'react'\nimport Menu from 'semantic-ui-react/dist/commonjs/collections/Menu'\nimport { connect } from 'react-redux'\nimport MineLevelMenuItem from 'components/MineLevelMenuItem'\n\nimport { getAllMineLevels } from 'MineLevels/reducer'\nimport { fetchMineLevels } from 'MineLevels/actions'\n\nexport const MineLevelMenus = ({ ...props }) => {\n const { levels, dispatch, ...rest } = props\n if (levels.length === 0) {\n return No levels configured\n }\n return (\n \n {levels.map(level => (\n \n ))}\n \n )\n}\n\nexport function mapStateToProps (state) {\n const levels = getAllMineLevels(state)\n\n return { levels }\n}\n\nconst ConnectedMineLevelMenus = connect(mapStateToProps)(MineLevelMenus)\n\nfunction actionOnMount (Wrapped, action) {\n class Wrapper extends Component {\n componentDidMount () {\n const actionObject = typeof action === 'function' ? action() : action\n this.props.dispatch(actionObject)\n }\n render () {\n return \n }\n }\n return connect()(Wrapper)\n}\n\nexport default actionOnMount(ConnectedMineLevelMenus, fetchMineLevels)\n","import React from \"react\";\nimport { Dropdown, Menu } from \"semantic-ui-react\";\nimport { Link } from \"react-router-dom\";\nimport { connect } from \"react-redux\";\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nimport {\n isBoomgateCrane,\n isTagTracking as _isTagTracking,\n isShowBackupRestore as _isShowBackupRestore,\n} from \"components/ConfigJs\";\n\nimport {\n isServiceBackupMonitor,\n isServiceTagTracker,\n} from \"components/Settings/reducer\";\n\nlet AdminMenu = ({\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n isServiceBackupMonitor,\n isServiceTagTracker,\n //\n strings, // localisation\n userSettings,\n}) => {\n const allowGuest = isUserGuest;\n const allowOperator = isUserSuper || isUserAdmin || isUserUser;\n const allowAdmin = isUserSuper || isUserAdmin;\n const allowSuper = isUserSuper;\n\n const isShowBackupRestore =\n userSettings?.feature?.includes(\"showBackupRestore\") ||\n _isShowBackupRestore();\n\n const isTagTracking =\n userSettings?.application?.includes(\"tagTracking\") || _isTagTracking();\n\n // railway_application\n const boomgateCrane = isBoomgateCrane() || false;\n const areaTitle = !boomgateCrane ? strings[\"Areas\"] : strings[\"Map Image\"];\n\n // APP_TERMINOLOGY\n const strNamedAreaGroups = strings[\"Lighting Control Layout\"];\n const strNamedAreas = strings[\"Polygons\"];\n\n return (\n \n \n \n {areaTitle}\n \n {/*\n \n {strNamedAreaGroups}\n \n \n {strNamedAreas}\n \n */}\n \n {strings[\"Controllers\"]}\n \n \n {strings[\"FireFlys\"]}\n \n {/* \n Bulk Positioning\n */}\n {/* \n {strings[\"Bulk Positioning\"]}\n */}\n\n \n {strings[\"Logs\"]}\n \n \n {strings[\"System Logs\"]}\n \n \n {strings[\"Browser Logs\"]}\n \n {/* \n Fault Logs\n */}\n {false && (\n <>\n \n {strings[\"Faults\"]}\n \n \n {strings[\"FireFly Faults\"]}\n \n \n {strings[\"Battery Faults\"]}\n \n \n {strings[\"Network Faults\"]}\n \n \n Status\n \n \n {strings[\"Controller Status\"]}\n \n \n {strings[\"FireFly Status\"]}\n \n \n )}\n {false && isTagTracking && (\n <>\n \n {strings[\"Tags\"]}\n \n \n {strings[\"Tags Map\"]}\n \n \n {strings[\"Tags\"]}\n \n \n {strings[\"Tags In Zones\"]}\n \n {allowAdmin && (\n \n {strings[\"Tag Zones\"]}\n \n )}\n \n )}\n \n {strings[\"Tools\"]}\n \n \n {strings[\"System Tools\"]}\n \n \n {isShowBackupRestore && (\n \n
{strings?.[\"Backup and Restore\"]}
\n \n
\n )}\n {isUserSuper && (\n \n
Localisation
\n
\n )}\n\n {isUserSuper && (\n <>\n \n \n
Advanced
\n
\n \n \n {`Advanced Parent ${strNamedAreas}`}\n \n \n {`Advanced All ${strNamedAreas}`}\n \n \n
{`Advanced All Events`}
\n
\n \n
Forced FireFlys
\n
\n \n
MQTT Messages
\n
\n \n )}\n
\n
\n );\n};\n\nAdminMenu.defaultProps = {};\n\nAdminMenu = connect((state) => ({\n isUserSuper: isUserSuper(state),\n isUserAdmin: isUserAdmin(state),\n isUserUser: isUserUser(state),\n isUserGuest: isUserGuest(state),\n //\n isServiceBackupMonitor: isServiceBackupMonitor(state),\n isServiceTagTracker: isServiceTagTracker(state),\n}))(AdminMenu);\n\nexport default AdminMenu;\n","import React from \"react\";\nimport { Dropdown, Menu } from \"semantic-ui-react\";\nimport { Link } from \"react-router-dom\";\nimport { connect } from \"react-redux\";\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nimport {\n isTagTracking,\n isTagTrackingMap as _isTagTrackingMap,\n} from \"components/ConfigJs\";\n\nlet TagTrackingMenu = ({\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n strings, // localisation\n}) => {\n const isTagTrackingMap = _isTagTrackingMap();\n\n const allowGuest = isUserGuest;\n const allowOperator = isUserSuper || isUserAdmin || isUserUser;\n const allowAdmin = isUserSuper || isUserAdmin;\n const allowSuper = isUserSuper;\n\n return (\n \n \n \n {strings?.[\"Tags In Zones\"]}\n \n {isTagTrackingMap && (\n \n {strings?.[\"Tag Map\"]}\n \n )}\n \n {strings?.[\"Tags\"]}\n \n {allowAdmin && (\n <>\n \n {strings?.[\"Tag Zones\"]}\n \n \n {strings?.[\"Users\"]}\n \n \n {strings?.[\"Personnel\"]}\n \n \n {strings?.[\"Vehicles\"]}\n \n \n )}\n \n \n );\n};\n\nTagTrackingMenu.defaultProps = {};\n\nTagTrackingMenu = connect((state) => ({\n isUserSuper: isUserSuper(state),\n isUserAdmin: isUserAdmin(state),\n isUserUser: isUserUser(state),\n isUserGuest: isUserGuest(state),\n}))(TagTrackingMenu);\n\nexport default TagTrackingMenu;\n","import React from \"react\";\nimport { Dropdown, Menu } from \"semantic-ui-react\";\nimport { Link } from \"react-router-dom\";\nimport { connect } from \"react-redux\";\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nlet OperatorMenu = ({ isUserSuper, level, strings }) => {\n return (\n \n \n \n {strings?.[\"Controller Status\"]}\n \n \n {strings?.[\"FireFly Status\"]}\n \n \n {strings?.[\"Faults\"]}\n \n \n {strings?.[\"FireFly Faults\"]}\n \n \n {strings?.[\"Battery Faults\"]}\n \n \n {strings?.[\"Network Faults\"]}\n \n \n {strings?.[\"Controller Reports\"]}\n \n \n \n );\n};\n\nOperatorMenu.defaultProps = {};\n\nOperatorMenu = connect((state) => ({\n isUserSuper: isUserSuper(state),\n isUserAdmin: isUserAdmin(state),\n isUserUser: isUserUser(state),\n isUserGuest: isUserGuest(state),\n}))(OperatorMenu);\n\nexport default OperatorMenu;\n","import React from \"react\";\nimport { Dropdown, Menu } from \"semantic-ui-react\";\nimport { Link } from \"react-router-dom\";\nimport { connect } from \"react-redux\";\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n} from \"auth/reducer\";\n\nimport {\n isLightingControl as _isLightingControl,\n isShowExternalTriggerEvent as _isShowExternalTriggerEvent,\n isShowScheduledEvent as _isShowScheduledEvent,\n isShowEventLog as _isShowEventLog,\n} from \"components/ConfigJs\";\n\nlet LightingControlMenu = ({\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n //\n strings, // localisation\n userSettings,\n}) => {\n const allowGuest = isUserGuest;\n const allowOperator = isUserSuper || isUserAdmin || isUserUser;\n const allowAdmin = isUserSuper || isUserAdmin;\n const allowSuper = isUserSuper;\n const isShowExternalTriggerEvent =\n userSettings?.feature?.includes(\"showExternalTriggerEvent\") ||\n _isShowExternalTriggerEvent();\n const isShowScheduledEvent =\n userSettings?.feature?.includes(\"showScheduledEvent\") ||\n _isShowScheduledEvent();\n\n const isShowEventLog = _isShowEventLog();\n const isLightingControl =\n userSettings?.application?.includes(\"smartLighting\") ||\n _isLightingControl();\n\n return (\n // \n // \n // \n // {strings?.[\"Lighting Control\"]}\n // \n // {allowAdmin && (\n // <>\n // \n // {strings?.[\"Lighting Control Layouts\"]}\n // \n // \n // {strings?.[\"Polygons\"]}\n // \n // \n // )}\n // {isShowEventLog && (\n // \n // {strings?.[\"Event Log\"]}\n // \n // )}\n // {(isShowExternalTriggerEvent || isShowScheduledEvent) && (\n // \n // )}\n // {isShowExternalTriggerEvent && (\n // \n // {strings?.[\"External Trigger Events\"]}\n // \n // )}\n // {isShowScheduledEvent && (\n // \n // {strings?.[\"Scheduled Jobs\"]}\n // \n // )}\n // \n // \n\n \n \n \n {strings?.[\"Lighting Control\"]}\n \n {allowAdmin && (\n <>\n \n {strings?.[\"Lighting Control Layouts\"]}\n \n \n {strings?.[\"Polygons\"]}\n \n \n )}\n {(isShowEventLog ||\n isShowExternalTriggerEvent ||\n isShowScheduledEvent) && (\n <>\n \n {strings[\"Lighting Events\"]}\n \n \n )}\n {isShowEventLog && (\n \n {strings?.[\"Event Log\"]}\n \n )}\n {isShowExternalTriggerEvent && (\n \n {strings?.[\"External Trigger Events\"]}\n \n )}\n {isShowScheduledEvent && (\n \n {strings?.[\"Scheduled Events\"]}\n \n )}\n {isShowScheduledEvent && (\n <>\n \n \n {strings?.[\"Scheduled Jobs\"]}\n \n \n )}\n \n \n );\n};\n\nLightingControlMenu.defaultProps = {};\n\nLightingControlMenu = connect((state) => ({\n isUserSuper: isUserSuper(state),\n isUserAdmin: isUserAdmin(state),\n isUserUser: isUserUser(state),\n isUserGuest: isUserGuest(state),\n}))(LightingControlMenu);\n\nexport default LightingControlMenu;\n","import React from \"react\";\nimport { Dropdown } from \"semantic-ui-react\";\n\nimport { Link } from \"react-router-dom\";\nimport { connect } from \"react-redux\";\nimport { logout, reset } from \"auth/actions\";\nimport { getEmail, getUsername } from \"auth/reducer\";\nimport { UpdateMqttReset } from \"components/WebWorker/actions\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { clearCookie } from \"cookies\";\n\n// #NOTE\n// #WIP - same functionality as\n// src/components/User/UserMenuLogout.js\n// >>>>COMBINE FUNCTIONS/COMPONENTS\n\nconst UserMenu = ({\n logout,\n reset,\n username,\n email,\n UpdateMqttReset,\n componentstate,\n //\n strings, // localisation\n}) => {\n const UserLogout = () => {\n UpdateMqttReset(true); // terminate webworker\n reset();\n\n // remove cache state for data fetch\n componentstate.remove(\"FETCH_ALL_DATA\");\n\n logout();\n\n // clear authentication cookie\n clearCookie(\"jwt-token\");\n };\n\n return (\n \n \n \n {strings?.[\"Profile\"]}\n \n \n {strings?.[\"Help\"]}\n \n \n {strings?.[\"Logout\"]}\n \n \n \n );\n};\n\nfunction mapStateToProps(state, props) {\n const username = getUsername(state);\n const email = getEmail(state);\n\n return {\n username,\n email,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n logout,\n reset,\n UpdateMqttReset,\n })(UserMenu)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\nimport { Button, Icon, Popup } from \"semantic-ui-react\";\n\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\n\nimport {\n TurnOnOffPokeTheWorker,\n SetPokeTheWorkerPollRate,\n} from \"components/Settings/actions\";\n\nexport class DataCollectButton extends Component {\n constructor(props) {\n super(props);\n this.state = {};\n }\n\n componentDidMount() {\n // not in use - yet?\n }\n\n componentDidUpdate(prevProps, prevState) {\n // not in use - yet?\n }\n\n clickAction = (e) => {\n //nothing for the moment\n // later add action to disable data collection\n };\n\n getButtonStyle = () => {\n const { isPokeTheWorker, isFetching } = this.props;\n\n // possible button colours\n // [\"red\",\"orange\",\"orange\",\"olive\",\"green\",\"teal\",\"blue\",\"violet\",\"purple\",\"pink\",\"brown\",\"grey\",\"black\",\"facebook\",\"google plus\",\"instagram\",\"linkedin\",\"twitter\",\"vk\",\"youtube\"].\n\n // and the current page faults timestamp (TS) is less than mqtt TS\n if (isPokeTheWorker || isFetching) {\n return \"light green\";\n } else {\n return \"\";\n }\n };\n\n getButtonLink = () => {\n return `/tools/system`;\n };\n\n render() {\n const buttonSize = this.props?.size || \"large\";\n\n return (\n \n \n {/* */}\n \n \n }\n />\n \n );\n }\n}\n\nfunction mapStateToProps(state) {\n const isPokeTheWorker = isOnOffPokeTheWorker(state);\n const isFetching = false; // get fetch status from API\n\n return {\n isPokeTheWorker,\n isFetching,\n };\n}\n\nexport default connect(mapStateToProps, {\n TurnOnOffPokeTheWorker,\n})(DataCollectButton);\n","import React from \"react\";\nimport { Dropdown, Menu } from \"semantic-ui-react\";\n\nimport { Link } from \"react-router-dom\";\nimport { connect } from \"react-redux\";\nimport { logout, reset } from \"auth/actions\";\nimport { getEmail, getUsername } from \"auth/reducer\";\nimport { UpdateMqttReset } from \"components/WebWorker/actions\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { clearCookie } from \"cookies\";\n\n// #NOTE\n// #WIP - same functionality as\n// src/components/User/UserMenuItem.js\n// >>>>COMBINE FUNCTIONS/COMPONENTS\n\nconst UserMenuLogout = ({\n logout,\n reset,\n username,\n email,\n UpdateMqttReset,\n componentstate,\n}) => {\n const UserLogout = () => {\n UpdateMqttReset(true); // terminate webworker\n reset();\n\n // remove cache state for data fetch\n componentstate.remove(\"FETCH_ALL_DATA\");\n\n logout();\n\n // clear authentication cookie\n clearCookie(\"jwt-token\");\n };\n\n return (\n \n Logout\n \n );\n};\n\nfunction mapStateToProps(state, props) {\n const username = getUsername(state);\n const email = getEmail(state);\n\n return {\n username,\n email,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n logout,\n reset,\n UpdateMqttReset,\n })(UserMenuLogout)\n);\n","import React from \"react\";\nimport { Dropdown, Menu } from \"semantic-ui-react\";\nimport { Link } from \"react-router-dom\";\n\nfunction TestMenu({ level }) {\n return (\n \n \n {/* #NOTE - these are disable. were used for testing */}\n {false && (\n <>\n \n Mqtt msgs\n \n \n Named Areas & Markers\n \n \n )}\n \n Test Marker Icons\n \n \n \n );\n}\n\nTestMenu.defaultProps = {};\n\nexport default TestMenu;\n","import { useEffect, useState } from \"react\";\nimport { isDebugScreensize } from \"components/ConfigJs\";\n\nfunction getWindowDimensions() {\n const { innerWidth: width, innerHeight: height } = window;\n\n if (isDebugScreensize()) {\n console.log(\n `isDebugScreensize: getWindowDimensions width `,\n width,\n `height`,\n height\n );\n\n return {\n width,\n height,\n };\n }\n}\n\nexport default function useWindowDimensions() {\n const [windowDimensions, setWindowDimensions] = useState(\n getWindowDimensions()\n );\n\n useEffect(() => {\n function handleResize() {\n setWindowDimensions(getWindowDimensions());\n }\n\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n return windowDimensions;\n}\n","import React from \"react\";\nimport { Menu, Container } from \"semantic-ui-react\";\nimport hash from \"object-hash\";\n\nimport { Link } from \"react-router-dom\";\nimport { connect } from \"react-redux\";\nimport { logout, reset } from \"auth/actions\";\nimport {\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n} from \"auth/reducer\";\n\nimport {\n isDevelopmentVersion as _isDevelopmentVersion,\n isExtendedNavMenu,\n isDemoMode as _isDemoMode,\n appResponsive,\n isDebugScreensize,\n isBoomgateCrane,\n isTagTracking as _isTagTracking,\n isLightingControl as _isLightingControl,\n configAppTitle as _configAppTitle,\n} from \"components/ConfigJs\";\n\nimport Logo from \"components/Logo\";\nimport MineLevelMenus from \"containers/MineLevelMenus\";\nimport AdminMenu from \"components/Menu/AdminMenuItem\";\nimport TagTrackingMenu from \"components/Menu/TagTrackingMenuItem\";\nimport OperatorMenu from \"components/Menu/OperatorMenuItem\"; // i.e. Status Menu\nimport LightingControlMenu from \"components/Menu/LightingControlMenuItem\";\nimport UserMenu from \"components/User/UserMenuItem\";\nimport HelpMenu from \"components/Help/HelpMenuItem\";\n\nimport AlarmButton from \"components/AlarmButton\";\nimport DataCollectButton from \"components/Tools/DataCollectButton\";\n\nimport UserMenuLogout from \"components/User/UserMenuLogout\";\n\nimport TestMenu from \"components/TestMenu\";\n//import ToolsMenu from \"components/Tools/ToolsMenuItem\";\n\nimport { LogIt } from \"components/Logger/actions\";\n\nimport {\n addErrorFlashMessage,\n clearFlashMessages,\n} from \"FlashMessages/actions\";\n\nimport NamedAreaDisplaySettings from \"pages/ControlRoomPage/NamedAreaDisplaySettings\";\n\nimport { isUserGuest } from \"auth/reducer\";\nimport { getUserSessionIp } from \"utils/messageToken\";\n\n//import Clock from \"components/Clock\";\n\nimport useWindowDimensions from \"utils/useWindowDimensions\";\nimport { useMediaQuery } from \"react-responsive\";\n\nconst Header = ({\n isAuthenticated,\n isUserSuper,\n isUserAdmin,\n isUserUser,\n isUserGuest,\n logout,\n reset,\n userSessionIp,\n //\n subHeader,\n showMinimal,\n //alarmButtonSize,\n //winDims,\n //language,\n //componentKey,\n strings, // localisation\n userSettings,\n}) => {\n //console.log(\"xxx header - --------------- \");\n //console.log(\"xxx header - language \", language);\n //console.log(\"xxx header - strings getLanguage \", strings?.getLanguage?.());\n //console.log(\"xxx header - strings \", JSON.stringify(strings));\n // console.log(\n // \"xxx header - FireFly Lighting System \",\n // strings?.[\"FireFly Lighting System\"]\n // );\n //console.log(\"xxx header - userSettings \", JSON.stringify(userSettings));\n\n const isTagTracking =\n userSettings?.application?.includes(\"tagTracking\") || _isTagTracking();\n const isLightingControl =\n userSettings?.application?.includes(\"smartLighting\") ||\n _isLightingControl();\n const configAppTitle = _configAppTitle();\n\n const isDevelopmentVersion =\n userSettings?.feature?.includes(\"showDevelopmentVersion\") ||\n _isDevelopmentVersion();\n const isDemoMode =\n userSettings?.feature?.includes(\"showDemoMode\") || _isDemoMode();\n\n //console.log(\"xxx isDemoMode\", isDemoMode);\n\n const allowGuest = isUserGuest;\n const allowOperator = isUserSuper || isUserAdmin || isUserUser;\n const allowAdmin = isUserSuper || isUserAdmin;\n const allowSuper = isUserSuper;\n\n //const { height, width } = winDims || {};\n const { height, width } = useWindowDimensions() || {};\n const { mobile, tablet, laptop, desktop } = appResponsive();\n\n const isDesktopOrLaptop = useMediaQuery({\n query: `(min-width: ${desktop}px)`,\n });\n\n const isTabletOrMobileDevice = useMediaQuery({\n query: `(max-width: ${mobile}px)`,\n });\n\n const isMobile = useMediaQuery({\n query: `(min-width: ${mobile}px)`,\n });\n\n const isTablet = useMediaQuery({\n query: `(min-width: ${tablet}px)`,\n });\n\n const isLaptop = useMediaQuery({\n query: `(min-width: ${laptop}px)`,\n });\n\n const isDesktop = useMediaQuery({\n query: `(min-width: ${desktop}px)`,\n });\n\n const isNoSpaceForButtons = useMediaQuery({\n query: `(min-width: 830px)`,\n });\n\n // sizes - 'mini', 'tiny', 'small', 'large', 'big', 'huge', and 'massive'\n let alarmButtonSize = \"large\";\n let hideAlarmButtons = false;\n if (isMobile) alarmButtonSize = \"mini\";\n if (isTablet) alarmButtonSize = \"mini\";\n if (isLaptop) alarmButtonSize = \"small\";\n if (isDesktop) alarmButtonSize = \"large\";\n if (isNoSpaceForButtons) hideAlarmButtons = true;\n\n if (isDebugScreensize()) {\n console.log(\n `isDebugScreensize: isMobile,isTablet,isLaptop,isDesktop, `,\n isMobile,\n isTablet,\n isLaptop,\n isDesktop\n );\n }\n\n let userLinks;\n let userLinksMinimal;\n\n // APP_TERMINOLOGY\n let strTitle =\n strings?.[`${configAppTitle}`] || strings?.[\"FireFly Lighting System\"];\n\n if (isDemoMode) {\n strTitle = `${strTitle} [DEMO]`;\n }\n\n const navButtons = (\n \n {\n // #NOTE - Main nav config option has been superceded in favour of per User settings in profile\n // Left here JIC things change again.\n false && (\n \n )\n }\n {allowOperator && hideAlarmButtons && (\n <>\n \n \n \n \n \n \n )}\n {/* */}\n {allowAdmin && (\n \n )}\n \n );\n\n if (isAuthenticated) {\n userLinksMinimal = (\n
\n \n
\n );\n\n userLinks = (\n
\n {/*
*/}\n {/* */}\n {false && !subHeader && allowSuper && (\n \n SESSION: {JSON.stringify(userSessionIp)} [w {width}, h: {height}]\n
\n )}\n\n {!subHeader && navButtons}\n\n {false && !subHeader && (\n \n {strTitle}\n \n )}\n {!subHeader && allowOperator && (\n \n \n \n )}\n {isTagTracking && allowOperator && (\n \n \n \n )}\n {!subHeader && isLightingControl && (\n \n \n \n )}\n\n {!subHeader && allowAdmin && (\n \n \n \n )}\n {!subHeader && allowAdmin && (\n \n {strings?.[\"Users\"]}\n \n )}\n {/* {allowSuper && (\n \n \n \n )} */}\n {false && allowSuper && (\n \n \n \n )}\n {!subHeader && (\n <>\n {false && (\n \n \n \n )}\n \n \n \n \n )}\n
\n );\n }\n\n return (\n \n \n \n \n \n \n {/* */}\n {strTitle}\n \n \n \n \n \n {!showMinimal && userLinks}\n {showMinimal && userLinksMinimal}\n \n \n \n \n );\n};\n\nfunction mapStateToProps(state, props) {\n return {\n isAuthenticated: isAuthenticated(state),\n isUserSuper: isUserSuper(state),\n isUserAdmin: isUserAdmin(state),\n isUserUser: isUserUser(state),\n isUserGuest: isUserGuest(state),\n userSessionIp: getUserSessionIp(),\n };\n}\n\nexport default connect(mapStateToProps, {\n logout,\n LogIt,\n addErrorFlashMessage,\n})(Header);\n","import React from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Container, Segment } from \"semantic-ui-react\";\n\nimport { getServerInfoVersion } from \"components/Settings/reducer\";\nimport { getServerTimestamp } from \"components/WebWorker/reducer\";\n\nimport preval from \"preval.macro\";\nimport packageJson from \"../../../package.json\";\n\nimport { getUserData } from \"auth/reducer\";\n\nconst dateTimeStamp = preval`module.exports = new Date().toLocaleString('en-US', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: false });`;\nconst year = new Date().getFullYear();\n\nconst Footer = (props) => (\n
\n \n \n

\n {`Copyright ${year} - IoT Automation Global | UI: ${packageJson.version} Built ${dateTimeStamp} ${\n props.serverVersion === undefined\n ? \"\"\n : `| SERVER: ${props.serverVersion} | SERVER TIME: ${new Date(\n props.serverTimestamp * 1000\n ).toLocaleString(props.userLanguage, {\n weekday: \"short\",\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: false,\n })}`\n }`}\n

\n
\n \n
\n);\n\nfunction mapStateToProps(state, props) {\n return {\n serverVersion: getServerInfoVersion(state),\n serverTimestamp: getServerTimestamp(state),\n userLanguage: getUserData(state)?.language || \"en-US\",\n };\n}\n\nexport default connect(mapStateToProps, null)(Footer);\n","import React from 'react'\nimport Header from 'semantic-ui-react/dist/commonjs/elements/Header'\n\nimport { withMineLevel } from 'ApplicationContexts'\n\nconst MineLevelPageHeader = ({ ...props }) => {\n return (\n
\n {props.mineLevel.name} - {props.children}\n
\n )\n}\n\nexport default withMineLevel(MineLevelPageHeader)\n","export const ALLOWED_LIGHT_COLORS = getConfigItem()\n\nfunction getConfigItem () {\n try {\n const val = getCookie('available-colors')\n const serverValues = JSON.parse(atob(val))\n return serverValues\n } catch (e) {\n return ['off', 'white', 'red', 'amber', 'green']\n }\n}\n\nfunction getCookie (name) {\n var value = '; ' + document.cookie\n var parts = value.split('; ' + name + '=')\n if (parts.length === 2) {\n return parts\n .pop()\n .split(';')\n .shift()\n }\n return null\n}\n\nexport function sanitizeLightSettings (lightSettings = 'off') {\n let { color = lightSettings } = lightSettings\n\n if (ALLOWED_LIGHT_COLORS.indexOf(color) === -1) {\n color = 'off'\n }\n\n return { color }\n}\n","import { sanitizeRegionShape } from 'utils/RegionShape'\nimport { sanitizeLightSettings } from 'firefly_light_colors'\nimport cuid from 'cuid'\n\nexport function resetSeismicOverlayEditor () {\n return { type: 'RESET_SEISMIC_OVERLAY_EDITOR' }\n}\n\nexport function addNewRegion (id, points, lightSettings) {\n return {\n type: 'ADD_NEW_REGION',\n payload: {\n id,\n points: sanitizeRegionShape(points),\n lightSettings: sanitizeLightSettings(lightSettings)\n }\n }\n}\n\nexport function changeDefaultLightSettings (lightSettings) {\n return {\n type: 'CHANGE_DEFAULT_LIGHT_SETTING',\n lightSettings: sanitizeLightSettings(lightSettings)\n }\n}\n\nexport function changeRegionLightSettings (id, lightSettings) {\n return {\n type: 'CHANGE_REGION_LIGHT_SETTING',\n payload: {\n id,\n lightSettings: sanitizeLightSettings(lightSettings)\n }\n }\n}\n\nexport function changeRegionShape (id, points) {\n return {\n type: 'CHANGE_REGION_SHAPE',\n payload: {\n id,\n points: sanitizeRegionShape(points)\n }\n }\n}\n\nfunction buildPlainAction (type) {\n return id => ({ type, payload: { id } })\n}\n\nexport const deleteRegion = buildPlainAction('DELETE_REGION')\nexport const lowerRegionPriority = buildPlainAction('LOWER_REGION_PRIORITY')\nexport const raiseRegionPriority = buildPlainAction('RAISE_REGION_PRIORITY')\n\nexport const saveAndApply = mineLevelId => ({\n type: 'SAVE_NEW_REGION_REQUEST',\n payload: {\n mineLevelId\n }\n})\n\nexport const forceWholeSettings = settings => {\n const regionSettings = { byId: {}, priority: [] }\n\n settings.regionSettings.forEach(region => {\n const id = cuid()\n regionSettings.byId[id] = { id, ...region }\n regionSettings.priority.push(id)\n })\n\n return {\n type: 'FORCE_WHOLE_SETTINGS',\n payload: {\n levelDefault: settings.levelDefault,\n regionSettings\n }\n }\n}\n\nexport const startEditingWithSeismicAsStart = (\n mineLevelId,\n seismicLayerId\n) => ({\n type: 'SEISMIC_EDITOR_START_WITH_SEISMIC_LAYER',\n payload: { mineLevelId, seismicLayerId }\n})\n","import React, { Component } from 'react'\nimport PropTypes from 'prop-types'\n\nimport Button from 'semantic-ui-react/dist/commonjs/elements/Button'\nimport Popup from 'semantic-ui-react/dist/commonjs/modules/Popup'\nimport { Table } from 'semantic-ui-react'\nimport { formatDateRelativeNow } from 'utils/format-date'\n\nimport { withMineLevel } from 'ApplicationContexts'\nimport { connect } from 'react-redux'\nimport {\n getMineLevelHistory,\n getIsLoadingSeismicLayersForMineLevel\n} from 'seismicOverlays/reducer'\nimport { fetchSeismicLayersForMineLevel } from 'seismicOverlays/actions'\nimport { startEditingWithSeismicAsStart } from 'pages/CreateSeismicOverlayPage/actions'\n\nimport BasicTable from 'components/BasicTable'\n\nfunction HeaderRow () {\n return (\n \n Id\n Created\n Since\n Default Color\n Regions #\n Actions\n \n )\n}\n\nfunction BuildItemRow (\n activeLayer,\n previewingId,\n onPreview,\n onReinstate,\n onStartEditorWithSeismic\n) {\n return function ({ item, error, wholeRowMessage, ...props }) {\n if (wholeRowMessage) {\n return (\n \n {wholeRowMessage}\n \n )\n }\n return (\n \n {item.id}\n {item.createdAt.toISOString()}\n {formatDateRelativeNow(item.createdAt)}\n {item.levelDefault.color}\n {item.regionSettings.length}\n \n {onPreview && (\n onPreview(item.id)}\n primary={item.id === previewingId}\n disabled={item.id === previewingId}\n />\n }\n />\n )}\n {onReinstate && (\n onReinstate(item.id)} />\n }\n />\n )}\n {onStartEditorWithSeismic && (\n onStartEditorWithSeismic(item.id)}\n />\n }\n />\n )}\n \n \n )\n }\n}\n\nclass SeismicLayerList extends Component {\n static propTypes = {\n layers: PropTypes.array.isRequired,\n isLoading: PropTypes.bool.isRequired,\n previewingId: PropTypes.any,\n onPreview: PropTypes.func,\n onStartEditorWithSeismic: PropTypes.func\n }\n\n render () {\n const {\n layers,\n isLoading,\n onPreview,\n onStartEditorWithSeismic,\n onReinstate,\n previewingId\n } = this.props\n\n return (\n item.id}\n />\n )\n }\n}\n\nclass ConnectedSeismicLayerList extends React.Component {\n componentDidMount () {\n this.props.fetchSeismicLayers()\n }\n componentDidUpdate (prevProps) {\n if (prevProps.mineLevel.id !== this.props.mineLevel.id) {\n this.props.fetchSeismicLayers()\n }\n }\n\n render () {\n const { fetchMineLevels, ...props } = this.props\n return \n }\n}\n\nfunction mapStateToProps (state, props) {\n return {\n layers: getMineLevelHistory(state, props.mineLevel.id),\n isLoading: getIsLoadingSeismicLayersForMineLevel(state, props.mineLevel.id)\n }\n}\n\nfunction mapDispatchToProps (dispatch, props) {\n return {\n fetchSeismicLayers: () => {\n dispatch(fetchSeismicLayersForMineLevel(props.mineLevel.id))\n },\n onStartEditorWithSeismic: seismicLayerId => {\n dispatch(\n startEditingWithSeismicAsStart(props.mineLevel.id, seismicLayerId)\n )\n }\n }\n}\nexport default withMineLevel(\n connect(mapStateToProps, mapDispatchToProps)(ConnectedSeismicLayerList)\n)\n","import React, { Component } from 'react'\nimport PropTypes from 'prop-types'\n\nimport Container from 'semantic-ui-react/dist/commonjs/elements/Container'\nimport Header from 'semantic-ui-react/dist/commonjs/elements/Header'\nimport Grid from 'semantic-ui-react/dist/commonjs/collections/Grid'\n\nimport { LayersControl } from 'react-leaflet'\nimport MineLevelMap from 'components/MineLevelMap'\nimport CurrentMineLevelFirefliesFeatureGroup from 'containers/CurrentMineLevelFirefliesFeatureGroup'\nimport MineLevelSeismicFeatureGroup from 'components/MineLevelSeismicFeatureGroup'\n\nimport MineLevelPageHeader from 'containers/MineLevelPageHeader'\nimport MineLevelSeismicLayerList from './MineLevelSeismicLayerList'\n// import PrintControl from 'react-leaflet-easyprint'\n\nclass MineLevelSeismicLayerSummaryPage extends Component {\n static propTypes = {\n children: PropTypes.node,\n className: PropTypes.string\n }\n\n constructor (props) {\n super(props)\n this.state = { previewId: null }\n }\n\n componentWillReceiveProps () {\n this.setState({ previewId: null })\n }\n\n selectForPreview = id => {\n this.setState({ previewId: id })\n }\n\n render () {\n const { previewId } = this.state\n const showPreview = previewId !== null\n\n /*\n \n */\n\n return (\n \n Seismic Layer List\n \n \n \n { console.log('Please reinstate', id) }}\n />\n \n {showPreview && (\n \n
Map View
\n \n \n \n \n \n \n \n \n
\n )}\n
\n
\n
\n )\n }\n}\n\nexport default MineLevelSeismicLayerSummaryPage\n","import Immutable from 'seamless-immutable'\nimport { createSelector } from 'reselect'\n\nexport function blankSeismic () {\n const state = undefined\n const action = {}\n return Immutable({\n levelDefault: levelDefault(state, action),\n regionSettings: regionsReducer(state, action),\n isSaving: false,\n savingError: ''\n })\n}\n\nfunction regionsReducer (state = Immutable({ byId: {}, priority: [] }), action) {\n const { type, payload } = action\n\n switch (type) {\n case 'ADD_NEW_REGION':\n return state\n .setIn(['byId', payload.id], payload)\n .set('priority', state.priority.concat([payload.id]))\n case 'CHANGE_REGION_SHAPE':\n return state.setIn(['byId', payload.id, 'points'], payload.points)\n\n case 'DELETE_REGION':\n return state\n .set('byId', state.byId.without(payload.id))\n .set(\n 'priority',\n Immutable(\n state.priority.asMutable().filter(elem => elem !== payload.id)\n )\n )\n case 'CHANGE_REGION_LIGHT_SETTING':\n return state.setIn(\n ['byId', payload.id, 'lightSettings'],\n payload.lightSettings\n )\n case 'RAISE_REGION_PRIORITY': {\n const index = state.priority.indexOf(payload.id)\n if (index < 1) {\n // not in list or at front of list\n return state\n }\n return state.set(\n 'priority',\n Immutable(swapIndexes(state.priority.asMutable(), index, index - 1))\n )\n }\n case 'LOWER_REGION_PRIORITY': {\n const index = state.priority.indexOf(payload.id)\n if (index === -1 || index === state.priority.length - 1) {\n // not in list or at back of list\n return state\n }\n return state.set(\n 'priority',\n Immutable(swapIndexes(state.priority.asMutable(), index, index + 1))\n )\n }\n default:\n return state\n }\n}\n\nfunction swapIndexes (list, index1, index2) {\n const newList = [...list]\n const temp = newList[index1]\n newList[index1] = newList[index2]\n newList[index2] = temp\n return newList\n}\nfunction levelDefault (state = { color: 'off' }, action) {\n if (action.type === 'CHANGE_DEFAULT_LIGHT_SETTING') {\n return action.lightSettings\n }\n return state\n}\n\nexport default function reduce (state = blankSeismic(), action = {}) {\n switch (action.type) {\n case 'RESET_SEISMIC_OVERLAY_EDITOR':\n return blankSeismic()\n\n case 'FORCE_WHOLE_SETTINGS':\n return Immutable({\n levelDefault: action.payload.levelDefault,\n regionSettings: action.payload.regionSettings\n })\n\n case 'SAVE_NEW_REGION_REQUEST':\n return state.setIn(['isSaving'], true).setIn(['savingError'], '')\n case 'SAVE_NEW_REGION_SUCCESS':\n return state.setIn(['isSaving'], false).setIn(['savingError'], '')\n case 'SAVE_NEW_REGION_FAILED':\n return state\n .setIn(['isSaving'], false)\n .setIn(['savingError'], action.payload)\n\n default:\n return state.merge([\n {\n levelDefault: levelDefault(state.levelDefault, action)\n },\n {\n regionSettings: regionsReducer(state.regionSettings, action)\n }\n ])\n }\n}\n\nexport const getEditingDefaultSettings = state =>\n state.editorSeismicLayer.levelDefault\n\nconst editorRegions = state => state.editorSeismicLayer.regionSettings\n\nexport const getEditingRegionsInOrder = createSelector(\n editorRegions,\n regionSettings => {\n return regionSettings.priority.map(id => {\n return regionSettings.byId[id]\n })\n }\n)\n","import React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport { connect } from 'react-redux'\nimport { Polygon } from 'react-leaflet'\nimport { EditControlFeatureGroup } from '@andrewdodd/react-leaflet-draw'\nimport cuid from 'cuid'\n\nimport { getEditingRegionsInOrder } from './reducer'\nimport * as actions from './actions'\nimport getSemanticColor from 'colorpalette'\n\nimport 'leaflet-draw/dist/leaflet.draw.css'\n\nfunction makeId (region) {\n return JSON.stringify(region.points)\n}\n\nexport class CreateRegionsMapEditor extends Component {\n static propTypes = {\n children: PropTypes.node,\n className: PropTypes.string\n }\n addRegion = evt => {\n const points = evt.layer.getLatLngs()[0]\n this.props.addRegion(points)\n }\n deleteRegion = e => {\n const { regionId } = e.props\n this.props.deleteRegion(regionId)\n }\n changeRegion = (e, layer) => {\n const points = layer.getLatLngs()[0]\n const { regionId } = e.props\n this.props.changeRegion(regionId, points)\n }\n\n render () {\n const renderId = new Date().getTime()\n const { onActivityStarted, onActivityStopped, opacity = 0.5 } = this.props\n return (\n Wups shapes cannot intersect'\n }\n },\n polyline: false\n },\n edit: {\n edit: {\n selectedPathOptions: {\n maintainColor: true,\n fillOpacity: 0.5\n // fillColor: nullm\n }\n },\n poly: {\n allowIntersection: false,\n drawError: {\n color: 'fuchsia',\n message: 'Wups shapes cannot intersect'\n }\n }\n },\n position: 'topright'\n }}\n >\n {this.props.orderedRegions\n .asMutable()\n .reverse()\n .map((region, idx) => {\n const { points, lightSettings: { color } } = region\n const semColor = getSemanticColor(color)\n return (\n \n )\n })}\n
\n )\n }\n}\n\nfunction mapStateToProps (state) {\n return {\n orderedRegions: getEditingRegionsInOrder(state)\n }\n}\n\nexport function mapDispatchToProps (dispatch, ownProps) {\n return {\n addRegion: shape => {\n dispatch(actions.addNewRegion(cuid(), shape))\n },\n deleteRegion: regionId => {\n dispatch(actions.deleteRegion(regionId))\n },\n changeRegion: (regionId, newShape) => {\n dispatch(actions.changeRegionShape(regionId, newShape))\n }\n }\n}\nexport default connect(mapStateToProps, mapDispatchToProps)(\n CreateRegionsMapEditor\n)\n","import React from \"react\";\n\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Icon from \"semantic-ui-react/dist/commonjs/elements/Icon\";\nimport Button from \"semantic-ui-react/dist/commonjs/elements/Button\";\nimport Menu from \"semantic-ui-react/dist/commonjs/collections/Menu\";\nimport Dropdown from \"semantic-ui-react/dist/commonjs/modules/Dropdown\";\nimport Form from \"semantic-ui-react/dist/commonjs/collections/Form\";\nimport List from \"semantic-ui-react/dist/commonjs/elements/List\";\nimport Divider from \"semantic-ui-react/dist/commonjs/elements/Divider\";\nimport Popup from \"semantic-ui-react/dist/commonjs/modules/Popup\";\n\nimport { connect } from \"react-redux\";\nimport { getEditingDefaultSettings, getEditingRegionsInOrder } from \"./reducer\";\nimport * as actions from \"./actions\";\n\nimport { ALLOWED_LIGHT_COLORS } from \"firefly_light_colors\";\nimport getSemanticColor from \"colorpalette\";\n\nfunction ChooseLightSettings({ ...props }) {\n const semColor = getSemanticColor(props.color);\n return (\n \n props.onChange(data.value)}\n options={ALLOWED_LIGHT_COLORS.map((color) => ({\n key: color,\n text: color,\n value: color,\n active: props.color === color,\n }))}\n />\n \n );\n}\n\nfunction UpDown({ ...props }) {\n const { onUp, onDown } = props;\n const buttonStyle = { padding: 0 };\n const iconStyle = { margin: 0 };\n return (\n \n \n \n \n );\n}\n\nfunction EditRegionSettingsList({ ...props }) {\n const { regions, regionActions } = props;\n const {\n changeLightSettings,\n raisePriority,\n lowerPriority,\n deleteRegion,\n } = regionActions;\n const lastIndex = regions.length - 1;\n if (lastIndex === -1) {\n return
No regions added
;\n }\n return (\n \n {regions.map((region, idx) => (\n \n \n raisePriority(region.id)}\n onDown={\n idx === lastIndex ? undefined : () => lowerPriority(region.id)\n }\n />\n \n \n \n \n \n changeLightSettings(region.id, color)}\n />\n deleteRegion(region.id)}\n />\n \n \n \n \n ))}\n \n );\n}\n\nexport function EditSeismicRegionSettings({ ...props }) {\n const { levelDefault, regions, changeDefaultColor, regionActions } = props;\n return (\n
\n
Defaults
\n \n }\n />\n \n
\n \n \n \n \n
\n
Regions
\n
\n \n \n
\n );\n}\n\nexport function mapStateToProps(state) {\n return {\n levelDefault: getEditingDefaultSettings(state),\n regions: getEditingRegionsInOrder(state),\n };\n}\n\nfunction mapDispatchToProps(dispatch, props) {\n return {\n changeDefaultColor: (color) =>\n dispatch(actions.changeDefaultLightSettings(color)),\n regionActions: {\n changeLightSettings: (id, color) =>\n dispatch(actions.changeRegionLightSettings(id, color)),\n deleteRegion: (id) => dispatch(actions.deleteRegion(id)),\n raisePriority: (id) => dispatch(actions.raiseRegionPriority(id)),\n lowerPriority: (id) => dispatch(actions.lowerRegionPriority(id)),\n },\n };\n}\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(EditSeismicRegionSettings);\n","import React, { Component } from \"react\";\nimport Header from \"semantic-ui-react/dist/commonjs/elements/Header\";\nimport Grid from \"semantic-ui-react/dist/commonjs/collections/Grid\";\nimport Button from \"semantic-ui-react/dist/commonjs/elements/Button\";\nimport Form from \"semantic-ui-react/dist/commonjs/collections/Form\";\nimport Radio from \"semantic-ui-react/dist/commonjs/addons/Radio\";\nimport { Message } from \"semantic-ui-react\";\nimport { LayersControl, Rectangle } from \"react-leaflet\";\n\nimport { connect } from \"react-redux\";\n\nimport MineLevelMap from \"components/MineLevelMap\";\nimport CurrentSeismicFeatureGroup from \"containers/CurrentSeismicFeatureGroup\";\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroup\";\nimport CreateRegionsMapEditor from \"./CreateRegionsMapEditor\";\nimport EditSeismicRegionSettings from \"./EditSeismicRegionSettings\";\nimport { saveAndApply, resetSeismicOverlayEditor } from \"./actions\";\nimport MineLevelPageHeader from \"containers/MineLevelPageHeader\";\nimport {\n getIsLoadingSeismicLayersForMineLevel,\n getCurrentSeismicLayer,\n} from \"seismicOverlays/reducer\";\n\nimport { withMineLevel } from \"ApplicationContexts\";\nimport \"react-input-range/lib/css/index.css\";\nimport InputRange from \"react-input-range\";\nimport getSemanticColor from \"colorpalette\";\n\nlet SaveSettingsButton = ({ ...props }) => {\n let text = \"Save and apply\";\n if (props.isSaving) {\n text = \"Busy saving\";\n } else if (props.isEditing) {\n text = \"Currently editing\";\n }\n return (\n {\n props.saveAndApply(props.mineLevel.id);\n }}\n disabled={props.isSaving || props.isEditing}\n >\n {text}\n \n );\n};\n\nSaveSettingsButton = withMineLevel(\n connect(\n (state) => {\n return { isSaving: state.editorSeismicLayer.isSaving };\n },\n { saveAndApply }\n )(SaveSettingsButton)\n);\n\nconst SaveError = connect((state) => {\n return { message: state.editorSeismicLayer.savingError };\n})(({ message }) => (message ? : null));\n\nclass UISettings extends Component {\n render() {\n const { opacity, onOpacityChange, showDefault, onToggleShowDefault } =\n this.props;\n return (\n
\n
UI
\n
\n \n \n \n \n \n \n `${Math.trunc(value * 100)}%`}\n value={opacity}\n onChange={(value) => onOpacityChange(value)}\n />\n \n
\n
\n );\n }\n}\n\nclass CreateSeismicOverlayPage extends Component {\n constructor(props) {\n super(props);\n this.state = { opacity: 0.5, showDefault: true, isEditing: false };\n this.onOpacityChange = this.onOpacityChange.bind(this);\n this.onToggleShowDefault = this.onToggleShowDefault.bind(this);\n }\n onStartedEditingShapes = (e) => {\n this.setState({ isEditing: true });\n };\n onStoppedEditingShapes = (e) => {\n this.setState({ isEditing: false });\n };\n\n onOpacityChange(opacity) {\n this.setState({ ...this.state, opacity });\n }\n\n onToggleShowDefault() {\n this.setState({ ...this.state, showDefault: !this.state.showDefault });\n }\n\n componentDidMount() {\n this.props.triggerReset();\n }\n componentDidUpdate(prevProps) {\n if (prevProps.mineLevel.id !== this.props.mineLevel.id) {\n this.setState({ ...this.state, opacity: 0.5, showDefault: false });\n this.props.triggerReset();\n }\n }\n render() {\n const { mineLevel, currentSeismicControlName } = this.props;\n let defaultLevel = [];\n if (this.state.showDefault) {\n const semColor = getSemanticColor(this.props.defaultLayerColor);\n const lineColor = semColor;\n let fill = semColor;\n if (semColor === \"white\") {\n const Pattern = (\n \n \n \n \n \n \n \n\n \n \n \n \n \n );\n defaultLevel.push(Pattern);\n fill = \"url(#WhitePattern)\";\n }\n\n defaultLevel.push(\n \n );\n }\n return (\n
\n Create seismic overlay\n \n \n \n \n
\n \n
\n \n \n
\n \n
Preview
\n \n \n \n \n \n \n \n \n \n {defaultLevel}\n \n \n
\n
\n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const { mineLevel } = props;\n let currentSeismicControlName = \"Active seismic\";\n\n if (getIsLoadingSeismicLayersForMineLevel(state, mineLevel.id)) {\n currentSeismicControlName = \"Loading active seismic...\";\n } else if (!getCurrentSeismicLayer(state, mineLevel.id)) {\n currentSeismicControlName = \"No active seismic\";\n }\n return {\n currentSeismicControlName,\n defaultLayerColor: state.editorSeismicLayer.levelDefault.color,\n };\n};\n\nfunction mapDispatchToProps(dispatch, props) {\n return {\n triggerReset: () => dispatch(resetSeismicOverlayEditor()),\n useActiveSeismicAsStartingPoint: () =>\n dispatch({\n type: \"SEISMIC_OVERLAY_EDITOR_USE_CURRENT_SETTINGS\",\n payload: { mineLevelId: props.mineLevel.id },\n }),\n };\n}\nexport default withMineLevel(\n connect(mapStateToProps, mapDispatchToProps)(CreateSeismicOverlayPage)\n);\n","import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\n\nimport { Container, Header } from \"semantic-ui-react\";\n\nimport MineLevelMap from \"components/MineLevelMap\";\nimport { LayersControl } from \"react-leaflet\";\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroup\";\nimport CurrentSeismicFeatureGroup from \"containers/CurrentSeismicFeatureGroup\";\n\nimport MineLevelPageHeader from \"containers/MineLevelPageHeader\";\n// import PrintControl from 'react-leaflet-easyprint'\n\nclass MineLevelSeismicLayerSummaryPage extends Component {\n static propTypes = {\n children: PropTypes.node,\n className: PropTypes.string,\n };\n\n /* */\n render() {\n return (\n \n Status\n
MineLevel Status Page
\n\n \n \n \n \n \n \n \n \n \n \n
\n );\n }\n}\n\n// export default withMineLevel(connect(mapStateToProps)(SeismicLevelOverviewPage))\nexport default MineLevelSeismicLayerSummaryPage;\n","import React from 'react'\n// import { Container, Header, Image } from 'semantic-ui-react'\nimport Header from 'semantic-ui-react/dist/commonjs/elements/Header'\n\nconst PageNotImplemented = ({\n description = 'no description provided',\n location\n}) => (\n
\n
Page not yet implemented
\n

This page is not yet implemented. Description: {description}

\n

\n Route match for {location.pathname}\n

\n
\n)\n\nexport default PageNotImplemented\n","import React from 'react'\nimport { Route } from 'react-router-dom'\n\nimport { connect } from 'react-redux'\nimport { withRouter } from 'react-router'\nimport { Switch } from 'react-router-dom'\nimport { getMineLevelByNameSlug } from 'MineLevels/reducer'\n\nimport MineLevelSeismicLayerSummaryPage from 'pages/MineLevelSeismicLayerSummaryPage'\nimport CreateSeismicOverlayPage from 'pages/CreateSeismicOverlayPage'\nimport MineLevelStatusPage from 'pages/MineLevelStatusPage'\nimport PageNotImplemented from 'components/PageNotImplemented'\n\nimport { MineLevelContext } from 'ApplicationContexts'\n\nfunction LevelSpecificPage ({ ...props }) {\n const { error, match, level } = props\n if (error) {\n return
{error}
\n }\n\n // NB: This is a bit ugly to have the MineLevel context stuff tied up with the route stuff\n // but hopefully there is a better way?\n return (\n \n \n \n \n \n \n \n \n )\n}\n\nexport function mapStateToProps (state, ownProps) {\n const match = ownProps.match\n const nameSlug = match.params.nameSlug\n const level = getMineLevelByNameSlug(state, nameSlug)\n return {\n level,\n match,\n error: level ? undefined : 'No level for slug'\n }\n}\n\nexport default withRouter(connect(mapStateToProps)(LevelSpecificPage))\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n addErrorFlashMessage,\n clearFlashMessages,\n} from \"FlashMessages/actions\";\n\nexport class CheckBrowser extends Component {\n constructor(props) {\n super(props);\n this.state = {};\n }\n\n // loads header and message to display on control screen page\n displayErrors(errorType, extraMessage) {\n let header;\n let message;\n\n switch (errorType) {\n case \"BROWSER_HAS_LIMITED_FUNCTIONALITY\":\n header = \"Browser Incompatible\";\n message =\n \"This browser does not support some functions. Please use Chrome.\";\n break;\n default:\n break;\n }\n //this.props.clearFlashMessages(); // clear off previous messages\n this.props.addErrorFlashMessage(header, message || \"Unknown problem\");\n console.log(header + \" - \" + message);\n }\n\n componentDidMount() {\n this.props.checkBrowser();\n }\n componentDidUpdate() {\n // not in use - yet?\n }\n render() {\n const { isBrowerOfLimitedFunctionality } = this.props;\n if (isBrowerOfLimitedFunctionality) {\n this.displayErrors(\"BROWSER_HAS_LIMITED_FUNCTIONALITY\", \"\");\n }\n\n return null;\n }\n}\n\nfunction mapStateToProps(state) {\n const { isBrowerOfLimitedFunctionality } = state.checkBrowser;\n return {\n isBrowerOfLimitedFunctionality,\n };\n}\n\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n checkBrowser: (checkBrowser) => {\n dispatch({ type: `CHECK_BROWSER` });\n },\n clearFlashMessages: () => {\n dispatch(clearFlashMessages());\n },\n addErrorFlashMessage: (error, extra) => {\n dispatch(addErrorFlashMessage(error, extra));\n },\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(CheckBrowser);\n","// Accepts the array and key\nexport const groupBy = (array, key) => {\n // Return the end result\n return array.reduce((result, currentValue) => {\n // If an array already present for key, push it to the array. Else create an array and push the object\n (result[currentValue[key]] = result[currentValue[key]] || []).push(\n currentValue\n );\n // Return the current iteration `result` value, this will be taken as next iteration `result` value and accumulate\n return result;\n }, {}); // empty object is the initial value for result object\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Pagination,\n Dropdown,\n Segment,\n Icon,\n Popup,\n Message,\n Tab,\n} from \"semantic-ui-react\";\n\nimport FlashMessagesList from \"FlashMessages\";\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport { DateTime } from \"luxon\";\nimport { ClearLog } from \"components/Logger/actions\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\n// tag specific operations\n//\nimport {\n getAllNamedAreaStatuses,\n getAllAreaStatuses,\n} from \"components/WebWorker/reducer\";\nimport { getAllTags } from \"components/Tags/reducer\";\nimport { fetchTags } from \"components/Tags/actions\";\nimport { fetchAllUsers } from \"components/UserAdmin/actions\";\nimport { groupBy } from \"utils/groupBy\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\nimport hash from \"object-hash\";\nimport { strings } from \"components/App/localisation\";\nimport Immutable from \"seamless-immutable\";\n\nimport { getAllAreasButtonState } from \"../../components/WebWorker/reducer\";\n\nconst colors = [\n \"purple\",\n \"olive\",\n \"blue\",\n \"violet\",\n \"teal\",\n \"pink\",\n \"brown\",\n \"grey\",\n \"black\",\n \"red\",\n \"orange\",\n \"yellow\",\n\n \"green\",\n];\n\nclass TagTrackingByZoneList extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n id: \"\",\n rssi: \"\",\n name: \"\",\n vehicle: \"\",\n tagZone: \"\",\n area: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n };\n }\n\n componentDidMount() {\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"tagsByZoneList\"\n );\n\n // console.log(\n // \"TagTrackingByZoneList filterInput componentDidMount\",\n // filterInput\n // );\n\n if (!_isEmpty(filterInput)) {\n //console.log(\"filterInput componentDidMount setState\", filterInput);\n this.setState({ filterInput: filterInput });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"tagsByZoneList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n this.setState({\n data: this.props.data,\n });\n }\n\n // const { filterInput: match } = this.state;\n // if (\n // JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n // JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n // ) {\n // let newData = [...this.props?.data]; // original data\n // newData = newData.filter(function (item) {\n // let checkMatch = true; // assume all included as default \"\" is always included\n // for (var key in match) {\n // checkMatch =\n // checkMatch &&\n // item[key]?.toLowerCase().includes(match[key].toLowerCase()); // remove item which don't match\n // }\n // return checkMatch;\n // });\n // this.setState({\n // data: newData,\n // });\n // // restore sort\n // const { column, direction } = this.state;\n // // #REVIEW - decide if need a default sort column\n // // column is initially undefined. i.e. no default sort column\n // if (column) {\n // newData = newData.slice().sort((a, b) =>\n // a[column].localeCompare(b[column], \"en\", {\n // numeric: true,\n // })\n // );\n // }\n // // newData = _.sortBy(newData, [column]);\n // if (direction === \"descending\") {\n // newData = newData.reverse();\n // }\n // this.setState({\n // data: newData,\n // });\n // }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n fetchStuff = () => {\n this.props.fetchAllUsers();\n this.props.fetchTags();\n };\n\n zoneContent = (data = [], zone, color) => {\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n // if enough faults display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const NbTags = (data) => {\n if (\n viewablesPage &&\n viewablesPage.length > 0 &&\n viewablesPage[0].id === \"\"\n ) {\n viewablesPage.shift();\n }\n\n return (\n \n \n {`${viewablesPage.length} `}\n

\n

\n {viewablesPage.length > 1 ? \"Tags\" : \"Tag\"}\n

\n \n );\n };\n\n return (\n
\n \n \n \n \n Zone: {zone}\n \n \n \n \n \n \n Tag ID\n Type\n {/* Name\n Vehicle\n RSSI */}\n Latest Report\n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n rssi,\n name,\n vehicle,\n tagZone,\n area,\n tagLink,\n tagType,\n lastStatusReport,\n }) => (\n \n {tagLink}\n {tagType}\n {/* {name}\n {vehicle} \n {rssi} */}\n {lastStatusReport}\n \n )\n )}\n {/* */}\n \n \n {pagination}\n
\n );\n };\n\n render() {\n const {\n //isLoading, error,\n levels, \n } = this.props;\n\n const {\n //column,\n data,\n //direction, filterInput\n } = this.state;\n\n const includeTitles = this.props.includeTitles === \"true\";\n const title = includeTitles ? (\n
{strings?.[\"Tags In Zones\"]}
\n ) : (\n
\n );\n\n // // total # of items to display\n // let itemsCount = 0;\n // // setup variable to display viewable items per page\n // let viewablesPage = [];\n // // check data exists. May not happen on initial startup when redux state not setup\n // if (data !== undefined) {\n // itemsCount = data.length;\n // viewablesPage = [...data];\n // }\n // // if enough faults display pagination\n // let pagination;\n // const { page, itemsPerPage } = this.state;\n\n // if (itemsCount > itemsPerPage) {\n // const totalPages = itemsCount / itemsPerPage;\n // viewablesPage = data.slice(\n // (page - 1) * itemsPerPage,\n // (page - 1) * itemsPerPage + itemsPerPage\n // );\n // pagination = (\n //
\n // \n // \n // items per page. Found {itemsCount} items.\n //
\n // );\n // }\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n return (\n
\n \n \n \n \n
{title}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {true && (\n \n
\n this.fetchStuff()}\n // onClick={this.props.ClearLog}\n >\n {strings?.[\"Update\"]}\n {/* */}\n {/* {itemsCount} */}\n \n }\n />\n
\n
\n )}\n {\n // data filter to level\n const levelData = data[level.id] || {};\n return {\n menuItem: level.name,\n render: () => (\n \n \n \n {_isEmpty(levelData) && (\n \n \n \n \n \n {strings?.[\"Tag Zone List Message Header\"]}\n \n {strings?.[\"Tag Zone List Message Content\"]}\n \n \n \n )}\n {Object.keys(levelData).map((zone, idx) => {\n return (\n \n {this.zoneContent(\n levelData[zone],\n `${zone}`,\n colors[idx]\n )}\n \n );\n })}\n \n \n \n ),\n };\n })}\n />\n \n
\n
\n );\n }\n}\n\nconst _prepData = (elements, allowToShowDetails) => {\n let filteredElements = {};\n\n //console.log(`xxx elements`, elements);\n //console.log(`xxx strings`, strings);\n\n // #WIP - force to only one area for testing\n let newElements;\n for (const area in elements) {\n newElements = elements[area];\n filteredElements[area] = {};\n for (const zone in newElements) {\n filteredElements[area][zone] = [];\n\n if (newElements[zone].length < 1) {\n filteredElements[area][zone][0] = {\n id: \"\",\n tagLink: strings?.[\"Click Update to fetch data.\"],\n tagType: \"\",\n rssi: \"\",\n name: ``,\n vehicle: ``,\n lastStatusReport: \"\",\n };\n }\n\n // only need a subset of data\n newElements[zone].forEach((tag, idx) => {\n const id = tag?.id || \"-\";\n const mac = tag?.mac || \"-\";\n const rssi = tag?.rssi || \"-\";\n const user_info = tag?.userInfo || {};\n const vehicle_info = tag?.vehicleInfo || {};\n const tagType = tag?.tagUserType;\n const lastUpdated = tag?.last_updated;\n\n const { firstname, lastname } = user_info;\n const { name, type } = vehicle_info;\n\n // is it a user _OR_ a vehicle\n\n let tagEntry = \"?\";\n switch (tagType) {\n case \"personnel\":\n if (allowToShowDetails) {\n tagEntry = `${firstname} ${lastname}`;\n } else {\n tagEntry = `${mac}`;\n } \n break;\n case \"vehicle\":\n tagEntry = `${name}`;\n break;\n case \"unknown\":\n tagEntry = `${mac}`;\n break;\n default:\n break;\n }\n\n // break down lastStatusReport as it may not be defined in object\n let lastStatusReport = \"-\";\n if (lastUpdated) {\n // see - https://moment.github.io/luxon/#/formatting?id=toformat\n lastStatusReport = DateTime.fromISO(lastUpdated).toFormat(\"FF\");\n }\n\n // compose new data set\n filteredElements[area][zone][idx] = {\n id: id,\n tagLink: {tagEntry} ,\n tagType: tagType === \"unknown\" ? \"?\" : tagType,\n rssi: rssi.toString(),\n name: `${firstname} ${lastname}`,\n vehicle: `${name}`,\n lastStatusReport,\n };\n });\n }\n }\n\n return filteredElements;\n};\n\nfunction mapStateToProps(state, props) {\n const tagData = getAllTags(state);\n\n const allAreas = getAllAreaStatuses(state);\n\n //console.log(\"xxx allAreas\", allAreas);\n\n // exclude ALL_AREAS, LEVEL_WIDE\n const allNamedAreas = getAllNamedAreaStatuses(state).filter(\n (na) => na.type !== \"LEVEL_WIDE\" && na.type !== \"ALL_AREAS\"\n );\n\n const tagZoneNamedAreas = allNamedAreas.filter(\n (na) => na.sub_type === \"tagzone\"\n );\n\n // accumulate array of area ids called \"levels\" - old school!\n let levels = [];\n\n // e.g. data: {area1: {zone1: [{id, rssi...}...], zone2: []}}\n let tagsByAreaByZone = {};\n\n allAreas.forEach((area) => {\n // console.log(\n // `tagsByAreaByZone ----PROCESS AREA ${area.id}-----------------`\n // );\n\n const { id } = area;\n levels.push({ id: id, name: id });\n\n const tagZoneNamedAreasByArea = tagZoneNamedAreas.filter(\n (na) => na.area === id\n );\n\n // console.log(\n // \"tagsByAreaByZone tagZoneNamedAreasByArea\",\n // tagZoneNamedAreasByArea\n // );\n\n const sortedByDatetagZoneNamedAreasByArea = Immutable.asMutable(\n tagZoneNamedAreasByArea\n ).sort((a, b) => a.name - b.name);\n\n const groupedTagZonesByAreaByParent = groupBy(\n sortedByDatetagZoneNamedAreasByArea,\n \"parent_name\"\n );\n\n // console.log(\n // \"tagsByAreaByZone groupedTagZonesByAreaByParent\",\n // groupedTagZonesByAreaByParent\n // );\n\n tagsByAreaByZone[id] = {};\n\n // console.log(\"tagsByAreaByZone tagData\", tagData);\n\n // #WIP - Tags may be in multiple areas so searching by 'area' property may not work.\n // consider changing the area to an array?\n const tagsByArea = tagData.filter((tag) =>\n tag.zones?.filter((z) => z.area === id)\n );\n\n // console.log(\"tagsByAreaByZone tagsByArea\", tagsByArea);\n\n for (const zone in groupedTagZonesByAreaByParent) {\n tagsByAreaByZone[id][zone] = [];\n tagsByArea.forEach((tag) => {\n if (tag.zones.some((z) => z.name === zone)) {\n tagsByAreaByZone[id][zone].push(tag);\n }\n });\n }\n\n // console.log(\"tagsByAreaByZone ===> tagsByAreaByZone\", tagsByAreaByZone);\n });\n\n const allowToShowDetails = getAllAreasButtonState(state) !== 0 ? true : false;\n\n // e.g. data: {area1: {zone1: [{id, rssi...}...], zone2: []}}\n const data = _prepData(tagsByAreaByZone, allowToShowDetails);\n\n // console.log(\"tagsByAreaByZone data\", data);\n // console.log(\"tagsByAreaByZone ---------------------\");\n\n return {\n levels,\n data,\n allowToShowDetails,\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n ClearLog,\n fetchTags,\n fetchAllUsers,\n saveUserSettingsComponentState,\n })(TagTrackingByZoneList)\n);\n","// see - https://github.com/skyeer/react-leaflet-custom-control\n// react-leaflet v2 wrapper for the leaflet-search-control\n//\n\nimport { Children } from \"react\";\nimport { render, unmountComponentAtNode } from \"react-dom\";\nimport { MapControl, withLeaflet } from \"react-leaflet\";\nimport L from \"leaflet\";\n//import PropTypes from \"prop-types\";\n\n//import SearchControl from \"./SearchControl\";\nimport SearchControl from \"../leaflet-search-control\";\n\nclass Control extends MapControl {\n constructor(props, context) {\n super(props);\n }\n\n createLeafletElement(options) {\n const searchControl = new SearchControl(options);\n return searchControl;\n }\n\n componentDidMount() {\n const { map } = this.props.leaflet;\n map.addControl(this.leafletElement);\n\n //To suppress control events from propagation\n const containerDiv = this.leafletElement.getContainer();\n L.DomEvent.disableClickPropagation(containerDiv);\n }\n\n // createLeafletElement({ position, className, placeholder, data }) {\n // this.leafletElement = new SearchControl({\n // position,\n // className,\n // placeholder,\n // data,\n // });\n // return this.leafletElement;\n // }\n\n // updateLeafletElement(fromProps, toProps) {\n // super.updateLeafletElement(fromProps, toProps);\n // this.renderContent();\n // }\n\n // componentDidMount() {\n // super.componentDidMount();\n // this.renderContent();\n // }\n\n // componentWillUnmount() {\n // unmountComponentAtNode(this.leafletElement.getContainer());\n // super.componentWillUnmount();\n // }\n\n // renderContent() {\n // const container = this.leafletElement.getContainer();\n // render(Children.only(this.props.children), container);\n // }\n}\n\nexport default withLeaflet(Control);\n","// see - src/admin/named-area-group/NamedAreaGroupSettingsModal.js\n\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Form,\n Segment,\n Modal,\n Header,\n Icon,\n Button,\n Grid,\n} from \"semantic-ui-react\";\nimport { reduxForm } from \"redux-form\";\n\nimport isEqual from \"lodash/isEqual\";\n\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nimport { tagTrackingUserDetailsCardPersonnel } from \"admin/tag-tracking/TagTrackingUserDetailsCardPersonnel\";\nimport { tagTrackingUserDetailsCardVehicle } from \"admin/tag-tracking/TagTrackingUserDetailsCardVehicle\";\nimport { tagTrackingUserDetailsCardUnknown } from \"admin/tag-tracking/TagTrackingUserDetailsCardUnknown\";\nimport { getTagById } from \"components/Tags/reducer\";\n\nimport { getAllAreasButtonState } from \"../../components/WebWorker/reducer\";\n\nclass TagTrackingMarkerPopupModal extends Component {\n constructor(props) {\n super(props);\n this.state = { modalOpen: false };\n }\n\n componentDidMount() {\n const { open, isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n\n if (open) {\n this.handleOpen();\n }\n\n if (isPokeTheWorker) {\n TurnOnOffPokeTheWorker(false);\n }\n }\n\n componentWillUnmount() {\n const { isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n TurnOnOffPokeTheWorker(true);\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleCancel = () => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.resetModal();\n\n // reset the form\n //this.setState({ value: \"\" }, () => this.props.reset());\n };\n\n render() {\n const { tagUserType, id, tagUserId, mac, allowToShowDetails } = this.props;\n\n const imageFilenameUnknown = \"tag-unknown.png\";\n const imageFilenameUser = \"avatar-construction.png\";\n const imageFilenameVehicle = \"avatar-dump-truck.png\";\n\n let urlImage = process.env.PUBLIC_URL + \"/images/\" + imageFilenameUnknown;\n switch (tagUserType) {\n case \"personnel\":\n urlImage = process.env.PUBLIC_URL + \"/images/\" + imageFilenameUser;\n break;\n case \"vehicle\":\n urlImage = process.env.PUBLIC_URL + \"/images/\" + imageFilenameVehicle;\n break;\n default:\n break;\n }\n\n return (\n \n {`Tag ${mac}`} }\n />\n \n \n
\n \n \n \n \n {tagUserType === \"unknown\" &&\n tagTrackingUserDetailsCardUnknown(\n urlImage,\n id,\n mac,\n true,\n true\n )}\n {tagUserType === \"vehicle\" &&\n tagTrackingUserDetailsCardVehicle(\n urlImage,\n tagUserId,\n true,\n allowToShowDetails\n )}\n {tagUserType === \"personnel\" &&\n tagTrackingUserDetailsCardPersonnel(\n urlImage,\n tagUserId,\n true,\n allowToShowDetails\n )}\n \n \n \n \n
\n
\n
\n \n \n \n
\n );\n }\n}\n\nTagTrackingMarkerPopupModal = reduxForm({\n form: \"tagTrackingMarkerPopupModal\",\n enableReinitialize: true,\n //keepDirtyOnReinitialize: true,\n touchOnChange: true,\n //validate,\n})(TagTrackingMarkerPopupModal);\n\nfunction mapStateToProps(state, props) {\n const {\n initialValues: { id },\n } = props;\n\n // derive mac from id. Format is `id~mac`\n const mac = id?.split?.(\"~\")?.[1] || \"\";\n\n const tag = getTagById(state, id);\n const { tagUserType, tagUserId } = tag;\n\n let tagUserData;\n switch (tagUserType) {\n case \"personnel\":\n tagUserData = { ...tag.userInfo };\n // temporary until nickname is setup (note - cloned above to be mutable)\n tagUserData.nick = `${\n tagUserData?.firstname\n }${tagUserData?.lastname?.charAt(0)}`;\n break;\n case \"vehicle\":\n tagUserData = { ...tag.vehicleInfo };\n break;\n default:\n break;\n }\n\n const allowToShowDetails = getAllAreasButtonState(state) !== 0 ? true : false;\n\n const newInitialVales = { id, mac, tagUserData };\n\n return {\n isPokeTheWorker: isOnOffPokeTheWorker(state),\n id,\n mac,\n tagUserId,\n tagUserType,\n initialValues: newInitialVales,\n allowToShowDetails,\n };\n}\n\nexport default connect(mapStateToProps, { TurnOnOffPokeTheWorker })(\n TagTrackingMarkerPopupModal\n);\n","import React from \"react\";\n\nimport { Form, Grid, Image, Segment, Header } from \"semantic-ui-react\";\nimport { Field } from \"redux-form\";\nimport { renderField } from \"admin/form-field\";\nimport { Link } from \"react-router-dom\";\n\n// do not check for 0 as falsy\nconst required = (value) => (value !== \"\" ? undefined : \"Required\");\nconst validate = (values) => {\n const errors = {};\n return errors;\n};\n\nexport const tagTrackingUserDetailsCardUnknown = (\n urlImage,\n tagId,\n mac,\n disabled\n) => {\n // if the card is 'disabled' it has been 'assigned'\n const cardTitle = disabled ? (\n {`Unassigned Tag`} \n ) : (\n \"Details\"\n );\n\n return (\n \n \n \n \n
{cardTitle}
\n
\n
\n \n \n \n \n \n \n \n \n
\n
\n );\n};\n","/*\n1Dec21 - stopped using this as the data update would re-drawn a layer with each hash().\n\nIssue refs:\n- https://github.com/PaulLeCam/react-leaflet/issues/389\n- \n\nSee also:\n- https://github.com/PaulLeCam/react-leaflet/issues/697\n- https://github.com/PaulLeCam/react-leaflet/issues/332\n- https://gist.github.com/Shrugsy/5e898173c965e7642db8927636bedf7a\n\n\nFor markercluster see:\n- https://stackoverflow.com/questions/59306768/marker-clustering-leaflet-markercluster-with-react-leaflet-2-0/59322023\n\n*/\n\n/*\nAbout 'react-leaflet-markercluster'\n\nSee - https://github.com/yuzhva/react-leaflet-markercluster/issues/69\n\nThis works for GeoJson but we need to use an older version of react-leaflet-markercluster (v2.0.0) which is compatible\nwith react-leaflet v2. We can't update react-leaflet to v3 until @andrewdodd EditFeatureLayer dependence is removed from the \ncode.\n*/\n\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { withMineLevel } from \"ApplicationContexts\";\n\nimport L from \"leaflet\";\n\nimport MarkerClusterGroup from \"react-leaflet-markercluster\";\nimport { GeoJSON } from \"react-leaflet\";\n\nimport { makeIcon } from \"components/Map/MakeIcon\";\n\nimport {\n getTagTrackingCoordinatesByAreaId,\n getTagIdsByAreaId,\n} from \"components/Tags/reducer\";\n\nimport hash from \"object-hash\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport TagTrackingMarkerPopupModal from \"admin/tag-tracking/TagTrackingMarkerPopupModal\";\n\nimport { getAllAreasButtonState } from \"../../components/WebWorker/reducer\";\n\n// #TODO #REVEW - write a geoJson parse checker\nfunction tryParseJSON(jsonObj) {\n try {\n var o = JSON.parse(JSON.stringify(jsonObj));\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,\n // but... JSON.parse(null) returns null, and typeof null === \"object\",\n // so we must check for that, too. Thankfully, null is falsey, so this suffices:\n if (o && typeof o === \"object\") {\n return true;\n }\n } catch (e) {}\n return false;\n}\n\n// props\n// - https://www.npmjs.com/package/react-leaflet-markercluster#api\n// - https://github.com/Leaflet/Leaflet.markercluster#all-options\n//\n// Function for creating custom icon for cluster group\n// https://github.com/Leaflet/Leaflet.markercluster#customising-the-clustered-markers\n// NOTE: iconCreateFunction is running by leaflet, which does not support ES6 arrow func syntax\n// eslint-disable-next-line\nconst createClusterCustomIcon = function (cluster) {\n return L.divIcon({\n html: `${cluster.getChildCount()}`,\n className: \"marker-cluster-custom\",\n iconSize: L.point(40, 40, true),\n });\n};\n\nconst filterTags = (tags, activeTagType) => {\n let filterTags = {};\n filterTags.type = \"FeatureCollection\";\n if (tags?.features !== undefined) {\n filterTags.features = tags.features.filter((tag) =>\n activeTagType.includes(tag.properties.tagUserType)\n );\n } else {\n filterTags.features = [];\n }\n return filterTags;\n};\n\nclass CurrentTagTrackingFeatureGroup extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n isOpenTagTrackingMarkerPopup: false,\n // modal for details of the marker\n isOpenTagTrackingMarkerPopupModal: {\n active: false,\n id: \"\",\n area: \"\",\n },\n tags: {},\n };\n }\n\n componentDidMount() {\n const { tags, activeTagType } = this.props;\n\n // update tag data from active filter buttons\n const newTags = filterTags(tags, activeTagType);\n this.setState({ tags: newTags });\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n // if the popup is open stop rendering\n if (nextState?.isOpenTagTrackingMarkerPopup === true) {\n return false;\n }\n return true;\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { tags, activeTagType } = this.props;\n\n // #NOTE - only recalculate the tag display data if the tags have changed,\n // or the tag filtering has changed.\n // This is to reduce the # of recalculations.\n\n if (prevProps.tags !== tags || prevProps.activeTagType !== activeTagType) {\n // update tag data from active filter buttons\n const newTags = filterTags(tags, activeTagType);\n this.setState({ tags: newTags });\n }\n }\n\n resetModal = () => {\n this.setState({\n isOpenTagTrackingMarkerPopupModal: {\n active: false,\n id: \"\",\n area: \"\",\n },\n });\n };\n\n render() {\n const { area, allowToShowDetails } = this.props;\n const { tags } = this.state;\n\n const onEachFeature = (feature, layer) => {\n let popupContent = ``;\n if (feature.properties && feature.properties.id) {\n const {\n properties: { id, status, tagUserType, userInfo, vehicleInfo, mac },\n } = feature;\n\n let tagEntry;\n switch (tagUserType) {\n case \"personnel\":\n if (allowToShowDetails) {\n const { firstname, lastname } = userInfo;\n tagEntry = `${firstname} ${lastname}`;\n } else {\n tagEntry = `${mac}`;\n }\n break;\n case \"vehicle\":\n if (allowToShowDetails) {\n const { name, type } = vehicleInfo;\n tagEntry = `${name}`;\n } else {\n tagEntry = `${mac}`;\n }\n break;\n case \"unknown\":\n tagEntry = `${mac}`;\n break;\n default:\n break;\n }\n\n //popupContent = `

Status: ${status?.toUpperCase()}

`;\n popupContent = ``;\n }\n\n layer.bindPopup(popupContent);\n layer.on(\"popupclose\", (a) => {\n this.setState({\n isOpenTagTrackingMarkerPopup: false,\n });\n });\n layer.on(\"popupopen\", (a) => {\n this.setState({\n isOpenTagTrackingMarkerPopup: true,\n });\n const popUp = a.target.getPopup();\n popUp\n .getElement()\n .querySelector(`.button-edit`)\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"data-key \",\n // e.target.dataset.key\n // );\n\n const id = e.target.dataset.key;\n if (!_isEmpty(id)) {\n const newModal = {\n active: true,\n id: id,\n area: area,\n };\n this.setState(\n {\n isOpenTagTrackingMarkerPopupModal: newModal,\n },\n () => console.log(`CLICK ON TAG ID: `, newModal)\n );\n this.setState({\n isOpenTagTrackingMarkerPopup: false,\n });\n }\n });\n });\n };\n\n const pointToLayer = (feature, latlng) => {\n const {\n properties: { tagUserType, status },\n } = feature;\n\n let tagIcon = \"TagUnknownMarker\";\n switch (tagUserType) {\n case \"personnel\":\n tagIcon = \"TagHardHat\";\n break;\n case \"vehicle\":\n tagIcon = \"TagTruckPickupMarker\";\n break;\n\n default:\n break;\n }\n\n let tagColor = \"Peru\";\n switch (status) {\n case \"lost\":\n tagColor = \"grey\";\n break;\n case \"initial\":\n tagColor = \"green\";\n break;\n\n default:\n break;\n }\n\n //return L.circleMarker(latlng, null); // Change marker to circle\n return L.marker(latlng, {\n icon: makeIcon(tagIcon, { stroke: tagColor, fill: tagColor }, 1), // default to purple as this is not a suppported active color\n });\n };\n\n const valid = !_isEmpty(tags) && tryParseJSON(tags);\n\n const isOpenSettingsModal =\n this.state.isOpenTagTrackingMarkerPopupModal.active === true;\n\n // #NOTE - comment in rendering.\n // Re-render *should* only happen if the tag has moved position or the tag filter has changed (see componentDidUpdate),\n // however in reality the coordinate data is update to such a high precision (with interpolation between FF coordinates) that the\n // tag data does update with every websocket data delivery.\n // So we have to rely on the server (websocket connection) being the arbitor of the need to update.\n //\n\n return (\n valid && (\n <>\n {isOpenSettingsModal && (\n this.handleSettingsSave(values)}\n resetModal={() => this.resetModal(false)}\n />\n )}\n\n \n \n \n \n )\n );\n }\n}\n\nexport function mapStateToProps(state, props) {\n\n const { mineLevel, activeTagType } = props;\n\n const tags = getTagTrackingCoordinatesByAreaId(state, mineLevel.id);\n const tagIds = getTagIdsByAreaId(state, mineLevel.id);\n const allowToShowDetails = getAllAreasButtonState(state) !== 0 ? true : false;\n\n // src/admin/tag-tracking/CurrentTagTrackingFeatureGroupGeoJson.js\n\n // console.log(\n // `CurrentTagTrackingFeatureGroupGeoJson ----- ${mineLevel.id} -------------`\n // );\n // console.log(\"CurrentTagTrackingFeatureGroupGeoJson tagIds\", tagIds);\n // console.log(\"CurrentTagTrackingFeatureGroupGeoJson tags\", tags);\n\n // #DEBUG - debugging the plot points - leave in place\n if (false) {\n console.log(`tagTracking - TAG_UPDATE CHANGE coordInfo tags ---- `, tags);\n if (tags) {\n tags.features.forEach((coord) => {\n const {\n id,\n geometry: { coordinates },\n properties: { easting, northing, tagUserType },\n } = coord;\n const coordInfo = `[${northing},${easting}]: [${coordinates.join(\n \", \"\n )}]`;\n\n if (false && id === `1A:1B:1C:1D:1E:1F`) {\n console.log(\n `tagTracking - TAG_UPDATE CHANGE coordInfo tags 1A:1B:1C:1D:1E:1F`,\n id,\n coordInfo,\n activeTagType,\n tagUserType\n );\n }\n });\n }\n }\n\n return {\n area: mineLevel.id,\n tags,\n tagIds,\n allowToShowDetails,\n };\n}\n\nexport default withMineLevel(\n connect(mapStateToProps)(CurrentTagTrackingFeatureGroup)\n);\n","// see - src/admin/named-area-group/NamedAreaGroupSettingsModal.js\n\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Form,\n Segment,\n Modal,\n Header,\n Icon,\n Button,\n Grid,\n} from \"semantic-ui-react\";\n\nimport isEqual from \"lodash/isEqual\";\n\nimport { isOnOffPokeTheWorker } from \"components/Settings/reducer\";\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nclass TagTrackingZonesMarkerPopupModal extends Component {\n constructor(props) {\n super(props);\n this.state = { modalOpen: false };\n }\n\n componentDidMount() {\n const { open, isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n\n if (open) {\n this.handleOpen();\n }\n\n if (isPokeTheWorker) {\n TurnOnOffPokeTheWorker(false);\n }\n }\n\n componentWillUnmount() {\n const { isPokeTheWorker, TurnOnOffPokeTheWorker } = this.props;\n if (!isPokeTheWorker) {\n TurnOnOffPokeTheWorker(true);\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { open } = this.props;\n if (!isEqual(this.props, prevProps)) {\n if (open) {\n this.handleOpen();\n }\n }\n }\n\n handleOpen = () => {\n this.setState({ modalOpen: true });\n };\n\n handleCancel = () => {\n // close the modal\n this.setState({ modalOpen: false });\n\n // reset the modal display\n this.props.resetModal();\n\n // reset the form\n //this.setState({ value: \"\" }, () => this.props.reset());\n };\n\n render() {\n const { id, label } = this.props;\n\n return (\n \n \n {`Tag Zone ${label}`}\n \n }\n />\n \n \n
\n \n \n \n ...more information to come. e.g. notes on the zone.\n \n \n \n
\n
\n
\n \n \n \n
\n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const {\n initialValues: { id, label },\n } = props;\n\n return {\n isPokeTheWorker: isOnOffPokeTheWorker(state),\n id,\n label,\n };\n}\n\nexport default connect(mapStateToProps, { TurnOnOffPokeTheWorker })(\n TagTrackingZonesMarkerPopupModal\n);\n","/*\n1Dec21 - stopped using this as the data update would re-drawn a layer with each hash().\n17Mar22 - being used again now....seems to be OK..? review comment and clarify?!\n\nIssue refs:\n- https://github.com/PaulLeCam/react-leaflet/issues/389\n- \n\nSee also:\n- https://github.com/PaulLeCam/react-leaflet/issues/697\n- https://github.com/PaulLeCam/react-leaflet/issues/332\n- https://gist.github.com/Shrugsy/5e898173c965e7642db8927636bedf7a\n\n\nFor markercluster see:\n- https://stackoverflow.com/questions/59306768/marker-clustering-leaflet-markercluster-with-react-leaflet-2-0/59322023\n*/\n\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { renderToString } from \"react-dom/server\";\n\nimport { withMineLevel } from \"ApplicationContexts\";\n\nimport L from \"leaflet\";\nimport { GeoJSON } from \"react-leaflet\";\n\nimport { makeIcon } from \"components/Map/MakeIcon\";\n\nimport {\n getTagTrackingCoordinatesByAreaId,\n getTagIdsByAreaId,\n} from \"components/Tags/reducer\";\n\nimport {\n getNamedAreaInfos,\n getNamedAreaInfosBySubTypeId,\n} from \"components/WebWorker/reducer\";\n\nimport { transformGeoJsonUtmToPixels } from \"components/Map/util-geoJsonToPixels\";\n\nimport hash from \"object-hash\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport TagTrackingZonesMarkerPopupModal from \"admin/tag-tracking/TagTrackingZonesMarkerPopupModal\";\nimport { NamedAreaPolygonPopup } from \"components/Map/NamedAreaPolygonPopup\";\nimport { features } from \"process\";\n\n//\n// #NOTE - 17Mar22 - temporarily disabled the modal dlg for polygon (tag zone) click for tags\n// and instead made it the same as std. map view - i.e. click through to the polygon edit page.\n//\nconst ENABLE_MODAL_DLG_POPUP = false;\n//\n\n// #TODO #REVEW - write a geoJson parse checker\nfunction tryParseJSON(jsonObj) {\n try {\n var o = JSON.parse(JSON.stringify(jsonObj));\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,\n // but... JSON.parse(null) returns null, and typeof null === \"object\",\n // so we must check for that, too. Thankfully, null is falsey, so this suffices:\n if (o && typeof o === \"object\") {\n return true;\n }\n } catch (e) {}\n return false;\n}\n\nclass CurrentTagTrackingZonesFeatureGroup extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n isOpenTagTrackingZonesMarkerPopup: false,\n // modal for details of the marker\n isOpenTagTrackingZonesMarkerPopupModal: {\n active: false,\n id: \"\",\n area: \"\",\n },\n };\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n // if the popup is open stop rendering\n if (nextState?.isOpenTagTrackingZonesMarkerPopup === true) {\n return false;\n }\n return true;\n }\n\n resetModal = () => {\n this.setState({\n isOpenTagTrackingZonesMarkerPopupModal: {\n active: false,\n id: \"\",\n label: \"\",\n area: \"\",\n },\n });\n };\n\n render() {\n const { area, geoJSONNamedAreas } = this.props;\n\n const onEachFeature = (feature, layer) => {\n let popupContent = ``;\n if (feature.properties && feature.properties.id) {\n const parentId = feature.properties.parent;\n const parentName = feature.properties.parent_name;\n if (ENABLE_MODAL_DLG_POPUP) {\n popupContent = ``;\n layer.bindPopup(popupContent);\n } else {\n const { properties } = feature;\n const { id, parent, parent_name, sub_type } = properties;\n const namedAreaPolygonPopup = renderToString(\n \n );\n layer.bindPopup(namedAreaPolygonPopup);\n }\n }\n\n const querySelectorId = ENABLE_MODAL_DLG_POPUP\n ? \".button-edit\"\n : \".popupNamedAreaPolygon\";\n\n layer.on(\"popupclose\", (a) => {\n this.setState({\n isOpenTagTrackingZonesMarkerPopup: false,\n });\n });\n layer.on(\"popupopen\", (a) => {\n this.setState({\n isOpenTagTrackingZonesMarkerPopup: true,\n });\n const popUp = a.target.getPopup();\n popUp\n .getElement()\n\n .querySelector(querySelectorId)\n .addEventListener(\"click\", (e) => {\n // console.log(\n // \"clicked edit on marker: \",\n // e,\n // \"target: \",\n // e.target,\n // \"data-key \",\n // e.target.dataset.key\n // );\n\n if (ENABLE_MODAL_DLG_POPUP) {\n const id = e.target.dataset.key;\n if (!_isEmpty(id)) {\n const newModal = {\n active: true,\n id: `${id.split(\":\")?.[0]}:${id.split(\":\")?.[1]}`, // #NOTE: 0 - area, 1 - parentId,\n label: id.split(\":\")?.[2], // 2 - additional label\n area: area,\n };\n this.setState(\n {\n isOpenTagTrackingZonesMarkerPopupModal: newModal,\n },\n () => console.log(`CLICK ON TAG ZONE ID: `, newModal)\n );\n this.setState({\n isOpenTagTrackingZonesMarkerPopup: false,\n });\n }\n } else {\n const id = e.target.getAttribute(\"dataid\");\n if (!_isEmpty(id)) {\n this.props.goto(`/admin/named-area/${id}`);\n } else {\n this.props.goto(`/admin/named-area/`);\n }\n this.setState({\n isOpenTagTrackingZonesMarkerPopup: false,\n });\n }\n });\n });\n };\n\n // styling for polygons\n const geojsonPolygonStyle = (feature) => {\n const { properties } = feature;\n\n // console.log(\"geoJSONNamedAreasUtm properties\", properties);\n\n const {\n style: { fillColor = \"rgb(0, 0, 0)\", fillOpacity = 0.5 },\n } = properties;\n\n // console.log(\n // \"geoJSONNamedAreasUtm properties\",\n // properties,\n // fillColor,\n // fillOpacity\n // );\n\n return {\n fillColor: fillColor,\n color: fillColor,\n weight: 1,\n opacity: 1,\n fillOpacity: fillOpacity,\n };\n };\n\n const filterTags = (feature, layer) => {\n return feature.properties.area === area;\n };\n\n const valid = true; // !_isEmpty(tags) && tryParseJSON(tags);\n\n const isOpenSettingsModal =\n this.state.isOpenTagTrackingZonesMarkerPopupModal.active === true;\n\n return (\n valid && (\n <>\n {isOpenSettingsModal && (\n this.handleSettingsSave(values)}\n resetModal={() => this.resetModal(false)}\n />\n )}\n {\n // swaps the coordinate references around so when polygons are created the pixel refer are [x,y] , not [y,x]\n // latitude , longitude, altitude\n return new L.LatLng(coords[1], coords[0], coords[2]); // <--------- Normal behavior\n }}\n filter={filterTags}\n />\n \n )\n );\n }\n}\n\nexport function mapStateToProps(state, props) {\n const { mineLevel } = props;\n\n // Named Area polygons\n let geoJSONNamedAreasUtm = getNamedAreaInfosBySubTypeId(state, \"tagzone\");\n\n // **********************************\n // similar to code in src/components/Map/MineLevelMapLeaflet.js\n // #NOTE - make common\n\n let geoJSONNamedAreas;\n\n if (\n typeof geoJSONNamedAreasUtm.features !== \"undefined\" &&\n geoJSONNamedAreasUtm.features.length\n ) {\n // deep clone - to stop geometry being converted on raw *utm data\n geoJSONNamedAreas = JSON.parse(JSON.stringify(geoJSONNamedAreasUtm));\n\n // transform the coordinates\n const mineLevelKey = mineLevel.id;\n let mineLevelObj = {};\n mineLevelObj[mineLevelKey] = { ...mineLevel };\n\n geoJSONNamedAreas = transformGeoJsonUtmToPixels(\n geoJSONNamedAreas,\n mineLevelObj,\n 1,\n false\n );\n } else {\n // add an empty geoJson featurecollection\n geoJSONNamedAreas = {\n type: \"FeatureCollection\",\n features: [],\n };\n }\n\n //console.log(`wwww geoJSONNamedAreas`, geoJSONNamedAreas);\n\n return {\n area: mineLevel.id,\n geoJSONNamedAreas,\n };\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n goto: (path) => dispatch(push(path)),\n});\n\nexport default withMineLevel(\n connect(\n mapStateToProps,\n mapDispatchToProps\n )(CurrentTagTrackingZonesFeatureGroup)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { withRouter, Prompt } from \"react-router\";\n\nimport { push } from \"react-router-redux\";\nimport {\n Button,\n Grid,\n Container,\n Segment,\n Header,\n Tab,\n Icon,\n Popup,\n} from \"semantic-ui-react\";\n\nimport { LayersControl } from \"react-leaflet\";\nimport SearchControl from \"components/leaflet-search-control/react-leaflet-search-control\";\n\nimport { getAreaStatuses } from \"components/WebWorker/reducer\";\nimport { getAllTagTrackingGeoJson } from \"components/Tags/reducer\";\nimport CurrentMineLevelFirefliesFeatureGroup from \"containers/CurrentMineLevelFirefliesFeatureGroupGeoJson\";\nimport CurrentTagTrackingFeatureGroup from \"admin/tag-tracking/CurrentTagTrackingFeatureGroupGeoJson\";\nimport CurrentTagTrackingZonesFeatureGroup from \"admin/tag-tracking/CurrentTagTrackingZonesFeatureGroupGeoJson\";\nimport { MineLevelMapById } from \"components/Map/MineLevelMap\";\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport FlashMessagesList from \"FlashMessages\";\nimport {\n fetchTagTrackingAreaStatuses,\n fetchTags,\n} from \"components/Tags/actions\";\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\nimport _isEqual from \"lodash/isEqual\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { strings } from \"components/App/localisation\";\n\n// #WIP - testing add search\nimport { getTagTrackingCoordinatesByAreaId } from \"components/Tags/reducer\";\n\nconst tagTypeDisplaySettings = [\n { type: \"unknown\", icon: \"fas fa-question fa-lg\", label: \"Unknown\" },\n { type: \"personnel\", icon: \"fas fa-hard-hat fa-lg\", label: \"Personnel\" },\n {\n type: \"vehicle\",\n icon: \"fas fa-truck-pickup fa-lg\",\n\n label: \"Vehicle\",\n },\n];\n\nfunction MapPositioningDisplay({\n mineLevelId,\n mapViewState,\n displayOptions,\n children,\n}) {\n if (!mineLevelId) {\n return
No mine level selected
;\n }\n\n return (\n \n {children}\n \n );\n}\n\nclass TagTrackingMap extends Component {\n constructor(props) {\n super(props);\n this.state = {\n activeTagType: [],\n activeIndex: 0,\n currentArea: \"\",\n // map view state\n mapViewState: {\n id: undefined,\n center: undefined,\n zoom: undefined,\n options: undefined,\n },\n //savedMapViewState: { id: \"\", options: [] },\n displayOptions: [\"showPanZoomButton\"],\n };\n }\n\n expandCollapse = (e) => {\n e.preventDefault();\n\n this.setState((prevState) => ({\n collapse: !prevState.collapse,\n }));\n };\n\n componentDidMount() {\n const {\n fetchTagTrackingAreaStatuses,\n areas,\n areaStatuses,\n fetchTags,\n displayTagTypes,\n savedMapViewStates,\n } = this.props;\n\n // set the default/startup area (tabs start from 1st area defined)\n // #WIP #TODO - this will need to change when the area order is changed\n //\n\n const currentMapTab = this.props.componentstate.get(\"tagTrackingMapTab\", 1);\n //console.log(\"currentMapTab componentDidMount\", currentMapTab);\n if (Number.isInteger(currentMapTab)) {\n this.setState({ activeIndex: currentMapTab });\n }\n\n //console.log(\"xxx tagTrackingMap \", currentMapTab);\n\n const newCurrentArea = areas?.[0];\n this.setState({ currentArea: newCurrentArea });\n this.setState({ activeTagType: displayTagTypes });\n\n fetchTagTrackingAreaStatuses(areaStatuses);\n fetchTags();\n\n // get system saved mapViewStates\n // load data for the currentArea displayed\n const savedMapViewStateForArea = savedMapViewStates.find(\n (mapState) => mapState.id === newCurrentArea\n );\n\n if (!_isEmpty(savedMapViewStateForArea)) {\n this.setState({ mapViewState: savedMapViewStateForArea });\n let newDisplayOptions = savedMapViewStateForArea?.options || [];\n // restore default display of showPanZoomButton\n // #WIP - move 'showPanZoomButton' to a config option!\n newDisplayOptions = [...newDisplayOptions, \"showPanZoomButton\"];\n if (savedMapViewStateForArea?.center && savedMapViewStateForArea?.zoom) {\n newDisplayOptions.push(\"showRestoreMapViewStateButton\");\n }\n this.setState({\n displayOptions: newDisplayOptions,\n });\n }\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n const checkState = _isEqual(nextState, this.state);\n\n // check if savedMapViewState has changed for the currentArea\n const nextsavedMapViewStateCurrentArea = nextProps.savedMapViewStates.find(\n (mapState) => mapState.id === this.state.currentArea\n );\n\n const checkSavedMapViewState = _isEqual(\n this.state.mapViewState, // i.e. savedMapViewState,\n nextsavedMapViewStateCurrentArea\n );\n\n return !checkState || !checkSavedMapViewState;\n }\n\n componentDidUpdate(prevProps, prevState) {\n // check if savedMapViewState has changed for the currentArea\n let newSavedMapViewStateCurrentArea = this.props.savedMapViewStates.find(\n (mapState) => mapState.id === this.state.currentArea\n );\n\n // if there is no mapViewState set and currentArea is defined\n // then setup an empty map view state for the area (i.e. only the 'id')\n if (newSavedMapViewStateCurrentArea === undefined && this.state.currentArea)\n newSavedMapViewStateCurrentArea = {\n id: this.state.currentArea,\n };\n\n // check if the map view state for the current area has changed\n if (\n JSON.stringify(this.state.mapViewState) !== // savedMapViewState\n JSON.stringify(newSavedMapViewStateCurrentArea)\n ) {\n // #WIP _ FIX THIS >>>>>>>>>>>> SHOULD NOT BE BOTH\n //this.setState({ savedMapViewState: newSavedMapViewStateCurrentArea });\n this.setState({ mapViewState: newSavedMapViewStateCurrentArea });\n\n let newDisplayOptions = newSavedMapViewStateCurrentArea?.options || [];\n // restore default display of showPanZoomButton\n // #WIP - move 'showPanZoomButton' to a config option!\n newDisplayOptions = [...newDisplayOptions, \"showPanZoomButton\"];\n if (\n newSavedMapViewStateCurrentArea?.center &&\n newSavedMapViewStateCurrentArea?.zoom\n ) {\n if (!newDisplayOptions.includes(\"showRestoreMapViewStateButton\")) {\n newDisplayOptions.push(\"showRestoreMapViewStateButton\");\n }\n }\n this.setState({\n displayOptions: newDisplayOptions,\n });\n }\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"tagTrackingMapTab\",\n key: 1,\n data: this.state.activeIndex,\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n }\n\n handleOnClick = (evt, data) => {\n const { tagType } = data;\n\n let newActiveTagType = [...this.state.activeTagType];\n\n if (newActiveTagType.includes(tagType)) {\n newActiveTagType = newActiveTagType.filter((tags) => tags !== tagType);\n } else {\n newActiveTagType.push(tagType);\n }\n this.setState({ activeTagType: newActiveTagType });\n };\n\n // #NOTE - removed the layer control for b/c a new layer was redrawing\n // with each geoJson update.\n //\n\n handleTabChange = (e, data) => {\n const { activeIndex, panes } = data;\n const currentArea = panes?.[activeIndex]?.area;\n this.setState({ currentArea: currentArea });\n this.setState({ activeIndex });\n };\n\n render() {\n const { displayTagTypes, areas } = this.props;\n const {\n currentArea,\n activeTagType,\n mapViewState = {},\n activeIndex,\n } = this.state;\n\n // load search control data\n const { tagsAreas } = this.props;\n\n // setup items for the searchControl\n let items = [];\n const tags = tagsAreas?.find((area) => area.id === currentArea);\n if (!_isEmpty(tags)) {\n tags.features.forEach((feature) => {\n const item = { feature };\n items.push(item);\n });\n }\n\n let isSearchControl = false;\n if (this.state.displayOptions.includes(\"showSearchControl\"))\n isSearchControl = true;\n\n // #NOTE - VERY IMPORTANT - changes to mapKey will triggger a map re-render.\n // options are removed to stop them re-rendering the map\n //\n let { options, ...mapKeyObject } = mapViewState;\n let mapKey = `${JSON.stringify(mapKeyObject)}`;\n if (isSearchControl) mapKey = `mapKey-showSearchControl`;\n\n const panes = areas.map((area, index) => ({\n menuItem: area?.replaceAll(\"_\", \" \"),\n area: area,\n render: () => (\n \n \n {isSearchControl && (\n \n )}\n \n \n \n \n {/*\n \n \n \n */}\n\n \n \n \n \n \n \n \n ),\n }));\n\n return (\n
\n \n \n \n \n
{strings?.[\"Tag Map\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n \n
\n {strings?.[\"Tag Map\"]} - {currentArea?.replace(\"_\", \" \")}\n
\n
\n
\n \n \n \n {displayTagTypes.map((tag, idx) => {\n const tagSetting = tagTypeDisplaySettings.find(\n (setting) => setting.type === tag\n );\n const active = activeTagType.includes(tagSetting?.type);\n const iconStyle = active\n ? { color: \"#2185d0\" }\n : { opacity: \"0.2\" };\n const popupMsg = active\n ? `Click to hide the ${tagSetting?.label} tags`\n : `Click to show the ${tagSetting?.label} tags`;\n return (\n \n this.handleOnClick(evt, data)\n }\n >\n \n \n }\n />\n );\n })}\n \n \n \n \n \n \n \n \n
\n
\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const areaStatuses = getAllAreaStatuses(state);\n const areas = areaStatuses.map((area) => area.id) || [];\n const allTagTrackingGeoJson = getAllTagTrackingGeoJson(state);\n\n //console.log(\"allTagTrackingGeoJson\", allTagTrackingGeoJson);\n\n const displayTagTypes = [\"personnel\", \"vehicle\", \"unknown\"]; // getDisplayTagTypes(state) - #WIP - proposed to get tag types from state/api request\n\n // track changes to the savedMapViewState\n let savedMapViewStates = [];\n let tagsAreas = [];\n areas.forEach((area) => {\n const mapViewState = props.componentstate.get(\"tagMapViewState\", area);\n if (mapViewState) savedMapViewStates.push(mapViewState);\n let tagsArea = getTagTrackingCoordinatesByAreaId(state, area) || {\n features: [],\n };\n tagsArea.id = area;\n tagsAreas.push(tagsArea);\n });\n\n return {\n areaStatuses,\n areas,\n allTagTrackingGeoJson,\n displayTagTypes,\n //\n tagsAreas,\n //\n savedMapViewStates,\n };\n};\n\nTagTrackingMap = withComponentStateCache(\n connect(mapStateToProps, { fetchTagTrackingAreaStatuses, fetchTags })(\n TagTrackingMap\n )\n);\n\nexport default TagTrackingMap;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport {\n Form,\n Container,\n Button,\n Icon,\n Segment,\n Header,\n Message,\n Grid,\n Checkbox,\n} from \"semantic-ui-react\";\n\nimport { Slider } from \"react-semantic-ui-range\";\nimport \"semantic-ui-css/semantic.min.css\";\n\nimport {\n Field,\n reduxForm,\n formValueSelector,\n SubmissionError,\n} from \"redux-form\";\n\nimport {\n renderInput,\n renderSelect,\n renderField,\n renderRadio,\n renderCheckbox,\n} from \"admin/form-field\";\n\nimport { SaveButton } from \"admin/SaveButton\";\nimport { DeleteButton } from \"admin/DeleteButton\";\n\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\n\nimport { getUserData, isUserSuper, isUserAdmin } from \"auth/reducer\";\nimport { getUserById, getAllUsers } from \"components/UserAdmin/reducer\";\nimport {\n deleteUser,\n changeRole,\n changePassword,\n changeName,\n changeLanguage,\n changeSettings,\n fetchAllUsers,\n} from \"components/UserAdmin/actions\";\n\nimport _isEmpty from \"lodash/isEmpty\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\nimport hash from \"object-hash\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport {\n allowedLanguages as _allowedLanguages,\n allowedRoles as _allowedRoles,\n allowedApplications as _allowedApplications,\n allowedFeatures as _allowedFeatures,\n} from \"components/ConfigJs\";\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst email = (value) =>\n value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i.test(value)\n ? \"Invalid email address\"\n : undefined;\n\nconst uniqueEmail = (value, allValues, props, name) =>\n props.allUserEmails.includes(value)\n ? \"This email has already been used\"\n : undefined;\n\nconst validate = (values) => {\n const required = [\"username\", \"email\", \"role\", \"language\"];\n\n const errors = {};\n\n required.forEach((r) => {\n if (!get(values, r)) {\n set(errors, r, \"Required\");\n }\n });\n\n if (get(values, \"password\") !== get(values, \"passwordConfirm\")) {\n set(errors, \"passwordConfirm\", \"Does not match\");\n }\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nclass UserEditForm extends Component {\n constructor(props) {\n super(props);\n this.state = {\n columnWidth: 6,\n hidden: true,\n submitted: false,\n //language: \"en-US\", // localisation\n };\n }\n\n componentDidMount() {\n const { initialize, initialValues } = this.props;\n initialize(initialValues);\n }\n\n componentDidUpdate(prevProps, prevState) {\n //\n }\n\n submitMyForm = (values) => {\n const { email: id, username, role, language, password, settings } = values;\n\n const {\n changeRole,\n changePassword,\n changeName,\n changeLanguage,\n changeSettings,\n initialValues,\n isSuper,\n } = this.props;\n\n //console.log(\"xxx userEditForm submitMyForm values\", values);\n\n // update user\n let changes = [];\n\n if (username !== initialValues.username) {\n changes.push({\n id: id,\n type: \"changeName\",\n username: username,\n });\n }\n\n if (role !== initialValues.role) {\n changes.push({\n id: id,\n type: \"changeRole\",\n role: role,\n });\n }\n\n if (language !== initialValues.language) {\n changes.push({\n id: id,\n type: \"changeLanguage\",\n language: language,\n });\n }\n\n if (password !== initialValues.password) {\n changes.push({\n id: id,\n type: \"changePassword\",\n password: password,\n });\n }\n\n if (JSON.stringify(settings) !== JSON.stringify(initialValues.settings)) {\n changes.push({\n id: id,\n type: \"changeSettings\",\n settings: settings,\n });\n }\n\n let promiseArray = [];\n\n changes.forEach((change) => {\n //console.log(\"change ... \", change);\n const { id, type, username, role, password, language, settings } = change;\n\n switch (type) {\n case \"changeRole\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n changeRole({\n values: { id, role },\n resolve,\n reject,\n });\n })\n );\n break;\n case \"changePassword\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n changePassword({\n values: { id, password },\n resolve,\n reject,\n });\n })\n );\n\n break;\n case \"changeName\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n changeName({\n values: { id, username },\n resolve,\n reject,\n });\n })\n );\n\n break;\n case \"changeLanguage\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n changeLanguage({\n values: { id, language },\n resolve,\n reject,\n });\n })\n );\n\n break;\n case \"changeSettings\":\n promiseArray.push(\n new Promise((resolve, reject) => {\n changeSettings({\n values: { id, settings },\n resolve,\n reject,\n });\n })\n );\n break;\n default:\n break;\n }\n });\n\n return Promise.all(promiseArray).then((results) => {\n //console.log(`onSubmitSuccess ${results}`);\n // wait for state change before redirecting page\n this.setState(\n {\n submitted: true,\n },\n () => {\n this.props.fetchAllUsers();\n if (isSuper) {\n this.props.goto(\"/user/admin\");\n } else {\n this.props.goto(`/user/profile/${id}`);\n }\n }\n );\n });\n // .catch((error) => {\n // console.log(`onSubmit ${error}`);\n // this.onSetError(\"failed\");\n // // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n // throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n // });\n\n //console.log(\"changes list\", changes);\n // return new Promise((resolve, reject) => {\n // update api\n // changeRole({ id, role })\n // changePassword({ id, password })\n // changeName({ id, name })\n // changeLanguage({ id, language })\n // changeSettings({ id, settings })\n\n // changes.forEach((change) => {\n // //console.log(\"change ... \", change);\n // const {\n // id,\n // type,\n // username,\n // role,\n // password,\n // language,\n // settings,\n // } = change;\n\n // switch (type) {\n // case \"changeRole\":\n // changeRole({\n // values: { id, role },\n // resolve,\n // reject,\n // });\n // break;\n // case \"changePassword\":\n // changePassword({\n // values: { id, password },\n // resolve,\n // reject,\n // });\n // break;\n // case \"changeName\":\n // changeName({\n // values: { id, username },\n // resolve,\n // reject,\n // });\n // break;\n // case \"changeLanguage\":\n // changeLanguage({\n // values: { id, language },\n // resolve,\n // reject,\n // });\n // break;\n // case \"changeSettings\":\n // changeSettings({\n // values: { id, settings },\n // resolve,\n // reject,\n // });\n // break;\n // default:\n // break;\n // }\n // });\n // // update positions\n\n // return resolve(\n // (function () {\n // console.log(\"saved users edit page\");\n // return null;\n // })()\n // );\n // //------------\n // }).then(\n // () => {\n // if (isSuper) {\n // this.props.goto(\"/user/admin\");\n // } else {\n // this.props.goto(`/user/profile/${id}`);\n // }\n // },\n // (msg) => {\n // console.log(\"action failed\", msg); // TODO probs should show this?\n // }\n // );\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n\n const { isSuper } = this.props;\n if (isSuper) {\n this.props.goto(\"/user/admin\");\n } else {\n this.props.goto(``); // go home\n }\n };\n\n changePassword = (e) => {\n e.preventDefault();\n //\n };\n\n toggleShow = (state) => {\n this.setState({ hidden: !this.state.hidden });\n };\n\n requestDelete = (id) => {\n const { deleteUser, goto } = this.props;\n\n return new Promise((resolve, reject) => {\n deleteUser({ values: { id }, resolve, reject });\n }).then(\n () => {\n console.log(\"successful User delete\");\n this.props.fetchAllUsers();\n goto(\"/user/admin\");\n },\n (msg) => {\n console.log(\"delete user failed\", msg); // TODO probs should show this?\n }\n );\n };\n\n onChangeApplication = (e, data) => {\n const { stateValueApplication, change } = this.props;\n const { optionkey } = data;\n\n let newApplication = [...stateValueApplication];\n\n // toggle - remove if exists\n if (newApplication.includes(optionkey)) {\n newApplication = newApplication.filter((app) => app !== optionkey);\n } else {\n newApplication.push(optionkey);\n }\n\n change(\"settings.application\", newApplication);\n };\n\n applicationRadiosContent = (\n options,\n stateValueApplication,\n isAdmin,\n isSuper\n ) => {\n let content = [];\n\n if (options.length === 0) {\n content.push(\n \n \n {this.props.strings?.[\"No applications enabled\"]}\n \n );\n }\n\n options.map((option, idx) => {\n content.push(\n \n \n \n \n );\n });\n\n return (\n \n
\n \n \n
\n {this.props.strings?.[\"Applications\"]}\n
\n
\n
\n {content}\n
\n
\n );\n };\n\n onChangeFeature = (e, data) => {\n const { stateValueFeature, change } = this.props;\n const { optionkey } = data;\n\n let newFeature = [...stateValueFeature];\n\n // toggle - remove if exists\n if (newFeature.includes(optionkey)) {\n newFeature = newFeature.filter((app) => app !== optionkey);\n } else {\n newFeature.push(optionkey);\n }\n\n change(\"settings.feature\", newFeature);\n };\n\n featureRadiosContent = (options, stateValueFeature, isAdmin, isSuper) => {\n let content = [];\n\n if (options.length === 0) {\n content.push(\n \n \n {this.props.strings?.[\"No features enabled\"]}\n \n );\n }\n\n options.map((option, idx) => {\n content.push(\n \n \n \n \n );\n });\n\n return (\n \n
\n \n \n
\n {this.props.strings?.[\"Features\"]}\n
\n
\n
\n {content}\n
\n
\n );\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n reset,\n error,\n allUserEmails,\n isSuper,\n isAdmin,\n isThisUser,\n initialValues,\n dataError, // Not to be confused with the form `error`\n strings, // localisation\n emailId,\n columnWidth,\n stateValueApplication,\n stateValueFeature,\n } = this.props;\n\n // APP_TERMINOLOGY\n\n if (dataError) {\n this.props.goto(\"\"); // redirect to home page\n // #NOTE #TODO - should pop a dlg if this happens\n return null;\n // return (\n // <>\n // \n // \n // \n // );\n }\n\n const settings = {\n start: columnWidth,\n min: 0,\n max: 16,\n step: 2,\n onChange: (value) => {\n //console.log(\"value\", value);\n this.props.change(\"settings.display.columnWidth\", value);\n },\n };\n\n const allowedLanguages = _allowedLanguages();\n const allowedRoles = _allowedRoles();\n const allowedApplications = _allowedApplications();\n const allowedFeatures = _allowedFeatures();\n\n return (\n <>\n this.submitMyForm(formValues)}\n />\n \n {error && }\n \n \n \n \n \n
{strings?.[\"User Details\"]}
\n \n \n option.value !== \"super\"\n )\n }\n validate={[required]}\n //className={!isSuper ? \"disabled-form-field\" : null}\n disabled={!isAdmin && !isSuper}\n />\n \n
\n \n
{strings?.[\"Change Password\"]}
\n \n }\n />\n \n }\n //validate={[required]}\n />\n
\n
\n \n \n \n \n \n {!isThisUser && ( // #NOTE - user can not delete themselves\n this.requestDelete(emailId)}\n strings={strings}\n />\n )}\n \n \n \n \n \n {/* this.changePassword(e)}\n color=\"purple\"\n >\n Change Password\n \n */}\n \n \n \n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n \n
{strings?.[\"Settings\"]}
\n {!pristine && !submitting && (\n \n \n \n {strings?.[\"USER_PROFILE_SETTING_MESSAGE\"]}\n \n \n )}\n \n
{strings?.[\"Display\"]}
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n \n \n \n \n \n
{strings?.[\"Options\"]}
\n {this.applicationRadiosContent(\n allowedApplications,\n stateValueApplication,\n isAdmin,\n isSuper\n )}\n {this.featureRadiosContent(\n allowedFeatures,\n stateValueFeature,\n isAdmin,\n isSuper\n )}\n
\n \n \n \n \n \n
\n \n );\n }\n}\n\nconst selector = formValueSelector(\"userEditForm\");\n\nUserEditForm = reduxForm({\n form: \"userEditForm\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: false,\n touchOnChange: true,\n validate,\n})(UserEditForm);\n\nconst mapDispatchToProps = (dispatch, props) => ({\n goto: (path) => dispatch(push(path)),\n deleteUser: (id) => dispatch(deleteUser(id)),\n changeRole: (data) => dispatch(changeRole(data)),\n changeName: (data) => dispatch(changeName(data)),\n changePassword: (data) => dispatch(changePassword(data)),\n changeLanguage: (data) => dispatch(changeLanguage(data)),\n changeSettings: (data) => dispatch(changeSettings(data)),\n fetchAllUsers: (data) => dispatch(fetchAllUsers(data)),\n});\n\nconst mapStateToProps = (state, props) => {\n const { id } = props;\n\n //console.log(\"xxxx id\", id);\n\n const allUsers = getAllUsers(state);\n\n // need all user emails to prevent duplicate accounts\n const allUserEmails = allUsers.map((user) => user.email);\n\n const userData = getUserById(state, id); // from fetch users\n\n const thisUser = getUserData(state); // from auth login\n const { email: thisUserId } = thisUser;\n\n // we could be maintaining another user's account,\n // so check if it is this user.\n const isThisUser =\n thisUserId !== undefined || \"\" ? thisUserId === userData?.email : false;\n\n // if it is this user apply the language change, but not for another user's account.\n const thisUserLang = isThisUser ? userData.language : thisUser.language;\n\n const dataError =\n !_isEmpty(userData) && !_isEmpty(thisUser)\n ? undefined\n : \"Error loading the page\";\n\n // console.log(\"xxxx isThisUser\", isThisUser);\n // console.log(\"xxxx UserEditForm thisUserLang\", thisUserLang);\n // console.log(\"xxxx getUser\", getUser);\n // console.log(\"xxxx thisUser\", thisUser);\n // console.log(\"xxxx dataError \", dataError);\n // console.log(\"xxxx userData \", userData);\n // console.log(\"xxxx localisedTerms\", localisedTerms);\n\n return {\n emailId: userData?.email,\n columnWidth: selector(state, \"settings.display.columnWidth\"),\n dataError: dataError,\n isSuper: isUserSuper(state), // `super` can change user status\n isAdmin: isUserAdmin(state),\n isThisUser,\n thisUserLang,\n allUserEmails: allUserEmails,\n initialValues: userData,\n stateValueApplication: selector(state, \"settings.application\") || [],\n stateValueFeature: selector(state, \"settings.feature\") || [],\n //\n //localisedTerms: getLocalisationByComponentId(state, \"UserEditForm\"), // localisation\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"onChange values\", values);\n },\n };\n};\n\nUserEditForm = connect(mapStateToProps, mapDispatchToProps)(UserEditForm);\n\nexport default UserEditForm;\n","import React, { Component } from \"react\";\nimport { push } from \"react-router-redux\";\n\nimport { Container, Header, Grid, Message } from \"semantic-ui-react\";\n\nimport { connect } from \"react-redux\";\n\nimport UserEditForm from \"components/User/UserEditForm\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport { SubmissionError } from \"redux-form\";\n\nimport { saveUser } from \"components/UserAdmin/actions\";\n\nimport { getLocalisationByComponentId } from \"components/Localisation/reducer\";\n\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\n// localisation\nimport { getUserData } from \"auth/reducer\";\nimport { getUserById } from \"components/UserAdmin/reducer\";\n// import LocalizedStrings from \"react-localization\";\n\n// let strings = new LocalizedStrings({\n// \"en-US\": {\n// \"User Profile\": \"User Profile\",\n// },\n// });\n\nclass UserEditPage extends Component {\n constructor(props) {\n super(props);\n this.state = {\n //language: \"en-US\", // localisation\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n\n // const { localisedTerms } = this.props;\n // if (!_isEmpty(localisedTerms)) {\n // strings.setContent(this.props.localisedTerms);\n // this.setState({ language: this.props.thisUserLang });\n // strings.setLanguage(this.props.thisUserLang);\n // console.log(\n // \"xxx UserEditPage - language set to \",\n // this.props.thisUserLang\n // );\n // }\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n componentDidUpdate(prevProps, prevState) {\n // if (\n // // this.props.localisedTerms !== prevProps.localisedTerms ||\n // this.props.thisUserLang !== prevProps.thisUserLang\n // ) {\n // //strings.setContent(this.props.localisedTerms);\n // this.setState({ language: this.props.thisUserLang });\n // //strings.setLanguage(this.state.language);\n // strings.setLanguage(this.props.thisUserLang);\n // console.log(\n // \"xxx UserEditPage - language changed to \",\n // this.props.thisUserLang\n // );\n // }\n }\n\n // https://stackoverflow.com/questions/40741743/how-to-implement-localization-in-reactjs\n // handleLanguageChange = (e) => {\n // e.preventDefault();\n // let lang = e.target.value;\n // this.setState((prevState) => ({\n // language: lang,\n // }));\n // };\n\n render() {\n const { id, dataError, strings } = this.props;\n\n if (dataError) {\n this.props.goto(\"\"); // redirect to home page\n // #NOTE #TODO - should pop a dlg if this happens\n return null;\n //{strings[\" return (\n // <>\n // \n // \n // \n // );\n }\n\n // console.log(\"xxx UserEditPage - strings\", strings);\n\n return (\n
\n \n \n \n \n
{strings?.[\"User Profile\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n {\n // return new Promise((resolve, reject) => {\n // console.log(\"UserEditPage values\", values);\n\n // // set email as `id`\n // const { email: id } = values;\n // const newValues = { id, ...values };\n\n // this.props.saveUser({ values: newValues, resolve, reject });\n // }).catch((error) => {\n // console.log(`onSubmit ${error}`);\n // //this.onSetError(\"failed\");\n // // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n // throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n // });\n // }}\n // onSubmitSuccess={(result, dispatch) => {\n // console.log(`onSubmitSuccess ${result}`);\n // this.props.goto(\"/user/profile/admin\");\n // }}\n // onSubmitFail={(errors) => {\n // console.log(`onSubmitFail ${errors}`);\n // }}\n // onCancel={() => {\n // this.props.goto(\"/user/profile/admin\");\n // }}\n />\n \n
\n
\n );\n }\n}\n\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n saveUser: (data) => dispatch(saveUser(data)),\n goto: (path) => dispatch(push(path)),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n };\n};\n\nfunction mapStateToProps(state, props) {\n const match = props.match;\n const id = match.params.id;\n\n // get language from most recent fetch to avoid need to log out/in\n const thisUser = getUserData(state);\n const { email: thisUserId } = thisUser;\n const thisUserLang = getUserById(state, thisUserId)?.language || \"en-US\";\n\n //console.log(\"xxxx UserEditPage thisUserLang\", thisUserLang);\n\n //const localisedTerms = getLocalisationByComponentId(state, \"UserEditPage\");\n\n // console.log(`xxxx UserPages props`, props);\n //console.log(\"xxxx thisUser\", thisUser);\n\n const dataError = id ? undefined : \"No User with this email (id)\";\n\n return {\n thisUserLang,\n //localisedTerms,\n id,\n dataError,\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UserEditPage);\n","// import React from \"react\";\n\n// const User = () =>
Nothing here yet...coming soon...user profile
;\n\n// export default User;\n\nimport React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\nimport { withRouter } from \"react-router\";\n\nimport UserEditPage from \"components/User/UserEditPage\";\n\nclass UserPages extends Component {\n render() {\n const { match, strings } = this.props;\n\n //console.log(`UserPages`, match);\n //console.log(\"xxx UserPages - strings \", strings);\n return (\n \n }\n />\n }\n />\n \n );\n }\n}\n\nexport default withRouter(UserPages);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport { Link } from \"react-router-dom\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Message,\n Icon,\n Checkbox,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DeleteButton } from \"admin/DeleteButton\";\nimport GenericButton from \"admin/GenericButton\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { getAllUsers } from \"components/UserAdmin/reducer\";\nimport { fetchAllUsers, deleteUser } from \"components/UserAdmin/actions\";\n\nimport { getEmail, getUserRole } from \"auth/reducer\";\n\nimport {\n allowedLanguages as _allowedLanguages,\n allowedRoles as _allowedRoles,\n} from \"components/ConfigJs\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ListUsers extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n userName: \"\",\n userEmail: \"\",\n userApplication: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n };\n }\n\n componentDidMount() {\n this.props.fetchAllUsers();\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n // #NOTE - can't select thisUser\n if (this.props.thisUser !== item.id) {\n newSelections[item.id] = true;\n }\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n isThisUser = (id) => this.props.thisUser === id;\n\n requestAction = (action) => {\n const { selections } = this.state;\n const { allUsers, thisUser } = this.props;\n // console.log(\"requestAction selections\", selections);\n // console.log(\"requestAction action \", action);\n // console.log(\"requestAction allUsers\", allUsers);\n\n const allUsersExceptThisUser = allUsers.filter(\n (user) => user.email !== thisUser.email\n );\n const { deleteUser, goto } = this.props;\n let users = [];\n for (var key in selections) {\n const selection = key;\n allUsersExceptThisUser.forEach((user, idx) => {\n const { email } = user;\n if (email === selection) {\n users.push(email);\n }\n });\n }\n\n let promiseArray = [];\n\n users.forEach((user) => {\n promiseArray.push(\n new Promise((resolve, reject) => {\n deleteUser({ values: { id: user }, resolve, reject });\n })\n );\n });\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\"DELETE USER: \", results);\n })\n .then(\n () => {\n goto(\"/user/admin\");\n },\n (errorMsg) => {\n console.log(\"delete failed\", errorMsg); // #TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, strings } = this.props;\n const { column, data, direction } = this.state;\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n\n // if enough items display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const usersFromDataById = (id) => allData.find((item) => item.id === id);\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let addButton;\n let deleteButton;\n let usersSelectedList;\n\n addButton = (\n \n \n \n {deleteButton}\n \n \n \n {viewablesPage.length} items displayed. {selectedCount} selected\n \n \n {usersSelectedList}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strings?.[\"Email\"]}\n \n \n {strings?.[\"Name\"]}\n \n \n {strings?.[\"Role\"]}\n \n \n {strings?.[\"Language\"]}\n \n \n {strings?.[\"Application\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({\n id,\n userEmailLink,\n userEmail,\n userName,\n userRole,\n userLang,\n userApplication,\n }) => (\n \n \n this.handleSelect(id)}\n disabled={this.isThisUser(id)}\n />\n \n {userEmailLink}\n {userName} \n {userRole}\n {userLang}\n {userApplication}\n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements, thisUserRole, allowedRoles, strings) => {\n let newElements = JSON.parse(JSON.stringify(elements));\n\n // super users are to be hidden\n if (thisUserRole !== \"super\")\n newElements = elements.filter((user) => user.role !== \"super\");\n\n let filteredElements = [];\n newElements.forEach(function (user, idx) {\n const { username, email, role, language, settings } = user;\n\n const { application } = settings;\n\n // localise the application list\n let newApplication = [];\n application.forEach((app) => {\n newApplication.push(strings?.[app]);\n });\n\n filteredElements[idx] = {\n id: email,\n userEmail: email,\n userEmailLink: {email} ,\n userName: username,\n userRole: allowedRoles.find((option) => option.key === role)?.text,\n userLang: language,\n userApplication: newApplication?.join(\", \"),\n };\n });\n\n return filteredElements;\n};\n\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n deleteUser: (data) => dispatch(deleteUser(data)),\n goto: (path) => dispatch(push(path)),\n fetchAllUsers: () => dispatch(fetchAllUsers()),\n };\n};\n\nconst mapStateToProps = (state, props) => {\n // #REVEW - no longer applicable? We do not track loading state ... for the moment forced values\n const isLoading = false;\n const error = false;\n\n const allUsers = getAllUsers(state);\n\n const thisUser = getEmail(state) || \"?\";\n const thisUserRole = getUserRole(state) || \"\";\n\n const allowedRoles = _allowedRoles();\n const data = _prepData(allUsers, thisUserRole, allowedRoles, props.strings);\n\n return {\n isLoading,\n error,\n data,\n allUsers,\n thisUser,\n thisUserRole,\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(ListUsers);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { push } from \"react-router-redux\";\nimport {\n Form,\n Container,\n Button,\n Icon,\n Segment,\n Header,\n Message,\n Grid,\n Checkbox,\n} from \"semantic-ui-react\";\n\nimport { Slider } from \"react-semantic-ui-range\";\nimport \"semantic-ui-css/semantic.min.css\";\n\nimport { formatRelative, parseISO, isPast } from \"date-fns\";\n\nimport { Field, reduxForm, formValueSelector } from \"redux-form\";\n\nimport {\n renderInput,\n renderSelect,\n renderField,\n renderRadio,\n renderCheckbox,\n} from \"admin/form-field\";\n\nimport { SaveButton } from \"admin/SaveButton\";\n\nimport { getFormValues } from \"redux-form\"; // #REVIEW - only used for debugging\n\nimport { isUserSuper, isUserAdmin } from \"auth/reducer\";\nimport { getAllUsers } from \"components/UserAdmin/reducer\";\nimport { fetchAllUsers } from \"components/UserAdmin/actions\";\n\nimport isEqual from \"lodash/isEqual\";\nimport get from \"lodash/get\";\nimport set from \"lodash/set\";\nimport hash from \"object-hash\";\n\nimport {\n allowedLanguages as _allowedLanguages,\n allowedRoles as _allowedRoles,\n allowedApplications as _allowedApplications,\n allowedFeatures as _allowedFeatures,\n} from \"components/ConfigJs\";\n\nimport { DEFAULT_SETTINGS } from \"utils/DEFAULTS\";\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst email = (value) =>\n value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i.test(value)\n ? \"Invalid email address\"\n : undefined;\n\nconst uniqueEmail = (value, allValues, props, name) =>\n props.allUserEmails.includes(value)\n ? \"This email has already been used\"\n : undefined;\n\nconst validate = (values) => {\n const required = [\n \"username\",\n \"email\",\n \"role\",\n \"language\",\n \"password\",\n \"passwordConfirm\",\n ];\n\n const errors = {};\n\n required.forEach((r) => {\n if (!get(values, r)) {\n set(errors, r, \"Required\");\n }\n });\n\n if (get(values, \"password\") !== get(values, \"passwordConfirm\")) {\n set(errors, \"passwordConfirm\", \"Does not match\");\n }\n\n //console.log(\"@@ validate errors\", errors);\n\n return errors;\n};\n\nclass UserCreateForm extends Component {\n constructor(props) {\n super(props);\n this.state = {\n columnWidth: 6,\n hidden: true,\n };\n }\n\n submitMyForm = (values) => {\n this.props.onSubmit(values);\n };\n\n cancelForm = (e) => {\n e.preventDefault();\n this.props.goto(\"/user/admin\");\n };\n\n toggleShow = (state) => {\n this.setState({ hidden: !this.state.hidden });\n };\n\n onChangeApplication = (e, data) => {\n const { stateValueApplication, change } = this.props;\n const { optionKey } = data;\n\n let newApplication = [...stateValueApplication];\n\n // toggle - remove if exists\n if (newApplication.includes(optionKey)) {\n newApplication = newApplication.filter((app) => app !== optionKey);\n } else {\n newApplication.push(optionKey);\n }\n\n change(\"settings.application\", newApplication);\n };\n\n applicationRadiosContent = (\n options,\n stateValueApplication,\n isAdmin,\n isSuper\n ) => {\n let content = [];\n\n if (options.length === 0) {\n content.push(\n \n \n {this.props.strings?.[\"No applications enabled\"]}\n \n );\n }\n\n options.map((option) => {\n content.push(\n \n \n \n \n );\n });\n\n return (\n \n
\n \n \n
\n {this.props.strings?.[\"Applications\"]}\n
\n
\n
\n {content}\n
\n
\n );\n };\n\n onChangeFeature = (e, data) => {\n const { stateValueFeature, change } = this.props;\n const { optionKey } = data;\n\n let newFeature = [...stateValueFeature];\n\n // toggle - remove if exists\n if (newFeature.includes(optionKey)) {\n newFeature = newFeature.filter((app) => app !== optionKey);\n } else {\n newFeature.push(optionKey);\n }\n\n change(\"settings.feature\", newFeature);\n };\n\n featureRadiosContent = (options, stateValueFeature, isAdmin, isSuper) => {\n let content = [];\n\n if (options.length === 0) {\n content.push(\n \n \n {this.props.strings?.[\"No features enabled\"]}\n \n );\n }\n\n options.map((option) => {\n content.push(\n \n \n \n \n );\n });\n\n return (\n \n
\n \n \n
\n {this.props.strings?.[\"Features\"]}\n
\n
\n
\n {content}\n
\n
\n );\n };\n\n render() {\n const {\n handleSubmit,\n pristine,\n submitting,\n reset,\n error,\n //reduxFormValues,\n allUserEmails,\n isSuper,\n isAdmin,\n initialValues,\n strings,\n stateValueApplication,\n stateValueFeature,\n } = this.props;\n\n // APP_TERMINOLOGY\n\n const {\n settings: {\n display: { columnWidth },\n },\n } = initialValues;\n\n const settings = {\n start: columnWidth,\n min: 0,\n max: 16,\n step: 2,\n onChange: (value) => {\n //console.log(\"value\", value);\n this.props.change(\"settings.columnWidth\", value);\n\n this.setState({\n columnWidth: value,\n });\n },\n };\n\n const allowedLanguages = _allowedLanguages();\n const allowedRoles = _allowedRoles();\n const allowedApplications = _allowedApplications();\n const allowedFeatures = _allowedFeatures();\n\n return (\n \n {error && }\n
\n \n \n \n \n
{strings?.[\"User Details\"]}
\n \n \n option.value !== \"super\"\n )\n }\n validate={[required]}\n //className={!isSuper ? \"disabled-form-field\" : null}\n disabled={!isAdmin && !isSuper}\n />\n \n
\n \n \n }\n />\n \n }\n />\n \n
\n \n \n \n \n \n \n \n \n \n \n {strings?.[\"Reset\"]}\n \n \n this.cancelForm(e)}\n >\n {strings?.[\"Cancel\"]}\n \n \n \n \n \n \n \n
{strings?.[\"Settings\"]}
\n \n
{strings?.[\"Display\"]}
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n
\n \n \n
{strings?.[\"Options\"]}
\n {this.applicationRadiosContent(\n allowedApplications,\n stateValueApplication,\n isAdmin,\n isSuper\n )}\n {this.featureRadiosContent(\n allowedFeatures,\n stateValueFeature,\n isAdmin,\n isSuper\n )}\n
\n \n \n \n \n
\n
\n );\n }\n}\n\nconst selector = formValueSelector(\"userCreateForm\");\n\nUserCreateForm = reduxForm({\n form: \"userCreateForm\",\n enableReinitialize: true,\n keepDirtyOnReinitialize: true,\n touchOnChange: true,\n validate,\n})(UserCreateForm);\n\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n goto: (path) => dispatch(push(path)),\n fetchAllUsers: () => dispatch(fetchAllUsers()),\n };\n};\n\nconst mapStateToProps = (state, props) => {\n const allUsers = getAllUsers(state);\n const allUserEmails = allUsers.map((user) => user.email);\n\n //console.log(\"allUsers\", allUsers);\n\n const newSettings = { ...DEFAULT_SETTINGS };\n\n return {\n isSuper: isUserSuper(state), // `super` can change user status\n isAdmin: isUserAdmin(state),\n allUserEmails: allUserEmails,\n initialValues: {\n settings: newSettings,\n },\n columnWidth: selector(state, \"settings.display.columnWidth\"),\n stateValueApplication: selector(state, \"settings.application\") || [],\n stateValueFeature: selector(state, \"settings.feature\") || [],\n onChange: (values, dispatch, props, previousValues) => {\n //console.log(\"onChange values\", values);\n },\n reduxFormValues: getFormValues(\"userCreateForm\")(state), // #REVIEW - only used for debugging,\n };\n};\n\nUserCreateForm = connect(mapStateToProps, mapDispatchToProps)(UserCreateForm);\n\nexport default UserCreateForm;\n","import React, { Component } from \"react\";\nimport { push } from \"react-router-redux\";\n\nimport { Container, Header, Grid, Message } from \"semantic-ui-react\";\n\nimport { connect } from \"react-redux\";\n\nimport UserCreateForm from \"components/UserAdmin/UserCreateForm\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport DataLoadingMessage from \"components/DataLoading/dataLoading\";\n\nimport { SubmissionError } from \"redux-form\";\n\nimport {\n saveUser,\n fetchAllUsers,\n deleteUser,\n} from \"components/UserAdmin/actions\";\n\nimport NavigationPromptModal from \"admin/NavigationPromptModal\";\n\nimport { TurnOnOffPokeTheWorker } from \"components/Settings/actions\";\n\nclass UserCreatePage extends Component {\n constructor(props) {\n super(props);\n this.state = {\n submitted: false,\n };\n }\n\n componentDidMount() {\n // turn off data collection\n this.props.TurnOnOffPokeTheWorker(false);\n }\n\n componentWillUnmount() {\n // turn on data collection\n this.props.TurnOnOffPokeTheWorker(true);\n }\n\n submitMyForm = (values) => {\n return new Promise((resolve, reject) => {\n //console.log(\"xxx UserCreate values\", values);\n\n // set email as `id`\n const { email: id } = values;\n const newValues = { id, ...values };\n this.props.saveUser({ values: newValues, resolve, reject });\n })\n .then(() => {\n this.props.fetchAllUsers();\n //this.onResetError();\n this.props.goto(\"/user/admin\");\n })\n .catch((error) => {\n console.log(`onSubmit error`, error);\n // see https://redux-form.com/6.1.1/docs/api/submissionerror.md/\n throw new SubmissionError(error.validationErrors); // required to catch as form submission error and prevent execute of onSubmitSuccess\n });\n };\n\n render() {\n const { id, error, strings } = this.props;\n\n if (error) {\n return (\n // placeholder\n null\n );\n }\n\n return (\n
\n this.submitMyForm(formValues)}\n />\n \n \n \n \n
{strings?.[\"Create New User\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n this.submitMyForm(values)}\n // #NOTE - disabled as this is fired as soon as submit,\n // *not* after successful completion of the Promise!!\n // onSubmitSuccess={(result, dispatch) => {\n // //console.log(`onSubmitSuccess ${result}`);\n // // wait for state change before redirecting page\n // this.setState(\n // {\n // submitted: true,\n // },\n // () => {\n // //this.onResetError();\n // this.props.goto(\"/user/admin\");\n // }\n // );\n // }}\n onSubmitFail={(errors) => {\n console.log(`onSubmitFail ${JSON.stringify(errors)}`);\n }}\n onCancel={() => {\n this.props.goto(\"/user/admin\");\n }}\n />\n \n
\n
\n );\n }\n}\n\nconst mapDispatchToProps = (dispatch, props) => {\n return {\n saveUser: (data) => dispatch(saveUser(data)),\n goto: (path) => dispatch(push(path)),\n fetchAllUsers: () => dispatch(fetchAllUsers()),\n TurnOnOffPokeTheWorker: (action) =>\n dispatch(TurnOnOffPokeTheWorker(action)),\n };\n};\n\nfunction mapStateToProps(state, props) {\n // placeholder\n return {};\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UserCreatePage);\n","// import React from \"react\";\n\n// const UserAdmin = () =>
Nothing here yet...coming soon...super admin
;\n\n// export default UserAdmin;\n\nimport React, { Component } from \"react\";\nimport { Switch, Route } from \"react-router-dom\";\nimport { withRouter } from \"react-router\";\n\nimport UserAdminList from \"components/UserAdmin/UserAdminList\";\n\nimport UserEditPage from \"components/User/UserEditPage\";\nimport UserCreatePage from \"components/UserAdmin/UserCreatePage\";\n\nclass UserAdminPages extends Component {\n render() {\n const { match, strings } = this.props;\n\n //console.log(`UserPages`, this.props);\n\n return (\n \n }\n />\n }\n />\n }\n />\n \n );\n }\n}\n\nexport default withRouter(UserAdminPages);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Container,\n Header,\n Grid,\n List,\n Segment,\n Message,\n Icon,\n} from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\n\nconst iconForFileType = (file) => {\n const fileArray = file.split(\".\");\n\n // assume last entry is file extension\n switch (fileArray[fileArray.length - 1].toLowerCase()) {\n case \"pdf\":\n return \"file pdf outline\";\n case \"jpg\":\n case \"png\":\n return \"file image outline\";\n case \"mp4\":\n return \"file video outline\";\n case \"zip\":\n case \"gz\":\n return \"file archive outline\";\n\n default:\n return \"file outline\";\n }\n};\n\nclass HelpFilesList extends Component {\n render() {\n const { folderFilesList, strings } = this.props;\n\n const noFilesMessage = strings?.[\"No Files\"];\n const filesMessage = (\n \n {folderFilesList?.map((file) => {\n return (\n \n {file}\n \n }\n />\n );\n })}\n \n );\n\n return (\n
\n \n \n \n \n
{strings?.[\"Help Files\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n {strings?.[\"Help Files\"]}\n {strings?.[\"Help Files Message\"]}\n \n \n \n {folderFilesList?.length ? filesMessage : noFilesMessage}\n \n
\n
\n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n return {\n folderFilesList: getFolderFileNamesListById(state, \"documents\"),\n };\n}\n\nexport default connect(mapStateToProps)(HelpFilesList);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n Container,\n Header,\n Grid,\n List,\n Segment,\n Message,\n Icon,\n} from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\n\nclass HelpFilesListAreas extends Component {\n render() {\n const { folderFilesList } = this.props;\n return (\n
\n \n \n \n \n
Help Files
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n Help files\n This area contains an assortment of help files and tips which have\n been prepared to assist you with Lighting Control, Controllers and\n the Firefly lighting control system in general. Click to open the\n files in a separate window.\n \n \n \n \n {folderFilesList?.map((file) => {\n return (\n \n \n {file}\n \n \n );\n })}\n \n \n
\n
\n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n return {\n folderFilesList: getFolderFileNamesListById(state, \"areas\"),\n };\n}\n\nexport default connect(mapStateToProps, null)(HelpFilesListAreas);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Container, Header, Grid, List, Segment } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\n\nclass ToolsMqtt extends Component {\n render() {\n return (\n
\n \n \n \n \n
MQTT Tools
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n Send Delete MQTT to ...\n Send Null MQTT to ...\n Clear MQTT broker database\n \n \n
\n
\n );\n }\n}\n\n//export default connect(null)(ToolsMqtt);\nexport default ToolsMqtt;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Container, Header, Grid, List, Segment } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\n\nclass ToolsDatabase extends Component {\n render() {\n // const controllers = [\n // {\n // id: \"74:e1:82:8c:ec:13\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS28\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737851.353281354 9548960.50196291)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"74:e1:82:91:60:c5\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS 14\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737552.989255152 9548627.62692841)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"0c:ae:7d:24:2f:75\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS 02\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737374.115666202 9548860.55998173)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"74:e1:82:91:03:b9\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS 06\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737166.079852615 9548969.57274285)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"04:a3:16:fd:75:60\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS 01\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737306.416302142 9548900.69111753)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:32:db\",\n // area: \"DMLZ_Extraction\",\n // name: \"ups21\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737150.922473644 9548953.78035979)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:60:2c\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS27\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737858.05801772 9548961.22397027)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"7c:66:9d:54:03:af\",\n // area: \"DMLZ_Extraction\",\n // name: \"dffc-36\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737319.945387662 9549553.78895927)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:60:08\",\n // area: \"DMLZ_Extraction\",\n // name: \"dffc-31\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737663.304252667 9549216.3928454)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"40:bd:32:e5:93:43\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS 15\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737660.669322774 9548624.52916733)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"7c:66:9d:4d:d6:5d\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS22\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737068.487366615 9549043.51966745)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"7c:66:9d:46:03:ca\",\n // area: \"DMLZ_Extraction\",\n // name: \"dffc-35\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737317.318450921 9549546.17550865)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"0c:ae:7d:24:d6:49\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS 13\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737473.441889625 9548718.83866327)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"74:e1:82:8c:e4:60\",\n // area: \"DMLZ_Extraction\",\n // name: \"dffc-23\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(736996.372842553 9549092.98420171)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:6a:a3\",\n // area: \"DMLZ_Extraction\",\n // name: \"dffc-34\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737422.839158499 9549483.07701795)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"1c:ba:8c:e3:21:a3\",\n // area: \"DMLZ_Extraction\",\n // name: \"DFFC-10\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737455.060924783 9548714.00609566)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:55:46\",\n // area: \"DMLZ_Extraction\",\n // name: \"DFFC-33\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737518.751235129 9549363.56519596)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"74:e1:82:8c:db:6f\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS32\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737567.712564145 9549289.74664204)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:2d:56\",\n // area: \"DMLZ_Extraction\",\n // name: \"UPS29\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737779.532027233 9549120.35130749)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:4f:a9\",\n // area: \"DMLZ_Extraction\",\n // name: \"dffc-24\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(736916.271537226 9549135.9592174)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:67:10\",\n // area: \"DMLZ_Extraction\",\n // name: \"ups30\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737658.644212408 9549203.68890362)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"74:e1:82:8c:c3:cc\",\n // area: \"DMLZ_Undercut\",\n // name: \"dffc-43\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737718.737209277 9549168.60167435)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"74:e1:82:8d:4b:86\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 12\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737278.208100737 9548925.32870088)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"0c:ae:7d:24:3e:1b\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 05\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737535.638830251 9548655.26907502)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"0c:ae:7d:24:4b:e3\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 17\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737380.273801567 9548851.66554107)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"0c:ae:7d:24:8c:c6\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 16\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737158.299041944 9548982.98449685)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"0c:ae:7d:24:8c:fc\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 07\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737538.323437115 9548656.5196655)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"0c:ae:7d:24:ef:d8\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 19\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737493.606319526 9548701.62078885)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"40:bd:32:e5:29:b3\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 11\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737379.825135911 9548879.04083912)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"40:bd:32:e6:3e:31\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 20\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737209.458973068 9548960.43161182)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"74:e1:82:8d:c8:3c\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 18\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737114.734055996 9549027.3425085)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:32:ab\",\n // area: \"DMLZ_Undercut\",\n // name: \"dffc-45\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737305.423321085 9549568.90914207)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c4:f3:12:81:67:2b\",\n // area: \"DMLZ_Undercut\",\n // name: \"ups37\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737212.453232057 9548957.7602412)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"f0:45:da:83:01:44\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 08\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737436.471721763 9548782.56314349)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"c8:df:84:d3:83:b2\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS 09\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737244.684285398 9548936.36730892)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"04:a3:16:fd:75:63\",\n // area: \"DMLZ_Undercut\",\n // name: \"UPS04\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737642.263054562 9548643.51803093)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"d0:ff:50:39:a3:10\",\n // area: \"DMLZ_Undercut\",\n // name: \"DFFC-44\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737406.481816212 9549499.84300068)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // {\n // id: \"7c:66:9d:48:cd:de\",\n // area: \"DMLZ_Undercut\",\n // name: \"dffc-3\",\n // location: \"Panel1,Panel2,Panel3,Panel4\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // utm: \"POINT(737533.877957206 9549362.61236947)\",\n // z: null,\n // ip: null,\n // master: true,\n // mode: \"operation\",\n // timestamp: null,\n // battery: false,\n // network: false,\n // sw_ver: \"UPS\",\n // type: \"UPS\",\n // emergency_source_active: null,\n // trigger_source: null,\n // emergency_config: null,\n // trigger_config: null,\n // },\n // ];\n\n // const fireflies = [\n // {\n // id: \"DMLZ_Extraction:DD19E:5\",\n // mac: \"24:0a:c4:51:1e:a4\",\n // area: \"DMLZ_Extraction\",\n // location: \"DD19E\",\n // position: 5,\n // utm: \"POINT(737382.232827574 9549314.74257347)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:DD22W:11\",\n // mac: \"b4:e6:2d:ad:9c:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"DD22W\",\n // position: 11,\n // utm: \"POINT(737225.529520075 9548897.34609137)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:DD22W:13\",\n // mac: \"b4:e6:2d:98:a7:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"DD22W\",\n // position: 13,\n // utm: \"POINT(737359.161195923 9549286.23095178)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:DD24E:17\",\n // mac: \"c4:4f:33:23:7d:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"DD24E\",\n // position: 17,\n // utm: \"POINT(737628.380567744 9549192.96209264)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:DD27E:16\",\n // mac: \"c4:4f:33:23:af:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"DD27E\",\n // position: 16,\n // utm: \"POINT(737394.936850181 9549137.05909116)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:1\",\n // mac: \"c4:4f:33:23:ce:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 1,\n // utm: \"POINT(737844.999568699 9548951.97288121)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:11\",\n // mac: \"c4:4f:33:23:60:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 11,\n // utm: \"POINT(737870.17449439 9548868.2813015)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:13\",\n // mac: \"24:0a:c4:50:d0:38\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 13,\n // utm: \"POINT(737863.875439816 9548852.15549792)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:15\",\n // mac: \"c4:4f:33:23:7c:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 15,\n // utm: \"POINT(737853.560396106 9548838.14442457)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:17\",\n // mac: \"24:0a:c4:50:c8:50\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 17,\n // utm: \"POINT(737843.172301757 9548825.05811535)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:19\",\n // mac: \"24:0a:c4:50:d0:00\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 19,\n // utm: \"POINT(737832.037306253 9548810.95706101)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:2\",\n // mac: \"b4:e6:2d:ad:0b:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 2,\n // utm: \"POINT(737868.81148203 9548859.85216343)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:21\",\n // mac: \"24:0a:c4:50:d3:0c\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 21,\n // utm: \"POINT(737820.231940555 9548796.93097222)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:3\",\n // mac: \"c4:4f:33:23:57:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 3,\n // utm: \"POINT(737850.84006177 9548935.64392156)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:4\",\n // mac: \"b4:e6:2d:98:a8:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 4,\n // utm: \"POINT(737848.105724652 9548831.70329245)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:5\",\n // mac: \"c4:4f:33:23:68:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 5,\n // utm: \"POINT(737856.454084961 9548918.16862837)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:6\",\n // mac: \"b4:e6:2d:98:f5:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 6,\n // utm: \"POINT(737826.357600941 9548803.72110944)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:7\",\n // mac: \"c4:4f:33:23:69:35\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 7,\n // utm: \"POINT(737861.619665877 9548900.10298882)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:EFD:9\",\n // mac: \"4c:11:ae:b7:f5:74\",\n // area: \"DMLZ_Extraction\",\n // location: \"EFD\",\n // position: 9,\n // utm: \"POINT(737866.635686744 9548881.90260662)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:1\",\n // mac: \"24:0a:c4:50:fc:50\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 1,\n // utm: \"POINT(737657.150899806 9549199.11195248)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:11\",\n // mac: \"c4:4f:33:23:66:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 11,\n // utm: \"POINT(737732.069335217 9549141.75352502)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:13\",\n // mac: \"c4:4f:33:1d:91:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 13,\n // utm: \"POINT(737747.352284061 9549130.48948462)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:15\",\n // mac: \"c4:4f:33:23:60:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 15,\n // utm: \"POINT(737762.635229686 9549119.22543956)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:2\",\n // mac: \"24:0a:c4:50:d3:78\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 2,\n // utm: \"POINT(737663.296025765 9549192.4416491)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:3\",\n // mac: \"4c:11:ae:b7:fc:10\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 3,\n // utm: \"POINT(737670.937507885 9549186.80963998)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:4\",\n // mac: \"4c:11:ae:b7:fc:d0\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 4,\n // utm: \"POINT(737678.57898909 9549181.17762969)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:5\",\n // mac: \"c4:4f:33:23:d3:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 5,\n // utm: \"POINT(737686.22046949 9549175.54561823)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:7\",\n // mac: \"24:0a:c4:50:d0:2c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 7,\n // utm: \"POINT(737701.503427988 9549164.28159183)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_E:9\",\n // mac: \"24:0a:c4:50:cf:2c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_E\",\n // position: 9,\n // utm: \"POINT(737716.786383268 9549153.01756075)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:1\",\n // mac: \"24:0a:c4:50:c7:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 1,\n // utm: \"POINT(737320.054717278 9549538.69790715)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:10\",\n // mac: \"c4:4f:33:23:dc:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 10,\n // utm: \"POINT(737381.671900721 9549492.14493391)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:11\",\n // mac: \"c4:4f:33:1e:14:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 11,\n // utm: \"POINT(737387.842414684 9549486.87501743)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:12\",\n // mac: \"c4:4f:33:23:dc:e1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 12,\n // utm: \"POINT(737395.346427649 9549480.8629537)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:13\",\n // mac: \"c4:4f:33:1e:c0:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 13,\n // utm: \"POINT(737401.439936462 9549476.18601661)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:14\",\n // mac: \"c4:4f:33:23:68:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 14,\n // utm: \"POINT(737408.799499759 9549470.839644)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:15\",\n // mac: \"c4:4f:33:23:9b:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 15,\n // utm: \"POINT(737417.421707123 9549463.71403991)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:16\",\n // mac: \"c4:4f:33:23:55:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 16,\n // utm: \"POINT(737424.705329795 9549458.07194082)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:17\",\n // mac: \"4c:11:ae:b7:fd:10\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 17,\n // utm: \"POINT(737431.544551795 9549453.17093751)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:18\",\n // mac: \"24:0a:c4:51:0e:5c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 18,\n // utm: \"POINT(737437.637356952 9549447.97587932)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:19\",\n // mac: \"4c:11:ae:b7:fc:d4\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 19,\n // utm: \"POINT(737444.624234503 9549442.7785448)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:2\",\n // mac: \"4c:11:ae:b7:fb:84\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 2,\n // utm: \"POINT(737326.673750655 9549534.97903498)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:20\",\n // mac: \"24:0a:c4:51:09:00\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 20,\n // utm: \"POINT(737452.952235226 9549437.13367231)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:21\",\n // mac: \"24:0a:c4:50:f9:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 21,\n // utm: \"POINT(737461.872913039 9549430.45125054)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:22\",\n // mac: \"c4:4f:33:23:ab:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 22,\n // utm: \"POINT(737467.375633201 9549425.55254214)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:23\",\n // mac: \"c4:4f:33:23:8c:fd\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 23,\n // utm: \"POINT(737474.652416835 9549419.17161814)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:24\",\n // mac: \"c4:4f:33:23:dc:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 24,\n // utm: \"POINT(737482.828787022 9549412.63930574)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:25\",\n // mac: \"c4:4f:33:23:69:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 25,\n // utm: \"POINT(737489.9663382 9549407.73731337)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:26\",\n // mac: \"4c:11:ae:b7:fb:f4\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 26,\n // utm: \"POINT(737497.399371582 9549401.79865636)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:27\",\n // mac: \"c4:4f:33:1e:bf:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 27,\n // utm: \"POINT(737504.248938873 9549397.06501462)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:28\",\n // mac: \"4c:11:ae:b7:f8:40\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 28,\n // utm: \"POINT(737509.311225636 9549394.97737186)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:29\",\n // mac: \"c4:4f:33:1c:ed:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 29,\n // utm: \"POINT(737511.068194064 9549387.26328247)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:3\",\n // mac: \"4c:11:ae:b7:fb:d0\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 3,\n // utm: \"POINT(737333.5100663 9549529.48659178)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:30\",\n // mac: \"4c:11:ae:b7:fc:cc\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 30,\n // utm: \"POINT(737513.278376217 9549378.08211361)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:4\",\n // mac: \"c4:4f:33:23:ae:65\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 4,\n // utm: \"POINT(737341.019362627 9549524.21346586)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:5\",\n // mac: \"4c:11:ae:b7:fd:2c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 5,\n // utm: \"POINT(737346.142402811 9549518.87343689)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:6\",\n // mac: \"c4:4f:33:23:dc:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 6,\n // utm: \"POINT(737353.427924888 9549513.74929198)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:7\",\n // mac: \"24:0a:c4:50:db:94\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 7,\n // utm: \"POINT(737360.191225727 9549508.47840588)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:8\",\n // mac: \"c4:4f:33:23:9a:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 8,\n // utm: \"POINT(737367.177389371 9549502.91106183)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_EAST:9\",\n // mac: \"c4:4f:33:23:d3:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_EAST\",\n // position: 9,\n // utm: \"POINT(737374.535208552 9549497.1206579)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:1\",\n // mac: \"c4:4f:33:23:ad:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 1,\n // utm: \"POINT(737360.868952218 9549510.25098583)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:10\",\n // mac: \"b4:e6:2d:ac:82:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 10,\n // utm: \"POINT(737430.809048253 9549511.31947177)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:12\",\n // mac: \"24:0a:c4:50:ce:50\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 12,\n // utm: \"POINT(737446.863363448 9549498.69689723)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:16\",\n // mac: \"b4:e6:2d:ab:ca:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 16,\n // utm: \"POINT(737474.496339825 9549470.81013823)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:17\",\n // mac: \"b4:e6:2d:ad:09:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 17,\n // utm: \"POINT(737478.043925339 9549460.44320787)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:19\",\n // mac: \"24:0a:c4:50:ca:d0\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 19,\n // utm: \"POINT(737472.038816588 9549442.85263243)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:2\",\n // mac: \"24:0a:c4:50:da:c4\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 2,\n // utm: \"POINT(737373.19328568 9549523.4626586)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:20\",\n // mac: \"c4:4f:33:23:b0:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 20,\n // utm: \"POINT(737467.925134458 9549436.35290356)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:3\",\n // mac: \"24:0a:c4:50:d0:4c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 3,\n // utm: \"POINT(737387.515438522 9549531.71043705)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:4\",\n // mac: \"4c:11:ae:b7:f4:5c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 4,\n // utm: \"POINT(737406.271460183 9549526.77582525)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:5\",\n // mac: \"24:0a:c4:50:e0:64\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 5,\n // utm: \"POINT(737422.630771369 9549516.81706694)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:6\",\n // mac: \"b4:e6:2d:98:f2:fd\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 6,\n // utm: \"POINT(737397.640794112 9549530.20252635)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:7\",\n // mac: \"4c:11:ae:b7:fa:ac\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 7,\n // utm: \"POINT(737454.889672379 9549492.02103263)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_to_NVD_Ramp:8\",\n // mac: \"b4:e6:2d:99:14:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_to_NVD_Ramp\",\n // position: 8,\n // utm: \"POINT(737414.749624655 9549522.01767397)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:1\",\n // mac: \"b4:e6:2d:ac:63:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 1,\n // utm: \"POINT(737649.704047371 9549201.26575396)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:10\",\n // mac: \"24:0a:c4:51:09:48\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 10,\n // utm: \"POINT(737588.174304884 9549254.0311215)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:11\",\n // mac: \"24:0a:c4:50:e9:38\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 11,\n // utm: \"POINT(737581.484851297 9549259.2282139)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:12\",\n // mac: \"c4:4f:33:23:cd:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 12,\n // utm: \"POINT(737574.948685504 9549266.05172717)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:13\",\n // mac: \"c4:4f:33:23:9a:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 13,\n // utm: \"POINT(737567.738088018 9549271.32370929)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:14\",\n // mac: \"c4:4f:33:1e:58:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 14,\n // utm: \"POINT(737560.082524306 9549277.33738107)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:15\",\n // mac: \"24:0a:c4:50:e6:dc\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 15,\n // utm: \"POINT(737553.020288725 9549282.3870766)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:16\",\n // mac: \"c4:4f:33:23:8d:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 16,\n // utm: \"POINT(737545.884334244 9549287.73298812)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:17\",\n // mac: \"c4:4f:33:1e:b0:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 17,\n // utm: \"POINT(737539.419515912 9549293.37264012)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:18\",\n // mac: \"c4:4f:33:23:ab:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 18,\n // utm: \"POINT(737533.696125871 9549297.7530228)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:19\",\n // mac: \"c4:4f:33:1e:a6:e1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 19,\n // utm: \"POINT(737527.52527442 9549301.9125771)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:2\",\n // mac: \"b4:e6:2d:ac:16:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 2,\n // utm: \"POINT(737641.82310669 9549206.53964868)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:20\",\n // mac: \"c4:4f:33:1c:e7:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 20,\n // utm: \"POINT(737525.083128351 9549307.83823446)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:21\",\n // mac: \"c4:4f:33:23:5f:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 21,\n // utm: \"POINT(737523.242917253 9549316.05508734)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:22\",\n // mac: \"c4:4f:33:23:b0:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 22,\n // utm: \"POINT(737521.625176739 9549323.90178048)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:23\",\n // mac: \"4c:11:ae:b7:f5:78\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 23,\n // utm: \"POINT(737520.155598878 9549331.45197677)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:24\",\n // mac: \"24:0a:c4:50:d0:84\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 24,\n // utm: \"POINT(737518.164277118 9549338.85571386)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:25\",\n // mac: \"c4:4f:33:23:ae:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 25,\n // utm: \"POINT(737516.767429664 9549345.73991956)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:26\",\n // mac: \"c4:4f:33:23:cd:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 26,\n // utm: \"POINT(737514.850699869 9549353.05235367)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:3\",\n // mac: \"4c:11:ae:b7:f2:f8\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 3,\n // utm: \"POINT(737634.985098481 9549211.88427933)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:4\",\n // mac: \"c4:4f:33:23:67:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 4,\n // utm: \"POINT(737629.03926447 9549216.63528639)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:5\",\n // mac: \"24:0a:c4:50:d2:40\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 5,\n // utm: \"POINT(737621.157791224 9549221.68645897)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:6\",\n // mac: \"c4:4f:33:23:67:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 6,\n // utm: \"POINT(737614.169228825 9549226.44027587)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:7\",\n // mac: \"c4:4f:33:23:7c:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 7,\n // utm: \"POINT(737607.782421987 9549233.41169597)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:8\",\n // mac: \"4c:11:ae:b7:f7:78\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 8,\n // utm: \"POINT(737601.693521095 9549240.38224144)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_W:9\",\n // mac: \"c4:4f:33:23:b0:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_W\",\n // position: 9,\n // utm: \"POINT(737594.709298622 9549246.76370342)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:1\",\n // mac: \"c4:4f:33:23:ce:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 1,\n // utm: \"POINT(737312.465103107 9549541.52180387)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:10\",\n // mac: \"b4:e6:2d:ac:47:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 10,\n // utm: \"POINT(737246.703570659 9549571.59211217)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:11\",\n // mac: \"c4:4f:33:23:ac:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 11,\n // utm: \"POINT(737238.075967969 9549576.20251598)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:12\",\n // mac: \"b4:e6:2d:ac:19:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 12,\n // utm: \"POINT(737229.741577328 9549579.03688528)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:14\",\n // mac: \"24:0a:c4:50:c9:14\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 14,\n // utm: \"POINT(737212.186088038 9549587.37070968)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:2\",\n // mac: \"c4:4f:33:23:5f:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 2,\n // utm: \"POINT(737304.132814951 9549544.95529524)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:3\",\n // mac: \"c4:4f:33:23:57:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 3,\n // utm: \"POINT(737297.436405249 9549547.78209335)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:4\",\n // mac: \"c4:4f:33:23:54:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 4,\n // utm: \"POINT(737291.188703262 9549551.05393343)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:5\",\n // mac: \"c4:4f:33:1e:39:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 5,\n // utm: \"POINT(737284.493303665 9549554.03131169)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:6\",\n // mac: \"c4:4f:33:23:d3:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 6,\n // utm: \"POINT(737277.054291429 9549557.45448462)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:7\",\n // mac: \"c4:4f:33:23:6a:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 7,\n // utm: \"POINT(737269.913591492 9549561.02475234)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:8\",\n // mac: \"24:0a:c4:50:e7:68\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 8,\n // utm: \"POINT(737262.47500063 9549564.59564275)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD_ACC_WEST:9\",\n // mac: \"c4:4f:33:23:69:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD_ACC_WEST\",\n // position: 9,\n // utm: \"POINT(737254.887016147 9549568.0192081)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:1\",\n // mac: \"b4:e6:2d:98:f0:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 1,\n // utm: \"POINT(737864.723234197 9548890.93222555)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:10\",\n // mac: \"24:0a:c4:50:cf:ac\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 10,\n // utm: \"POINT(737816.106847818 9549038.13134143)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:11\",\n // mac: \"b4:e6:2d:ac:c4:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 11,\n // utm: \"POINT(737808.945873 9549062.19531828)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:12\",\n // mac: \"c4:4f:33:23:60:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 12,\n // utm: \"POINT(737811.382429112 9549054.05055308)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:13\",\n // mac: \"b4:e6:2d:ad:8e:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 13,\n // utm: \"POINT(737795.405621808 9549095.82025311)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:14\",\n // mac: \"c4:4f:33:23:61:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 14,\n // utm: \"POINT(737805.618828661 9549071.3042493)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:15\",\n // mac: \"b4:e6:2d:98:a4:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 15,\n // utm: \"POINT(737770.276701235 9549113.59341529)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:16\",\n // mac: \"c4:4f:33:23:7c:fd\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 16,\n // utm: \"POINT(737800.152160778 9549088.18723554)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:17\",\n // mac: \"b4:e6:2d:ac:5a:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 17,\n // utm: \"POINT(737739.710810098 9549136.1215054)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:18\",\n // mac: \"24:0a:c4:50:d4:1c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 18,\n // utm: \"POINT(737787.377399246 9549101.68636889)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:19\",\n // mac: \"b4:e6:2d:98:a5:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 19,\n // utm: \"POINT(737709.144905977 9549158.64957687)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:2\",\n // mac: \"24:0a:c4:51:05:3c\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 2,\n // utm: \"POINT(737838.197092111 9548970.67281677)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:20\",\n // mac: \"b4:e6:2d:ad:9a:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 20,\n // utm: \"POINT(737693.861949195 9549169.91360561)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:08\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:3\",\n // mac: \"b4:e6:2d:aa:fa:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 3,\n // utm: \"POINT(737853.497730533 9548926.75867563)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:4\",\n // mac: \"c4:4f:33:1c:f6:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 4,\n // utm: \"POINT(737832.949752843 9548986.00153769)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:5\",\n // mac: \"b4:e6:2d:99:11:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 5,\n // utm: \"POINT(737841.966047991 9548959.56513782)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:6\",\n // mac: \"c4:4f:33:23:ce:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 6,\n // utm: \"POINT(737826.743813186 9549004.95804416)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:7\",\n // mac: \"b4:e6:2d:ac:56:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 7,\n // utm: \"POINT(737830.291892228 9548994.81274739)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:8\",\n // mac: \"c4:4f:33:23:cd:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 8,\n // utm: \"POINT(737821.130167026 9549022.58125846)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NFD:9\",\n // mac: \"b4:e6:2d:ab:f7:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"NFD\",\n // position: 9,\n // utm: \"POINT(737819.212576692 9549029.68886028)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NU_35_4:1\",\n // mac: \"c4:4f:33:23:b2:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NU_35_4\",\n // position: 1,\n // utm: \"POINT(737267.963047779 9549555.70176734)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NU_35_4:2\",\n // mac: \"c4:4f:33:1d:2d:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"NU_35_4\",\n // position: 2,\n // utm: \"POINT(737256.553854224 9549541.18334245)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NU_35_4:3\",\n // mac: \"c4:4f:33:23:d0:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"NU_35_4\",\n // position: 3,\n // utm: \"POINT(737245.144663994 9549526.664918)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NU_35_4:4\",\n // mac: \"c4:4f:33:23:60:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"NU_35_4\",\n // position: 4,\n // utm: \"POINT(737233.735476871 9549512.146494)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NU_35_4:5\",\n // mac: \"c4:4f:33:23:63:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"NU_35_4\",\n // position: 5,\n // utm: \"POINT(737222.326293074 9549497.62807044)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NU_35_4:6\",\n // mac: \"24:0a:c4:50:d0:cc\",\n // area: \"DMLZ_Extraction\",\n // location: \"NU_35_4\",\n // position: 6,\n // utm: \"POINT(737210.917112489 9549483.10964733)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:NU_35_4:7\",\n // mac: \"c4:4f:33:23:5e:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"NU_35_4\",\n // position: 7,\n // utm: \"POINT(737199.507935012 9549468.59122466)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:1\",\n // mac: \"4c:11:ae:b7:fc:8c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 1,\n // utm: \"POINT(737662.335710436 9548629.63031513)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:11\",\n // mac: \"c4:4f:33:23:67:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 11,\n // utm: \"POINT(737579.051644087 9548623.85843066)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:13\",\n // mac: \"24:0a:c4:50:c8:34\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 13,\n // utm: \"POINT(737560.29308216 9548627.75573703)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:2\",\n // mac: \"24:0a:c4:50:ce:8c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 2,\n // utm: \"POINT(737655.259375637 9548629.35261564)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:3\",\n // mac: \"24:0a:c4:51:0e:60\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 3,\n // utm: \"POINT(737647.735971716 9548629.00260963)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:4\",\n // mac: \"c4:4f:33:23:63:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 4,\n // utm: \"POINT(737639.093585962 9548627.98949523)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:5\",\n // mac: \"c4:4f:33:23:af:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 5,\n // utm: \"POINT(737631.198351778 9548627.86285256)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:7\",\n // mac: \"c4:4f:33:23:7c:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 7,\n // utm: \"POINT(737615.99901221 9548625.83172568)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P_NU:9\",\n // mac: \"4c:11:ae:b7:f5:18\",\n // area: \"DMLZ_Extraction\",\n // location: \"P_NU\",\n // position: 9,\n // utm: \"POINT(737596.034149211 9548624.2570434)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:1\",\n // mac: \"b4:e6:2d:99:05:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 1,\n // utm: \"POINT(737476.950648547 9548712.61468361)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:10\",\n // mac: \"b4:e6:2d:99:10:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 10,\n // utm: \"POINT(737588.148542129 9548851.70514315)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:11\",\n // mac: \"b4:e6:2d:98:fd:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 11,\n // utm: \"POINT(737602.797001788 9548870.16224922)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:12\",\n // mac: \"b4:e6:2d:98:f7:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 12,\n // utm: \"POINT(737614.605466873 9548885.51957248)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:13\",\n // mac: \"b4:e6:2d:99:11:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 13,\n // utm: \"POINT(737626.560614624 9548899.98869854)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:2\",\n // mac: \"b4:e6:2d:98:a8:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 2,\n // utm: \"POINT(737491.150156961 9548729.88920423)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:3\",\n // mac: \"b4:e6:2d:ac:4d:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 3,\n // utm: \"POINT(737501.487731269 9548743.6844395)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:4\",\n // mac: \"b4:e6:2d:99:04:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 4,\n // utm: \"POINT(737513.867287789 9548758.53463396)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:5\",\n // mac: \"b4:e6:2d:ac:59:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 5,\n // utm: \"POINT(737525.224284981 9548772.26548464)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:6\",\n // mac: \"b4:e6:2d:ac:4e:f5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 6,\n // utm: \"POINT(737541.367828341 9548792.49421549)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:7\",\n // mac: \"b4:e6:2d:ac:48:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 7,\n // utm: \"POINT(737553.323741132 9548807.25925796)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:8\",\n // mac: \"b4:e6:2d:99:13:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 8,\n // utm: \"POINT(737564.234339875 9548821.28724043)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10:9\",\n // mac: \"b4:e6:2d:ad:8f:01\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10\",\n // position: 9,\n // utm: \"POINT(737576.191832508 9548836.64415747)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:1\",\n // mac: \"b4:e6:2d:98:f2:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 1,\n // utm: \"POINT(737782.30308247 9549098.00063763)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:10\",\n // mac: \"b4:e6:2d:99:04:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 10,\n // utm: \"POINT(737366.471814587 9549516.59707753)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:2\",\n // mac: \"b4:e6:2d:ad:9e:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 2,\n // utm: \"POINT(737773.033121559 9549084.11668973)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:3\",\n // mac: \"b4:e6:2d:98:a2:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 3,\n // utm: \"POINT(737760.775417538 9549068.7602798)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:4\",\n // mac: \"b4:e6:2d:98:90:4d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 4,\n // utm: \"POINT(737749.419223801 9549055.62091791)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:5\",\n // mac: \"b4:e6:2d:98:9a:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 5,\n // utm: \"POINT(737738.505791646 9549042.47972028)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:6\",\n // mac: \"b4:e6:2d:98:f5:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 6,\n // utm: \"POINT(737726.25059332 9549025.34972922)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:7\",\n // mac: \"b4:e6:2d:99:8f:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 7,\n // utm: \"POINT(737716.385413772 9549012.50150745)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:8\",\n // mac: \"b4:e6:2d:aa:fa:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 8,\n // utm: \"POINT(737703.225794553 9548995.6708559)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P10N:9\",\n // mac: \"b4:e6:2d:98:fd:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P10N\",\n // position: 9,\n // utm: \"POINT(737690.226963171 9548981.35542716)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:1\",\n // mac: \"b4:e6:2d:99:08:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 1,\n // utm: \"POINT(737459.739208008 9548737.66784354)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:10\",\n // mac: \"b4:e6:2d:98:f3:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 10,\n // utm: \"POINT(737564.361435593 9548869.22862312)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:11\",\n // mac: \"b4:e6:2d:99:05:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 11,\n // utm: \"POINT(737575.871579155 9548884.43877218)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:2\",\n // mac: \"b4:e6:2d:aa:fb:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 2,\n // utm: \"POINT(737468.858713744 9548750.07187028)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:3\",\n // mac: \"b4:e6:2d:98:a6:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 3,\n // utm: \"POINT(737479.4709812 9548763.65634332)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:4\",\n // mac: \"b4:e6:2d:ac:4d:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 4,\n // utm: \"POINT(737490.228360001 9548776.64956029)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:5\",\n // mac: \"b4:e6:2d:99:14:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 5,\n // utm: \"POINT(737503.531196684 9548793.33460794)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:6\",\n // mac: \"b4:e6:2d:ad:8f:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 6,\n // utm: \"POINT(737515.487656733 9548808.09965089)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:7\",\n // mac: \"b4:e6:2d:ac:57:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 7,\n // utm: \"POINT(737527.593866103 9548823.16023521)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:8\",\n // mac: \"b4:e6:2d:ac:46:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 8,\n // utm: \"POINT(737539.850297458 9548838.66432807)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11:9\",\n // mac: \"b4:e6:2d:8e:a8:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11\",\n // position: 9,\n // utm: \"POINT(737552.105946192 9548853.87248968)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11N:1\",\n // mac: \"b4:e6:2d:ac:48:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11N\",\n // position: 1,\n // utm: \"POINT(737759.113785739 9549116.11448844)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11N:3\",\n // mac: \"b4:e6:2d:ad:9b:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11N\",\n // position: 3,\n // utm: \"POINT(737738.184454593 9549089.53572932)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11N:4\",\n // mac: \"b4:e6:2d:99:03:bd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11N\",\n // position: 4,\n // utm: \"POINT(737726.825127253 9549074.47310597)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11N:5\",\n // mac: \"4c:11:ae:b7:fa:4c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11N\",\n // position: 5,\n // utm: \"POINT(737715.470364097 9549061.18609865)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11N:6\",\n // mac: \"b4:e6:2d:aa:54:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11N\",\n // position: 6,\n // utm: \"POINT(737701.121604208 9549042.8761153)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P11N:7\",\n // mac: \"b4:e6:2d:99:13:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P11N\",\n // position: 7,\n // utm: \"POINT(737686.775061377 9549025.45394262)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12:1\",\n // mac: \"b4:e6:2d:ac:f9:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12\",\n // position: 1,\n // utm: \"POINT(737443.578353406 9548766.56371398)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12:2\",\n // mac: \"b4:e6:2d:ad:9b:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12\",\n // position: 2,\n // utm: \"POINT(737456.425928255 9548780.1421971)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12N:1\",\n // mac: \"c4:4f:33:23:5f:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12N\",\n // position: 1,\n // utm: \"POINT(737732.258890721 9549130.39088346)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12N:2\",\n // mac: \"c4:4f:33:23:63:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12N\",\n // position: 2,\n // utm: \"POINT(737723.371390508 9549120.64855947)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12N:3\",\n // mac: \"24:0a:c4:50:d0:94\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12N\",\n // position: 3,\n // utm: \"POINT(737712.786474227 9549107.35949603)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12N:4\",\n // mac: \"c4:4f:33:23:7b:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12N\",\n // position: 4,\n // utm: \"POINT(737701.394226976 9549089.92945437)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12N:5\",\n // mac: \"c4:4f:33:1e:b8:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12N\",\n // position: 5,\n // utm: \"POINT(737688.813270685 9549074.27820128)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P12N:6\",\n // mac: \"4c:11:ae:b7:f3:98\",\n // area: \"DMLZ_Extraction\",\n // location: \"P12N\",\n // position: 6,\n // utm: \"POINT(737676.235028108 9549059.51475657)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:1\",\n // mac: \"b4:e6:2d:98:f1:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 1,\n // utm: \"POINT(737429.578511678 9548795.16040332)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:10\",\n // mac: \"b4:e6:2d:ac:49:21\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 10,\n // utm: \"POINT(737554.455514192 9548953.44895166)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:2\",\n // mac: \"b4:e6:2d:98:a6:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 2,\n // utm: \"POINT(737441.685477248 9548810.66544484)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:4\",\n // mac: \"b4:e6:2d:ad:96:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 4,\n // utm: \"POINT(737474.416859502 9548851.71122732)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:5\",\n // mac: \"b4:e6:2d:98:a6:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 5,\n // utm: \"POINT(737490.337643237 9548872.97655165)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:6\",\n // mac: \"b4:e6:2d:ab:eb:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 6,\n // utm: \"POINT(737505.28693634 9548892.03531135)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:7\",\n // mac: \"b4:e6:2d:99:10:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 7,\n // utm: \"POINT(737517.988179092 9548907.89130289)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:8\",\n // mac: \"b4:e6:2d:99:a5:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 8,\n // utm: \"POINT(737529.34584443 9548921.69691803)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13:9\",\n // mac: \"b4:e6:2d:ac:49:bd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13\",\n // position: 9,\n // utm: \"POINT(737543.394583117 9548939.19772454)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:1\",\n // mac: \"c4:4f:33:23:65:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 1,\n // utm: \"POINT(737710.643858737 9549150.72093939)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:10\",\n // mac: \"c4:4f:33:23:ce:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 10,\n // utm: \"POINT(737614.041491936 9549029.19042354)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:11\",\n // mac: \"c4:4f:33:23:70:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 11,\n // utm: \"POINT(737615.284969553 9549029.63908617)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:12\",\n // mac: \"24:0a:c4:50:ff:dc\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 12,\n // utm: \"POINT(737603.029380792 9549014.28291652)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:13\",\n // mac: \"b4:e6:2d:98:f0:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 13,\n // utm: \"POINT(737589.578579796 9548997.59820889)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:14\",\n // mac: \"c4:4f:33:23:7a:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 14,\n // utm: \"POINT(737578.070156004 9548983.12787164)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:15\",\n // mac: \"c4:4f:33:23:67:61\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 15,\n // utm: \"POINT(737566.563700966 9548969.39770026)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:2\",\n // mac: \"24:0a:c4:50:e4:44\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 2,\n // utm: \"POINT(737703.037175765 9549140.56742842)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:22\",\n // mac: \"c4:4f:33:1d:df:39\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 22,\n // utm: \"POINT(737457.379431298 9548830.67649854)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:3\",\n // mac: \"c4:4f:33:23:67:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 3,\n // utm: \"POINT(737692.423448207 9549127.31543376)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:4\",\n // mac: \"24:0a:c4:50:cf:d8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 4,\n // utm: \"POINT(737681.809723417 9549114.06343945)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:5\",\n // mac: \"c4:4f:33:1e:b7:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 5,\n // utm: \"POINT(737671.196001389 9549100.8114455)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:6\",\n // mac: \"24:0a:c4:50:cf:80\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 6,\n // utm: \"POINT(737660.582282123 9549087.5594519)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:7\",\n // mac: \"24:0a:c4:50:e7:88\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 7,\n // utm: \"POINT(737649.968565623 9549074.30745866)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:8\",\n // mac: \"c4:4f:33:23:b7:19\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 8,\n // utm: \"POINT(737640.995700527 9549063.30762127)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P13N:9\",\n // mac: \"c4:4f:33:1d:26:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P13N\",\n // position: 9,\n // utm: \"POINT(737628.741140924 9549047.80347326)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:1\",\n // mac: \"24:0a:c4:50:c7:90\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 1,\n // utm: \"POINT(737411.549943632 9548821.69291789)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:2f:75\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:10\",\n // mac: \"b4:e6:2d:99:12:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 10,\n // utm: \"POINT(737580.732185088 9549032.22875932)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:11\",\n // mac: \"b4:e6:2d:ac:4c:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 11,\n // utm: \"POINT(737566.985824609 9549016.293141)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:12\",\n // mac: \"b4:e6:2d:99:12:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 12,\n // utm: \"POINT(737553.830583063 9548998.58099749)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:13\",\n // mac: \"b4:e6:2d:ac:0b:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 13,\n // utm: \"POINT(737541.579782446 9548985.00121892)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:2\",\n // mac: \"c4:4f:33:23:b0:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 2,\n // utm: \"POINT(737423.773754297 9548837.09142812)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:2f:75\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:3\",\n // mac: \"b4:e6:2d:ac:48:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 3,\n // utm: \"POINT(737435.997568759 9548852.48993883)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:2f:75\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:5\",\n // mac: \"b4:e6:2d:ac:4e:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 5,\n // utm: \"POINT(737642.315955932 9549111.9649083)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:6\",\n // mac: \"b4:e6:2d:aa:fb:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 6,\n // utm: \"POINT(737629.757782432 9549095.3950596)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:7\",\n // mac: \"b4:e6:2d:ac:4e:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 7,\n // utm: \"POINT(737618.399444324 9549081.22820959)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:8\",\n // mac: \"b4:e6:2d:ac:4e:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 8,\n // utm: \"POINT(737605.248910853 9549065.29116389)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14:9\",\n // mac: \"b4:e6:2d:ac:46:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14\",\n // position: 9,\n // utm: \"POINT(737592.694202678 9549049.35237255)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14N:1\",\n // mac: \"24:0a:c4:50:d0:98\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14N\",\n // position: 1,\n // utm: \"POINT(737687.310379662 9549170.83229478)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14N:2\",\n // mac: \"c4:4f:33:23:b0:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14N\",\n // position: 2,\n // utm: \"POINT(737678.061950812 9549157.74515666)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14N:3\",\n // mac: \"c4:4f:33:1d:fe:61\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14N\",\n // position: 3,\n // utm: \"POINT(737666.575405493 9549143.25869711)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P14N:4\",\n // mac: \"c4:4f:33:23:67:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P14N\",\n // position: 4,\n // utm: \"POINT(737655.08886354 9549128.77223799)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15:1\",\n // mac: \"b4:e6:2d:ac:48:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15\",\n // position: 1,\n // utm: \"POINT(737399.870197393 9548854.72082997)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:2f:75\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15:2\",\n // mac: \"b4:e6:2d:98:9a:65\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15\",\n // position: 2,\n // utm: \"POINT(737411.902002181 9548869.96660292)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:2f:75\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:1\",\n // mac: \"c4:4f:33:23:5f:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 1,\n // utm: \"POINT(737662.176447044 9549186.06611611)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:10\",\n // mac: \"c4:4f:33:1e:a7:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 10,\n // utm: \"POINT(737559.195706612 9549055.39464197)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:11\",\n // mac: \"24:0a:c4:50:ce:80\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 11,\n // utm: \"POINT(737544.401436801 9549037.53136012)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:12\",\n // mac: \"c4:4f:33:23:70:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 12,\n // utm: \"POINT(737532.592797337 9549022.17516028)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:13\",\n // mac: \"b4:e6:2d:98:f1:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 13,\n // utm: \"POINT(737519.590189211 9549005.79536241)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:15\",\n // mac: \"b4:e6:2d:98:f0:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 15,\n // utm: \"POINT(737495.075680969 9548974.32215234)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:2\",\n // mac: \"24:0a:c4:50:cf:ec\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 2,\n // utm: \"POINT(737654.102714482 9549174.84188796)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:3\",\n // mac: \"24:0a:c4:50:cf:b0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 3,\n // utm: \"POINT(737643.494306205 9549162.73629171)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:4\",\n // mac: \"c4:4f:33:23:60:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 4,\n // utm: \"POINT(737631.690696727 9549149.3015428)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:5\",\n // mac: \"c4:4f:33:23:67:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 5,\n // utm: \"POINT(737618.461833939 9549132.02811589)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:6\",\n // mac: \"c4:4f:33:23:65:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 6,\n // utm: \"POINT(737606.57857521 9549116.60023634)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:7\",\n // mac: \"c4:4f:33:1d:25:e1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 7,\n // utm: \"POINT(737594.176198056 9549102.05882456)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:8\",\n // mac: \"c4:4f:33:1e:a4:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 8,\n // utm: \"POINT(737572.496363905 9549071.91876372)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P15N:9\",\n // mac: \"b4:e6:2d:ad:9a:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P15N\",\n // position: 9,\n // utm: \"POINT(737507.48453109 9548991.30560471)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:1\",\n // mac: \"4c:11:ae:b7:f6:14\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 1,\n // utm: \"POINT(737376.683777367 9548874.46216775)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:2f:75\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:11\",\n // mac: \"c4:4f:33:1e:51:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 11,\n // utm: \"POINT(737508.355084301 9549038.65251332)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:12\",\n // mac: \"24:0a:c4:51:0f:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 12,\n // utm: \"POINT(737496.165843611 9549024.89997308)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:13\",\n // mac: \"24:0a:c4:50:ff:94\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 13,\n // utm: \"POINT(737541.21152016 9549081.00744524)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:14\",\n // mac: \"24:0a:c4:50:cd:d4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 14,\n // utm: \"POINT(737531.672163588 9549068.61562194)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:2\",\n // mac: \"24:0a:c4:50:db:70\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 2,\n // utm: \"POINT(737469.195622587 9548989.03936562)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:3\",\n // mac: \"24:0a:c4:51:0e:6c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 3,\n // utm: \"POINT(737399.24917899 9548901.33284749)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:4\",\n // mac: \"4c:11:ae:b7:f6:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 4,\n // utm: \"POINT(737414.494118684 9548920.52719258)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:5\",\n // mac: \"c4:4f:33:1d:c2:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 5,\n // utm: \"POINT(737430.036279971 9548939.72244799)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:6\",\n // mac: \"c4:4f:33:23:9b:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 6,\n // utm: \"POINT(737444.980870234 9548957.73489663)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16:7\",\n // mac: \"c4:4f:33:24:25:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16\",\n // position: 7,\n // utm: \"POINT(737456.640514705 9548973.09564076)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:1\",\n // mac: \"c4:4f:33:23:5f:01\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 1,\n // utm: \"POINT(737637.196329383 9549203.14836342)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:12\",\n // mac: \"b4:e6:2d:99:11:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 12,\n // utm: \"POINT(737509.267200666 9549044.78498888)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:14\",\n // mac: \"24:0a:c4:51:0e:14\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 14,\n // utm: \"POINT(737482.950200883 9549007.94292769)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:3\",\n // mac: \"c4:4f:33:23:68:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 3,\n // utm: \"POINT(737619.411939931 9549181.29683111)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:4\",\n // mac: \"c4:4f:33:1e:bf:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 4,\n // utm: \"POINT(737607.310668867 9549167.68876105)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:5\",\n // mac: \"4c:11:ae:b7:f5:54\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 5,\n // utm: \"POINT(737596.544811865 9549152.32182183)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:6\",\n // mac: \"c4:4f:33:23:7d:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 6,\n // utm: \"POINT(737583.985697754 9549135.22925921)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:7\",\n // mac: \"c4:4f:33:23:cb:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 7,\n // utm: \"POINT(737572.03120689 9549121.05027679)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:8\",\n // mac: \"c4:4f:33:23:71:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 8,\n // utm: \"POINT(737558.878744419 9549104.51388896)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P16N:9\",\n // mac: \"4c:11:ae:b7:fa:c0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P16N\",\n // position: 9,\n // utm: \"POINT(737546.023401954 9549087.67908364)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:1\",\n // mac: \"c4:4f:33:23:ce:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 1,\n // utm: \"POINT(737352.149373783 9548890.80654894)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:10\",\n // mac: \"24:0a:c4:50:e7:0c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 10,\n // utm: \"POINT(737448.58220018 9549012.53288425)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:11\",\n // mac: \"b4:e6:2d:aa:54:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 11,\n // utm: \"POINT(737459.462716669 9549026.15654427)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:12\",\n // mac: \"b4:e6:2d:ab:ca:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 12,\n // utm: \"POINT(737470.343236174 9549039.78020466)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:13\",\n // mac: \"b4:e6:2d:ab:ca:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 13,\n // utm: \"POINT(737481.223758592 9549053.40386543)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:14\",\n // mac: \"24:0a:c4:50:dd:f4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 14,\n // utm: \"POINT(737492.104283916 9549067.02752658)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:15\",\n // mac: \"b4:e6:2d:ad:09:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 15,\n // utm: \"POINT(737502.984812041 9549080.65118812)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:16\",\n // mac: \"24:0a:c4:50:e6:e8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 16,\n // utm: \"POINT(737513.865343184 9549094.27485003)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:2\",\n // mac: \"24:0a:c4:50:d1:dc\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 2,\n // utm: \"POINT(737364.554986729 9548906.6017653)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:3\",\n // mac: \"c4:4f:33:1d:f5:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 3,\n // utm: \"POINT(737375.541387423 9548920.84752258)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:4\",\n // mac: \"c4:4f:33:1e:be:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 4,\n // utm: \"POINT(737387.050514871 9548935.60963834)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:5\",\n // mac: \"b4:e6:2d:a3:85:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 5,\n // utm: \"POINT(737394.179660948 9548944.41458983)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:6\",\n // mac: \"b4:e6:2d:ab:ca:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 6,\n // utm: \"POINT(737405.060162995 9548958.03824796)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:7\",\n // mac: \"b4:e6:2d:ad:08:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 7,\n // utm: \"POINT(737415.940667957 9548971.66190646)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:8\",\n // mac: \"b4:e6:2d:ad:08:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 8,\n // utm: \"POINT(737426.821175714 9548985.28556535)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17:9\",\n // mac: \"b4:e6:2d:ab:ca:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17\",\n // position: 9,\n // utm: \"POINT(737437.701686491 9548998.90922461)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:1\",\n // mac: \"b4:e6:2d:98:f1:61\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 1,\n // utm: \"POINT(737613.709762171 9549221.70673937)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:2\",\n // mac: \"b4:e6:2d:ad:0a:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 2,\n // utm: \"POINT(737603.042220111 9549208.36238866)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:3\",\n // mac: \"c4:4f:33:1d:b2:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 3,\n // utm: \"POINT(737592.374680842 9549195.01803832)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:4\",\n // mac: \"24:0a:c4:50:e7:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 4,\n // utm: \"POINT(737581.70714437 9549181.67368834)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:5\",\n // mac: \"24:0a:c4:51:0f:0c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 5,\n // utm: \"POINT(737571.039610692 9549168.32933872)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:6\",\n // mac: \"b4:e6:2d:ad:0b:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 6,\n // utm: \"POINT(737560.372079697 9549154.98498947)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:7\",\n // mac: \"b4:e6:2d:ab:fd:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 7,\n // utm: \"POINT(737549.70455161 9549141.64064058)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:8\",\n // mac: \"b4:e6:2d:a4:9b:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 8,\n // utm: \"POINT(737539.037026314 9549128.29629205)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P17N:9\",\n // mac: \"c4:4f:33:23:7c:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P17N\",\n // position: 9,\n // utm: \"POINT(737528.369503816 9549114.95194388)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:1\",\n // mac: \"c4:4f:33:23:8d:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 1,\n // utm: \"POINT(737324.183160763 9548905.08299883)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:10\",\n // mac: \"b4:e6:2d:ad:08:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 10,\n // utm: \"POINT(737416.458503443 9549020.7858298)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:11\",\n // mac: \"b4:e6:2d:ad:09:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 11,\n // utm: \"POINT(737426.71133216 9549033.6417016)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:12\",\n // mac: \"b4:e6:2d:ad:0a:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 12,\n // utm: \"POINT(737436.964163574 9549046.49757373)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:13\",\n // mac: \"b4:e6:2d:98:f7:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 13,\n // utm: \"POINT(737447.216997574 9549059.3534462)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:14\",\n // mac: \"b4:e6:2d:98:a8:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 14,\n // utm: \"POINT(737457.469834046 9549072.20931901)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:15\",\n // mac: \"b4:e6:2d:ad:09:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 15,\n // utm: \"POINT(737467.722673212 9549085.06519216)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:16\",\n // mac: \"24:0a:c4:50:cb:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 16,\n // utm: \"POINT(737479.622716667 9549101.17233581)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:2\",\n // mac: \"24:0a:c4:51:06:c4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 2,\n // utm: \"POINT(737334.643255556 9548917.48455741)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:3\",\n // mac: \"c4:4f:33:23:ae:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 3,\n // utm: \"POINT(737344.688774362 9548930.79473668)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:4\",\n // mac: \"4c:11:ae:b7:fb:90\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 4,\n // utm: \"POINT(737354.941585091 9548943.65060612)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:5\",\n // mac: \"c4:4f:33:23:af:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 5,\n // utm: \"POINT(737366.030427829 9548957.20588923)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:6\",\n // mac: \"c4:4f:33:23:57:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 6,\n // utm: \"POINT(737376.046477467 9548970.64454692)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:7\",\n // mac: \"c4:4f:33:23:70:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 7,\n // utm: \"POINT(737384.866114953 9548982.31045179)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:8\",\n // mac: \"c4:4f:33:23:ae:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 8,\n // utm: \"POINT(737395.952853653 9548995.07408723)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18:9\",\n // mac: \"c4:4f:33:23:b0:bd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18\",\n // position: 9,\n // utm: \"POINT(737214.963811696 9548891.46364874)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:1\",\n // mac: \"c4:4f:33:1e:a8:19\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 1,\n // utm: \"POINT(737592.163601966 9549241.73976869)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:2\",\n // mac: \"24:0a:c4:50:ce:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 2,\n // utm: \"POINT(737580.985849195 9549227.58558087)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:3\",\n // mac: \"24:0a:c4:50:e4:78\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 3,\n // utm: \"POINT(737569.808099616 9549213.43139348)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:4\",\n // mac: \"b4:e6:2d:99:08:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 4,\n // utm: \"POINT(737558.63035301 9549199.2772065)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:5\",\n // mac: \"b4:e6:2d:ab:ca:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 5,\n // utm: \"POINT(737547.452609594 9549185.12301995)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:6\",\n // mac: \"c4:4f:33:23:ad:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 6,\n // utm: \"POINT(737536.274869148 9549170.96883381)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:7\",\n // mac: \"c4:4f:33:23:71:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 7,\n // utm: \"POINT(737525.097131899 9549156.8146481)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P18N:8\",\n // mac: \"c4:4f:33:23:7c:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P18N\",\n // position: 8,\n // utm: \"POINT(737513.919397625 9549142.6604628)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:1\",\n // mac: \"c4:4f:33:1d:92:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 1,\n // utm: \"POINT(737299.500992481 9548922.16445425)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:10\",\n // mac: \"24:0a:c4:50:fc:28\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 10,\n // utm: \"POINT(737406.737314993 9549056.68174741)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:11\",\n // mac: \"c4:4f:33:1d:9b:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 11,\n // utm: \"POINT(737417.386750657 9549072.25122909)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:12\",\n // mac: \"c4:4f:33:23:cf:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 12,\n // utm: \"POINT(737429.354304606 9549087.33337813)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:13\",\n // mac: \"c4:4f:33:1e:be:21\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 13,\n // utm: \"POINT(737441.321861976 9549102.41552765)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:14\",\n // mac: \"c4:4f:33:23:5e:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 14,\n // utm: \"POINT(737453.28942287 9549117.49767764)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:15\",\n // mac: \"c4:4f:33:23:cf:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 15,\n // utm: \"POINT(737465.256987405 9549132.5798281)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:2\",\n // mac: \"4c:11:ae:b7:fc:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 2,\n // utm: \"POINT(737309.885713221 9548934.19794097)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:3\",\n // mac: \"c4:4f:33:23:7c:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 3,\n // utm: \"POINT(737321.469150959 9548948.8902723)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:4\",\n // mac: \"24:0a:c4:50:d0:1c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 4,\n // utm: \"POINT(737331.261782074 9548962.33027142)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:5\",\n // mac: \"4c:11:ae:b7:fd:64\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 5,\n // utm: \"POINT(737342.992417195 9548976.35668109)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:6\",\n // mac: \"b4:e6:2d:ab:ca:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 6,\n // utm: \"POINT(737354.201314804 9548990.23659017)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:7\",\n // mac: \"b4:e6:2d:aa:ed:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 7,\n // utm: \"POINT(737374.673131109 9549014.445328)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:8\",\n // mac: \"b4:e6:2d:ab:ca:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 8,\n // utm: \"POINT(737386.035545027 9549030.09773075)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19:9\",\n // mac: \"24:0a:c4:50:ce:f4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19\",\n // position: 9,\n // utm: \"POINT(737395.378448056 9549042.4310599)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19N:1\",\n // mac: \"4c:11:ae:b7:fa:04\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19N\",\n // position: 1,\n // utm: \"POINT(737570.173678114 9549262.95748149)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19N:2\",\n // mac: \"c4:4f:33:23:71:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19N\",\n // position: 2,\n // utm: \"POINT(737560.906288227 9549250.99540132)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19N:3\",\n // mac: \"c4:4f:33:23:64:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19N\",\n // position: 3,\n // utm: \"POINT(737549.251645295 9549237.56053411)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19N:4\",\n // mac: \"c4:4f:33:23:7c:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19N\",\n // position: 4,\n // utm: \"POINT(737536.992952068 9549221.02393693)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19N:5\",\n // mac: \"4c:11:ae:b7:fd:74\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19N\",\n // position: 5,\n // utm: \"POINT(737523.294570094 9549204.58508973)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19N:6\",\n // mac: \"c4:4f:33:23:65:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19N\",\n // position: 6,\n // utm: \"POINT(737512.929856107 9549190.75253361)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P19N:7\",\n // mac: \"c4:4f:33:23:55:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P19N\",\n // position: 7,\n // utm: \"POINT(737499.855036227 9549175.39889642)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:1\",\n // mac: \"b4:e6:2d:ac:49:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 1,\n // utm: \"POINT(737266.44111817 9548925.65803148)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:10\",\n // mac: \"b4:e6:2d:99:10:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 10,\n // utm: \"POINT(737366.652399221 9549056.83019569)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:11\",\n // mac: \"b4:e6:2d:ac:51:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 11,\n // utm: \"POINT(737377.75259216 9549070.91198744)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:12\",\n // mac: \"24:0a:c4:50:e7:f0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 12,\n // utm: \"POINT(737388.852788146 9549084.99377961)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:13\",\n // mac: \"c4:4f:33:23:63:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 13,\n // utm: \"POINT(737399.952987284 9549099.07557219)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:14\",\n // mac: \"24:0a:c4:50:ce:ac\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 14,\n // utm: \"POINT(737411.053189352 9549113.15736519)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:15\",\n // mac: \"24:0a:c4:50:f8:9c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 15,\n // utm: \"POINT(737422.153394462 9549127.23915861)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:16\",\n // mac: \"c4:4f:33:23:d4:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 16,\n // utm: \"POINT(737433.253602618 9549141.32095244)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:2\",\n // mac: \"b4:e6:2d:ab:d7:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 2,\n // utm: \"POINT(737277.355593058 9548940.86938507)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:3\",\n // mac: \"b4:e6:2d:ad:0b:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 3,\n // utm: \"POINT(737290.06092049 9548957.40176816)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:4\",\n // mac: \"b4:e6:2d:ab:ca:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 4,\n // utm: \"POINT(737302.914546786 9548973.57406619)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:5\",\n // mac: \"b4:e6:2d:aa:54:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 5,\n // utm: \"POINT(737313.599516645 9548986.49357305)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:6\",\n // mac: \"b4:e6:2d:ad:08:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 6,\n // utm: \"POINT(737322.251657779 9549000.50303284)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:7\",\n // mac: \"b4:e6:2d:aa:54:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 7,\n // utm: \"POINT(737333.351838545 9549014.58482293)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:8\",\n // mac: \"24:0a:c4:51:13:d0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 8,\n // utm: \"POINT(737344.452022468 9549028.66661344)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20:9\",\n // mac: \"b4:e6:2d:ad:09:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20\",\n // position: 9,\n // utm: \"POINT(737355.552209325 9549042.74840436)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:1\",\n // mac: \"b4:e6:2d:aa:55:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 1,\n // utm: \"POINT(737546.691034452 9549282.99588077)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:10\",\n // mac: \"24:0a:c4:50:db:6c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 10,\n // utm: \"POINT(737460.664559248 9549173.0244705)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:11\",\n // mac: \"c4:4f:33:23:ae:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 11,\n // utm: \"POINT(737451.10607335 9549160.80542651)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:2\",\n // mac: \"c4:4f:33:23:54:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 2,\n // utm: \"POINT(737537.132528089 9549270.7768339)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:3\",\n // mac: \"b4:e6:2d:ad:8f:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 3,\n // utm: \"POINT(737527.574024097 9549258.55778736)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:4\",\n // mac: \"b4:e6:2d:ab:ca:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 4,\n // utm: \"POINT(737518.015522361 9549246.33874114)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:5\",\n // mac: \"4c:11:ae:b7:fb:98\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 5,\n // utm: \"POINT(737508.457022893 9549234.11969523)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:6\",\n // mac: \"b4:e6:2d:ad:0a:09\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 6,\n // utm: \"POINT(737498.898525574 9549221.90064965)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:7\",\n // mac: \"b4:e6:2d:ab:ca:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 7,\n // utm: \"POINT(737489.340030629 9549209.68160438)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:8\",\n // mac: \"4c:11:ae:b7:fc:d8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 8,\n // utm: \"POINT(737479.781537942 9549197.46255944)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P20N:9\",\n // mac: \"b4:e6:2d:ab:cf:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P20N\",\n // position: 9,\n // utm: \"POINT(737470.223047518 9549185.24351481)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:db:6f\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21:1\",\n // mac: \"24:0a:c4:50:f8:cc\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21\",\n // position: 1,\n // utm: \"POINT(737241.914467966 9548944.36466836)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:1\",\n // mac: \"24:0a:c4:50:cc:6c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 1,\n // utm: \"POINT(737524.101188457 9549299.47872017)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:10\",\n // mac: \"c4:4f:33:23:60:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 10,\n // utm: \"POINT(737407.853265593 9549153.30105161)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:12\",\n // mac: \"c4:4f:33:23:b0:e1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 12,\n // utm: \"POINT(737382.020438987 9549120.81713125)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:13\",\n // mac: \"4c:11:ae:b7:f3:1c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 13,\n // utm: \"POINT(737369.104031897 9549104.57517187)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:2\",\n // mac: \"c4:4f:33:23:d1:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 2,\n // utm: \"POINT(737511.184736104 9549283.23675482)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:3\",\n // mac: \"24:0a:c4:50:ce:d4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 3,\n // utm: \"POINT(737498.268287963 9549266.99479001)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:4\",\n // mac: \"24:0a:c4:50:c8:48\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 4,\n // utm: \"POINT(737485.351843818 9549250.75282575)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:5\",\n // mac: \"c4:4f:33:23:5f:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 5,\n // utm: \"POINT(737472.435403886 9549234.51086204)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:6\",\n // mac: \"4c:11:ae:b7:f5:0c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 6,\n // utm: \"POINT(737459.518967951 9549218.26889887)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:7\",\n // mac: \"24:0a:c4:50:e4:30\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 7,\n // utm: \"POINT(737446.602536233 9549202.02693624)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:8\",\n // mac: \"c4:4f:33:23:ce:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 8,\n // utm: \"POINT(737433.686108617 9549185.78497415)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P21N:9\",\n // mac: \"c4:4f:33:23:57:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P21N\",\n // position: 9,\n // utm: \"POINT(737420.769684997 9549169.54301261)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22:1\",\n // mac: \"b4:e6:2d:ad:9b:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22\",\n // position: 1,\n // utm: \"POINT(737209.916443878 9548955.84338561)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22N:1\",\n // mac: \"24:0a:c4:50:cf:04\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22N\",\n // position: 1,\n // utm: \"POINT(737512.722573988 9549336.94909944)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22N:2\",\n // mac: \"c4:4f:33:23:69:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22N\",\n // position: 2,\n // utm: \"POINT(737501.062626585 9549321.59360188)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22N:3\",\n // mac: \"c4:4f:33:1e:21:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22N\",\n // position: 3,\n // utm: \"POINT(737487.476410163 9549302.07197176)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22N:4\",\n // mac: \"c4:4f:33:23:57:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22N\",\n // position: 4,\n // utm: \"POINT(737473.960382453 9549284.85889848)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22N:5\",\n // mac: \"c4:4f:33:1e:9e:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22N\",\n // position: 5,\n // utm: \"POINT(737460.444359367 9549267.64582583)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22N:6\",\n // mac: \"c4:4f:33:23:66:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22N\",\n // position: 6,\n // utm: \"POINT(737446.928340686 9549250.4327538)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P22N:7\",\n // mac: \"c4:4f:33:1d:c4:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"P22N\",\n // position: 7,\n // utm: \"POINT(737433.412326523 9549233.2196824)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:1\",\n // mac: \"b4:e6:2d:98:a6:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 1,\n // utm: \"POINT(737187.32784282 9548976.02697869)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:10\",\n // mac: \"c4:4f:33:23:7c:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 10,\n // utm: \"POINT(737288.608301498 9549103.36798003)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:11\",\n // mac: \"c4:4f:33:23:66:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 11,\n // utm: \"POINT(737299.861701346 9549117.51698224)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:12\",\n // mac: \"4c:11:ae:b7:f4:ec\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 12,\n // utm: \"POINT(737311.115104417 9549131.66598485)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:13\",\n // mac: \"c4:4f:33:23:b2:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 13,\n // utm: \"POINT(737322.368510501 9549145.81498787)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:14\",\n // mac: \"c4:4f:33:23:af:35\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 14,\n // utm: \"POINT(737334.552436732 9549160.55702564)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:15\",\n // mac: \"c4:4f:33:1e:95:f5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 15,\n // utm: \"POINT(737221.709687101 9549583.49524913)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:2\",\n // mac: \"b4:e6:2d:98:a4:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 2,\n // utm: \"POINT(737198.581214607 9548990.1759772)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:3\",\n // mac: \"b4:e6:2d:ad:09:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 3,\n // utm: \"POINT(737209.834589629 9549004.32497612)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:4\",\n // mac: \"b4:e6:2d:ac:46:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 4,\n // utm: \"POINT(737221.087967656 9549018.47397545)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:5\",\n // mac: \"b4:e6:2d:ad:16:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 5,\n // utm: \"POINT(737232.341348796 9549032.62297519)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:6\",\n // mac: \"b4:e6:2d:ad:42:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 6,\n // utm: \"POINT(737243.594733168 9549046.77197534)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:7\",\n // mac: \"b4:e6:2d:ac:44:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 7,\n // utm: \"POINT(737254.848120547 9549060.9209759)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:8\",\n // mac: \"b4:e6:2d:98:f7:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 8,\n // utm: \"POINT(737266.101511044 9549075.06997687)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23:9\",\n // mac: \"b4:e6:2d:98:a8:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23\",\n // position: 9,\n // utm: \"POINT(737277.35490477 9549089.21897825)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23N:1\",\n // mac: \"c4:4f:33:23:af:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23N\",\n // position: 1,\n // utm: \"POINT(737505.372404306 9549373.81218865)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23N:10\",\n // mac: \"24:0a:c4:50:cb:50\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23N\",\n // position: 10,\n // utm: \"POINT(737475.333055692 9549449.3386319)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23N:2\",\n // mac: \"24:0a:c4:50:cc:58\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23N\",\n // position: 2,\n // utm: \"POINT(737496.401290791 9549361.40495647)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23N:3\",\n // mac: \"4c:11:ae:b7:f5:ac\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23N\",\n // position: 3,\n // utm: \"POINT(737484.208226431 9549347.14354433)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23N:4\",\n // mac: \"24:0a:c4:50:c7:48\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23N\",\n // position: 4,\n // utm: \"POINT(737472.489484617 9549331.95274522)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P23N:9\",\n // mac: \"4c:11:ae:b7:fa:50\",\n // area: \"DMLZ_Extraction\",\n // location: \"P23N\",\n // position: 9,\n // utm: \"POINT(737175.651668784 9548915.85799718)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24:1\",\n // mac: \"b4:e6:2d:ad:8f:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24\",\n // position: 1,\n // utm: \"POINT(737161.146759222 9548989.56152634)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:03:b9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:1\",\n // mac: \"c4:4f:33:23:70:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 1,\n // utm: \"POINT(737488.758257799 9549400.19315846)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:10\",\n // mac: \"24:0a:c4:50:c9:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 10,\n // utm: \"POINT(737383.835614168 9549267.56585092)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:11\",\n // mac: \"c4:4f:33:23:b6:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 11,\n // utm: \"POINT(737462.468220069 9549485.04709231)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:46:03:ca\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:2\",\n // mac: \"c4:4f:33:23:9b:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 2,\n // utm: \"POINT(737477.100172951 9549385.45678914)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:3\",\n // mac: \"c4:4f:33:23:ae:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 3,\n // utm: \"POINT(737465.442091336 9549370.72042027)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:4\",\n // mac: \"4c:11:ae:b7:f4:c0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 4,\n // utm: \"POINT(737453.784013073 9549355.98405187)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:5\",\n // mac: \"24:0a:c4:50:d2:04\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 5,\n // utm: \"POINT(737442.125938271 9549341.24768391)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:6\",\n // mac: \"24:0a:c4:50:d0:7c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 6,\n // utm: \"POINT(737430.467866707 9549326.51131641)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:7\",\n // mac: \"c4:4f:33:23:f0:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 7,\n // utm: \"POINT(737418.809798599 9549311.77494936)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:8\",\n // mac: \"4c:11:ae:b7:fd:80\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 8,\n // utm: \"POINT(737407.151733738 9549297.03858276)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P24N:9\",\n // mac: \"c4:4f:33:23:d1:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P24N\",\n // position: 9,\n // utm: \"POINT(737395.493672333 9549282.30221661)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:55:46\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25:1\",\n // mac: \"c4:4f:33:23:d1:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25\",\n // position: 1,\n // utm: \"POINT(737135.856934851 9549002.0579235)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:1\",\n // mac: \"c4:4f:33:23:65:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 1,\n // utm: \"POINT(737464.972906195 9549418.45647093)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:10\",\n // mac: \"c4:4f:33:23:61:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 10,\n // utm: \"POINT(737371.890329558 9549301.77833783)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:2\",\n // mac: \"24:0a:c4:50:e6:9c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 2,\n // utm: \"POINT(737454.630387156 9549405.49223254)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:3\",\n // mac: \"24:0a:c4:50:cd:98\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 3,\n // utm: \"POINT(737444.287870746 9549392.5279945)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:4\",\n // mac: \"c4:4f:33:23:b2:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 4,\n // utm: \"POINT(737433.945356962 9549379.5637568)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:5\",\n // mac: \"c4:4f:33:23:7c:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 5,\n // utm: \"POINT(737423.602845806 9549366.59951945)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:6\",\n // mac: \"24:0a:c4:50:e3:f0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 6,\n // utm: \"POINT(737413.260337278 9549353.63528243)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:7\",\n // mac: \"24:0a:c4:50:d3:d4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 7,\n // utm: \"POINT(737402.917831488 9549340.67104577)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P25N:8\",\n // mac: \"c4:4f:33:23:60:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P25N\",\n // position: 8,\n // utm: \"POINT(737392.575328219 9549327.70680945)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:1\",\n // mac: \"24:0a:c4:50:d1:30\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 1,\n // utm: \"POINT(737111.776050824 9549021.65357739)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:10\",\n // mac: \"c4:4f:33:23:ae:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 10,\n // utm: \"POINT(737214.514219688 9549151.55633732)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:11\",\n // mac: \"c4:4f:33:23:ac:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 11,\n // utm: \"POINT(737225.929587881 9549165.98997947)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:12\",\n // mac: \"4c:11:ae:b7:fd:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 12,\n // utm: \"POINT(737237.344959287 9549180.42362206)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:13\",\n // mac: \"4c:11:ae:b7:f8:60\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 13,\n // utm: \"POINT(737248.760333904 9549194.85726508)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:14\",\n // mac: \"24:0a:c4:50:db:78\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 14,\n // utm: \"POINT(737260.175711737 9549209.29090853)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:15\",\n // mac: \"c4:4f:33:23:69:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 15,\n // utm: \"POINT(737271.591092784 9549223.72455241)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:16\",\n // mac: \"c4:4f:33:23:ad:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 16,\n // utm: \"POINT(737283.006477044 9549238.15819673)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:17\",\n // mac: \"24:0a:c4:50:db:50\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 17,\n // utm: \"POINT(737294.421864403 9549252.59184148)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:2\",\n // mac: \"24:0a:c4:51:0e:28\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 2,\n // utm: \"POINT(737123.191390086 9549036.08721566)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:3\",\n // mac: \"c4:4f:33:23:c3:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 3,\n // utm: \"POINT(737134.606732452 9549050.52085435)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:4\",\n // mac: \"c4:4f:33:23:b6:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 4,\n // utm: \"POINT(737146.022078144 9549064.95449348)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:5\",\n // mac: \"c4:4f:33:23:cd:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 5,\n // utm: \"POINT(737157.437427048 9549079.38813304)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:6\",\n // mac: \"c4:4f:33:23:70:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 6,\n // utm: \"POINT(737168.852779173 9549093.82177303)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:7\",\n // mac: \"24:0a:c4:50:f8:f8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 7,\n // utm: \"POINT(737180.26813451 9549108.25541346)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:8\",\n // mac: \"4c:11:ae:b7:fc:1c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 8,\n // utm: \"POINT(737191.683493058 9549122.68905431)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26:9\",\n // mac: \"c4:4f:33:1e:ae:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26\",\n // position: 9,\n // utm: \"POINT(737203.09885482 9549137.1226956)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:1\",\n // mac: \"c4:4f:33:23:af:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 1,\n // utm: \"POINT(737441.901388105 9549439.08538802)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:10\",\n // mac: \"24:0a:c4:50:cf:30\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 10,\n // utm: \"POINT(737342.840081846 9549311.95221459)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:2\",\n // mac: \"c4:4f:33:23:d3:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 2,\n // utm: \"POINT(737430.89456434 9549424.95947814)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:3\",\n // mac: \"4c:11:ae:b7:fb:d8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 3,\n // utm: \"POINT(737419.887743465 9549410.83356869)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:4\",\n // mac: \"c4:4f:33:23:9b:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 4,\n // utm: \"POINT(737408.880925702 9549396.70765967)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:5\",\n // mac: \"24:0a:c4:51:09:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 5,\n // utm: \"POINT(737397.874110831 9549382.58175108)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:6\",\n // mac: \"c4:4f:33:23:c3:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 6,\n // utm: \"POINT(737386.867299073 9549368.45584293)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:7\",\n // mac: \"c4:4f:33:1d:95:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 7,\n // utm: \"POINT(737375.860490207 9549354.3299352)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:8\",\n // mac: \"c4:4f:33:23:5e:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 8,\n // utm: \"POINT(737364.853684453 9549340.20402789)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P26N:9\",\n // mac: \"c4:4f:33:23:66:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P26N\",\n // position: 9,\n // utm: \"POINT(737353.846881703 9549326.07812103)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27:1\",\n // mac: \"24:0a:c4:51:13:f8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27\",\n // position: 1,\n // utm: \"POINT(737087.393335684 9549039.17846926)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27:2\",\n // mac: \"c4:4f:33:23:5e:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27\",\n // position: 2,\n // utm: \"POINT(737100.244567467 9549054.38528835)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27:3\",\n // mac: \"c4:4f:33:1e:b8:35\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27\",\n // position: 3,\n // utm: \"POINT(737113.095803222 9549069.59210785)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:1\",\n // mac: \"c4:4f:33:23:b0:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 1,\n // utm: \"POINT(737418.226954237 9549457.05245282)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:10\",\n // mac: \"c4:4f:33:1d:d1:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 10,\n // utm: \"POINT(737321.253627176 9549334.67027312)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:11\",\n // mac: \"4c:11:ae:b7:fa:9c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 11,\n // utm: \"POINT(737310.478827369 9549321.07225507)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:12\",\n // mac: \"c4:4f:33:1d:14:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 12,\n // utm: \"POINT(737299.70403042 9549307.47423741)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:2\",\n // mac: \"c4:4f:33:23:8d:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 2,\n // utm: \"POINT(737407.452128695 9549443.45443132)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:3\",\n // mac: \"c4:4f:33:23:d4:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 3,\n // utm: \"POINT(737396.677306013 9549429.8564102)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:4\",\n // mac: \"c4:4f:33:23:55:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 4,\n // utm: \"POINT(737385.902486189 9549416.25838946)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:5\",\n // mac: \"24:0a:c4:51:09:40\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 5,\n // utm: \"POINT(737375.127669221 9549402.66036911)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:6\",\n // mac: \"24:0a:c4:50:e6:88\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 6,\n // utm: \"POINT(737364.352855115 9549389.06234914)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:7\",\n // mac: \"c4:4f:33:23:af:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 7,\n // utm: \"POINT(737353.578043869 9549375.46432956)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:8\",\n // mac: \"24:0a:c4:50:e4:e8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 8,\n // utm: \"POINT(737342.803235485 9549361.86631036)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P27N:9\",\n // mac: \"24:0a:c4:50:d2:74\",\n // area: \"DMLZ_Extraction\",\n // location: \"P27N\",\n // position: 9,\n // utm: \"POINT(737332.028429844 9549348.26829155)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28:1\",\n // mac: \"c4:4f:33:23:cf:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28\",\n // position: 1,\n // utm: \"POINT(737066.894364643 9549060.46997554)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28:2\",\n // mac: \"24:0a:c4:50:c6:84\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28\",\n // position: 2,\n // utm: \"POINT(737075.790400888 9549072.86898545)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28:3\",\n // mac: \"c4:4f:33:1d:8f:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28\",\n // position: 3,\n // utm: \"POINT(737087.517047244 9549085.48712668)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:4d:d6:5d\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:1\",\n // mac: \"c4:4f:33:24:24:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 1,\n // utm: \"POINT(737394.21794023 9549475.24235093)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:10\",\n // mac: \"c4:4f:33:23:57:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 10,\n // utm: \"POINT(737295.715741033 9549350.80607014)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:11\",\n // mac: \"c4:4f:33:1d:a6:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 11,\n // utm: \"POINT(737284.771066929 9549336.9798187)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:12\",\n // mac: \"c4:4f:33:23:5f:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 12,\n // utm: \"POINT(737273.826395886 9549323.15356767)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:2\",\n // mac: \"4c:11:ae:b7:fa:b4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 2,\n // utm: \"POINT(737383.273239678 9549461.41609592)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:3\",\n // mac: \"c4:4f:33:23:69:4d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 3,\n // utm: \"POINT(737372.32854196 9549447.5898413)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:4\",\n // mac: \"c4:4f:33:23:58:bd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 4,\n // utm: \"POINT(737361.383847309 9549433.76358708)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:5\",\n // mac: \"c4:4f:33:1e:08:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 5,\n // utm: \"POINT(737350.439155493 9549419.93733326)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:6\",\n // mac: \"24:0a:c4:50:ff:60\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 6,\n // utm: \"POINT(737339.494466745 9549406.11107984)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:7\",\n // mac: \"24:0a:c4:50:cf:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 7,\n // utm: \"POINT(737328.549780834 9549392.28482682)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:8\",\n // mac: \"24:0a:c4:50:e8:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 8,\n // utm: \"POINT(737317.605097987 9549378.45857419)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P28N:9\",\n // mac: \"24:0a:c4:50:ff:54\",\n // area: \"DMLZ_Extraction\",\n // location: \"P28N\",\n // position: 9,\n // utm: \"POINT(737306.660417979 9549364.63232196)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:6a:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:1\",\n // mac: \"b4:e6:2d:ac:b3:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 1,\n // utm: \"POINT(737369.9846928 9549493.13689735)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:10\",\n // mac: \"b4:e6:2d:ac:23:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 10,\n // utm: \"POINT(737257.88793823 9549351.38388626)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:11\",\n // mac: \"b4:e6:2d:98:f1:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 11,\n // utm: \"POINT(737245.481500405 9549335.28817854)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:2\",\n // mac: \"b4:e6:2d:98:a6:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 2,\n // utm: \"POINT(737359.224238347 9549479.84820769)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:3\",\n // mac: \"b4:e6:2d:98:f0:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 3,\n // utm: \"POINT(737346.51952658 9549463.63533886)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:4\",\n // mac: \"b4:e6:2d:98:a4:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 4,\n // utm: \"POINT(737333.963246388 9549447.2140211)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:5\",\n // mac: \"b4:e6:2d:ac:48:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 5,\n // utm: \"POINT(737323.20319393 9549434.07330756)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:6\",\n // mac: \"b4:e6:2d:ad:44:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 6,\n // utm: \"POINT(737310.1981491 9549416.94338624)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:7\",\n // mac: \"b4:e6:2d:aa:fb:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 7,\n // utm: \"POINT(737297.195854802 9549400.8492442)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:8\",\n // mac: \"b4:e6:2d:ac:75:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 8,\n // utm: \"POINT(737284.043819889 9549384.45956482)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29N:9\",\n // mac: \"b4:e6:2d:ad:9a:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29N\",\n // position: 9,\n // utm: \"POINT(737271.337100091 9549367.47683288)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:1\",\n // mac: \"c4:4f:33:1e:4c:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 1,\n // utm: \"POINT(737042.364022823 9549078.80533948)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:10\",\n // mac: \"c4:4f:33:1d:a8:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 10,\n // utm: \"POINT(737147.360473461 9549211.4765909)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:11\",\n // mac: \"c4:4f:33:1e:42:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 11,\n // utm: \"POINT(737159.128899483 9549225.72442947)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:12\",\n // mac: \"c4:4f:33:23:66:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 12,\n // utm: \"POINT(737170.805405639 9549240.41634091)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:13\",\n // mac: \"c4:4f:33:23:65:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 13,\n // utm: \"POINT(737184.79976326 9549258.50410619)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:14\",\n // mac: \"c4:4f:33:23:61:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 14,\n // utm: \"POINT(737195.864463609 9549274.16044773)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:15\",\n // mac: \"c4:4f:33:1e:b3:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 15,\n // utm: \"POINT(737207.964757872 9549287.15288738)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:16\",\n // mac: \"c4:4f:33:1e:b4:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 16,\n // utm: \"POINT(737219.026984895 9549301.92020778)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:17\",\n // mac: \"c4:4f:33:23:d3:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 17,\n // utm: \"POINT(737232.030418279 9549318.45667714)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:2\",\n // mac: \"c4:4f:33:23:60:4d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 2,\n // utm: \"POINT(737054.04049542 9549093.49724649)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:3\",\n // mac: \"24:0a:c4:50:e8:30\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 3,\n // utm: \"POINT(737065.716971368 9549108.18915394)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:4\",\n // mac: \"c4:4f:33:23:cb:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 4,\n // utm: \"POINT(737077.393450566 9549122.88106183)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:5\",\n // mac: \"c4:4f:33:23:68:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 5,\n // utm: \"POINT(737089.069933229 9549137.57297017)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:6\",\n // mac: \"24:0a:c4:50:fc:88\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 6,\n // utm: \"POINT(737100.746419253 9549152.26487895)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:7\",\n // mac: \"c4:4f:33:1e:c0:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 7,\n // utm: \"POINT(737112.422908519 9549166.95678817)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:8\",\n // mac: \"c4:4f:33:1d:b5:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 8,\n // utm: \"POINT(737124.099401254 9549181.64869783)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P29S:9\",\n // mac: \"c4:4f:33:23:68:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P29S\",\n // position: 9,\n // utm: \"POINT(737135.775897345 9549196.34060794)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:1\",\n // mac: \"4c:11:ae:b7:f4:f0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 1,\n // utm: \"POINT(737345.898972998 9549510.52751348)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:10\",\n // mac: \"24:0a:c4:50:d4:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 10,\n // utm: \"POINT(737235.444881403 9549368.82814027)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:11\",\n // mac: \"c4:4f:33:23:af:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 11,\n // utm: \"POINT(737222.887204242 9549351.70348722)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:12\",\n // mac: \"c4:4f:33:23:62:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 12,\n // utm: \"POINT(737209.73347299 9549336.2716484)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:13\",\n // mac: \"c4:4f:33:23:af:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 13,\n // utm: \"POINT(737195.983649435 9549319.142834)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:14\",\n // mac: \"4c:11:ae:b7:fd:44\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 14,\n // utm: \"POINT(737184.027825992 9549304.38231936)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:15\",\n // mac: \"24:0a:c4:50:c7:f4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 15,\n // utm: \"POINT(737170.276454501 9549286.66186384)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:16\",\n // mac: \"c4:4f:33:23:63:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 16,\n // utm: \"POINT(737156.523521936 9549268.35065274)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:17\",\n // mac: \"c4:4f:33:23:af:61\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 17,\n // utm: \"POINT(737143.37268242 9549252.40445897)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:2\",\n // mac: \"4c:11:ae:b7:fb:d4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 2,\n // utm: \"POINT(737335.586632228 9549497.66717741)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:3\",\n // mac: \"24:0a:c4:51:0d:bc\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 3,\n // utm: \"POINT(737324.224851637 9549482.30851223)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:4\",\n // mac: \"24:0a:c4:51:0e:e0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 4,\n // utm: \"POINT(737311.673814794 9549467.39734225)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:5\",\n // mac: \"4c:11:ae:b7:fc:28\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 5,\n // utm: \"POINT(737299.716291223 9549451.44877051)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:6\",\n // mac: \"c4:4f:33:23:cd:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 6,\n // utm: \"POINT(737287.459326903 9549434.6132781)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:7\",\n // mac: \"c4:4f:33:1d:81:35\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 7,\n // utm: \"POINT(737273.714776622 9549419.55731271)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:8\",\n // mac: \"c4:4f:33:23:70:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 8,\n // utm: \"POINT(737260.262126118 9549401.83680001)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30N:9\",\n // mac: \"24:0a:c4:51:0e:94\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30N\",\n // position: 9,\n // utm: \"POINT(737247.407051169 9549385.00228075)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P30S:1\",\n // mac: \"c4:4f:33:23:ce:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P30S\",\n // position: 1,\n // utm: \"POINT(737020.524678415 9549100.57755379)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:1\",\n // mac: \"b4:e6:2d:98:f1:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 1,\n // utm: \"POINT(737322.558120816 9549527.88630403)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:10\",\n // mac: \"4c:11:ae:b7:f5:84\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 10,\n // utm: \"POINT(737210.464971602 9549387.76177275)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:11\",\n // mac: \"c4:4f:33:23:69:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 11,\n // utm: \"POINT(737195.937542017 9549368.24334667)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:12\",\n // mac: \"c4:4f:33:23:b0:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 12,\n // utm: \"POINT(737182.028572589 9549349.95223524)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:13\",\n // mac: \"c4:4f:33:1d:7a:4d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 13,\n // utm: \"POINT(737169.759129487 9549334.88959152)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:14\",\n // mac: \"c4:4f:33:23:ce:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 14,\n // utm: \"POINT(737160.181136473 9549322.48311005)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:15\",\n // mac: \"24:0a:c4:50:d0:08\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 15,\n // utm: \"POINT(737148.810000252 9549308.89686603)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:16\",\n // mac: \"c4:4f:33:1e:a6:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 16,\n // utm: \"POINT(737137.52985719 9549295.91909928)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:17\",\n // mac: \"24:0a:c4:50:ce:fc\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 17,\n // utm: \"POINT(737126.172052486 9549282.0401022)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:18\",\n // mac: \"c4:4f:33:23:67:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 18,\n // utm: \"POINT(737113.021082348 9549265.79841078)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:2\",\n // mac: \"c4:4f:33:23:68:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 2,\n // utm: \"POINT(737312.845098712 9549516.37087325)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:3\",\n // mac: \"24:0a:c4:50:ff:78\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 3,\n // utm: \"POINT(737301.6362172 9549502.49173768)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:4\",\n // mac: \"c4:4f:33:23:d4:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 4,\n // utm: \"POINT(737289.680180872 9549487.7263557)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:5\",\n // mac: \"c4:4f:33:23:7c:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 5,\n // utm: \"POINT(737277.422578186 9549471.62453432)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:6\",\n // mac: \"24:0a:c4:51:09:78\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 6,\n // utm: \"POINT(737265.169942704 9549457.44957935)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:7\",\n // mac: \"c4:4f:33:1e:a4:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 7,\n // utm: \"POINT(737253.213484084 9549442.39565746)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:8\",\n // mac: \"24:0a:c4:50:c6:d0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 8,\n // utm: \"POINT(737240.807056106 9549426.30142093)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31N:9\",\n // mac: \"24:0a:c4:50:c6:f0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31N\",\n // position: 9,\n // utm: \"POINT(737226.605254648 9549407.25107459)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P31S:1\",\n // mac: \"c4:4f:33:23:ae:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P31S\",\n // position: 1,\n // utm: \"POINT(736991.948454931 9549109.56814059)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:1\",\n // mac: \"b4:e6:2d:ac:88:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 1,\n // utm: \"POINT(737295.548251204 9549543.38233436)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:10\",\n // mac: \"c4:4f:33:23:65:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 10,\n // utm: \"POINT(737181.15127064 9549399.38122526)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:11\",\n // mac: \"c4:4f:33:23:57:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 11,\n // utm: \"POINT(737168.14548115 9549381.95537136)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:12\",\n // mac: \"c4:4f:33:23:61:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 12,\n // utm: \"POINT(737154.696345221 9549365.86241533)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:2\",\n // mac: \"c4:4f:33:23:ce:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 2,\n // utm: \"POINT(737283.230665486 9549527.25182542)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:3\",\n // mac: \"c4:4f:33:23:67:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 3,\n // utm: \"POINT(737271.125663805 9549512.48699768)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:4\",\n // mac: \"c4:4f:33:23:64:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 4,\n // utm: \"POINT(737259.019881339 9549497.42623676)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:5\",\n // mac: \"c4:4f:33:23:b0:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 5,\n // utm: \"POINT(737247.51151192 9549482.95577163)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:6\",\n // mac: \"c4:4f:33:23:64:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 6,\n // utm: \"POINT(737233.910644505 9549465.82741317)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:7\",\n // mac: \"24:0a:c4:51:14:10\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 7,\n // utm: \"POINT(737220.458349768 9549448.55069592)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:8\",\n // mac: \"c4:4f:33:23:72:c1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 8,\n // utm: \"POINT(736993.44580297 9549112.67172742)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32N:9\",\n // mac: \"24:0a:c4:50:ce:9c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32N\",\n // position: 9,\n // utm: \"POINT(737194.899903915 9549416.06527024)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:1\",\n // mac: \"c4:4f:33:1e:bf:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 1,\n // utm: \"POINT(736963.681755662 9549123.25659118)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:10\",\n // mac: \"c4:4f:33:23:ce:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 10,\n // utm: \"POINT(737078.745539239 9549269.3368951)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:11\",\n // mac: \"c4:4f:33:23:7c:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 11,\n // utm: \"POINT(737091.922265554 9549286.42200851)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:12\",\n // mac: \"4c:11:ae:b7:f5:e4\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 12,\n // utm: \"POINT(737106.271012178 9549304.73300551)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:13\",\n // mac: \"c4:4f:33:23:60:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 13,\n // utm: \"POINT(737117.927528047 9549318.90580263)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:15\",\n // mac: \"c4:4f:33:23:cb:65\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 15,\n // utm: \"POINT(737040.390908304 9549220.64345551)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:2\",\n // mac: \"c4:4f:33:23:cf:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 2,\n // utm: \"POINT(736976.466604304 9549139.48773386)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:3\",\n // mac: \"c4:4f:33:23:71:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 3,\n // utm: \"POINT(736989.251457095 9549155.71887709)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:4\",\n // mac: \"24:0a:c4:51:0e:34\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 4,\n // utm: \"POINT(737002.036313814 9549171.95002087)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:5\",\n // mac: \"c4:4f:33:23:70:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 5,\n // utm: \"POINT(737014.821174568 9549188.1811652)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:6\",\n // mac: \"4c:11:ae:b7:fd:90\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 6,\n // utm: \"POINT(737027.606039472 9549204.41231008)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:8\",\n // mac: \"c4:4f:33:23:ce:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 8,\n // utm: \"POINT(737053.175781281 9549236.87460149)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P32S:9\",\n // mac: \"4c:11:ae:b7:fd:3c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P32S\",\n // position: 9,\n // utm: \"POINT(737065.960658186 9549253.10574802)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P33S:1\",\n // mac: \"c4:4f:33:23:66:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P33S\",\n // position: 1,\n // utm: \"POINT(736938.103090818 9549139.30421456)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:1\",\n // mac: \"c4:4f:33:23:b0:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 1,\n // utm: \"POINT(736914.316433605 9549157.11563484)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:10\",\n // mac: \"24:0a:c4:50:d0:34\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 10,\n // utm: \"POINT(737001.730932691 9549316.06014216)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:11\",\n // mac: \"24:0a:c4:50:ca:c8\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 11,\n // utm: \"POINT(737016.375928801 9549333.8207469)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:12\",\n // mac: \"c4:4f:33:1d:ea:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 12,\n // utm: \"POINT(737030.426047618 9549351.84026822)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:13\",\n // mac: \"c4:4f:33:1c:ef:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 13,\n // utm: \"POINT(737041.780714009 9549367.50460028)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:15\",\n // mac: \"c4:4f:33:23:f0:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 15,\n // utm: \"POINT(737059.379635365 9549390.25902894)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:2\",\n // mac: \"c4:4f:33:23:71:39\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 2,\n // utm: \"POINT(736904.80474993 9549193.33582051)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:3\",\n // mac: \"c4:4f:33:23:ce:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 3,\n // utm: \"POINT(736916.986679712 9549209.06199254)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:4\",\n // mac: \"c4:4f:33:23:7c:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 4,\n // utm: \"POINT(736929.168613074 9549224.78816509)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:5\",\n // mac: \"c4:4f:33:1e:c0:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 5,\n // utm: \"POINT(736941.350550234 9549240.51433818)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:6\",\n // mac: \"c4:4f:33:23:cd:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 6,\n // utm: \"POINT(736953.532491084 9549256.24051181)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:7\",\n // mac: \"c4:4f:33:1e:ab:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 7,\n // utm: \"POINT(736965.714435621 9549271.96668597)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:8\",\n // mac: \"c4:4f:33:1c:fc:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 8,\n // utm: \"POINT(736977.896383734 9549287.69286066)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P35S:9\",\n // mac: \"c4:4f:33:1d:82:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P35S\",\n // position: 9,\n // utm: \"POINT(736990.078335645 9549303.41903589)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P36S:1\",\n // mac: \"c4:4f:33:23:66:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P36S\",\n // position: 1,\n // utm: \"POINT(736867.641735072 9549194.38703217)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:4f:a9\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:1\",\n // mac: \"b4:e6:2d:99:13:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 1,\n // utm: \"POINT(737648.803483946 9548638.17378631)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:10\",\n // mac: \"b4:e6:2d:98:9a:21\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 10,\n // utm: \"POINT(737746.273434936 9548762.248137)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:11\",\n // mac: \"b4:e6:2d:ab:e8:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 11,\n // utm: \"POINT(737757.103444039 9548776.03417798)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:12\",\n // mac: \"b4:e6:2d:99:10:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 12,\n // utm: \"POINT(737767.933455931 9548789.82021937)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:2\",\n // mac: \"b4:e6:2d:ac:46:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 2,\n // utm: \"POINT(737659.633466925 9548651.95982366)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:3\",\n // mac: \"b4:e6:2d:99:15:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 3,\n // utm: \"POINT(737670.4634527 9548665.74586142)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:4\",\n // mac: \"b4:e6:2d:ac:46:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 4,\n // utm: \"POINT(737681.293441488 9548679.53189958)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:5\",\n // mac: \"b4:e6:2d:ad:9f:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 5,\n // utm: \"POINT(737692.123433176 9548693.31793814)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:6\",\n // mac: \"b4:e6:2d:ac:46:39\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 6,\n // utm: \"POINT(737702.953427658 9548707.10397711)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:7\",\n // mac: \"b4:e6:2d:aa:fa:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 7,\n // utm: \"POINT(737713.783425153 9548720.89001648)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:8\",\n // mac: \"b4:e6:2d:99:13:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 8,\n // utm: \"POINT(737724.61342555 9548734.67605625)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4:9\",\n // mac: \"b4:e6:2d:ad:07:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4\",\n // position: 9,\n // utm: \"POINT(737735.443428734 9548748.46209642)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4N:1\",\n // mac: \"b4:e6:2d:98:9a:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4N\",\n // position: 1,\n // utm: \"POINT(737855.812833681 9548900.41482017)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4N:2\",\n // mac: \"b4:e6:2d:99:8f:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4N\",\n // position: 2,\n // utm: \"POINT(737844.902612536 9548886.5964581)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4N:3\",\n // mac: \"b4:e6:2d:ac:4d:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4N\",\n // position: 3,\n // utm: \"POINT(737833.99239433 9548872.77809644)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4N:4\",\n // mac: \"b4:e6:2d:98:a3:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4N\",\n // position: 4,\n // utm: \"POINT(737823.082178949 9548858.95973517)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4N:5\",\n // mac: \"b4:e6:2d:ad:8d:fd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4N\",\n // position: 5,\n // utm: \"POINT(737812.171966623 9548845.14137431)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4N:6\",\n // mac: \"b4:e6:2d:99:06:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4N\",\n // position: 6,\n // utm: \"POINT(737801.26175723 9548831.32301385)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P4N:7\",\n // mac: \"b4:e6:2d:ac:10:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"P4N\",\n // position: 7,\n // utm: \"POINT(737790.351550668 9548817.50465378)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:60:2c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:1\",\n // mac: \"b4:e6:2d:ad:8e:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 1,\n // utm: \"POINT(737607.60714985 9548635.25000945)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:10\",\n // mac: \"b4:e6:2d:98:f4:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 10,\n // utm: \"POINT(737719.012265393 9548776.66013098)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:11\",\n // mac: \"b4:e6:2d:aa:54:19\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 11,\n // utm: \"POINT(737731.390630538 9548792.37236931)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:12\",\n // mac: \"b4:e6:2d:ac:4c:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 12,\n // utm: \"POINT(737743.768999359 9548808.08460815)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:2\",\n // mac: \"b4:e6:2d:98:a3:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 2,\n // utm: \"POINT(737619.985480907 9548650.9622431)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:3\",\n // mac: \"b4:e6:2d:ab:fd:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 3,\n // utm: \"POINT(737632.363815641 9548666.67447727)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:4\",\n // mac: \"b4:e6:2d:98:a5:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 4,\n // utm: \"POINT(737644.742154271 9548682.38671195)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:5\",\n // mac: \"b4:e6:2d:98:f1:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 5,\n // utm: \"POINT(737657.120496695 9548698.09894716)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:6\",\n // mac: \"b4:e6:2d:aa:54:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 6,\n // utm: \"POINT(737669.498842793 9548713.81118288)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:7\",\n // mac: \"b4:e6:2d:98:fd:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 7,\n // utm: \"POINT(737681.87719279 9548729.52341913)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:8\",\n // mac: \"b4:e6:2d:ac:4d:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 8,\n // utm: \"POINT(737694.255546573 9548745.23565589)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5:9\",\n // mac: \"b4:e6:2d:ac:05:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5\",\n // position: 9,\n // utm: \"POINT(737706.633904034 9548760.94789318)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:1\",\n // mac: \"24:0a:c4:50:e7:18\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 1,\n // utm: \"POINT(737841.437150259 9548928.71507542)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:2\",\n // mac: \"b4:e6:2d:99:13:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 2,\n // utm: \"POINT(737831.875780752 9548918.23473773)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:3\",\n // mac: \"b4:e6:2d:ac:03:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 3,\n // utm: \"POINT(737819.622558541 9548903.76641014)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:4\",\n // mac: \"c4:4f:33:1d:d8:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 4,\n // utm: \"POINT(737806.171377562 9548886.93377512)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:5\",\n // mac: \"b4:e6:2d:ac:b2:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 5,\n // utm: \"POINT(737793.911878225 9548870.09797391)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:6\",\n // mac: \"b4:e6:2d:98:e7:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 6,\n // utm: \"POINT(737779.56541309 9548852.67585414)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:7\",\n // mac: \"24:0a:c4:50:d3:fc\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 7,\n // utm: \"POINT(737766.111074788 9548834.6594916)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P5N:8\",\n // mac: \"c4:4f:33:23:54:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"P5N\",\n // position: 8,\n // utm: \"POINT(737752.961688034 9548819.30575344)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:1\",\n // mac: \"b4:e6:2d:ac:46:65\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 1,\n // utm: \"POINT(737568.054820306 9548633.80152312)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:10\",\n // mac: \"b4:e6:2d:98:fd:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 10,\n // utm: \"POINT(737681.817650558 9548777.4191859)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:11\",\n // mac: \"b4:e6:2d:ab:c9:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 11,\n // utm: \"POINT(737694.457984774 9548793.37670664)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:12\",\n // mac: \"b4:e6:2d:aa:fa:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 12,\n // utm: \"POINT(737707.098322821 9548809.3342279)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:13\",\n // mac: \"b4:e6:2d:aa:fa:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 13,\n // utm: \"POINT(737719.738664918 9548825.2917497)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:14\",\n // mac: \"b4:e6:2d:98:a3:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 14,\n // utm: \"POINT(737732.379010957 9548841.24927202)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:15\",\n // mac: \"b4:e6:2d:ac:53:61\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 15,\n // utm: \"POINT(737745.019360824 9548857.20679488)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:2\",\n // mac: \"b4:e6:2d:98:f0:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 2,\n // utm: \"POINT(737580.695119048 9548649.75903909)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:3\",\n // mac: \"b4:e6:2d:ac:87:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 3,\n // utm: \"POINT(737593.335421731 9548665.71655559)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:4\",\n // mac: \"b4:e6:2d:ac:4c:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 4,\n // utm: \"POINT(737605.975728248 9548681.67407262)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:5\",\n // mac: \"b4:e6:2d:ac:48:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 5,\n // utm: \"POINT(737618.616038815 9548697.63159017)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:6\",\n // mac: \"b4:e6:2d:ad:96:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 6,\n // utm: \"POINT(737631.256353324 9548713.58910826)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:7\",\n // mac: \"b4:e6:2d:ad:8d:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 7,\n // utm: \"POINT(737643.896671666 9548729.54662688)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:8\",\n // mac: \"b4:e6:2d:ad:9e:65\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 8,\n // utm: \"POINT(737656.536994059 9548745.50414602)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6:9\",\n // mac: \"b4:e6:2d:ac:05:01\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6\",\n // position: 9,\n // utm: \"POINT(737669.177320393 9548761.4616657)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6N:1\",\n // mac: \"b4:e6:2d:98:a4:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6N\",\n // position: 1,\n // utm: \"POINT(737831.404775928 9548965.29002623)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6N:2\",\n // mac: \"b4:e6:2d:ac:57:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6N\",\n // position: 2,\n // utm: \"POINT(737819.677054514 9548952.29997662)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6N:3\",\n // mac: \"b4:e6:2d:ac:ad:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6N\",\n // position: 3,\n // utm: \"POINT(737806.969231911 9548934.94746129)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6N:4\",\n // mac: \"24:0a:c4:50:d0:9c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6N\",\n // position: 4,\n // utm: \"POINT(737795.836057962 9548921.58591393)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6N:5\",\n // mac: \"b4:e6:2d:ac:4f:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6N\",\n // position: 5,\n // utm: \"POINT(737785.074732456 9548908.00142704)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6N:6\",\n // mac: \"c4:4f:33:23:57:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6N\",\n // position: 6,\n // utm: \"POINT(737772.813672382 9548890.57374964)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P6N:7\",\n // mac: \"c4:4f:33:23:b0:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P6N\",\n // position: 7,\n // utm: \"POINT(737760.259528605 9548874.92247788)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:1\",\n // mac: \"b4:e6:2d:99:04:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 1,\n // utm: \"POINT(737542.69943543 9548649.7015065)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:10\",\n // mac: \"b4:e6:2d:ad:8d:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 10,\n // utm: \"POINT(737657.218373732 9548794.50942098)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:11\",\n // mac: \"b4:e6:2d:ac:4e:e1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 11,\n // utm: \"POINT(737669.942720131 9548810.59919196)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:12\",\n // mac: \"b4:e6:2d:ab:fc:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 12,\n // utm: \"POINT(737682.667070635 9548826.68896347)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:13\",\n // mac: \"b4:e6:2d:ac:4f:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 13,\n // utm: \"POINT(737695.391425025 9548842.77873553)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:14\",\n // mac: \"b4:e6:2d:98:fd:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 14,\n // utm: \"POINT(737708.115783518 9548858.86850813)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:15\",\n // mac: \"b4:e6:2d:98:f1:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 15,\n // utm: \"POINT(737720.840145898 9548874.95828127)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:2\",\n // mac: \"b4:e6:2d:ac:49:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 2,\n // utm: \"POINT(737555.42374597 9548665.79127261)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:3\",\n // mac: \"b4:e6:2d:ac:48:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 3,\n // utm: \"POINT(737568.148060397 9548681.88103927)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:4\",\n // mac: \"b4:e6:2d:a4:6b:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 4,\n // utm: \"POINT(737580.872378932 9548697.97080647)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:5\",\n // mac: \"b4:e6:2d:aa:54:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 5,\n // utm: \"POINT(737593.596701353 9548714.0605742)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:6\",\n // mac: \"b4:e6:2d:98:a8:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 6,\n // utm: \"POINT(737606.321027879 9548730.15034248)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:7\",\n // mac: \"b4:e6:2d:98:f1:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 7,\n // utm: \"POINT(737619.045358293 9548746.24011129)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:8\",\n // mac: \"b4:e6:2d:aa:54:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 8,\n // utm: \"POINT(737631.769692814 9548762.32988065)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7:9\",\n // mac: \"b4:e6:2d:ac:4d:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7\",\n // position: 9,\n // utm: \"POINT(737644.494031222 9548778.41965054)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7N:1\",\n // mac: \"b4:e6:2d:98:a7:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7N\",\n // position: 1,\n // utm: \"POINT(737819.877883941 9548999.79739861)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7N:2\",\n // mac: \"4c:11:ae:b7:fa:b0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7N\",\n // position: 2,\n // utm: \"POINT(737809.416463733 9548986.95194194)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7N:3\",\n // mac: \"24:0a:c4:50:e7:9c\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7N\",\n // position: 3,\n // utm: \"POINT(737797.160829556 9548971.59579156)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7N:4\",\n // mac: \"b4:e6:2d:98:f7:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7N\",\n // position: 4,\n // utm: \"POINT(737785.498629116 9548955.35025423)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7N:5\",\n // mac: \"c4:4f:33:23:a1:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7N\",\n // position: 5,\n // utm: \"POINT(737773.840574624 9548941.17627008)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7N:6\",\n // mac: \"c4:4f:33:23:ab:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7N\",\n // position: 6,\n // utm: \"POINT(737761.290895 9548926.70872262)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P7N:7\",\n // mac: \"b4:e6:2d:ad:8d:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P7N\",\n // position: 7,\n // utm: \"POINT(737748.431597286 9548908.39481918)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:1\",\n // mac: \"b4:e6:2d:99:13:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 1,\n // utm: \"POINT(737520.483829351 9548669.88420484)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:10\",\n // mac: \"b4:e6:2d:ac:46:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 10,\n // utm: \"POINT(737625.489889645 9548802.65157654)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:11\",\n // mac: \"b4:e6:2d:98:a8:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 11,\n // utm: \"POINT(737637.157246487 9548817.403509)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:12\",\n // mac: \"b4:e6:2d:ac:43:19\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 12,\n // utm: \"POINT(737648.824606693 9548832.15544191)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:13\",\n // mac: \"b4:e6:2d:99:13:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 13,\n // utm: \"POINT(737660.491970255 9548846.90737527)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:14\",\n // mac: \"b4:e6:2d:ac:8e:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 14,\n // utm: \"POINT(737672.159337177 9548861.6593091)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:15\",\n // mac: \"b4:e6:2d:99:10:65\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 15,\n // utm: \"POINT(737683.826707453 9548876.41124337)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:16\",\n // mac: \"b4:e6:2d:98:a2:35\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 16,\n // utm: \"POINT(737695.494081093 9548891.1631781)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:17\",\n // mac: \"b4:e6:2d:aa:54:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 17,\n // utm: \"POINT(737707.161457979 9548905.91511329)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:2\",\n // mac: \"b4:e6:2d:ac:4c:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 2,\n // utm: \"POINT(737532.151155959 9548684.63613321)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:3\",\n // mac: \"b4:e6:2d:ac:49:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 3,\n // utm: \"POINT(737543.818485922 9548699.38806204)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:4\",\n // mac: \"b4:e6:2d:ac:49:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 4,\n // utm: \"POINT(737555.485819247 9548714.13999132)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:5\",\n // mac: \"b4:e6:2d:98:e7:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 5,\n // utm: \"POINT(737567.153155933 9548728.89192106)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:6\",\n // mac: \"b4:e6:2d:99:13:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 6,\n // utm: \"POINT(737578.820495975 9548743.64385125)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:7\",\n // mac: \"b4:e6:2d:ad:8f:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 7,\n // utm: \"POINT(737590.487839383 9548758.39578189)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:8\",\n // mac: \"b4:e6:2d:ac:49:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 8,\n // utm: \"POINT(737602.155186036 9548773.14771299)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8:9\",\n // mac: \"b4:e6:2d:98:a6:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8\",\n // position: 9,\n // utm: \"POINT(737613.822536161 9548787.89964454)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:91:60:c5\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:1\",\n // mac: \"b4:e6:2d:99:10:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 1,\n // utm: \"POINT(737806.859291483 9549034.01280716)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:2\",\n // mac: \"b4:e6:2d:ac:4c:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 2,\n // utm: \"POINT(737796.136048229 9549018.35664092)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:3\",\n // mac: \"b4:e6:2d:98:a2:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 3,\n // utm: \"POINT(737783.773620903 9549002.85280304)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:4\",\n // mac: \"b4:e6:2d:ac:49:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 4,\n // utm: \"POINT(737771.411197448 9548987.34896565)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:5\",\n // mac: \"b4:e6:2d:99:11:f5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 5,\n // utm: \"POINT(737759.048777644 9548971.84512876)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:6\",\n // mac: \"b4:e6:2d:ac:46:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 6,\n // utm: \"POINT(737746.686361704 9548956.34129236)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:7\",\n // mac: \"b4:e6:2d:98:f7:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 7,\n // utm: \"POINT(737734.323949413 9548940.83745646)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P8N:8\",\n // mac: \"b4:e6:2d:ad:95:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P8N\",\n // position: 8,\n // utm: \"POINT(737721.96154088 9548925.33362104)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:ec:13\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:1\",\n // mac: \"b4:e6:2d:ac:0e:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 1,\n // utm: \"POINT(737496.998084973 9548688.73856103)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:10\",\n // mac: \"b4:e6:2d:ad:9b:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 10,\n // utm: \"POINT(737599.375516389 9548817.05072322)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:11\",\n // mac: \"b4:e6:2d:99:10:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 11,\n // utm: \"POINT(737611.334121924 9548832.70357138)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:12\",\n // mac: \"b4:e6:2d:99:04:75\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 12,\n // utm: \"POINT(737622.993079672 9548847.76534611)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:13\",\n // mac: \"b4:e6:2d:98:fd:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 13,\n // utm: \"POINT(737635.398022374 9548863.12107753)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:14\",\n // mac: \"b4:e6:2d:98:a8:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 14,\n // utm: \"POINT(737647.505677549 9548878.77353921)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:15\",\n // mac: \"b4:e6:2d:98:f3:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 15,\n // utm: \"POINT(737662.45373195 9548897.67375881)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:16\",\n // mac: \"b4:e6:2d:98:f7:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 16,\n // utm: \"POINT(737674.560215149 9548912.88232547)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:2\",\n // mac: \"b4:e6:2d:ad:8e:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 2,\n // utm: \"POINT(737509.850597577 9548704.53386491)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:3\",\n // mac: \"b4:e6:2d:99:04:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 3,\n // utm: \"POINT(737521.805085419 9548718.70735309)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9:4\",\n // mac: \"24:0a:c4:50:ff:b0\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9\",\n // position: 4,\n // utm: \"POINT(737533.424594372 9548733.03175829)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9N:1\",\n // mac: \"b4:e6:2d:98:8f:e9\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9N\",\n // position: 1,\n // utm: \"POINT(737795.328347425 9549065.41285793)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:P9N:2\",\n // mac: \"b4:e6:2d:ac:57:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"P9N\",\n // position: 2,\n // utm: \"POINT(737784.267071114 9549050.94132504)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:2d:56\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_E_P7_P10:11\",\n // mac: \"c4:4f:33:1d:9e:85\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_E_P7_P10\",\n // position: 11,\n // utm: \"POINT(737538.476258736 9548642.72666016)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_E_P7_P10:7\",\n // mac: \"c4:4f:33:23:64:55\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_E_P7_P10\",\n // position: 7,\n // utm: \"POINT(737509.519636954 9548671.69961654)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_E_P7_P10:9\",\n // mac: \"c4:4f:33:23:74:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_E_P7_P10\",\n // position: 9,\n // utm: \"POINT(737523.997950194 9548657.21314078)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:1\",\n // mac: \"c4:4f:33:23:b1:0d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 1,\n // utm: \"POINT(737674.998578471 9548630.1137785)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:10\",\n // mac: \"c4:4f:33:1e:b1:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 10,\n // utm: \"POINT(737733.094143964 9548686.48309042)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:11\",\n // mac: \"c4:4f:33:23:b0:65\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 11,\n // utm: \"POINT(737739.965162816 9548693.56780358)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:12\",\n // mac: \"c4:4f:33:23:64:1d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 12,\n // utm: \"POINT(737746.542203749 9548702.13285113)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:13\",\n // mac: \"c4:4f:33:23:64:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 13,\n // utm: \"POINT(737758.951091973 9548719.11826724)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:14\",\n // mac: \"c4:4f:33:23:65:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 14,\n // utm: \"POINT(737752.522617199 9548710.40374615)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:15\",\n // mac: \"24:0a:c4:50:c6:ac\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 15,\n // utm: \"POINT(737766.123998831 9548727.6787341)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:16\",\n // mac: \"c4:4f:33:23:b3:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 16,\n // utm: \"POINT(737773.447387131 9548736.83654088)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:17\",\n // mac: \"24:0a:c4:50:e8:00\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 17,\n // utm: \"POINT(737780.771194806 9548746.13944804)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:18\",\n // mac: \"c4:4f:33:23:b5:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 18,\n // utm: \"POINT(737787.795957111 9548754.99435855)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:19\",\n // mac: \"c4:4f:33:23:64:39\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 19,\n // utm: \"POINT(737796.162424909 9548764.29938224)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:2\",\n // mac: \"c4:4f:33:23:ca:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 2,\n // utm: \"POINT(737684.092048355 9548632.67898595)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:20\",\n // mac: \"c4:4f:33:23:a0:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 20,\n // utm: \"POINT(737801.996258859 9548773.45861483)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:21\",\n // mac: \"c4:4f:33:23:65:99\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 21,\n // utm: \"POINT(737809.469432326 9548782.90896717)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:3\",\n // mac: \"c4:4f:33:23:b3:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 3,\n // utm: \"POINT(737691.621380631 9548635.24767926)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:4\",\n // mac: \"c4:4f:33:1e:7b:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 4,\n // utm: \"POINT(737697.967499064 9548641.00112656)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:5\",\n // mac: \"24:0a:c4:50:ca:ac\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 5,\n // utm: \"POINT(737703.718562676 9548647.05206085)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:6\",\n // mac: \"c4:4f:33:23:66:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 6,\n // utm: \"POINT(737709.39830395 9548654.28738632)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:7\",\n // mac: \"c4:4f:33:23:b0:01\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 7,\n // utm: \"POINT(737715.676825891 9548662.63143429)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:8\",\n // mac: \"c4:4f:33:23:d1:05\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 8,\n // utm: \"POINT(737722.32774569 9548670.97423174)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_NE_Fringe:9\",\n // mac: \"c4:4f:33:23:d2:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_NE_Fringe\",\n // position: 9,\n // utm: \"POINT(737728.233094854 9548679.0234685)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:1\",\n // mac: \"c4:4f:33:1e:bf:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 1,\n // utm: \"POINT(737265.008711044 9548919.14906954)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:10\",\n // mac: \"4c:11:ae:b7:fb:0c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 10,\n // utm: \"POINT(737196.423688091 9548951.44013799)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:11\",\n // mac: \"24:0a:c4:50:f6:b0\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 11,\n // utm: \"POINT(737186.239801724 9548958.93954474)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:12\",\n // mac: \"24:0a:c4:50:f8:d4\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 12,\n // utm: \"POINT(737178.432000739 9548963.69523676)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:13\",\n // mac: \"24:0a:c4:51:0f:28\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 13,\n // utm: \"POINT(737170.773158472 9548968.45053279)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:14\",\n // mac: \"24:0a:c4:50:e7:70\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 14,\n // utm: \"POINT(737164.082747068 9548973.27724333)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:15\",\n // mac: \"c4:4f:33:23:69:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 15,\n // utm: \"POINT(737155.753586912 9548978.03431569)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:16\",\n // mac: \"4c:11:ae:b7:fa:88\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 16,\n // utm: \"POINT(737148.542994148 9548983.30630885)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:17\",\n // mac: \"c4:4f:33:23:ab:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 17,\n // utm: \"POINT(737141.181479328 9548987.83886087)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:18\",\n // mac: \"c4:4f:33:23:ab:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 18,\n // utm: \"POINT(737134.937550971 9548992.5164164)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:19\",\n // mac: \"c4:4f:33:23:8d:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 19,\n // utm: \"POINT(737129.218314839 9548998.45030914)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:2\",\n // mac: \"c4:4f:33:1e:af:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 2,\n // utm: \"POINT(737257.122116168 9548922.27733007)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:20\",\n // mac: \"c4:4f:33:23:ab:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 20,\n // utm: \"POINT(737123.346979639 9549003.20085968)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:21\",\n // mac: \"c4:4f:33:1e:a8:2d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 21,\n // utm: \"POINT(737116.65676015 9549008.10154935)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:22\",\n // mac: \"24:0a:c4:50:da:b4\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 22,\n // utm: \"POINT(737109.596692145 9549013.96501206)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:3\",\n // mac: \"c4:4f:33:1e:ae:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 3,\n // utm: \"POINT(737248.343139882 9548925.92584626)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:4\",\n // mac: \"c4:4f:33:23:c3:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 4,\n // utm: \"POINT(737240.157840668 9548928.75896132)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:5\",\n // mac: \"c4:4f:33:1e:bb:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 5,\n // utm: \"POINT(737231.97371916 9548932.03597668)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:6\",\n // mac: \"4c:11:ae:b7:fa:40\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 6,\n // utm: \"POINT(737223.865451123 9548935.83067825)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:7\",\n // mac: \"c4:4f:33:23:a3:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 7,\n // utm: \"POINT(737215.980425318 9548939.55080251)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:8\",\n // mac: \"4c:11:ae:b7:fb:c4\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 8,\n // utm: \"POINT(737207.875885984 9548944.75118949)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P20_P26:9\",\n // mac: \"c4:4f:33:23:ae:35\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P20_P26\",\n // position: 9,\n // utm: \"POINT(737201.258583318 9548949.05982115)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:1\",\n // mac: \"c4:4f:33:1e:a4:11\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 1,\n // utm: \"POINT(737106.477963303 9549017.52451721)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:10\",\n // mac: \"c4:4f:33:23:58:b1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 10,\n // utm: \"POINT(737034.769057576 9549079.56531033)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:11\",\n // mac: \"c4:4f:33:23:61:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 11,\n // utm: \"POINT(737025.999641092 9549086.83949147)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:12\",\n // mac: \"4c:11:ae:b7:fd:18\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 12,\n // utm: \"POINT(737018.566562794 9549092.48218943)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:13\",\n // mac: \"c4:4f:33:23:69:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 13,\n // utm: \"POINT(737011.352470068 9549096.42175891)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:14\",\n // mac: \"c4:4f:33:23:67:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 14,\n // utm: \"POINT(737004.358831072 9549099.25168758)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:15\",\n // mac: \"24:0a:c4:50:cf:5c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 15,\n // utm: \"POINT(736992.677083363 9549103.64782866)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:16\",\n // mac: \"c4:4f:33:1e:bd:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 16,\n // utm: \"POINT(736988.063858952 9549105.36156217)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:17\",\n // mac: \"c4:4f:33:23:71:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 17,\n // utm: \"POINT(736979.583370369 9549109.23120543)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:18\",\n // mac: \"c4:4f:33:23:8d:b5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 18,\n // utm: \"POINT(736971.323772183 9549112.1384692)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:19\",\n // mac: \"24:0a:c4:50:e7:84\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 19,\n // utm: \"POINT(736962.989302146 9549114.89796219)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:2\",\n // mac: \"c4:4f:33:1c:fc:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 2,\n // utm: \"POINT(737098.972867963 9549024.05277005)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:20\",\n // mac: \"4c:11:ae:b7:f9:ac\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 20,\n // utm: \"POINT(736955.405508637 9549119.87498824)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:21\",\n // mac: \"c4:4f:33:1d:72:41\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 21,\n // utm: \"POINT(736948.566903189 9549124.99800755)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:22\",\n // mac: \"4c:11:ae:b7:f6:10\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 22,\n // utm: \"POINT(736941.729276901 9549130.4909441)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:23\",\n // mac: \"24:0a:c4:51:09:64\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 23,\n // utm: \"POINT(736934.890866073 9549135.6879457)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:24\",\n // mac: \"4c:11:ae:b7:f6:54\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 24,\n // utm: \"POINT(736927.978366746 9549141.0331111)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:25\",\n // mac: \"4c:11:ae:b7:f8:18\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 25,\n // utm: \"POINT(736919.951415159 9549147.41700509)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:26\",\n // mac: \"24:0a:c4:50:c7:4c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 26,\n // utm: \"POINT(736913.78233941 9549152.24231134)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:27\",\n // mac: \"c4:4f:33:23:ab:79\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 27,\n // utm: \"POINT(736907.464695563 9549157.21597875)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:28\",\n // mac: \"24:0a:c4:51:09:60\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 28,\n // utm: \"POINT(736900.47771373 9549162.56133881)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:29\",\n // mac: \"c4:4f:33:23:ad:09\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 29,\n // utm: \"POINT(736893.416447465 9549167.98087903)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:3\",\n // mac: \"c4:4f:33:23:55:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 3,\n // utm: \"POINT(737089.386091619 9549032.07071405)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:30\",\n // mac: \"4c:11:ae:b7:f6:f4\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 30,\n // utm: \"POINT(736889.477645296 9549171.2466106)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:4\",\n // mac: \"24:0a:c4:50:f8:e0\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 4,\n // utm: \"POINT(737078.015615006 9549041.49683758)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:5\",\n // mac: \"c4:4f:33:23:a9:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 5,\n // utm: \"POINT(737067.537911498 9549050.55067229)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:6\",\n // mac: \"c4:4f:33:23:57:51\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 6,\n // utm: \"POINT(737060.924715515 9549056.41294581)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:7\",\n // mac: \"24:0a:c4:50:cb:f8\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 7,\n // utm: \"POINT(737054.31151861 9549062.27521876)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:8\",\n // mac: \"24:0a:c4:50:db:3c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 8,\n // utm: \"POINT(737047.103660306 9549068.5829719)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_P26_P32:9\",\n // mac: \"24:0a:c4:50:e7:14\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_P26_P32\",\n // position: 9,\n // utm: \"POINT(737039.597686189 9549074.81753041)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:1\",\n // mac: \"24:0a:c4:50:ce:f8\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 1,\n // utm: \"POINT(737480.618532508 9548690.98714319)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:10\",\n // mac: \"c4:4f:33:23:5f:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 10,\n // utm: \"POINT(737429.143595557 9548715.55226103)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:11\",\n // mac: \"c4:4f:33:23:ce:19\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 11,\n // utm: \"POINT(737425.733659943 9548721.62846295)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:12\",\n // mac: \"c4:4f:33:23:60:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 12,\n // utm: \"POINT(737422.32293764 9548727.40925252)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:13\",\n // mac: \"c4:4f:33:23:60:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 13,\n // utm: \"POINT(737418.911814697 9548733.0407064)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:14\",\n // mac: \"c4:4f:33:23:60:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 14,\n // utm: \"POINT(737416.172381008 9548739.18894813)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:15\",\n // mac: \"24:0a:c4:50:e8:18\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 15,\n // utm: \"POINT(737418.576955124 9548747.17263529)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:16\",\n // mac: \"c4:4f:33:23:b6:c5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 16,\n // utm: \"POINT(737423.806581931 9548753.22692887)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:17\",\n // mac: \"24:0a:c4:50:fc:48\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 17,\n // utm: \"POINT(737429.776738041 9548757.64919576)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:18\",\n // mac: \"c4:4f:33:23:70:a5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 18,\n // utm: \"POINT(737436.337427932 9548760.07196708)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:2\",\n // mac: \"24:0a:c4:51:08:f8\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 2,\n // utm: \"POINT(737474.79931873 9548687.31801032)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:3\",\n // mac: \"4c:11:ae:b7:f8:14\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 3,\n // utm: \"POINT(737468.681737384 9548683.48742804)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:4\",\n // mac: \"c4:4f:33:23:65:59\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 4,\n // utm: \"POINT(737461.675589824 9548681.58200788)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:5\",\n // mac: \"c4:4f:33:23:60:fd\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 5,\n // utm: \"POINT(737453.636086021 9548683.22854268)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:6\",\n // mac: \"c4:4f:33:23:71:dd\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 6,\n // utm: \"POINT(737447.099602511 9548689.90505514)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:7\",\n // mac: \"c4:4f:33:23:70:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 7,\n // utm: \"POINT(737441.45922593 9548697.46744978)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:8\",\n // mac: \"4c:11:ae:b7:f2:f0\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 8,\n // utm: \"POINT(737436.860376166 9548704.58297743)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp_Undercut_SVD:9\",\n // mac: \"c4:4f:33:23:60:8d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp_Undercut_SVD\",\n // position: 9,\n // utm: \"POINT(737433.301087655 9548710.51134758)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:1\",\n // mac: \"24:0a:c4:50:da:ec\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 1,\n // utm: \"POINT(737189.516288712 9548949.38952141)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:15\",\n // mac: \"b4:e6:2d:98:a7:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 15,\n // utm: \"POINT(737232.41937479 9548905.55350354)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:17\",\n // mac: \"b4:e6:2d:99:04:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 17,\n // utm: \"POINT(737238.547965093 9548915.22478154)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:2\",\n // mac: \"24:0a:c4:50:e7:a4\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 2,\n // utm: \"POINT(737182.625536878 9548943.03913759)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:3\",\n // mac: \"b4:e6:2d:98:f7:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 3,\n // utm: \"POINT(737177.217569947 9548933.89495666)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:4\",\n // mac: \"4c:11:ae:b7:fc:b8\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 4,\n // utm: \"POINT(737178.357145975 9548906.21145762)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:5\",\n // mac: \"24:0a:c4:51:08:c8\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 5,\n // utm: \"POINT(737189.128003197 9548896.56333806)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:6\",\n // mac: \"24:0a:c4:50:db:9c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 6,\n // utm: \"POINT(737203.036035088 9548890.31177896)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:7\",\n // mac: \"24:0a:c4:50:e4:88\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 7,\n // utm: \"POINT(737184.242154845 9548902.96982418)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:8\",\n // mac: \"24:0a:c4:51:1e:e0\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 8,\n // utm: \"POINT(737228.687445201 9548902.08385975)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_Ramp:9\",\n // mac: \"b4:e6:2d:99:8f:49\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_Ramp\",\n // position: 9,\n // utm: \"POINT(737194.78167896 9548893.92130606)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:10\",\n // mac: \"4c:11:ae:b7:f5:20\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 10,\n // utm: \"POINT(737415.361986095 9548798.60094458)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:11\",\n // mac: \"4c:11:ae:b7:f3:4c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 11,\n // utm: \"POINT(737410.021868225 9548807.04989585)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:12\",\n // mac: \"c4:4f:33:23:b6:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 12,\n // utm: \"POINT(737405.127406973 9548815.05128226)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:13\",\n // mac: \"c4:4f:33:23:66:f9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 13,\n // utm: \"POINT(737400.97777318 9548823.0529717)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:3\",\n // mac: \"c4:4f:33:1e:a4:f5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 3,\n // utm: \"POINT(737452.000007964 9548740.20355202)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:5\",\n // mac: \"c4:4f:33:1e:af:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 5,\n // utm: \"POINT(737447.40350411 9548748.20623287)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:7\",\n // mac: \"c4:4f:33:23:b0:d5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 7,\n // utm: \"POINT(737431.679476554 9548772.95788635)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_W_P11_P20:9\",\n // mac: \"c4:4f:33:1e:a7:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_W_P11_P20\",\n // position: 9,\n // utm: \"POINT(737420.553926147 9548790.44786672)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:1\",\n // mac: \"b4:e6:2d:ac:27:69\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 1,\n // utm: \"POINT(737495.041318902 9548686.18608745)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:10\",\n // mac: \"b4:e6:2d:99:11:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 10,\n // utm: \"POINT(737516.758794161 9548664.45637926)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:11\",\n // mac: \"b4:e6:2d:ad:96:09\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 11,\n // utm: \"POINT(737502.280478461 9548678.9428526)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:12\",\n // mac: \"b4:e6:2d:98:9a:71\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 12,\n // utm: \"POINT(737487.802158173 9548693.42932108)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:13\",\n // mac: \"b4:e6:2d:ac:05:29\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 13,\n // utm: \"POINT(737480.562996271 9548700.6725535)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:14\",\n // mac: \"b4:e6:2d:ac:be:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 14,\n // utm: \"POINT(737466.084668934 9548715.15901469)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:15\",\n // mac: \"b4:e6:2d:ac:4f:b9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 15,\n // utm: \"POINT(737456.968703298 9548732.12557233)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:16\",\n // mac: \"b4:e6:2d:ac:e6:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 16,\n // utm: \"POINT(737442.657644635 9548756.06088629)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:17\",\n // mac: \"b4:e6:2d:ac:b4:61\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 17,\n // utm: \"POINT(737437.613870313 9548763.91678744)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:18\",\n // mac: \"b4:e6:2d:ad:9a:95\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 18,\n // utm: \"POINT(737426.488309028 9548781.40579034)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:2\",\n // mac: \"b4:e6:2d:98:a2:7d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 2,\n // utm: \"POINT(737473.323833188 9548707.91578471)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:20\",\n // mac: \"b4:e6:2d:98:fd:31\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 20,\n // utm: \"POINT(737411.371904878 9548810.59578394)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:21\",\n // mac: \"b4:e6:2d:ac:4f:6d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 21,\n // utm: \"POINT(737402.177385856 9548826.00888675)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:22\",\n // mac: \"b4:e6:2d:ac:fb:3d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 22,\n // utm: \"POINT(737392.23719676 9548841.27600177)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:23\",\n // mac: \"b4:e6:2d:ad:95:d9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 23,\n // utm: \"POINT(737383.487427985 9548855.80011453)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:24\",\n // mac: \"b4:e6:2d:ac:3b:25\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 24,\n // utm: \"POINT(737372.652296483 9548870.62570102)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:25\",\n // mac: \"b4:e6:2d:98:a6:09\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 25,\n // utm: \"POINT(737358.379323661 9548880.57746567)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:26\",\n // mac: \"b4:e6:2d:98:f3:e5\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 26,\n // utm: \"POINT(737342.308609667 9548887.13073291)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:27\",\n // mac: \"b4:e6:2d:ac:24:45\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 27,\n // utm: \"POINT(737325.492630286 9548893.39003869)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:28\",\n // mac: \"b4:e6:2d:ad:9a:a1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 28,\n // utm: \"POINT(737310.465578111 9548900.08849619)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:29\",\n // mac: \"b4:e6:2d:ad:8d:ed\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 29,\n // utm: \"POINT(737293.202873383 9548906.49694829)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:3\",\n // mac: \"b4:e6:2d:98:f1:5d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 3,\n // utm: \"POINT(737624.044781711 9548626.55010181)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:30\",\n // mac: \"b4:e6:2d:98:fd:15\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 30,\n // utm: \"POINT(737276.539309913 9548913.93958296)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:4\",\n // mac: \"b4:e6:2d:ac:be:09\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 4,\n // utm: \"POINT(737605.718837995 9548625.11916085)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:5\",\n // mac: \"b4:e6:2d:98:a3:a9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 5,\n // utm: \"POINT(737587.097397552 9548624.57746168)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:6\",\n // mac: \"b4:e6:2d:ac:64:9d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 6,\n // utm: \"POINT(737568.926378881 9548625.3650339)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:7\",\n // mac: \"b4:e6:2d:ac:85:91\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 7,\n // utm: \"POINT(737553.153435186 9548631.62475414)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:93:43\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:8\",\n // mac: \"b4:e6:2d:ac:57:bd\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 8,\n // utm: \"POINT(737545.715411245 9548635.48341802)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SFD_West:9\",\n // mac: \"b4:e6:2d:98:f1:ad\",\n // area: \"DMLZ_Extraction\",\n // location: \"SFD_West\",\n // position: 9,\n // utm: \"POINT(737531.237105052 9548649.96990107)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:1\",\n // mac: \"c4:4f:33:23:d0:f1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 1,\n // utm: \"POINT(737521.21278378 9549056.3743305)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:11\",\n // mac: \"c4:4f:33:23:d3:cd\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 11,\n // utm: \"POINT(737588.164583294 9548801.95644895)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:12\",\n // mac: \"c4:4f:33:23:61:81\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 12,\n // utm: \"POINT(737577.102291937 9548787.1945862)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:13\",\n // mac: \"24:0a:c4:50:cc:c0\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 13,\n // utm: \"POINT(737532.872442026 9549071.73939704)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:15\",\n // mac: \"c4:4f:33:1e:b9:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 15,\n // utm: \"POINT(737130.705548261 9549334.70458965)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:e4:60\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:17\",\n // mac: \"c4:4f:33:23:69:89\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 17,\n // utm: \"POINT(737566.936106649 9548773.31782025)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:18\",\n // mac: \"24:0a:c4:50:e7:8c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 18,\n // utm: \"POINT(737494.609805587 9549021.67342169)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:2\",\n // mac: \"c4:4f:33:1e:b4:c9\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 2,\n // utm: \"POINT(737461.861746454 9548723.60441113)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"1c:ba:8c:e3:21:a3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:3\",\n // mac: \"24:0a:c4:51:0e:a8\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 3,\n // utm: \"POINT(737207.454508286 9549431.86466985)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:54:03:af\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:4\",\n // mac: \"24:0a:c4:50:ff:84\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 4,\n // utm: \"POINT(737544.817835094 9548746.16069361)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:5\",\n // mac: \"c4:4f:33:23:6c:4d\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 5,\n // utm: \"POINT(737476.751283875 9548805.2436603)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:6\",\n // mac: \"24:0a:c4:50:d2:0c\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 6,\n // utm: \"POINT(737466.587459559 9548792.24980371)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:SVD_FW1:8\",\n // mac: \"c4:4f:33:23:5f:d1\",\n // area: \"DMLZ_Extraction\",\n // location: \"SVD_FW1\",\n // position: 8,\n // utm: \"POINT(737556.774636084 9548761.21599568)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:d6:49\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Extraction:UCL_SFD:2\",\n // mac: \"c4:4f:33:23:d7:35\",\n // area: \"DMLZ_Extraction\",\n // location: \"UCL_SFD\",\n // position: 2,\n // utm: \"POINT(737235.339111852 9548910.65223104)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:db\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD-31:1\",\n // mac: \"c4:4f:33:23:ab:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD-31\",\n // position: 1,\n // utm: \"POINT(737311.308733989 9549554.92131627)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD-31:2\",\n // mac: \"c4:4f:33:23:61:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD-31\",\n // position: 2,\n // utm: \"POINT(737299.051106448 9549538.7527077)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD-31:3\",\n // mac: \"c4:4f:33:1e:ab:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD-31\",\n // position: 3,\n // utm: \"POINT(737286.792483992 9549522.21398816)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD-31:4\",\n // mac: \"c4:4f:33:23:af:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD-31\",\n // position: 4,\n // utm: \"POINT(737273.042515775 9549505.08346224)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD-31:5\",\n // mac: \"c4:4f:33:23:60:61\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD-31\",\n // position: 5,\n // utm: \"POINT(737258.395790608 9549486.77428475)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD-32:1\",\n // mac: \"24:0a:c4:50:ca:44\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD-32\",\n // position: 1,\n // utm: \"POINT(737281.994984306 9549566.61784608)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:1\",\n // mac: \"b4:e6:2d:98:f3:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 1,\n // utm: \"POINT(737492.448939011 9548714.49707967)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:10\",\n // mac: \"b4:e6:2d:98:a2:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 10,\n // utm: \"POINT(737596.5088707 9548849.03699112)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:11\",\n // mac: \"b4:e6:2d:ac:4f:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 11,\n // utm: \"POINT(737608.071102025 9548863.98587261)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:12\",\n // mac: \"c4:4f:33:23:68:61\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 12,\n // utm: \"POINT(737619.633336566 9548878.93475459)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:13\",\n // mac: \"c4:4f:33:23:61:99\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 13,\n // utm: \"POINT(737629.289818201 9548638.37235198)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:14\",\n // mac: \"c4:4f:33:1e:bc:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 14,\n // utm: \"POINT(737654.498540845 9548651.32785758)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:15\",\n // mac: \"c4:4f:33:23:72:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 15,\n // utm: \"POINT(737598.149806244 9548635.64560121)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:17\",\n // mac: \"c4:4f:33:23:67:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 17,\n // utm: \"POINT(737683.199480717 9548689.13167071)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:2\",\n // mac: \"b4:e6:2d:99:11:e1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 2,\n // utm: \"POINT(737504.011140398 9548729.44595677)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:3\",\n // mac: \"b4:e6:2d:ac:1d:21\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 3,\n // utm: \"POINT(737515.573345 9548744.39483436)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:4\",\n // mac: \"b4:e6:2d:ad:96:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 4,\n // utm: \"POINT(737527.135553039 9548759.34371243)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:5\",\n // mac: \"b4:e6:2d:aa:55:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 5,\n // utm: \"POINT(737538.697764297 9548774.29259099)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:6\",\n // mac: \"b4:e6:2d:ad:8e:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 6,\n // utm: \"POINT(737550.25997899 9548789.24147004)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:7\",\n // mac: \"b4:e6:2d:99:6e:0d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 7,\n // utm: \"POINT(737561.822196903 9548804.19034958)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:8\",\n // mac: \"b4:e6:2d:98:a3:95\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 8,\n // utm: \"POINT(737573.384418249 9548819.1392296)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10E:9\",\n // mac: \"b4:e6:2d:ac:49:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10E\",\n // position: 9,\n // utm: \"POINT(737584.946642808 9548834.08811012)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD10W:1\",\n // mac: \"b4:e6:2d:98:a4:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD10W\",\n // position: 1,\n // utm: \"POINT(737477.473423686 9548740.87518303)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:1\",\n // mac: \"b4:e6:2d:98:f2:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 1,\n // utm: \"POINT(737474.199785578 9548742.06762629)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:10\",\n // mac: \"b4:e6:2d:ad:9a:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 10,\n // utm: \"POINT(737578.678660554 9548875.96015823)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:11\",\n // mac: \"b4:e6:2d:99:8f:35\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 11,\n // utm: \"POINT(737590.287441237 9548890.8371086)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:12\",\n // mac: \"b4:e6:2d:aa:fb:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 12,\n // utm: \"POINT(737601.896225154 9548905.71405945)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:13\",\n // mac: \"b4:e6:2d:99:08:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 13,\n // utm: \"POINT(737613.505012407 9548920.59101076)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:2\",\n // mac: \"b4:e6:2d:98:f1:49\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 2,\n // utm: \"POINT(737485.80853607 9548756.94457239)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:3\",\n // mac: \"b4:e6:2d:98:f2:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 3,\n // utm: \"POINT(737497.417289903 9548771.82151896)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:4\",\n // mac: \"b4:e6:2d:99:11:6d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 4,\n // utm: \"POINT(737509.026047192 9548786.698466)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:5\",\n // mac: \"b4:e6:2d:98:9b:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 5,\n // utm: \"POINT(737520.634807708 9548801.57541352)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:6\",\n // mac: \"b4:e6:2d:ad:40:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 6,\n // utm: \"POINT(737532.243571572 9548816.45236151)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:7\",\n // mac: \"b4:e6:2d:98:9a:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 7,\n // utm: \"POINT(737543.852338886 9548831.32930998)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:8\",\n // mac: \"b4:e6:2d:98:f0:e1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 8,\n // utm: \"POINT(737555.461109436 9548846.20625892)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11E:9\",\n // mac: \"b4:e6:2d:98:a4:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11E\",\n // position: 9,\n // utm: \"POINT(737567.069883321 9548861.08320834)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11W:1\",\n // mac: \"b4:e6:2d:98:f1:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11W\",\n // position: 1,\n // utm: \"POINT(737459.6768733 9548770.66404761)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11W:2\",\n // mac: \"b4:e6:2d:ac:86:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11W\",\n // position: 2,\n // utm: \"POINT(737471.779918187 9548784.68885733)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11W:3\",\n // mac: \"b4:e6:2d:98:f5:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11W\",\n // position: 3,\n // utm: \"POINT(737490.405410471 9548786.56295281)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11W:4\",\n // mac: \"b4:e6:2d:ac:81:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11W\",\n // position: 4,\n // utm: \"POINT(737502.510270314 9548801.32760045)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD11W:5\",\n // mac: \"b4:e6:2d:99:a5:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD11W\",\n // position: 5,\n // utm: \"POINT(737514.317921959 9548816.3889771)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12E:1\",\n // mac: \"b4:e6:2d:98:a5:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12E\",\n // position: 1,\n // utm: \"POINT(737459.858312503 9548776.87822426)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12E:2\",\n // mac: \"b4:e6:2d:98:4d:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12E\",\n // position: 2,\n // utm: \"POINT(737470.900558548 9548789.87007717)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12E:3\",\n // mac: \"b4:e6:2d:99:11:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12E\",\n // position: 3,\n // utm: \"POINT(737482.844032623 9548799.9001751)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12E:4\",\n // mac: \"b4:e6:2d:ad:9b:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12E\",\n // position: 4,\n // utm: \"POINT(737494.951174908 9548815.40466097)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12E:5\",\n // mac: \"b4:e6:2d:ac:16:6d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12E\",\n // position: 5,\n // utm: \"POINT(737506.162122167 9548830.17169039)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12W:1\",\n // mac: \"b4:e6:2d:ac:53:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12W\",\n // position: 1,\n // utm: \"POINT(737442.914850934 9548797.19486584)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12W:2\",\n // mac: \"b4:e6:2d:ac:48:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12W\",\n // position: 2,\n // utm: \"POINT(737453.975412817 9548811.37042007)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD12W:3\",\n // mac: \"b4:e6:2d:99:03:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD12W\",\n // position: 3,\n // utm: \"POINT(737460.089584164 9548813.86963484)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13E:1\",\n // mac: \"b4:e6:2d:ac:db:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13E\",\n // position: 1,\n // utm: \"POINT(737443.042650899 9548803.40918624)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13E:2\",\n // mac: \"b4:e6:2d:ac:92:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13E\",\n // position: 2,\n // utm: \"POINT(737454.693340493 9548816.54739719)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"f0:45:da:83:01:44\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:1\",\n // mac: \"b4:e6:2d:98:a5:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 1,\n // utm: \"POINT(737718.722728348 9549163.86939567)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:10\",\n // mac: \"b4:e6:2d:ac:7b:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 10,\n // utm: \"POINT(737788.138316203 9549107.75054901)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:11\",\n // mac: \"c4:4f:33:1e:07:8d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 11,\n // utm: \"POINT(737795.71875971 9549101.51609242)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:12\",\n // mac: \"b4:e6:2d:98:a4:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 12,\n // utm: \"POINT(737801.961305119 9549096.3202576)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:13\",\n // mac: \"c4:4f:33:23:68:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 13,\n // utm: \"POINT(737807.754619359 9549090.23786859)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:14\",\n // mac: \"b4:e6:2d:ac:bd:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 14,\n // utm: \"POINT(737812.651808411 9549083.26998357)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:15\",\n // mac: \"c4:4f:33:1d:02:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 15,\n // utm: \"POINT(737816.061370693 9549077.04687628)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:16\",\n // mac: \"b4:e6:2d:99:8f:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 16,\n // utm: \"POINT(737819.464618611 9549068.45445897)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:17\",\n // mac: \"4c:11:ae:b7:f3:14\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 17,\n // utm: \"POINT(737822.56562844 9549058.23694828)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:18\",\n // mac: \"b4:e6:2d:98:94:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 18,\n // utm: \"POINT(737825.815987242 9549048.16622773)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:19\",\n // mac: \"c4:4f:33:23:cd:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 19,\n // utm: \"POINT(737828.916995783 9549037.94793618)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:2\",\n // mac: \"c4:4f:33:23:72:0d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 2,\n // utm: \"POINT(737726.896170156 9549156.59452427)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:20\",\n // mac: \"b4:e6:2d:ad:8f:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 20,\n // utm: \"POINT(737831.87221198 9549028.91573891)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:3\",\n // mac: \"b4:e6:2d:98:f7:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 3,\n // utm: \"POINT(737734.029727102 9549150.36021881)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:4\",\n // mac: \"c4:4f:33:23:5f:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 4,\n // utm: \"POINT(737740.719556783 9549145.31162555)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:5\",\n // mac: \"b4:e6:2d:ac:4e:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 5,\n // utm: \"POINT(737747.408614352 9549139.96781289)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:6\",\n // mac: \"c4:4f:33:1d:58:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 6,\n // utm: \"POINT(737755.881656844 9549133.2872115)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:7\",\n // mac: \"b4:e6:2d:ac:74:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 7,\n // utm: \"POINT(737765.544368081 9549125.86210298)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:8\",\n // mac: \"c4:4f:33:23:5f:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 8,\n // utm: \"POINT(737773.569736935 9549118.88681695)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13EN:9\",\n // mac: \"c4:4f:33:23:d1:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13EN\",\n // position: 9,\n // utm: \"POINT(737780.704173389 9549112.95137563)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:1\",\n // mac: \"b4:e6:2d:98:a7:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 1,\n // utm: \"POINT(737425.563365528 9548825.65083469)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:2\",\n // mac: \"b4:e6:2d:ac:48:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 2,\n // utm: \"POINT(737437.445704766 9548840.71202196)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:3\",\n // mac: \"b4:e6:2d:ac:57:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 3,\n // utm: \"POINT(737449.912640651 9548852.36839108)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:4\",\n // mac: \"c4:4f:33:23:9b:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 4,\n // utm: \"POINT(737469.140266799 9548856.01651861)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:5\",\n // mac: \"b4:e6:2d:99:8f:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 5,\n // utm: \"POINT(737479.905022655 9548870.93271189)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:6\",\n // mac: \"b4:e6:2d:ad:95:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 6,\n // utm: \"POINT(737492.010809323 9548885.99331389)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:7\",\n // mac: \"b4:e6:2d:98:a5:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 7,\n // utm: \"POINT(737504.114929476 9548900.38806595)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:8\",\n // mac: \"b4:e6:2d:ad:9c:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 8,\n // utm: \"POINT(737516.595771694 9548916.48345585)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13W:9\",\n // mac: \"b4:e6:2d:98:fd:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13W\",\n // position: 9,\n // utm: \"POINT(737527.510510777 9548931.76918391)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:1\",\n // mac: \"c4:4f:33:23:62:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 1,\n // utm: \"POINT(737708.611467603 9549170.70218472)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:10\",\n // mac: \"c4:4f:33:23:a9:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 10,\n // utm: \"POINT(737648.857667061 9549219.09803743)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:11\",\n // mac: \"c4:4f:33:23:55:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 11,\n // utm: \"POINT(737642.317179136 9549224.29504184)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:12\",\n // mac: \"c4:4f:33:23:54:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 12,\n // utm: \"POINT(737634.585080981 9549228.92458386)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:2\",\n // mac: \"c4:4f:33:23:a9:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 2,\n // utm: \"POINT(737702.36851456 9549175.74945718)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:3\",\n // mac: \"24:0a:c4:50:da:80\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 3,\n // utm: \"POINT(737696.720196156 9549180.35032974)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:4\",\n // mac: \"c4:4f:33:1e:bd:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 4,\n // utm: \"POINT(737690.924907208 9549185.6926755)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:5\",\n // mac: \"24:0a:c4:50:e6:e4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 5,\n // utm: \"POINT(737685.129612322 9549191.03508602)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:6\",\n // mac: \"24:0a:c4:50:e7:60\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 6,\n // utm: \"POINT(737679.483687959 9549196.52519856)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:7\",\n // mac: \"c4:4f:33:23:6a:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 7,\n // utm: \"POINT(737672.348942876 9549202.31487818)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:8\",\n // mac: \"24:0a:c4:50:e7:24\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 8,\n // utm: \"POINT(737665.063656911 9549207.51314643)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD13WN:9\",\n // mac: \"c4:4f:33:23:9b:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD13WN\",\n // position: 9,\n // utm: \"POINT(737657.036711257 9549213.89759208)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:1\",\n // mac: \"b4:e6:2d:99:11:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 1,\n // utm: \"POINT(737424.300701836 9548827.05988576)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:2\",\n // mac: \"b4:e6:2d:98:90:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 2,\n // utm: \"POINT(737436.106216072 9548841.23346855)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:3\",\n // mac: \"b4:e6:2d:98:a4:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 3,\n // utm: \"POINT(737449.631251282 9548857.84396152)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:4\",\n // mac: \"b4:e6:2d:98:a2:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 4,\n // utm: \"POINT(737461.288599476 9548872.31388011)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:5\",\n // mac: \"b4:e6:2d:ad:86:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 5,\n // utm: \"POINT(737472.945558056 9548886.63583426)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:6\",\n // mac: \"b4:e6:2d:98:a4:a5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 6,\n // utm: \"POINT(737485.348889345 9548901.5476816)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:7\",\n // mac: \"b4:e6:2d:ad:18:05\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 7,\n // utm: \"POINT(737496.111790536 9548915.72404804)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:8\",\n // mac: \"b4:e6:2d:98:fd:35\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 8,\n // utm: \"POINT(737506.873737075 9548929.60448303)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14E:9\",\n // mac: \"b4:e6:2d:98:a5:05\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14E\",\n // position: 9,\n // utm: \"POINT(737515.54093442 9548939.93924417)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD14W:1\",\n // mac: \"b4:e6:2d:ac:cb:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD14W\",\n // position: 1,\n // utm: \"POINT(737408.062401852 9548854.69907284)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD15E:1\",\n // mac: \"b4:e6:2d:ad:40:a5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD15E\",\n // position: 1,\n // utm: \"POINT(737410.291920713 9548852.76956551)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:4b:e3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD15W:1\",\n // mac: \"b4:e6:2d:aa:54:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD15W\",\n // position: 1,\n // utm: \"POINT(737391.442222656 9548878.71405378)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD15W:2\",\n // mac: \"b4:e6:2d:98:a8:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD15W\",\n // position: 2,\n // utm: \"POINT(737400.855022592 9548889.63870338)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD15W:3\",\n // mac: \"b4:e6:2d:98:f3:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD15W\",\n // position: 3,\n // utm: \"POINT(737418.888803167 9548892.10627093)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD15W:4\",\n // mac: \"b4:e6:2d:98:fd:0d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD15W\",\n // position: 4,\n // utm: \"POINT(737431.583439322 9548904.50188827)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD15W:5\",\n // mac: \"b4:e6:2d:98:a4:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD15W\",\n // position: 5,\n // utm: \"POINT(737442.944275506 9548919.71244726)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16E:1\",\n // mac: \"b4:e6:2d:ac:87:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16E\",\n // position: 1,\n // utm: \"POINT(737392.758697647 9548882.40976229)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16E:2\",\n // mac: \"b4:e6:2d:ac:b2:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16E\",\n // position: 2,\n // utm: \"POINT(737403.976552006 9548896.43695481)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16E:3\",\n // mac: \"b4:e6:2d:ad:3b:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16E\",\n // position: 3,\n // utm: \"POINT(737415.194409452 9548910.46414772)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16E:4\",\n // mac: \"b4:e6:2d:ad:23:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16E\",\n // position: 4,\n // utm: \"POINT(737426.412270105 9548924.49134103)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16E:5\",\n // mac: \"b4:e6:2d:ac:e4:7d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16E\",\n // position: 5,\n // utm: \"POINT(737437.630133737 9548938.51853474)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16W:1\",\n // mac: \"b4:e6:2d:ac:4f:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16W\",\n // position: 1,\n // utm: \"POINT(737380.000098239 9548889.10221038)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16W:2\",\n // mac: \"b4:e6:2d:ad:9b:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16W\",\n // position: 2,\n // utm: \"POINT(737391.434347064 9548903.68371137)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16W:3\",\n // mac: \"b4:e6:2d:98:a4:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16W\",\n // position: 3,\n // utm: \"POINT(737402.868599128 9548918.26521281)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16W:4\",\n // mac: \"b4:e6:2d:ad:1b:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16W\",\n // position: 4,\n // utm: \"POINT(737414.302854425 9548932.8467147)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD16W:5\",\n // mac: \"b4:e6:2d:ac:0d:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD16W\",\n // position: 5,\n // utm: \"POINT(737425.737113072 9548947.42821704)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17E:1\",\n // mac: \"b4:e6:2d:ac:48:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17E\",\n // position: 1,\n // utm: \"POINT(737368.402332945 9548896.97531937)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17E:2\",\n // mac: \"b4:e6:2d:98:a3:99\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17E\",\n // position: 2,\n // utm: \"POINT(737380.212258887 9548912.77656498)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17E:3\",\n // mac: \"b4:e6:2d:ac:4c:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17E\",\n // position: 3,\n // utm: \"POINT(737392.022188339 9548928.57781117)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17E:4\",\n // mac: \"b4:e6:2d:ac:76:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17E\",\n // position: 4,\n // utm: \"POINT(737403.83212131 9548944.37905794)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17E:5\",\n // mac: \"84:0d:8e:0b:d0:e8\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17E\",\n // position: 5,\n // utm: \"POINT(737415.64205779 9548960.18030528)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17E:6\",\n // mac: \"b4:e6:2d:ac:b3:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17E\",\n // position: 6,\n // utm: \"POINT(737427.451997778 9548975.98155321)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e5:29:b3\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17W:1\",\n // mac: \"b4:e6:2d:ac:56:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17W\",\n // position: 1,\n // utm: \"POINT(737355.142686268 9548908.10813892)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17W:2\",\n // mac: \"b4:e6:2d:98:a8:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17W\",\n // position: 2,\n // utm: \"POINT(737366.799631836 9548922.87401191)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17W:3\",\n // mac: \"b4:e6:2d:99:08:99\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17W\",\n // position: 3,\n // utm: \"POINT(737378.45658087 9548937.63988537)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17W:4\",\n // mac: \"c4:4f:33:23:67:35\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17W\",\n // position: 4,\n // utm: \"POINT(737389.550334802 9548950.7796071)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17W:5\",\n // mac: \"c4:4f:33:1d:24:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17W\",\n // position: 5,\n // utm: \"POINT(737400.315889196 9548965.54785407)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD17W:6\",\n // mac: \"c4:4f:33:23:68:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD17W\",\n // position: 6,\n // utm: \"POINT(737411.072346124 9548978.24457119)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18E:1\",\n // mac: \"b4:e6:2d:98:a6:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18E\",\n // position: 1,\n // utm: \"POINT(737339.960094147 9548912.29155608)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18E:2\",\n // mac: \"b4:e6:2d:ad:9b:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18E\",\n // position: 2,\n // utm: \"POINT(737351.480766538 9548927.30440748)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18E:3\",\n // mac: \"b4:e6:2d:ad:08:6d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18E\",\n // position: 3,\n // utm: \"POINT(737363.001442242 9548942.31725939)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18E:4\",\n // mac: \"b4:e6:2d:98:9b:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18E\",\n // position: 4,\n // utm: \"POINT(737374.522121256 9548957.33011179)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18E:5\",\n // mac: \"c4:4f:33:1e:a2:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18E\",\n // position: 5,\n // utm: \"POINT(737389.169765581 9548976.23116718)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18W:1\",\n // mac: \"b4:e6:2d:98:f4:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18W\",\n // position: 1,\n // utm: \"POINT(737310.646382605 9548923.31901712)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18W:2\",\n // mac: \"b4:e6:2d:ac:bd:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18W\",\n // position: 2,\n // utm: \"POINT(737321.553320515 9548937.79094872)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD18W:3\",\n // mac: \"b4:e6:2d:98:f3:91\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD18W\",\n // position: 3,\n // utm: \"POINT(737337.503258238 9548943.22343391)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD19E:1\",\n // mac: \"b4:e6:2d:98:f6:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD19E\",\n // position: 1,\n // utm: \"POINT(737316.957688218 9548933.06,816486)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD19E:2\",\n // mac: \"b4:e6:2d:98:9a:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD19E\",\n // position: 2,\n // utm: \"POINT(737329.662523697 9548949.26162504)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD19E:3\",\n // mac: \"b4:e6:2d:98:f3:6d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD19E\",\n // position: 3,\n // utm: \"POINT(737342.36736317 9548965.45508577)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD19E:4\",\n // mac: \"b4:e6:2d:ac:46:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD19E\",\n // position: 4,\n // utm: \"POINT(737355.072206638 9548981.64854705)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:4b:86\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD19W:1\",\n // mac: \"b4:e6:2d:98:9a:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD19W\",\n // position: 1,\n // utm: \"POINT(737298.028477726 9548928.82733133)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20E:1\",\n // mac: \"b4:e6:2d:ac:8f:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20E\",\n // position: 1,\n // utm: \"POINT(737293.312599815 9548947.92774423)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20E:2\",\n // mac: \"b4:e6:2d:99:08:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20E\",\n // position: 2,\n // utm: \"POINT(737305.001373213 9548963.01907864)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20E:3\",\n // mac: \"b4:e6:2d:ac:8e:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20E\",\n // position: 3,\n // utm: \"POINT(737316.690150126 9548978.11041355)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20E:4\",\n // mac: \"b4:e6:2d:ac:bd:95\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20E\",\n // position: 4,\n // utm: \"POINT(737328.378930317 9548993.20174895)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20E:5\",\n // mac: \"b4:e6:2d:98:f4:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20E\",\n // position: 5,\n // utm: \"POINT(737340.067714025 9549008.29308485)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20E:6\",\n // mac: \"b4:e6:2d:ad:8f:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20E\",\n // position: 6,\n // utm: \"POINT(737351.756501013 9549023.38442124)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:1\",\n // mac: \"b4:e6:2d:98:90:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 1,\n // utm: \"POINT(737257.724418244 9548952.68318733)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:2\",\n // mac: \"b4:e6:2d:ad:8f:5d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 2,\n // utm: \"POINT(737266.536508309 9548962.05578328)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:3\",\n // mac: \"b4:e6:2d:aa:fb:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 3,\n // utm: \"POINT(737285.311440197 9548964.07751404)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:4\",\n // mac: \"84:0d:8e:0b:cf:ac\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 4,\n // utm: \"POINT(737296.818533824 9548978.25192641)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:5\",\n // mac: \"b4:e6:2d:99:8f:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 5,\n // utm: \"POINT(737308.923361588 9548992.86865996)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:6\",\n // mac: \"b4:e6:2d:ac:e8:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 6,\n // utm: \"POINT(737320.435968827 9549008.818683)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:7\",\n // mac: \"b4:e6:2d:98:95:0d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 7,\n // utm: \"POINT(737332.242959565 9549023.58418136)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD20W:8\",\n // mac: \"b4:e6:2d:aa:fa:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD20W\",\n // position: 8,\n // utm: \"POINT(737343.900208709 9549038.05414326)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21E:1\",\n // mac: \"b4:e6:2d:ad:9b:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21E\",\n // position: 1,\n // utm: \"POINT(737255.853351514 9548949.35886849)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21E:2\",\n // mac: \"b4:e6:2d:98:f1:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21E\",\n // position: 2,\n // utm: \"POINT(737267.586623091 9548964.27251969)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21E:3\",\n // mac: \"b4:e6:2d:98:f4:95\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21E\",\n // position: 3,\n // utm: \"POINT(737277.449265036 9548976.37974146)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21E:4\",\n // mac: \"b4:e6:2d:ad:8d:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21E\",\n // position: 4,\n // utm: \"POINT(737289.258445941 9548991.88506971)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c8:df:84:d3:83:b2\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21W:1\",\n // mac: \"b4:e6:2d:98:94:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21W\",\n // position: 1,\n // utm: \"POINT(737238.504759978 9548951.47645757)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21W:2\",\n // mac: \"b4:e6:2d:ac:8e:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21W\",\n // position: 2,\n // utm: \"POINT(737250.064263392 9548966.48922292)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21W:3\",\n // mac: \"b4:e6:2d:98:a5:21\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21W\",\n // position: 3,\n // utm: \"POINT(737261.623770139 9548981.50198877)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21W:4\",\n // mac: \"b4:e6:2d:99:13:8d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21W\",\n // position: 4,\n // utm: \"POINT(737273.183280213 9548996.51475511)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21W:5\",\n // mac: \"b4:e6:2d:98:f5:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21W\",\n // position: 5,\n // utm: \"POINT(737284.742793618 9549011.52752194)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21W:6\",\n // mac: \"b4:e6:2d:ad:8d:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21W\",\n // position: 6,\n // utm: \"POINT(737296.302310353 9549026.54028927)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD21W:7\",\n // mac: \"b4:e6:2d:ac:72:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD21W\",\n // position: 7,\n // utm: \"POINT(737307.861830418 9549041.55305709)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22E:1\",\n // mac: \"24:0a:c4:51:0e:f8\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22E\",\n // position: 1,\n // utm: \"POINT(737225.71539997 9548958.90879985)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22E:2\",\n // mac: \"b4:e6:2d:98:f2:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22E\",\n // position: 2,\n // utm: \"POINT(737237.399370758 9548974.14318968)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22E:3\",\n // mac: \"24:0a:c4:51:09:0c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22E\",\n // position: 3,\n // utm: \"POINT(737249.083344955 9548989.37758003)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22E:4\",\n // mac: \"b4:e6:2d:98:a6:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22E\",\n // position: 4,\n // utm: \"POINT(737260.767322557 9549004.61197089)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22E:5\",\n // mac: \"b4:e6:2d:99:11:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22E\",\n // position: 5,\n // utm: \"POINT(737272.451303567 9549019.84636227)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22E:6\",\n // mac: \"b4:e6:2d:ac:0c:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22E\",\n // position: 6,\n // utm: \"POINT(737284.135287983 9549035.08075416)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22E:7\",\n // mac: \"b4:e6:2d:ac:be:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22E\",\n // position: 7,\n // utm: \"POINT(737295.81927569 9549050.31514656)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:1\",\n // mac: \"b4:e6:2d:ad:90:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 1,\n // utm: \"POINT(737213.371388007 9548966.9318309)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:10\",\n // mac: \"b4:e6:2d:ac:46:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 10,\n // utm: \"POINT(737318.410235993 9549102.93199655)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:2\",\n // mac: \"b4:e6:2d:ac:57:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 2,\n // utm: \"POINT(737225.042357606 9548982.04295842)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:3\",\n // mac: \"b4:e6:2d:ad:9b:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 3,\n // utm: \"POINT(737236.713330483 9548997.15408644)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:4\",\n // mac: \"b4:e6:2d:ab:cc:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 4,\n // utm: \"POINT(737248.384306865 9549012.26521496)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:5\",\n // mac: \"b4:e6:2d:98:f4:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 5,\n // utm: \"POINT(737260.055286518 9549027.37634398)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:6\",\n // mac: \"b4:e6:2d:ac:88:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 6,\n // utm: \"POINT(737271.726269682 9549042.4874735)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:7\",\n // mac: \"b4:e6:2d:ac:ee:05\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 7,\n // utm: \"POINT(737283.397256118 9549057.59860351)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:8\",\n // mac: \"b4:e6:2d:ac:57:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 8,\n // utm: \"POINT(737295.068246057 9549072.70973403)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD22W:9\",\n // mac: \"b4:e6:2d:ad:8e:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD22W\",\n // position: 9,\n // utm: \"POINT(737306.739239275 9549087.82086504)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:1\",\n // mac: \"b4:e6:2d:98:f5:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 1,\n // utm: \"POINT(737201.627001734 9548975.6931099)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:10\",\n // mac: \"b4:e6:2d:98:a4:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 10,\n // utm: \"POINT(737305.999147849 9549111.5840909)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:11\",\n // mac: \"b4:e6:2d:ad:9a:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 11,\n // utm: \"POINT(737317.596069802 9549126.68309131)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:12\",\n // mac: \"b4:e6:2d:ac:56:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 12,\n // utm: \"POINT(737329.192994995 9549141.78209222)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:2\",\n // mac: \"b4:e6:2d:98:a5:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 2,\n // utm: \"POINT(737213.223893503 9548990.79210577)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:3\",\n // mac: \"b4:e6:2d:ac:6a:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 3,\n // utm: \"POINT(737224.820788517 9549005.89110216)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:4\",\n // mac: \"b4:e6:2d:ac:be:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 4,\n // utm: \"POINT(737236.417686993 9549020.99009904)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:5\",\n // mac: \"b4:e6:2d:ac:45:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 5,\n // utm: \"POINT(737248.014588715 9549036.08909643)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:6\",\n // mac: \"b4:e6:2d:ac:56:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 6,\n // utm: \"POINT(737259.611493794 9549051.18809431)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:7\",\n // mac: \"b4:e6:2d:ac:7b:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 7,\n // utm: \"POINT(737271.208402334 9549066.28709271)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:8\",\n // mac: \"b4:e6:2d:98:f4:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 8,\n // utm: \"POINT(737282.805314113 9549081.3860916)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23E:9\",\n // mac: \"b4:e6:2d:ab:ca:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23E\",\n // position: 9,\n // utm: \"POINT(737294.40222936 9549096.485091)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"40:bd:32:e6:3e:31\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:1\",\n // mac: \"b4:e6:2d:ac:4c:91\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 1,\n // utm: \"POINT(737187.944965017 9548984.01562241)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:10\",\n // mac: \"b4:e6:2d:98:f4:91\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 10,\n // utm: \"POINT(737292.44108375 9549118.74532392)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:11\",\n // mac: \"b4:e6:2d:ad:9a:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 11,\n // utm: \"POINT(737304.051780394 9549133.71529318)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:12\",\n // mac: \"b4:e6:2d:98:f4:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 12,\n // utm: \"POINT(737315.662480274 9549148.68526292)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:13\",\n // mac: \"b4:e6:2d:ad:9b:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 13,\n // utm: \"POINT(737327.273183616 9549163.65523316)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:2\",\n // mac: \"b4:e6:2d:ad:8e:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 2,\n // utm: \"POINT(737199.555631401 9548998.9855873)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:3\",\n // mac: \"b4:e6:2d:ac:4d:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 3,\n // utm: \"POINT(737211.166301246 9549013.95555268)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:4\",\n // mac: \"b4:e6:2d:ac:4c:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 4,\n // utm: \"POINT(737222.776974447 9549028.92551855)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:5\",\n // mac: \"b4:e6:2d:ad:8e:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 5,\n // utm: \"POINT(737234.387650884 9549043.8954849)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:6\",\n // mac: \"b4:e6:2d:aa:55:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 6,\n // utm: \"POINT(737245.998330778 9549058.86545173)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:7\",\n // mac: \"b4:e6:2d:ad:8e:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 7,\n // utm: \"POINT(737257.609014026 9549073.83541905)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:8\",\n // mac: \"b4:e6:2d:99:09:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 8,\n // utm: \"POINT(737269.219700509 9549088.80538685)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD23W:9\",\n // mac: \"b4:e6:2d:ac:a2:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD23W\",\n // position: 9,\n // utm: \"POINT(737280.830390451 9549103.77535514)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:1\",\n // mac: \"b4:e6:2d:ac:95:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 1,\n // utm: \"POINT(737175.303048222 9548991.44756434)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:10\",\n // mac: \"b4:e6:2d:98:a4:e1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 10,\n // utm: \"POINT(737278.820941933 9549125.34336875)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:11\",\n // mac: \"b4:e6:2d:98:f1:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 11,\n // utm: \"POINT(737290.322946555 9549140.22068276)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:12\",\n // mac: \"b4:e6:2d:99:04:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 12,\n // utm: \"POINT(737301.824954464 9549155.09799726)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:13\",\n // mac: \"b4:e6:2d:99:10:95\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 13,\n // utm: \"POINT(737313.326965669 9549169.97531223)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:14\",\n // mac: \"b4:e6:2d:ad:9b:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 14,\n // utm: \"POINT(737324.828980156 9549184.85262769)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:2\",\n // mac: \"b4:e6:2d:ac:be:0d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 2,\n // utm: \"POINT(737186.805023331 9549006.32487402)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:3\",\n // mac: \"b4:e6:2d:ad:9f:35\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 3,\n // utm: \"POINT(737198.307001626 9549021.20218417)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:4\",\n // mac: \"b4:e6:2d:98:f4:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 4,\n // utm: \"POINT(737209.808983211 9549036.07949481)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:5\",\n // mac: \"b4:e6:2d:98:a5:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 5,\n // utm: \"POINT(737221.310968085 9549050.95680593)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:6\",\n // mac: \"b4:e6:2d:99:03:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 6,\n // utm: \"POINT(737232.81295625 9549065.83411753)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:7\",\n // mac: \"b4:e6:2d:ac:1e:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 7,\n // utm: \"POINT(737244.314947706 9549080.71142961)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:8\",\n // mac: \"b4:e6:2d:99:86:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 8,\n // utm: \"POINT(737255.816942456 9549095.58874217)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24E:9\",\n // mac: \"b4:e6:2d:98:f0:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24E\",\n // position: 9,\n // utm: \"POINT(737267.318940605 9549110.46605522)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:1\",\n // mac: \"b4:e6:2d:98:a5:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 1,\n // utm: \"POINT(737163.411977155 9549000.94906695)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:10\",\n // mac: \"b4:e6:2d:99:11:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 10,\n // utm: \"POINT(737267.21989061 9549134.86626523)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:11\",\n // mac: \"b4:e6:2d:98:f3:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 11,\n // utm: \"POINT(737278.754119746 9549149.74595633)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:12\",\n // mac: \"b4:e6:2d:ad:9e:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 12,\n // utm: \"POINT(737290.288352189 9549164.6256479)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:13\",\n // mac: \"b4:e6:2d:ac:a2:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 13,\n // utm: \"POINT(737301.822587934 9549179.50533996)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:14\",\n // mac: \"b4:e6:2d:98:94:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 14,\n // utm: \"POINT(737313.356826984 9549194.3850325)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:15\",\n // mac: \"b4:e6:2d:ac:c9:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 15,\n // utm: \"POINT(737324.891069343 9549209.26472552)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:16\",\n // mac: \"b4:e6:2d:ad:8f:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 16,\n // utm: \"POINT(737336.425315005 9549224.14441902)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:2\",\n // mac: \"b4:e6:2d:98:a7:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 2,\n // utm: \"POINT(737174.946176536 9549015.82875373)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:3\",\n // mac: \"b4:e6:2d:98:f0:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 3,\n // utm: \"POINT(737186.480379223 9549030.70844099)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:4\",\n // mac: \"b4:e6:2d:99:05:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 4,\n // utm: \"POINT(737198.014585217 9549045.58812873)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:5\",\n // mac: \"b4:e6:2d:ad:9b:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 5,\n // utm: \"POINT(737209.548794515 9549060.46781695)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:6\",\n // mac: \"b4:e6:2d:ac:15:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 6,\n // utm: \"POINT(737221.083007122 9549075.34750565)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:7\",\n // mac: \"b4:e6:2d:ac:64:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 7,\n // utm: \"POINT(737232.617223035 9549090.22719482)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:8\",\n // mac: \"b4:e6:2d:99:11:c5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 8,\n // utm: \"POINT(737244.151442255 9549105.10688448)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD24W:9\",\n // mac: \"b4:e6:2d:99:11:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD24W\",\n // position: 9,\n // utm: \"POINT(737255.685664777 9549119.98657462)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:1\",\n // mac: \"b4:e6:2d:99:04:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 1,\n // utm: \"POINT(737151.073931899 9549010.89565759)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:10\",\n // mac: \"b4:e6:2d:98:a8:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 10,\n // utm: \"POINT(737254.209038256 9549143.57169606)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:11\",\n // mac: \"b4:e6:2d:99:11:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 11,\n // utm: \"POINT(737265.668510869 9549158.31348046)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:12\",\n // mac: \"b4:e6:2d:ac:46:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 12,\n // utm: \"POINT(737277.127986737 9549173.05526532)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:13\",\n // mac: \"b4:e6:2d:ac:57:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 13,\n // utm: \"POINT(737288.58746576 9549187.79705065)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:2\",\n // mac: \"b4:e6:2d:ac:76:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 2,\n // utm: \"POINT(737162.533375169 9549025.63743777)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:3\",\n // mac: \"b4:e6:2d:98:a6:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 3,\n // utm: \"POINT(737173.99282159 9549040.37921842)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:4\",\n // mac: \"b4:e6:2d:98:f1:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 4,\n // utm: \"POINT(737185.452271379 9549055.12099954)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:5\",\n // mac: \"b4:e6:2d:98:a8:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 5,\n // utm: \"POINT(737196.91172432 9549069.86278112)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:6\",\n // mac: \"b4:e6:2d:98:a5:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 6,\n // utm: \"POINT(737208.37118063 9549084.60456318)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:7\",\n // mac: \"b4:e6:2d:98:f1:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 7,\n // utm: \"POINT(737219.830640202 9549099.3463457)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:8\",\n // mac: \"b4:e6:2d:98:e7:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 8,\n // utm: \"POINT(737231.290102922 9549114.08812868)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25E:9\",\n // mac: \"b4:e6:2d:98:a7:99\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25E\",\n // position: 9,\n // utm: \"POINT(737242.749569018 9549128.82991214)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:c6\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:1\",\n // mac: \"b4:e6:2d:99:15:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 1,\n // utm: \"POINT(737139.030894716 9549019.43576608)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:10\",\n // mac: \"b4:e6:2d:ac:a5:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 10,\n // utm: \"POINT(737242.566610207 9549152.92741232)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:11\",\n // mac: \"b4:e6:2d:98:f6:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 11,\n // utm: \"POINT(737254.070595058 9549167.75981984)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:12\",\n // mac: \"b4:e6:2d:99:10:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 12,\n // utm: \"POINT(737265.574583196 9549182.59222783)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:13\",\n // mac: \"b4:e6:2d:98:f7:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 13,\n // utm: \"POINT(737277.078574625 9549197.4246363)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:14\",\n // mac: \"b4:e6:2d:ac:46:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 14,\n // utm: \"POINT(737288.582569228 9549212.25704525)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:15\",\n // mac: \"b4:e6:2d:98:a3:d1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 15,\n // utm: \"POINT(737300.086567228 9549227.08945468)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:16\",\n // mac: \"b4:e6:2d:ad:9c:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 16,\n // utm: \"POINT(737311.590568518 9549241.92186458)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:17\",\n // mac: \"b4:e6:2d:ac:49:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 17,\n // utm: \"POINT(737323.094573091 9549256.75427496)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:18\",\n // mac: \"b4:e6:2d:98:f7:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 18,\n // utm: \"POINT(737334.598580843 9549271.58668581)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:19\",\n // mac: \"b4:e6:2d:ac:59:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 19,\n // utm: \"POINT(737346.10259199 9549286.41909715)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:2\",\n // mac: \"b4:e6:2d:98:a7:95\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 2,\n // utm: \"POINT(737150.534849974 9549034.26816932)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:20\",\n // mac: \"b4:e6:2d:ac:46:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 20,\n // utm: \"POINT(737357.606606425 9549301.25150896)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:21\",\n // mac: \"b4:e6:2d:ad:8e:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 21,\n // utm: \"POINT(737369.110624145 9549316.08392125)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:22\",\n // mac: \"c4:4f:33:23:57:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 22,\n // utm: \"POINT(737380.614645152 9549330.91633402)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:23\",\n // mac: \"b4:e6:2d:98:a3:8d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 23,\n // utm: \"POINT(737392.118669332 9549345.74874726)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:24\",\n // mac: \"b4:e6:2d:99:10:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 24,\n // utm: \"POINT(737403.622696909 9549360.58116099)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:25\",\n // mac: \"b4:e6:2d:ac:4e:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 25,\n // utm: \"POINT(737415.126727773 9549375.41357519)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:26\",\n // mac: \"b4:e6:2d:aa:fa:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 26,\n // utm: \"POINT(737426.63076192 9549390.24598987)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:27\",\n // mac: \"b4:e6:2d:ac:4d:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 27,\n // utm: \"POINT(737438.134799242 9549405.07840503)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:28\",\n // mac: \"b4:e6:2d:ac:48:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 28,\n // utm: \"POINT(737449.638839963 9549419.91082067)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:29\",\n // mac: \"b4:e6:2d:a5:11:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 29,\n // utm: \"POINT(737461.142883965 9549434.74323679)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:3\",\n // mac: \"b4:e6:2d:ac:8a:c5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 3,\n // utm: \"POINT(737162.03880852 9549049.10057303)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:4\",\n // mac: \"b4:e6:2d:98:f7:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 4,\n // utm: \"POINT(737173.542770357 9549063.93297721)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:5\",\n // mac: \"b4:e6:2d:ac:7e:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 5,\n // utm: \"POINT(737185.04673537 9549078.76538188)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:6\",\n // mac: \"b4:e6:2d:ac:04:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 6,\n // utm: \"POINT(737196.550703785 9549093.59778701)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:7\",\n // mac: \"b4:e6:2d:98:9a:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 7,\n // utm: \"POINT(737208.054675487 9549108.43019263)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:8\",\n // mac: \"b4:e6:2d:99:14:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 8,\n // utm: \"POINT(737219.558650475 9549123.26259871)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD25W:9\",\n // mac: \"b4:e6:2d:98:f1:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD25W\",\n // position: 9,\n // utm: \"POINT(737231.062628751 9549138.09500528)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:1\",\n // mac: \"b4:e6:2d:98:a5:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 1,\n // utm: \"POINT(737137.658614183 9549021.54795184)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:10\",\n // mac: \"b4:e6:2d:98:a7:91\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 10,\n // utm: \"POINT(737204.719098784 9549130.46463651)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:11\",\n // mac: \"b4:e6:2d:99:04:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 11,\n // utm: \"POINT(737251.501642984 9549190.10812736)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:12\",\n // mac: \"b4:e6:2d:98:f1:7d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 12,\n // utm: \"POINT(737216.974303327 9549145.67456914)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:13\",\n // mac: \"b4:e6:2d:99:06:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 13,\n // utm: \"POINT(737262.524361159 9549203.88377993)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:14\",\n // mac: \"b4:e6:2d:ac:84:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 14,\n // utm: \"POINT(737274.218616433 9549218.24271148)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:15\",\n // mac: \"b4:e6:2d:99:8f:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 15,\n // utm: \"POINT(737285.727561599 9549232.93506674)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:16\",\n // mac: \"c4:4f:33:23:58:95\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 16,\n // utm: \"POINT(737298.505592605 9549248.73382409)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:17\",\n // mac: \"c4:4f:33:23:ce:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 17,\n // utm: \"POINT(737310.540017532 9549264.97846328)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:18\",\n // mac: \"c4:4f:33:23:67:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 18,\n // utm: \"POINT(737320.481972312 9549278.56521834)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:19\",\n // mac: \"24:0a:c4:51:06:98\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 19,\n // utm: \"POINT(737332.363717613 9549293.40456553)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:2\",\n // mac: \"b4:e6:2d:ad:8e:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 2,\n // utm: \"POINT(737149.203875915 9549035.90724271)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:20\",\n // mac: \"4c:11:ae:b7:f3:90\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 20,\n // utm: \"POINT(737344.321122804 9549308.68762148)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:21\",\n // mac: \"24:0a:c4:51:0e:38\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 21,\n // utm: \"POINT(737355.940334034 9549322.82481891)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:22\",\n // mac: \"c4:4f:33:1e:b3:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 22,\n // utm: \"POINT(737367.264184003 9549337.92460031)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:23\",\n // mac: \"c4:4f:33:23:cd:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 23,\n // utm: \"POINT(737378.923291298 9549353.06,048775)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:24\",\n // mac: \"c4:4f:33:23:67:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 24,\n // utm: \"POINT(737390.282129784 9549367.30936097)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:25\",\n // mac: \"c4:4f:33:1e:ae:8d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 25,\n // utm: \"POINT(737401.269166407 9549381.78117669)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:26\",\n // mac: \"c4:4f:33:23:70:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 26,\n // utm: \"POINT(737412.553924846 9549396.17822095)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:27\",\n // mac: \"c4:4f:33:23:6b:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 27,\n // utm: \"POINT(737424.434912098 9549410.72165542)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:3\",\n // mac: \"b4:e6:2d:98:f4:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 3,\n // utm: \"POINT(737161.011286401 9549050.82072206)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:4\",\n // mac: \"b4:e6:2d:ac:6f:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 4,\n // utm: \"POINT(737164.701904971 9549066.27361878)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:6\",\n // mac: \"b4:e6:2d:ad:93:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 6,\n // utm: \"POINT(737169.886855373 9549083.505955)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:7\",\n // mac: \"b4:e6:2d:98:fc:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 7,\n // utm: \"POINT(737181.695229979 9549098.85500633)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26E:9\",\n // mac: \"b4:e6:2d:ad:12:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26E\",\n // position: 9,\n // utm: \"POINT(737192.607093914 9549112.90078778)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:1\",\n // mac: \"b4:e6:2d:ac:48:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 1,\n // utm: \"POINT(737118.980371178 9549041.75814751)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:10\",\n // mac: \"b4:e6:2d:ac:49:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 10,\n // utm: \"POINT(737219.5655684 9549172.30701115)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:11\",\n // mac: \"b4:e6:2d:ac:46:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 11,\n // utm: \"POINT(737230.741716991 9549186.81244275)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:12\",\n // mac: \"b4:e6:2d:99:06:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 12,\n // utm: \"POINT(737241.917868583 9549201.31787481)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:13\",\n // mac: \"b4:e6:2d:98:f3:7d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 13,\n // utm: \"POINT(737253.094023392 9549215.82330733)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:14\",\n // mac: \"b4:e6:2d:98:f1:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 14,\n // utm: \"POINT(737264.270181314 9549230.32874031)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:15\",\n // mac: \"c4:4f:33:23:cf:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 15,\n // utm: \"POINT(737275.446342346 9549244.83417376)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:16\",\n // mac: \"b4:e6:2d:99:13:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 16,\n // utm: \"POINT(737286.622506484 9549259.33960766)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:17\",\n // mac: \"c4:4f:33:23:66:d1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 17,\n // utm: \"POINT(737297.798673734 9549273.84504204)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:18\",\n // mac: \"c4:4f:33:24:24:d1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 18,\n // utm: \"POINT(737308.97484409 9549288.35047687)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:19\",\n // mac: \"c4:4f:33:23:d3:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 19,\n // utm: \"POINT(737320.15101756 9549302.85591216)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:2\",\n // mac: \"b4:e6:2d:98:f4:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 2,\n // utm: \"POINT(737130.156491771 9549056.26357496)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:20\",\n // mac: \"c4:4f:33:23:66:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 20,\n // utm: \"POINT(737331.327194022 9549317.36134792)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:21\",\n // mac: \"4c:11:ae:b7:f5:f0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 21,\n // utm: \"POINT(737342.503373711 9549331.86678414)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:22\",\n // mac: \"c4:4f:33:23:64:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 22,\n // utm: \"POINT(737353.679556501 9549346.37222083)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:23\",\n // mac: \"c4:4f:33:23:71:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 23,\n // utm: \"POINT(737364.855742408 9549360.87765797)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:24\",\n // mac: \"4c:11:ae:b7:f4:f8\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 24,\n // utm: \"POINT(737376.031931417 9549375.38309558)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:25\",\n // mac: \"24:0a:c4:50:cf:0c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 25,\n // utm: \"POINT(737387.208123536 9549389.88853366)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:26\",\n // mac: \"24:0a:c4:50:e0:78\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 26,\n // utm: \"POINT(737398.384318764 9549404.39397219)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:27\",\n // mac: \"24:0a:c4:50:d2:9c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 27,\n // utm: \"POINT(737409.855809364 9549417.86284442)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:3\",\n // mac: \"b4:e6:2d:ac:48:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 3,\n // utm: \"POINT(737141.332615477 9549070.76900287)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:4\",\n // mac: \"b4:e6:2d:ac:84:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 4,\n // utm: \"POINT(737152.508742291 9549085.27443124)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:5\",\n // mac: \"b4:e6:2d:ac:8e:5d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 5,\n // utm: \"POINT(737163.68487211 9549099.77986007)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:6\",\n // mac: \"b4:e6:2d:ad:09:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 6,\n // utm: \"POINT(737174.861005143 9549114.28528937)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:7\",\n // mac: \"b4:e6:2d:ac:4f:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 7,\n // utm: \"POINT(737186.037141295 9549128.79071912)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:8\",\n // mac: \"b4:e6:2d:ac:cb:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 8,\n // utm: \"POINT(737197.213280551 9549143.29614933)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD26W:9\",\n // mac: \"b4:e6:2d:99:13:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD26W\",\n // position: 9,\n // utm: \"POINT(737208.389422924 9549157.80158001)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8d:c8:3c\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:1\",\n // mac: \"b4:e6:2d:ac:ae:7d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 1,\n // utm: \"POINT(737116.00279342 9549042.35791544)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:10\",\n // mac: \"b4:e6:2d:ad:9c:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 10,\n // utm: \"POINT(737205.156173349 9549182.98739026)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:11\",\n // mac: \"b4:e6:2d:98:f5:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 11,\n // utm: \"POINT(737216.817403565 9549198.93706906)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:12\",\n // mac: \"b4:e6:2d:99:11:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 12,\n // utm: \"POINT(737226.978838134 9549211.04354545)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:13\",\n // mac: \"b4:e6:2d:ad:96:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 13,\n // utm: \"POINT(737238.040311914 9549225.51513469)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:14\",\n // mac: \"c4:4f:33:23:60:21\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 14,\n // utm: \"POINT(737249.40363209 9549241.46561273)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:17\",\n // mac: \"24:0a:c4:50:d0:28\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 17,\n // utm: \"POINT(737282.286237442 9549283.40151997)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:18\",\n // mac: \"b4:e6:2d:ac:5d:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 18,\n // utm: \"POINT(737295.141524214 9549300.23586664)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:19\",\n // mac: \"c4:4f:33:23:ab:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 19,\n // utm: \"POINT(737308.593439718 9549317.36457251)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:2\",\n // mac: \"b4:e6:2d:ad:9a:a5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 2,\n // utm: \"POINT(737131.247260889 9549061.4053949)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:20\",\n // mac: \"24:0a:c4:50:e7:90\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 20,\n // utm: \"POINT(737321.449519778 9549334.49486253)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:21\",\n // mac: \"24:0a:c4:51:0e:a4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 21,\n // utm: \"POINT(737332.209960061 9549347.78352325)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:22\",\n // mac: \"4c:11:ae:b7:fb:e0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 22,\n // utm: \"POINT(737344.17071749 9549364.32431917)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:23\",\n // mac: \"24:0a:c4:50:e8:d4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 23,\n // utm: \"POINT(737355.527004388 9549377.61140492)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:24\",\n // mac: \"4c:11:ae:b7:fd:28\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 24,\n // utm: \"POINT(737367.185923947 9549392.67331819)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:25\",\n // mac: \"24:0a:c4:50:e6:d4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 25,\n // utm: \"POINT(737380.339158312 9549409.5068995)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:26\",\n // mac: \"c4:4f:33:23:9b:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 26,\n // utm: \"POINT(737395.288553913 9549429.59104019)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:3\",\n // mac: \"b4:e6:2d:ac:e3:49\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 3,\n // utm: \"POINT(737139.790717651 9549081.28447308)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:4\",\n // mac: \"b4:e6:2d:ab:fc:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 4,\n // utm: \"POINT(737139.984599652 9549098.22632919)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:5\",\n // mac: \"b4:e6:2d:98:a5:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 5,\n // utm: \"POINT(737151.343968264 9549112.69710648)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:6\",\n // mac: \"b4:e6:2d:99:15:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 6,\n // utm: \"POINT(737163.301532346 9549128.05411072)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:7\",\n // mac: \"b4:e6:2d:ad:95:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 7,\n // utm: \"POINT(737173.764796077 9549141.63945941)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:8\",\n // mac: \"b4:e6:2d:99:14:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 8,\n // utm: \"POINT(737182.435839363 9549153.45394154)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27E:9\",\n // mac: \"b4:e6:2d:ac:56:05\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27E\",\n // position: 9,\n // utm: \"POINT(737195.291094046 9549170.28825866)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27EN:1\",\n // mac: \"b4:e6:2d:ac:83:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27EN\",\n // position: 1,\n // utm: \"POINT(737436.925005438 9549458.33457794)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27EN:14\",\n // mac: \"24:0a:c4:50:c7:1c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27EN\",\n // position: 14,\n // utm: \"POINT(737271.524240721 9549269.52100001)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27EN:15\",\n // mac: \"c4:4f:33:1e:b3:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27EN\",\n // position: 15,\n // utm: \"POINT(737261.807712469 9549256.67349094)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27EN:2\",\n // mac: \"c4:4f:33:23:ab:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27EN\",\n // position: 2,\n // utm: \"POINT(737426.916404761 9549447.70734833)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27EN:3\",\n // mac: \"c4:4f:33:23:b0:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27EN\",\n // position: 3,\n // utm: \"POINT(737407.246190512 9549444.94810995)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:1\",\n // mac: \"c4:4f:33:23:ac:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 1,\n // utm: \"POINT(737408.092361627 9549483.11453913)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:10\",\n // mac: \"24:0a:c4:50:da:a8\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 10,\n // utm: \"POINT(737303.006724972 9549345.19730739)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:11\",\n // mac: \"c4:4f:33:24:25:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 11,\n // utm: \"POINT(737288.361596511 9549327.48032681)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:12\",\n // mac: \"4c:11:ae:b7:f3:34\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 12,\n // utm: \"POINT(737272.216674072 9549305.92069456)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:2\",\n // mac: \"c4:4f:33:23:ad:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 2,\n // utm: \"POINT(737396.567402749 9549468.02340529)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:3\",\n // mac: \"24:0a:c4:50:d0:b0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 3,\n // utm: \"POINT(737385.042447183 9549452.93227195)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:4\",\n // mac: \"c4:4f:33:23:ad:61\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 4,\n // utm: \"POINT(737373.517494932 9549437.84113912)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:5\",\n // mac: \"c4:4f:33:24:25:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 5,\n // utm: \"POINT(737361.992545999 9549422.75000681)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:6\",\n // mac: \"c4:4f:33:1e:bf:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 6,\n // utm: \"POINT(737350.467600381 9549407.658875)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:7\",\n // mac: \"4c:11:ae:b7:fb:b0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 7,\n // utm: \"POINT(737338.94265808 9549392.5677437)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:8\",\n // mac: \"4c:11:ae:b7:fd:0c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 8,\n // utm: \"POINT(737327.417719087 9549377.47661292)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD27N:9\",\n // mac: \"c4:4f:33:1d:6e:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD27N\",\n // position: 9,\n // utm: \"POINT(737315.892783418 9549362.38548264)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:1\",\n // mac: \"c4:4f:33:23:ae:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 1,\n // utm: \"POINT(737384.456121705 9549501.38186329)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:10\",\n // mac: \"c4:4f:33:1e:14:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 10,\n // utm: \"POINT(737271.755733216 9549356.82196518)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:11\",\n // mac: \"4c:11:ae:b7:fb:b4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 11,\n // utm: \"POINT(737258.595468606 9549337.32497276)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:12\",\n // mac: \"24:0a:c4:50:cf:cc\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 12,\n // utm: \"POINT(737239.470535009 9549315.47629963)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:2\",\n // mac: \"c4:4f:33:1d:0a:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 2,\n // utm: \"POINT(737373.097216147 9549487.05265286)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:3\",\n // mac: \"24:0a:c4:50:ff:9c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 3,\n // utm: \"POINT(737361.440005232 9549472.5762019)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:4\",\n // mac: \"4c:11:ae:b7:f5:34\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 4,\n // utm: \"POINT(737351.276375357 9549459.89345333)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:5\",\n // mac: \"c4:4f:33:23:67:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 5,\n // utm: \"POINT(737341.105489456 9549444.2357017)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:6\",\n // mac: \"c4:4f:33:23:54:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 6,\n // utm: \"POINT(737327.957756808 9549429.47366103)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:7\",\n // mac: \"c4:4f:33:1e:b1:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 7,\n // utm: \"POINT(737315.998570678 9549413.52471982)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:8\",\n // mac: \"24:0a:c4:50:cb:c8\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 8,\n // utm: \"POINT(737300.453360267 9549393.44216014)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD28N:9\",\n // mac: \"c4:4f:33:23:ad:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD28N\",\n // position: 9,\n // utm: \"POINT(737288.487904952 9549375.12574104)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:1\",\n // mac: \"24:0a:c4:50:e8:d8\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 1,\n // utm: \"POINT(737360.731076333 9549519.20220685)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:10\",\n // mac: \"4c:11:ae:b7:fc:b4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 10,\n // utm: \"POINT(737249.612092855 9549376.26354977)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:11\",\n // mac: \"24:0a:c4:50:e6:6c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 11,\n // utm: \"POINT(737234.067292832 9549356.33000879)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:12\",\n // mac: \"24:0a:c4:51:09:a4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 12,\n // utm: \"POINT(737217.474696157 9549334.47591752)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:13\",\n // mac: \"4c:11:ae:b7:fb:f8\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 13,\n // utm: \"POINT(737202.526150683 9549314.68812409)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:14\",\n // mac: \"24:0a:c4:50:ff:d0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 14,\n // utm: \"POINT(737187.573680892 9549293.41948642)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:15\",\n // mac: \"4c:11:ae:b7:fc:9c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 15,\n // utm: \"POINT(737172.62826927 9549274.81466265)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:16\",\n // mac: \"24:0a:c4:51:0f:24\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 16,\n // utm: \"POINT(737157.976868661 9549254.73003011)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:17\",\n // mac: \"c4:4f:33:1e:5f:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 17,\n // utm: \"POINT(737142.731203044 9549235.23859174)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:18\",\n // mac: \"24:0a:c4:51:09:2c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 18,\n // utm: \"POINT(737126.890487886 9549216.04428163)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:19\",\n // mac: \"c4:4f:33:23:aa:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 19,\n // utm: \"POINT(737111.045861656 9549195.37043265)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:2\",\n // mac: \"c4:4f:33:23:ad:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 2,\n // utm: \"POINT(737350.804131178 9549506.50406714)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:20\",\n // mac: \"c4:4f:33:23:a9:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 20,\n // utm: \"POINT(737095.802571214 9549176.76681393)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:21\",\n // mac: \"c4:4f:33:23:ab:35\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 21,\n // utm: \"POINT(737082.34208999 9549156.38285426)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:22\",\n // mac: \"c4:4f:33:1d:bc:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 22,\n // utm: \"POINT(737067.40300109 9549140.14645356)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:23\",\n // mac: \"c4:4f:33:1e:a4:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 23,\n // utm: \"POINT(737053.349832146 9549120.94808193)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:24\",\n // mac: \"24:0a:c4:51:08:fc\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 24,\n // utm: \"POINT(737038.401338469 9549101.15917243)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:3\",\n // mac: \"4c:11:ae:b7:f7:3c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 3,\n // utm: \"POINT(737340.041713892 9549492.47579417)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:4\",\n // mac: \"4c:11:ae:b7:f4:64\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 4,\n // utm: \"POINT(737329.132324318 9549479.18625986)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:5\",\n // mac: \"24:0a:c4:51:0e:b0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 5,\n // utm: \"POINT(737316.876780573 9549463.83133721)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:6\",\n // mac: \"c4:4f:33:23:8e:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 6,\n // utm: \"POINT(737304.322136154 9549448.03271699)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:7\",\n // mac: \"24:0a:c4:51:09:30\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 7,\n // utm: \"POINT(737291.61580012 9549431.19774165)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:8\",\n // mac: \"c4:4f:33:1d:f5:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 8,\n // utm: \"POINT(737279.209345927 9549415.10162434)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD29N:9\",\n // mac: \"c4:4f:33:23:6a:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD29N\",\n // position: 9,\n // utm: \"POINT(737264.858185126 9549395.90351454)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"d0:ff:50:39:a3:10\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD30N:1\",\n // mac: \"4c:11:ae:b7:f9:a0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD30N\",\n // position: 1,\n // utm: \"POINT(737337.782986075 9549539.24720912)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD30N:2\",\n // mac: \"4c:11:ae:b7:fc:70\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD30N\",\n // position: 2,\n // utm: \"POINT(737326.424414206 9549525.36136617)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD30N:3\",\n // mac: \"c4:4f:33:23:ac:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD30N\",\n // position: 3,\n // utm: \"POINT(737314.768642399 9549511.48305381)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD30N:4\",\n // mac: \"c4:4f:33:1e:bc:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD30N\",\n // position: 4,\n // utm: \"POINT(737304.603285352 9549497.89706435)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD30N:5\",\n // mac: \"24:0a:c4:50:db:38\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD30N\",\n // position: 5,\n // utm: \"POINT(737292.045901752 9549481.06176567)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD30N:6\",\n // mac: \"c4:4f:33:23:a9:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD30N\",\n // position: 6,\n // utm: \"POINT(737279.493121846 9549465.99919983)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD30N:7\",\n // mac: \"24:0a:c4:50:e4:34\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD30N\",\n // position: 7,\n // utm: \"POINT(737267.83257061 9549450.34372843)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:32:ab\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:1\",\n // mac: \"b4:e6:2d:ad:9a:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 1,\n // utm: \"POINT(737649.86427865 9548645.12611332)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:10\",\n // mac: \"c4:4f:33:1e:a6:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 10,\n // utm: \"POINT(737696.951366393 9548706.99780271)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:11\",\n // mac: \"c4:4f:33:23:54:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 11,\n // utm: \"POINT(737769.447787569 9548801.21079836)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:12\",\n // mac: \"4c:11:ae:b7:fb:ac\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 12,\n // utm: \"POINT(737714.589958217 9548730.03470379)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:13\",\n // mac: \"c4:4f:33:23:a3:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 13,\n // utm: \"POINT(737792.018616801 9548830.44797857)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:14\",\n // mac: \"c4:4f:33:23:ac:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 14,\n // utm: \"POINT(737803.379700636 9548845.5098209)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:2\",\n // mac: \"b4:e6:2d:98:9a:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 2,\n // utm: \"POINT(737659.281366778 9548657.38202132)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:3\",\n // mac: \"b4:e6:2d:98:fd:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 3,\n // utm: \"POINT(737668.696886076 9548669.04645431)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:4\",\n // mac: \"b4:e6:2d:ac:7d:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 4,\n // utm: \"POINT(737663.916024269 9548663.73238544)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:5\",\n // mac: \"b4:e6:2d:ac:85:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 5,\n // utm: \"POINT(737688.730655738 9548696.51422403)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:6\",\n // mac: \"b4:e6:2d:ac:81:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 6,\n // utm: \"POINT(737673.48208387 9548675.98835656)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:7\",\n // mac: \"b4:e6:2d:ad:8f:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 7,\n // utm: \"POINT(737724.605266783 9548743.17827805)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:8\",\n // mac: \"b4:e6:2d:98:9a:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 8,\n // utm: \"POINT(737735.365763504 9548756.46718886)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD4W:9\",\n // mac: \"b4:e6:2d:98:f5:91\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD4W\",\n // position: 9,\n // utm: \"POINT(737746.576685703 9548771.08687933)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:1\",\n // mac: \"b4:e6:2d:ad:8f:21\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 1,\n // utm: \"POINT(737629.459247961 9548646.51144495)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:10\",\n // mac: \"b4:e6:2d:99:13:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 10,\n // utm: \"POINT(737738.549970292 9548787.74848454)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:11\",\n // mac: \"b4:e6:2d:ac:49:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 11,\n // utm: \"POINT(737750.671179987 9548803.44149164)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:12\",\n // mac: \"b4:e6:2d:ac:05:0d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 12,\n // utm: \"POINT(737761.752081513 9548820.09600174)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:13\",\n // mac: \"b4:e6:2d:aa:fb:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 13,\n // utm: \"POINT(737771.467127634 9548832.35173358)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:2\",\n // mac: \"b4:e6:2d:ac:7b:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 2,\n // utm: \"POINT(737641.580424622 9548662.20444719)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:3\",\n // mac: \"b4:e6:2d:ad:9c:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 3,\n // utm: \"POINT(737653.701605052 9548677.89744997)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:4\",\n // mac: \"b4:e6:2d:ac:65:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 4,\n // utm: \"POINT(737665.822789147 9548693.59045329)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:5\",\n // mac: \"b4:e6:2d:ad:8f:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 5,\n // utm: \"POINT(737677.943976891 9548709.28345714)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:6\",\n // mac: \"b4:e6:2d:99:12:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 6,\n // utm: \"POINT(737690.06516819 9548724.97646154)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:7\",\n // mac: \"b4:e6:2d:ac:4d:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 7,\n // utm: \"POINT(737702.186363257 9548740.66946648)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:8\",\n // mac: \"84:0d:8e:0b:cf:94\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 8,\n // utm: \"POINT(737714.307561978 9548756.36247196)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5E:9\",\n // mac: \"b4:e6:2d:99:12:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5E\",\n // position: 9,\n // utm: \"POINT(737726.428764249 9548772.05547798)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:1\",\n // mac: \"b4:e6:2d:98:a2:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 1,\n // utm: \"POINT(737610.539475269 9548645.67395374)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:10\",\n // mac: \"b4:e6:2d:ac:85:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 10,\n // utm: \"POINT(737717.23704155 9548783.72199047)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:11\",\n // mac: \"b4:e6:2d:99:04:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 11,\n // utm: \"POINT(737729.09234421 9548799.0606638)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:12\",\n // mac: \"b4:e6:2d:98:f5:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 12,\n // utm: \"POINT(737740.947650368 9548814.39933764)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:13\",\n // mac: \"b4:e6:2d:ac:04:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 13,\n // utm: \"POINT(737752.80296003 9548829.738012)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:14\",\n // mac: \"b4:e6:2d:ac:46:35\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 14,\n // utm: \"POINT(737764.65827318 9548845.07668687)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:15\",\n // mac: \"b4:e6:2d:99:8f:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 15,\n // utm: \"POINT(737776.513589831 9548860.41536226)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:16\",\n // mac: \"b4:e6:2d:99:13:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 16,\n // utm: \"POINT(737788.368909979 9548875.75403817)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:17\",\n // mac: \"b4:e6:2d:ac:46:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 17,\n // utm: \"POINT(737800.224233509 9548891.0927146)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:2\",\n // mac: \"b4:e6:2d:ac:10:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 2,\n // utm: \"POINT(737622.394746441 9548661.01262243)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:3\",\n // mac: \"b4:e6:2d:98:a8:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 3,\n // utm: \"POINT(737634.250020996 9548676.35129163)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:4\",\n // mac: \"b4:e6:2d:ab:e6:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 4,\n // utm: \"POINT(737646.105299166 9548691.68996135)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:5\",\n // mac: \"b4:e6:2d:ad:9a:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 5,\n // utm: \"POINT(737657.960580836 9548707.02863158)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:6\",\n // mac: \"b4:e6:2d:ac:04:c5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 6,\n // utm: \"POINT(737669.815866004 9548722.36730233)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:7\",\n // mac: \"b4:e6:2d:ac:4f:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 7,\n // utm: \"POINT(737681.671154674 9548737.70597359)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:8\",\n // mac: \"b4:e6:2d:ac:4d:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 8,\n // utm: \"POINT(737693.526446839 9548753.04464537)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD5W:9\",\n // mac: \"b4:e6:2d:ac:4f:21\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD5W\",\n // position: 9,\n // utm: \"POINT(737705.381742504 9548768.38331766)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:1\",\n // mac: \"b4:e6:2d:aa:fb:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 1,\n // utm: \"POINT(737588.334572933 9548642.03380305)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:10\",\n // mac: \"b4:e6:2d:ad:8e:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 10,\n // utm: \"POINT(737693.013126101 9548777.00761631)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:11\",\n // mac: \"b4:e6:2d:ac:4f:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 11,\n // utm: \"POINT(737704.64409328 9548792.00470912)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:12\",\n // mac: \"b4:e6:2d:98:f6:95\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 12,\n // utm: \"POINT(737716.275063824 9548807.00180242)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:13\",\n // mac: \"b4:e6:2d:99:04:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 13,\n // utm: \"POINT(737727.90603773 9548821.99889621)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:14\",\n // mac: \"b4:e6:2d:98:a7:b9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 14,\n // utm: \"POINT(737739.537014886 9548836.99599049)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:15\",\n // mac: \"b4:e6:2d:98:a2:49\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 15,\n // utm: \"POINT(737751.167995518 9548851.99308526)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:16\",\n // mac: \"b4:e6:2d:ac:47:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 16,\n // utm: \"POINT(737762.798979508 9548866.99018052)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:17\",\n // mac: \"b4:e6:2d:ac:0c:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 17,\n // utm: \"POINT(737774.429966864 9548881.98727627)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:2\",\n // mac: \"b4:e6:2d:ad:4c:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 2,\n // utm: \"POINT(737599.965509844 9548657.03089146)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:3\",\n // mac: \"b4:e6:2d:ad:9e:49\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 3,\n // utm: \"POINT(737611.596450002 9548672.02798036)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:4\",\n // mac: \"b4:e6:2d:99:8f:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 4,\n // utm: \"POINT(737623.227393643 9548687.02506974)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:5\",\n // mac: \"b4:e6:2d:ab:fc:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 5,\n // utm: \"POINT(737634.858340639 9548702.02215961)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:6\",\n // mac: \"b4:e6:2d:ad:6c:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 6,\n // utm: \"POINT(737646.489291004 9548717.01924997)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:7\",\n // mac: \"b4:e6:2d:98:f2:21\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 7,\n // utm: \"POINT(737658.120244737 9548732.01634083)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:8\",\n // mac: \"b4:e6:2d:ad:2b:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 8,\n // utm: \"POINT(737669.751201823 9548747.01343216)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6E:9\",\n // mac: \"b4:e6:2d:ab:fc:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6E\",\n // position: 9,\n // utm: \"POINT(737681.38216228 9548762.01052399)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:1\",\n // mac: \"b4:e6:2d:ac:46:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 1,\n // utm: \"POINT(737570.61017851 9548642.52483698)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:10\",\n // mac: \"b4:e6:2d:98:f4:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 10,\n // utm: \"POINT(737676.079516748 9548779.14454158)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:11\",\n // mac: \"b4:e6:2d:99:03:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 11,\n // utm: \"POINT(737687.798349136 9548794.32451129)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:12\",\n // mac: \"b4:e6:2d:aa:54:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 12,\n // utm: \"POINT(737699.517185051 9548809.5044815)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:13\",\n // mac: \"b4:e6:2d:ac:49:7d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 13,\n // utm: \"POINT(737711.236024277 9548824.68445222)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:14\",\n // mac: \"b4:e6:2d:aa:54:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 14,\n // utm: \"POINT(737722.954867032 9548839.86442345)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:15\",\n // mac: \"b4:e6:2d:ac:46:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 15,\n // utm: \"POINT(737734.673713093 9548855.04439518)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:16\",\n // mac: \"b4:e6:2d:98:f6:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 16,\n // utm: \"POINT(737746.392562687 9548870.22436742)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:2\",\n // mac: \"c4:4f:33:23:66:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 2,\n // utm: \"POINT(737580.999246612 9548656.03056541)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:3\",\n // mac: \"b4:e6:2d:99:15:6d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 3,\n // utm: \"POINT(737594.04778536 9548672.8847678)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:4\",\n // mac: \"b4:e6:2d:99:06:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 4,\n // utm: \"POINT(737605.766593808 9548688.06473396)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:5\",\n // mac: \"b4:e6:2d:ad:9c:05\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 5,\n // utm: \"POINT(737617.485405783 9548703.24470064)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:6\",\n // mac: \"b4:e6:2d:ac:8a:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 6,\n // utm: \"POINT(737629.204221071 9548718.42466782)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:7\",\n // mac: \"b4:e6:2d:98:a8:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 7,\n // utm: \"POINT(737640.923039888 9548733.6046355)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:8\",\n // mac: \"b4:e6:2d:98:f4:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 8,\n // utm: \"POINT(737652.641862014 9548748.78460369)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD6W:9\",\n // mac: \"b4:e6:2d:98:a2:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD6W\",\n // position: 9,\n // utm: \"POINT(737664.360687673 9548763.96457238)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:1\",\n // mac: \"b4:e6:2d:ac:47:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 1,\n // utm: \"POINT(737557.672448927 9548650.9934096)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:10\",\n // mac: \"b4:e6:2d:99:8f:5d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 10,\n // utm: \"POINT(737663.098307448 9548787.0385586)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:11\",\n // mac: \"b4:e6:2d:ac:6d:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 11,\n // utm: \"POINT(737674.812308776 9548802.15468875)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:12\",\n // mac: \"b4:e6:2d:ac:50:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 12,\n // utm: \"POINT(737686.526313518 9548817.27081941)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:13\",\n // mac: \"b4:e6:2d:ad:9b:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 13,\n // utm: \"POINT(737698.24032167 9548832.38695056)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:14\",\n // mac: \"b4:e6:2d:ad:9b:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 14,\n // utm: \"POINT(737709.954333233 9548847.50308221)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:15\",\n // mac: \"b4:e6:2d:98:a2:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 15,\n // utm: \"POINT(737721.66834821 9548862.61921435)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:16\",\n // mac: \"b4:e6:2d:98:f5:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 16,\n // utm: \"POINT(737733.382366598 9548877.735347)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:17\",\n // mac: \"b4:e6:2d:ac:4c:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 17,\n // utm: \"POINT(737745.096388395 9548892.85148015)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:18\",\n // mac: \"b4:e6:2d:ac:4d:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 18,\n // utm: \"POINT(737756.810413605 9548907.96761379)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:19\",\n // mac: \"b4:e6:2d:aa:54:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 19,\n // utm: \"POINT(737768.524442224 9548923.08374794)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:2\",\n // mac: \"b4:e6:2d:99:8f:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 2,\n // utm: \"POINT(737569.386419544 9548666.10953528)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:20\",\n // mac: \"b4:e6:2d:ad:9b:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 20,\n // utm: \"POINT(737780.238474252 9548938.19988258)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:3\",\n // mac: \"b4:e6:2d:aa:54:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 3,\n // utm: \"POINT(737581.100393571 9548681.22566146)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:4\",\n // mac: \"b4:e6:2d:98:a3:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 4,\n // utm: \"POINT(737592.814371012 9548696.34178813)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:5\",\n // mac: \"b4:e6:2d:aa:fa:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 5,\n // utm: \"POINT(737604.52835187 9548711.45791529)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:6\",\n // mac: \"b4:e6:2d:98:a2:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 6,\n // utm: \"POINT(737616.24233625 9548726.57404296)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:7\",\n // mac: \"b4:e6:2d:ac:9c:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 7,\n // utm: \"POINT(737627.956323928 9548741.69017113)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:8\",\n // mac: \"b4:e6:2d:ab:fd:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 8,\n // utm: \"POINT(737639.67031502 9548756.80629979)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7E:9\",\n // mac: \"b4:e6:2d:ac:46:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7E\",\n // position: 9,\n // utm: \"POINT(737651.384309526 9548771.92242894)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:8c:fc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:1\",\n // mac: \"b4:e6:2d:98:94:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 1,\n // utm: \"POINT(737546.229509503 9548661.08565337)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:10\",\n // mac: \"b4:e6:2d:98:a7:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 10,\n // utm: \"POINT(737651.383841775 9548796.80743992)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:11\",\n // mac: \"b4:e6:2d:98:94:a5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 11,\n // utm: \"POINT(737663.06,7673498 9548811.8876409)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:12\",\n // mac: \"b4:e6:2d:98:9a:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 12,\n // utm: \"POINT(737674.751508503 9548826.96784238)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:13\",\n // mac: \"b4:e6:2d:ac:48:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 13,\n // utm: \"POINT(737686.435347014 9548842.04804435)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:14\",\n // mac: \"b4:e6:2d:99:14:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 14,\n // utm: \"POINT(737698.11918892 9548857.12824682)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:15\",\n // mac: \"b4:e6:2d:98:f0:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 15,\n // utm: \"POINT(737709.803034105 9548872.20844979)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:16\",\n // mac: \"b4:e6:2d:98:e7:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 16,\n // utm: \"POINT(737721.486882798 9548887.28865326)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:17\",\n // mac: \"b4:e6:2d:ac:88:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 17,\n // utm: \"POINT(737733.170734772 9548902.36885722)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:18\",\n // mac: \"b4:e6:2d:98:f5:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 18,\n // utm: \"POINT(737744.854590253 9548917.44906167)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:19\",\n // mac: \"b4:e6:2d:ac:b9:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 19,\n // utm: \"POINT(737756.538449125 9548932.52926663)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:2\",\n // mac: \"b4:e6:2d:aa:fa:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 2,\n // utm: \"POINT(737557.913310668 9548676.16584989)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:20\",\n // mac: \"c4:4f:33:23:d3:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 20,\n // utm: \"POINT(737767.599859682 9548946.65635499)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:21\",\n // mac: \"c4:4f:33:23:71:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 21,\n // utm: \"POINT(737780.155184032 9548962.60253541)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:22\",\n // mac: \"c4:4f:33:1e:b7:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 22,\n // utm: \"POINT(737790.913355233 9548975.00876823)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:23\",\n // mac: \"c4:4f:33:1e:a3:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 23,\n // utm: \"POINT(737804.069042118 9548992.73784723)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:24\",\n // mac: \"c4:4f:33:23:65:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 24,\n // utm: \"POINT(737812.743169256 9549005.58769473)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:25\",\n // mac: \"b4:e6:2d:98:f7:7d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 25,\n // utm: \"POINT(737820.818086854 9549017.25521224)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:3\",\n // mac: \"b4:e6:2d:ac:cf:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 3,\n // utm: \"POINT(737569.597115117 9548691.24604691)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:4\",\n // mac: \"b4:e6:2d:ac:56:55\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 4,\n // utm: \"POINT(737581.280923073 9548706.32624443)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:5\",\n // mac: \"b4:e6:2d:98:a5:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 5,\n // utm: \"POINT(737592.964734316 9548721.40644244)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:6\",\n // mac: \"b4:e6:2d:aa:fb:5d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 6,\n // utm: \"POINT(737604.648549061 9548736.48664094)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:7\",\n // mac: \"b4:e6:2d:ad:7f:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 7,\n // utm: \"POINT(737616.332367091 9548751.56683994)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:8\",\n // mac: \"b4:e6:2d:ac:93:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 8,\n // utm: \"POINT(737628.016188629 9548766.64703944)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD7W:9\",\n // mac: \"b4:e6:2d:ad:9b:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD7W\",\n // position: 9,\n // utm: \"POINT(737639.70001356 9548781.72723943)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:1\",\n // mac: \"b4:e6:2d:ad:8f:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 1,\n // utm: \"POINT(737534.189233358 9548670.73557947)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:10\",\n // mac: \"b4:e6:2d:ac:47:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 10,\n // utm: \"POINT(737639.642567296 9548806.7339675)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:11\",\n // mac: \"b4:e6:2d:99:14:d1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 11,\n // utm: \"POINT(737651.359621418 9548821.84490199)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:12\",\n // mac: \"b4:e6:2d:ac:93:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 12,\n // utm: \"POINT(737663.076679064 9548836.95583697)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:13\",\n // mac: \"b4:e6:2d:98:f0:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 13,\n // utm: \"POINT(737674.793740008 9548852.06677246)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:14\",\n // mac: \"b4:e6:2d:ad:96:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 14,\n // utm: \"POINT(737686.510804371 9548867.17770843)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:15\",\n // mac: \"b4:e6:2d:aa:54:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 15,\n // utm: \"POINT(737698.227872251 9548882.28864491)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:16\",\n // mac: \"b4:e6:2d:ac:48:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 16,\n // utm: \"POINT(737709.944943435 9548897.39958188)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:17\",\n // mac: \"b4:e6:2d:98:a3:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 17,\n // utm: \"POINT(737721.662018139 9548912.51051936)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:18\",\n // mac: \"c4:4f:33:23:b0:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 18,\n // utm: \"POINT(737733.37909615 9548927.62145733)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:19\",\n // mac: \"b4:e6:2d:98:f5:05\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 19,\n // utm: \"POINT(737745.096177567 9548942.73239579)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:2\",\n // mac: \"b4:e6:2d:ac:d3:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 2,\n // utm: \"POINT(737545.906256868 9548685.84650949)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:3\",\n // mac: \"b4:e6:2d:99:11:8d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 3,\n // utm: \"POINT(737557.623283683 9548700.95744001)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:4\",\n // mac: \"b4:e6:2d:ac:4d:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 4,\n // utm: \"POINT(737569.340313911 9548716.06837101)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:5\",\n // mac: \"b4:e6:2d:ac:be:11\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 5,\n // utm: \"POINT(737581.057347664 9548731.17930252)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:6\",\n // mac: \"b4:e6:2d:ad:8e:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 6,\n // utm: \"POINT(737592.774384718 9548746.29023453)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:7\",\n // mac: \"b4:e6:2d:ac:84:61\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 7,\n // utm: \"POINT(737604.491425297 9548761.40116702)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:8\",\n // mac: \"b4:e6:2d:99:11:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 8,\n // utm: \"POINT(737616.20846918 9548776.51210002)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8E:9\",\n // mac: \"b4:e6:2d:98:f1:6d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8E\",\n // position: 9,\n // utm: \"POINT(737627.925516477 9548791.62303351)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:1\",\n // mac: \"24:0a:c4:50:d3:28\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 1,\n // utm: \"POINT(737523.341579793 9548680.08403163)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:10\",\n // mac: \"b4:e6:2d:ac:7d:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 10,\n // utm: \"POINT(737628.321617933 9548816.87303412)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:11\",\n // mac: \"b4:e6:2d:99:06:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 11,\n // utm: \"POINT(737639.919512688 9548831.8744381)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:12\",\n // mac: \"b4:e6:2d:99:14:61\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 12,\n // utm: \"POINT(737651.517410901 9548846.87584257)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:13\",\n // mac: \"24:0a:c4:50:ce:3c\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 13,\n // utm: \"POINT(737663.11531235 9548861.87724754)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:14\",\n // mac: \"c4:4f:33:23:68:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 14,\n // utm: \"POINT(737674.713217259 9548876.87865299)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:15\",\n // mac: \"c4:4f:33:1e:49:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 15,\n // utm: \"POINT(737687.767975759 9548894.64667377)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:16\",\n // mac: \"24:0a:c4:50:d0:04\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 16,\n // utm: \"POINT(737697.909037003 9548906.88146539)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:17\",\n // mac: \"c4:4f:33:23:af:21\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 17,\n // utm: \"POINT(737709.506951949 9548921.88287232)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:18\",\n // mac: \"c4:4f:33:23:92:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 18,\n // utm: \"POINT(737721.104870133 9548936.88427976)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:19\",\n // mac: \"c4:4f:33:23:d0:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 19,\n // utm: \"POINT(737732.702791768 9548951.88568768)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:2\",\n // mac: \"b4:e6:2d:98:f2:05\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 2,\n // utm: \"POINT(737535.538579858 9548696.86182002)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:20\",\n // mac: \"c4:4f:33:23:65:5d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 20,\n // utm: \"POINT(737744.300716642 9548966.8870961)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:21\",\n // mac: \"c4:4f:33:1e:a9:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 21,\n // utm: \"POINT(737755.898644975 9548981.88850501)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:22\",\n // mac: \"c4:4f:33:1e:54:ed\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 22,\n // utm: \"POINT(737767.49657654 9548996.88991442)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:23\",\n // mac: \"c4:4f:33:23:cd:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 23,\n // utm: \"POINT(737779.094511564 9549011.89132432)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:3\",\n // mac: \"b4:e6:2d:ac:81:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 3,\n // utm: \"POINT(737547.136447939 9548711.86322006)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:4\",\n // mac: \"b4:e6:2d:ac:bd:c5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 4,\n // utm: \"POINT(737558.734319372 9548726.86462059)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:5\",\n // mac: \"b4:e6:2d:98:f1:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 5,\n // utm: \"POINT(737570.332194039 9548741.86602162)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:6\",\n // mac: \"b4:e6:2d:98:a8:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 6,\n // utm: \"POINT(737581.930072168 9548756.86742313)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:8\",\n // mac: \"b4:e6:2d:ac:89:61\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 8,\n // utm: \"POINT(737605.125838357 9548786.87022764)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD8W:9\",\n // mac: \"b4:e6:2d:98:f5:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD8W\",\n // position: 9,\n // utm: \"POINT(737616.723726413 9548801.87163064)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:1\",\n // mac: \"b4:e6:2d:98:f5:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 1,\n // utm: \"POINT(737512.945039057 9548692.09943838)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:10\",\n // mac: \"c4:4f:33:23:cd:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 10,\n // utm: \"POINT(737617.38119457 9548827.37632821)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:11\",\n // mac: \"c4:4f:33:1e:b4:fd\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 11,\n // utm: \"POINT(737628.9852287 9548842.40709623)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:12\",\n // mac: \"4c:11:ae:b7:f4:e4\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 12,\n // utm: \"POINT(737640.589266069 9548857.43786474)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:13\",\n // mac: \"c4:4f:33:23:69:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 13,\n // utm: \"POINT(737652.193306799 9548872.46863374)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:14\",\n // mac: \"c4:4f:33:23:71:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 14,\n // utm: \"POINT(737663.797350982 9548887.49940325)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:15\",\n // mac: \"c4:4f:33:23:65:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 15,\n // utm: \"POINT(737675.401398411 9548902.53017325)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:16\",\n // mac: \"c4:4f:33:23:71:81\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 16,\n // utm: \"POINT(737687.00544919 9548917.56094374)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:17\",\n // mac: \"c4:4f:33:1e:18:a5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 17,\n // utm: \"POINT(737698.609503325 9548932.59171474)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:18\",\n // mac: \"24:0a:c4:50:ce:c0\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 18,\n // utm: \"POINT(737710.213560918 9548947.62248622)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:19\",\n // mac: \"c4:4f:33:23:66:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 19,\n // utm: \"POINT(737721.817621749 9548962.65325821)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:2\",\n // mac: \"b4:e6:2d:98:f1:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 2,\n // utm: \"POINT(737524.549042899 9548707.13020193)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:20\",\n // mac: \"c4:4f:33:23:70:7d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 20,\n // utm: \"POINT(737733.421685935 9548977.68403069)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:3\",\n // mac: \"b4:e6:2d:98:f2:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 3,\n // utm: \"POINT(737536.153050094 9548722.16096598)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:4\",\n // mac: \"b4:e6:2d:98:a3:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 4,\n // utm: \"POINT(737547.757060752 9548737.19173053)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:5\",\n // mac: \"b4:e6:2d:ac:4d:61\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 5,\n // utm: \"POINT(737559.361074656 9548752.22249557)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:6\",\n // mac: \"b4:e6:2d:98:f1:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 6,\n // utm: \"POINT(737570.965091911 9548767.25326111)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:7\",\n // mac: \"b4:e6:2d:ad:8f:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 7,\n // utm: \"POINT(737582.569112629 9548782.28402714)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:8\",\n // mac: \"b4:e6:2d:ad:9e:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 8,\n // utm: \"POINT(737594.173136587 9548797.31479367)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9E:9\",\n // mac: \"c4:4f:33:23:af:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9E\",\n // position: 9,\n // utm: \"POINT(737605.777163904 9548812.34556069)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:3e:1b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9W:1\",\n // mac: \"b4:e6:2d:ad:9a:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9W\",\n // position: 1,\n // utm: \"POINT(737500.007704036 9548700.27206358)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9W:2\",\n // mac: \"b4:e6:2d:ac:8f:a5\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9W\",\n // position: 2,\n // utm: \"POINT(737511.965465843 9548715.67827891)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9W:3\",\n // mac: \"b4:e6:2d:ad:9b:e1\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9W\",\n // position: 3,\n // utm: \"POINT(737523.923231318 9548731.08449475)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:DD9W:4\",\n // mac: \"b4:e6:2d:ad:9a:ad\",\n // area: \"DMLZ_Undercut\",\n // location: \"DD9W\",\n // position: 4,\n // utm: \"POINT(737535.881000236 9548746.4907111)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"0c:ae:7d:24:ef:d8\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:1\",\n // mac: \"c4:4f:33:23:af:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 1,\n // utm: \"POINT(737636.24323261 9549236.88847268)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:10\",\n // mac: \"24:0a:c4:50:ce:28\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 10,\n // utm: \"POINT(737697.697321653 9549211.71767464)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:11\",\n // mac: \"24:0a:c4:50:cf:e4\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 11,\n // utm: \"POINT(737704.532221883 9549205.19057325)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:12\",\n // mac: \"24:0a:c4:50:d0:60\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 12,\n // utm: \"POINT(737710.179303756 9549200.14312351)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:13\",\n // mac: \"c4:4f:33:23:7c:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 13,\n // utm: \"POINT(737713.88207659 9549192.14498027)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:14\",\n // mac: \"c4:4f:33:23:5f:6d\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 14,\n // utm: \"POINT(737711.474726254 9549183.12396712)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:15\",\n // mac: \"24:0a:c4:50:ff:a4\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 15,\n // utm: \"POINT(737706.987829176 9549176.32873215)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:2\",\n // mac: \"c4:4f:33:23:7c:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 2,\n // utm: \"POINT(737641.470588973 9549242.05232893)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:3\",\n // mac: \"24:0a:c4:50:c6:a4\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 3,\n // utm: \"POINT(737647.733206936 9549244.40319787)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:4\",\n // mac: \"c4:4f:33:23:67:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 4,\n // utm: \"POINT(737655.477959117 9549243.93923995)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:5\",\n // mac: \"4c:11:ae:b7:fd:98\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 5,\n // utm: \"POINT(737662.617440092 9549239.92543751)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:6\",\n // mac: \"c4:4f:33:23:64:bd\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 6,\n // utm: \"POINT(737669.902730589 9549234.72749498)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:7\",\n // mac: \"4c:11:ae:b7:fd:a4\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 7,\n // utm: \"POINT(737676.591003549 9549229.08716561)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:8\",\n // mac: \"c4:4f:33:23:67:49\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 8,\n // utm: \"POINT(737683.577200683 9549223.44650039)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:E_Ramp_NVD_E_ACC_to_NFD:9\",\n // mac: \"c4:4f:33:23:7c:31\",\n // area: \"DMLZ_Undercut\",\n // location: \"E_Ramp_NVD_E_ACC_to_NFD\",\n // position: 9,\n // utm: \"POINT(737690.859343826 9549217.06435591)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"74:e1:82:8c:c3:cc\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:10\",\n // mac: \"c4:4f:33:23:a9:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 10,\n // utm: \"POINT(737488.222489569 9549422.83385677)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:12\",\n // mac: \"4c:11:ae:b7:fb:a8\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 12,\n // utm: \"POINT(737474.029409039 9549435.22834075)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:13\",\n // mac: \"c4:4f:33:23:c3:cd\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 13,\n // utm: \"POINT(737578.103358369 9549275.76825156)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:14\",\n // mac: \"c4:4f:33:1e:ae:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 14,\n // utm: \"POINT(737587.026038265 9549270.11926034)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:15\",\n // mac: \"c4:4f:33:23:af:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 15,\n // utm: \"POINT(737594.756256698 9549264.1773663)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:16\",\n // mac: \"c4:4f:33:23:6a:99\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 16,\n // utm: \"POINT(737602.782821994 9549257.6425478)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:17\",\n // mac: \"c4:4f:33:1e:ba:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 17,\n // utm: \"POINT(737611.104156745 9549249.92267235)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:18\",\n // mac: \"c4:4f:33:1e:87:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 18,\n // utm: \"POINT(737422.969819265 9549476.12717728)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:19\",\n // mac: \"24:0a:c4:51:09:84\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 19,\n // utm: \"POINT(737415.239188945 9549481.91893553)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:2\",\n // mac: \"c4:4f:33:23:61:51\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 2,\n // utm: \"POINT(737526.751037963 9549346.96125917)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:21\",\n // mac: \"24:0a:c4:51:09:50\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 21,\n // utm: \"POINT(737399.334201313 9549494.68724941)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:22\",\n // mac: \"24:0a:c4:50:cf:40\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 22,\n // utm: \"POINT(737392.941423875 9549499.4372613)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:23\",\n // mac: \"24:0a:c4:50:e7:98\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 23,\n // utm: \"POINT(737385.80624655 9549505.07972885)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:24\",\n // mac: \"c4:4f:33:1e:b4:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 24,\n // utm: \"POINT(737379.413117806 9549509.68561695)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:25\",\n // mac: \"24:0a:c4:51:09:18\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 25,\n // utm: \"POINT(737373.171690808 9549515.32473562)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:26\",\n // mac: \"c4:4f:33:1e:ac:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 26,\n // utm: \"POINT(737366.03572227 9549520.6700917)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:27\",\n // mac: \"c4:4f:33:1e:ab:29\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 27,\n // utm: \"POINT(737359.04988997 9549526.45921734)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:28\",\n // mac: \"c4:4f:33:23:d4:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 28,\n // utm: \"POINT(737350.574027674 9549532.07318833)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:29\",\n // mac: \"4c:11:ae:b7:fb:cc\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 29,\n // utm: \"POINT(737344.185242091 9549538.32023769)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:30\",\n // mac: \"c4:4f:33:23:b0:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 30,\n // utm: \"POINT(737337.796455514 9549544.56728612)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:4\",\n // mac: \"c4:4f:33:1e:bd:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 4,\n // utm: \"POINT(737530.282011544 9549330.36605679)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:6\",\n // mac: \"4c:11:ae:b7:fc:84\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 6,\n // utm: \"POINT(737534.709088654 9549314.65616152)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_East:8\",\n // mac: \"c4:4f:33:1e:b3:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_East\",\n // position: 8,\n // utm: \"POINT(737502.644939324 9549412.73368454)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:1\",\n // mac: \"c4:4f:33:23:68:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 1,\n // utm: \"POINT(737523.671682021 9549365.17909073)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:1\",\n // mac: \"b4:e6:2d:ac:46:49\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 1,\n // utm: \"POINT(737525.881661165 9549356.14468822)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:10\",\n // mac: \"24:0a:c4:50:e9:44\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 10,\n // utm: \"POINT(737556.997701979 9549293.86151505)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:11\",\n // mac: \"c4:4f:33:23:cd:c5\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 11,\n // utm: \"POINT(737480.502600521 9549431.71314752)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:12\",\n // mac: \"c4:4f:33:23:69:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 12,\n // utm: \"POINT(737571.412096436 9549280.5639453)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:13\",\n // mac: \"24:0a:c4:50:e8:24\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 13,\n // utm: \"POINT(737464.152031821 9549444.77416138)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:14\",\n // mac: \"b4:e6:2d:99:11:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 14,\n // utm: \"POINT(737586.868171219 9549267.05814209)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:15\",\n // mac: \"b4:e6:2d:99:11:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 15,\n // utm: \"POINT(737595.938044657 9549260.67006269)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:16\",\n // mac: \"84:0d:8e:0b:cf:6c\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 16,\n // utm: \"POINT(737603.816003666 9549254.28639268)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:17\",\n // mac: \"b4:e6:2d:ac:bd:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 17,\n // utm: \"POINT(737611.54500139 9549247.90307595)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:18\",\n // mac: \"c4:4f:33:23:d4:d9\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 18,\n // utm: \"POINT(737620.170105377 9549242.40498467)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:19\",\n // mac: \"c4:4f:33:23:ac:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 19,\n // utm: \"POINT(737628.491427003 9549234.69220038)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:2\",\n // mac: \"c4:4f:33:23:ce:d5\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 2,\n // utm: \"POINT(737521.457873423 9549372.87720077)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:20\",\n // mac: \"c4:4f:33:24:24:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 20,\n // utm: \"POINT(737406.324958582 9549490.67903849)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:3\",\n // mac: \"c4:4f:33:1e:78:71\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 3,\n // utm: \"POINT(737519.396163137 9549381.75832833)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:5\",\n // mac: \"24:0a:c4:50:e7:cc\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 5,\n // utm: \"POINT(737517.198724107 9549395.97467434)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:7\",\n // mac: \"c4:4f:33:23:57:a9\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 7,\n // utm: \"POINT(737510.190366305 9549407.38702458)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:8\",\n // mac: \"c4:4f:33:23:8c:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 8,\n // utm: \"POINT(737546.000009448 9549303.37011438)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:NVD_West:9\",\n // mac: \"c4:4f:33:23:5f:4d\",\n // area: \"DMLZ_Undercut\",\n // location: \"NVD_West\",\n // position: 9,\n // utm: \"POINT(737494.474541041 9549420.43357347)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"7c:66:9d:48:cd:de\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:1\",\n // mac: \"b4:e6:2d:98:f2:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 1,\n // utm: \"POINT(737638.825482303 9548639.19928899)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:10\",\n // mac: \"b4:e6:2d:98:a8:35\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 10,\n // utm: \"POINT(737486.922822097 9548709.03695045)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:11\",\n // mac: \"b4:e6:2d:99:15:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 11,\n // utm: \"POINT(737540.55222907 9548654.43821303)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:12\",\n // mac: \"b4:e6:2d:ac:49:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 12,\n // utm: \"POINT(737464.971937896 9548744.89715155)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:13\",\n // mac: \"b4:e6:2d:98:a6:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 13,\n // utm: \"POINT(737523.16412192 9548669.57625556)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:14\",\n // mac: \"b4:e6:2d:99:12:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 14,\n // utm: \"POINT(737443.46407422 9548779.28281698)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:15\",\n // mac: \"c4:4f:33:23:58:91\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 15,\n // utm: \"POINT(737506.222893646 9548684.71323667)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:16\",\n // mac: \"b4:e6:2d:98:f7:1d\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 16,\n // utm: \"POINT(737422.409822858 9548816.18925226)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:17\",\n // mac: \"b4:e6:2d:98:a2:75\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 17,\n // utm: \"POINT(737492.551807944 9548697.1845523)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:18\",\n // mac: \"b4:e6:2d:ac:57:e5\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 18,\n // utm: \"POINT(737412.918949125 9548832.49095371)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:19\",\n // mac: \"b4:e6:2d:ac:49:c5\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 19,\n // utm: \"POINT(737479.798719683 9548718.82040155)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:2\",\n // mac: \"b4:e6:2d:98:a7:c9\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 2,\n // utm: \"POINT(737618.114339306 9548636.9976817)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:20\",\n // mac: \"b4:e6:2d:ad:1c:dd\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 20,\n // utm: \"POINT(737475.947820473 9548727.11821173)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:21\",\n // mac: \"b4:e6:2d:ac:9b:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 21,\n // utm: \"POINT(737470.314896999 9548737.49094088)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:22\",\n // mac: \"b4:e6:2d:99:a5:39\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 22,\n // utm: \"POINT(737464.08692159 9548748.16118736)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:23\",\n // mac: \"b4:e6:2d:98:a5:01\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 23,\n // utm: \"POINT(737459.343818113 9548757.05187209)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:24\",\n // mac: \"b4:e6:2d:ad:6e:69\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 24,\n // utm: \"POINT(737331.634762884 9548906.54289884)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:25\",\n // mac: \"b4:e6:2d:ac:45:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 25,\n // utm: \"POINT(737449.099760258 9548769.94624787)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:27\",\n // mac: \"c4:4f:33:23:65:79\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 27,\n // utm: \"POINT(737438.125530493 9548788.32363824)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:28\",\n // mac: \"24:0a:c4:50:fc:54\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 28,\n // utm: \"POINT(737432.487503179 9548796.77370867)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:3\",\n // mac: \"b4:e6:2d:ad:9b:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 3,\n // utm: \"POINT(737700.946221706 9548653.58612955)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:4\",\n // mac: \"b4:e6:2d:a4:67:59\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 4,\n // utm: \"POINT(737607.530996494 9548636.21200378)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:5\",\n // mac: \"b4:e6:2d:ac:4c:a1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 5,\n // utm: \"POINT(737567.020214858 9548636.7635024)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:6\",\n // mac: \"b4:e6:2d:ad:8e:e9\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 6,\n // utm: \"POINT(737549.472850059 9548648.05200551)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:7\",\n // mac: \"c4:4f:33:23:ac:49\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 7,\n // utm: \"POINT(737577.591864345 9548635.10683246)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:8\",\n // mac: \"b4:e6:2d:ac:8f:45\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 8,\n // utm: \"POINT(737515.139593002 9548676.84742938)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FE:9\",\n // mac: \"b4:e6:2d:ac:46:e1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FE\",\n // position: 9,\n // utm: \"POINT(737558.095946813 9548641.8147514)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"04:a3:16:fd:75:63\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:1\",\n // mac: \"24:0a:c4:50:d0:54\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 1,\n // utm: \"POINT(737202.900402892 9548965.03161025)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:10\",\n // mac: \"c4:4f:33:23:5f:a5\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 10,\n // utm: \"POINT(737137.230883219 9549011.08619294)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:11\",\n // mac: \"24:0a:c4:50:ff:68\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 11,\n // utm: \"POINT(737127.860673398 9549020.4243883)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:12\",\n // mac: \"c4:4f:33:1e:a6:89\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 12,\n // utm: \"POINT(737121.61966887 9549026.95090692)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:13\",\n // mac: \"c4:4f:33:23:67:65\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 13,\n // utm: \"POINT(737127.119453628 9549021.46681383)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:14\",\n // mac: \"24:0a:c4:51:0e:88\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 14,\n // utm: \"POINT(737100.516915951 9549044.47287179)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:15\",\n // mac: \"c4:4f:33:23:f0:e1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 15,\n // utm: \"POINT(737089.068222152 9549052.63913339)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:16\",\n // mac: \"c4:4f:33:23:54:f1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 16,\n // utm: \"POINT(737077.923730485 9549063.02645183)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:16\",\n // mac: \"c4:4f:33:24:24:b5\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 16,\n // utm: \"POINT(737096.640718217 9549048.32239451)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:17\",\n // mac: \"c4:4f:33:1e:ae:e1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 17,\n // utm: \"POINT(737067.797113517 9549069.85415845)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:18\",\n // mac: \"c4:4f:33:23:67:25\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 18,\n // utm: \"POINT(737063.268405333 9549073.79078857)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:19\",\n // mac: \"c4:4f:33:23:69:41\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 19,\n // utm: \"POINT(737051.172247818 9549085.14210377)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:2\",\n // mac: \"24:0a:c4:50:ce:14\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 2,\n // utm: \"POINT(737197.532819641 9548970.81309463)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:20\",\n // mac: \"c4:4f:33:23:68:19\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 20,\n // utm: \"POINT(737041.364839296 9549094.63626204)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:21\",\n // mac: \"c4:4f:33:23:b6:c1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 21,\n // utm: \"POINT(737033.035673628 9549099.09882478)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:22\",\n // mac: \"24:0a:c4:50:ce:18\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 22,\n // utm: \"POINT(737021.429757824 9549105.34460792)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:23\",\n // mac: \"c4:4f:33:1e:b5:b1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 23,\n // utm: \"POINT(737013.997494516 9549110.39612392)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:24\",\n // mac: \"24:0a:c4:50:d3:6c\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 24,\n // utm: \"POINT(737004.7749529 9549115.45256326)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:25\",\n // mac: \"c4:4f:33:23:60:09\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 25,\n // utm: \"POINT(736995.225220039 9549121.16058656)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:26\",\n // mac: \"c4:4f:33:23:63:99\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 26,\n // utm: \"POINT(736986.241998104 9549127.85775765)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:27\",\n // mac: \"c4:4f:33:23:9b:3d\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 27,\n // utm: \"POINT(736977.258774924 9549134.55492713)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:28\",\n // mac: \"c4:4f:33:1c:f8:d1\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 28,\n // utm: \"POINT(736968.275550724 9549141.25209498)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:29\",\n // mac: \"c4:4f:33:23:f0:85\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 29,\n // utm: \"POINT(736959.292325385 9549147.94926122)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:3\",\n // mac: \"24:0a:c4:50:d0:b4\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 3,\n // utm: \"POINT(737192.855816002 9548973.82241332)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:30\",\n // mac: \"24:0a:c4:50:ce:0c\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 30,\n // utm: \"POINT(736950.309098916 9549154.64642585)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:4\",\n // mac: \"c4:4f:33:23:60:f5\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 4,\n // utm: \"POINT(737188.069289794 9548976.02465153)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:5\",\n // mac: \"c4:4f:33:23:66:2d\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 5,\n // utm: \"POINT(737177.211509677 9548984.04094107)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:6\",\n // mac: \"c4:4f:33:23:af:15\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 6,\n // utm: \"POINT(737176.022206202 9548984.34210392)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:7\",\n // mac: \"24:0a:c4:51:0e:50\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 7,\n // utm: \"POINT(737165.040363877 9548993.25490725)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:8\",\n // mac: \"24:0a:c4:50:cf:bc\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 8,\n // utm: \"POINT(737155.518691519 9548999.93485522)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW1:9\",\n // mac: \"24:0a:c4:50:d0:88\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW1\",\n // position: 9,\n // utm: \"POINT(737146.748389802 9549004.84601923)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW2:1\",\n // mac: \"c4:4f:33:23:ad:f9\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW2\",\n // position: 1,\n // utm: \"POINT(737222.126213529 9548954.03472182)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:SVD_FW2:2\",\n // mac: \"b4:e6:2d:ab:fc:9d\",\n // area: \"DMLZ_Undercut\",\n // location: \"SVD_FW2\",\n // position: 2,\n // utm: \"POINT(737235.219806432 9548948.38025427)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // {\n // id: \"DMLZ_Undercut:UCL_SFD:1\",\n // mac: \"4c:11:ae:b7:fa:60\",\n // area: \"DMLZ_Undercut\",\n // location: \"UCL_SFD\",\n // position: 1,\n // utm: \"POINT(737257.531404844 9548936.18414103)\",\n // utm_zone_number: 53,\n // utm_zone_letter: 77,\n // z: null,\n // controller: \"c4:f3:12:81:67:2b\",\n // color: \"GREEN\",\n // state: \"ON\",\n // reported_color: \"GREEN\",\n // reported_state: \"ON\",\n // on_time: null,\n // off_time: null,\n // train: null,\n // timestamp_status: 1616716329,\n // timestamp_state_change: 1618970385,\n // sw_ver: 3.06,\n // reason: null,\n // priority: null,\n // },\n // ];\n\n // function onlyUnique(value, index, self) {\n // return self.indexOf(value) === index;\n // }\n\n // const controllerIds = controllers.map((item) => item.id);\n\n // console.log(`controllerIds`, controllerIds);\n\n // let controllerLocations = [];\n\n // controllerIds.forEach((element) => {\n // const ffs = fireflies.filter((ff) => ff.controller === element);\n\n // const locations = ffs.map((ff) => ff.location);\n\n // const unique = locations.filter(onlyUnique);\n\n // controllerLocations[element] = unique;\n // });\n\n // console.log(`controllerLocations`, controllerLocations);\n\n // controllerIds.forEach((id, index) =>\n // console.log(`${id}, ${controllerLocations[id].join(\",\")}`)\n // );\n\n return (\n
\n \n \n \n \n
Database Tools
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n Save Database\n Restore Database\n Oranges\n Clear Database\n \n \n {/* {JSON.stringify(controllerLocations)} */}\n
\n
\n );\n }\n}\n\n//export default connect(null)(ToolsDatabase);\nexport default ToolsDatabase;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Container, Header, Grid, List, Segment } from \"semantic-ui-react\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { XTerm } from \"xterm-for-react\";\n\nconst Terminal = () => {\n const xtermRef = React.useRef(null);\n React.useEffect(() => {\n // You can call any method in XTerm.js by using 'xterm xtermRef.current.terminal.[What you want to call]\n xtermRef.current.terminal.writeln(\n \"Hello, World! ... nothing to see here...\"\n );\n }, []);\n\n return (\n // Create a new terminal and set it's ref.\n \n );\n};\n\nclass ToolsTerminal extends Component {\n render() {\n return (\n
\n \n \n \n \n
Terminal
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n
\n
\n );\n }\n}\n\nexport default ToolsTerminal;\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Slider } from \"react-semantic-ui-range\";\nimport \"semantic-ui-css/semantic.min.css\";\n\nimport {\n Container,\n Header,\n Grid,\n List,\n Segment,\n Popup,\n Button,\n Icon,\n Message,\n Checkbox,\n Divider,\n} from \"semantic-ui-react\";\n\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { messageToken, getUserSessionIp } from \"utils/messageToken\";\nimport { microTime } from \"utils/microTime\";\nimport { toFireflyColor } from \"utils/toFireflyColor\";\nimport { sleep } from \"utils/sleep\";\n\nimport { mqttPublish } from \"components/WebWorker/actions\";\nimport {\n getFaults,\n getAllNamedAreaEvents,\n getNamedAreaEventsByAreaId,\n getButtonPrioritysInNamedAreaGroupByAreaId,\n getNamedAreaEventButtonGroupState,\n} from \"components/WebWorker/reducer\";\n\nimport { saveNewNamedAreaEvent } from \"NamedAreas/actions\";\nimport {\n activateNamedAreaEvent,\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n waitEventTimeOut,\n updateButtonGroupState,\n} from \"OperationalChanges/actions\";\n\nimport {\n getServerInfo,\n isOnOffPokeTheWorker,\n isDisabledPokeTheWorker,\n getPollRates,\n getMqttBroker,\n} from \"components/Settings/reducer\";\n\nimport {\n getPrevNamedAreaGroups,\n getPrevNamedAreaGroupButtonStates,\n} from \"NamedAreaGroups/reducer\";\n\nimport { ClearFaults } from \"components/MQTT/actions\";\n\nimport {\n TurnOnOffPokeTheWorker,\n DisablePokeTheWorker,\n SetPokeTheWorkerPollRate,\n fetchServerInfo,\n} from \"components/Settings/actions\";\n\nimport { deleteEventLog } from \"components/EventLog/actions\";\nimport { deleteScheduledEventJobs } from \"NamedAreas/actions\";\n\nimport { updateRemoteButtonClick } from \"OperationalChanges/actions\";\nimport _ from \"lodash\";\n\nimport { getMapImages } from \"components/Settings/reducer\";\nimport { DateTime } from \"luxon\";\n\nconst buttonData = [\n \"IOT_Office:f6044b5d-6042-40b3-b8f3-3fd29ac83e61:2\",\n \"IOT_Office:84b8a00e-bd76-49aa-9b38-a914e1ddfc53:1\",\n];\n\nclass ToolsSystem extends Component {\n constructor(props) {\n super(props);\n this.state = {\n workerPollRate: this.props.pollRates.worker,\n workerDisable: this.props.pollRates.disable,\n isLightControlSim: false,\n lightControlSimRate: 5000,\n };\n }\n\n componentDidMount() {\n // #FETCHS\n this.props.fetchServerInfo();\n }\n\n componentDidUpdate(prevProps, prevState) {\n this.props.mapImages.map((img) => {\n const bannerImg = document.getElementById(`${img.id}`);\n bannerImg.src = \"data:image/png;base64,\" + img.imageData;\n });\n }\n\n sendEventClearMsg = () => {\n this.props.mqttPublish({\n topic: `system/event/clear`,\n qos: 0,\n message: {\n clear_events: true,\n token: messageToken(),\n },\n retained: false,\n });\n };\n\n // #NOTE\n // Sends individual clear messages for each fault.\n // This is superceded in favour of `sendFaultClearMsg`\n // Which instructs the server to clear the db of all fault data.\n //\n // Left in place here for reference.\n //\n sendFaultDeleteMsg = () => {\n const faults = this.props.faults;\n\n faults.forEach((fault, idx) => {\n const { type, subtype, id } = fault;\n\n const faultTopic = () => {\n return `fault/${id}/${type}`;\n };\n\n const faultMsg = (id, type, subtype) => {\n return {\n id,\n type,\n subtype,\n active: false,\n delete: true,\n token: messageToken(),\n };\n };\n\n switch (type) {\n case \"network\":\n case \"battery\":\n case \"firefly\":\n // send deactive message\n\n this.props.mqttPublish({\n topic: faultTopic(id, type, subtype),\n qos: 0,\n message: faultMsg(id, type),\n retained: false,\n });\n\n // send null message\n this.props.mqttPublish({\n topic: faultTopic(id, type),\n qos: 0,\n message: {},\n retained: true,\n });\n break;\n\n default:\n break;\n }\n });\n\n // #NOTE\n // #WIP - this clears the fault state _BUT_ this should wait for an ACK from the publish\n // before proceeding.\n // I am waiting for this to be implemented.\n\n // #NOTE - this clears the fault state locally, but note that the `system/fault/clear`\n // is also receive by the worker and will clear the state from the front end.\n this.props.ClearFaults();\n };\n\n sendFaultClearMsg = () => {\n // Other clients need to receive this message to clear their states _but_ mqtt does not process empty messages.\n // So send an additional message with the anticipated ongoing format.\n this.props.mqttPublish({\n topic: `system/fault/clear`,\n qos: 0,\n message: {\n clear_faults: true,\n token: messageToken(),\n },\n retained: false,\n });\n\n // #NOTE\n // #WIP - this clears the fault state _BUT_ this should wait for an ACK from the publish\n // before proceeding.\n // I am waiting for this to be implemented.\n\n // #NOTE - this clears the fault state locally, but note that the `system/fault/clear`\n // is also receive by the worker and will clear the state from the front end.\n this.props.ClearFaults();\n };\n\n handleDeleteEventLog = () => {\n this.props.deleteEventLog({ start: 0, end: 0 });\n };\n\n handleDeleteEventJob = () => {\n this.props.deleteScheduledEventJobs();\n };\n\n onChangeCheckbox = (evt, data) => {\n let checked = data.checked;\n\n this.props.DisablePokeTheWorker(!checked);\n\n this.setState({\n workerDisable: !checked,\n });\n };\n\n handleTimeout = (timerProps) => {\n const sampleRandomButton = _.sample(buttonData);\n //console.log(`sim sampleRandomButton`, sampleRandomButton);\n //console.log(`sim this.props`, this.props);\n this.props.updateRemoteButtonClick([sampleRandomButton]);\n };\n\n onChangeLightControlSimCheckbox = (evt, data) => {\n let checked = data.checked;\n\n this.setState({\n isLightControlSim: checked,\n });\n };\n\n // #DEBUG - reports lighting events\n reportDebugLightingEvents = () => {\n const {\n allNamedAreaEvents,\n namedAreaEventsByAreaId,\n namedAreaGroupButtons,\n namedAreaEventButtonGroupState,\n saveNewNamedAreaEvent,\n updateButtonGroupState,\n buttonGroupStates,\n cancelNamedAreaEvent,\n activateNamedAreaEvent,\n prevNamedAreaGroups,\n prevNamedAreaGroupButtonStates,\n } = this.props;\n\n //console.clear();\n console.log(\"report UPDATE_NAMED_AREA_GROUP --------\");\n\n // fitler for test_area, active\n const activeAllNamedAreaEvents = namedAreaEventsByAreaId\n .filter((event) => event.active)\n .map((event) => {\n const { id, priority } = event;\n return { id, priority };\n });\n\n const sortActiveAllNamedAreaEvents = [...activeAllNamedAreaEvents].sort(\n (a, b) => b.priority - a.priority\n );\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP sortFilteredAllNamedAreaEvents\",\n sortActiveAllNamedAreaEvents\n );\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtons\",\n namedAreaGroupButtons\n );\n\n let namedAreaGroupButtonStates = [];\n namedAreaGroupButtons.forEach((button) => {\n const {\n id: buttonId,\n priority: buttonPriority,\n event: buttonEvent,\n level,\n group,\n } = button;\n\n const isActiveEvent = activeAllNamedAreaEvents.some(\n (event) =>\n event.id.includes(buttonId) && event.priority === buttonPriority\n );\n\n // namedAreaGroupButtonStates.push({\n // id: buttonId,\n // buttonPriority: buttonPriority,\n // eventId: isActiveEvent?.id,\n // eventPriority: isActiveEvent?.priority,\n // });\n\n namedAreaGroupButtonStates.push({\n id: buttonId,\n priority: buttonPriority,\n active: isActiveEvent,\n buttonEvent: buttonEvent,\n level,\n group,\n });\n });\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates\",\n namedAreaGroupButtonStates\n );\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP prevNamedAreaGroupButtonStates\",\n prevNamedAreaGroupButtonStates\n );\n\n // ------------------------------\n // restore to previous state\n // ------------------------------\n\n if (true) {\n //\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP buttonGroupState\",\n buttonGroupStates\n );\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates -------------------------\"\n );\n\n let newButtonGroupState = { ...buttonGroupStates };\n let newActiveEventList = [];\n\n namedAreaGroupButtonStates.forEach((button, index) => {\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates namedAreaGroupButtonState\",\n button\n );\n\n const { id, buttonEvent, level, priority } = button;\n\n // search for previous events with the same id\n const prevNamedAreaGroupButtonState = prevNamedAreaGroupButtonStates?.[\n \"test_area\"\n ]?.filter((button) => button.id === id && button.level === level);\n // if find more than one event determine which, if any, to restore to previous state\n //\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates prevNamedAreaGroupButtonState\",\n prevNamedAreaGroupButtonState\n );\n\n // initially lets deal with first/top .............\n //\n // #NOTE - since the events are stepped through from highest priority first,\n // the next highest priority event will be set active.\n //\n // #REVIEW\n // - set the lowest active?\n // - only set if in same group?\n // - only set if on same level?\n //\n const restoreToButton = prevNamedAreaGroupButtonState?.[0];\n\n // if a previous event was found and event was active\n if (restoreToButton && restoreToButton?.active) {\n // and if the event has not already been set here (only one event per polygon)\n if (!newActiveEventList.includes(id)) {\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP namedAreaGroupButtonStates restoreToButton ####### ---> \",\n restoreToButton,\n \"buttonEvent \",\n buttonEvent\n );\n\n newButtonGroupState[id] = { 0: priority };\n updateButtonGroupState(newButtonGroupState);\n activateNamedAreaEvent(buttonEvent);\n newActiveEventList.push(id);\n }\n }\n });\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP prevNamedAreaGroups\",\n prevNamedAreaGroups\n );\n }\n\n // ------------------------------\n\n if (false) {\n //\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP buttonGroupState\",\n buttonGroupStates\n );\n\n let newButtonGroupState = { ...buttonGroupStates };\n\n namedAreaGroupButtonStates.forEach((button, index) => {\n // #TEST - only one time through\n\n if (false) {\n const { id, active, buttonEvent, priority } = button;\n\n switch (active) {\n case true:\n console.log(\n \"UPDATE_NAMED_AREA_GROUP cancelNamedAreaEvent\",\n buttonEvent\n );\n newButtonGroupState[id] = { 0: -1 };\n updateButtonGroupState(newButtonGroupState);\n cancelNamedAreaEvent(buttonEvent);\n\n break;\n case false:\n console.log(\n \"UPDATE_NAMED_AREA_GROUP activateNamedAreaEvent\",\n buttonEvent\n );\n newButtonGroupState[id] = { 0: priority };\n updateButtonGroupState(newButtonGroupState);\n activateNamedAreaEvent(buttonEvent);\n break;\n\n default:\n break;\n }\n }\n });\n\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP prevNamedAreaGroups\",\n prevNamedAreaGroups\n );\n }\n\n // ------------------------------\n const activeNamedAreaGroupButtonStates = namedAreaGroupButtonStates.filter(\n (button) => button.active\n );\n\n // #TESTING -\n // ^ ... retained the system state above, so now test by 1st clearing all messages.\n // wait for 2 seconds, then resend the same setup again.\n\n //this.sendEventClearMsg();\n //sleep(1000); // wait for the clear event to go through\n //console.log(\"report UPDATE_NAMED_AREA_GROUP finished sleep!\");\n\n // #NOTE #WIP #REVIEW - SIMILAR CODE TO src/components/WebWorker/reducer.js\n //\n let promiseArray = [];\n if (false) {\n activeNamedAreaGroupButtonStates.reverse().forEach((namedArea, index) => {\n // prepare message token\n const userSessionIp = getUserSessionIp();\n const token = messageToken(userSessionIp);\n const timestamp = microTime();\n\n const { id, button } = namedArea;\n const {\n priority,\n active,\n active_color,\n active_state,\n on_time,\n off_time,\n train,\n relay_active,\n } = button;\n\n const buttonGroupState = namedAreaEventButtonGroupState[id];\n\n let eventMsg = {};\n eventMsg = {\n id: `${id}:${timestamp}`,\n priority: priority,\n active: !active,\n active_color: toFireflyColor(active_color),\n active_state: active_state,\n on_time: on_time,\n off_time: off_time,\n train: train,\n button_groups: JSON.stringify(buttonGroupState),\n timestamp: timestamp,\n precanned: 0, // not used ATM\n relay_event_active: relay_active || 0,\n token: token,\n };\n\n console.log(\"report UPDATE_NAMED_AREA_GROUP eventMsg\", eventMsg);\n\n if (false) {\n const eventPayload = {\n topic: `named_area/${eventMsg.id}/event`,\n qos: 0,\n message: eventMsg,\n retained: true,\n };\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveNewNamedAreaEvent({\n values: eventPayload,\n resolve,\n reject,\n });\n })\n );\n }\n });\n }\n console.log(\n \"report UPDATE_NAMED_AREA_GROUP sending promiseArray\",\n promiseArray\n );\n\n // send out active events .....\n if (promiseArray.length > 0) {\n Promise.all(promiseArray).then((results) => {\n console.log(\"SUCCESS UPDATE_NAMED_AREA_GROUP - results \", results);\n });\n }\n\n console.log(\"report UPDATE_NAMED_AREA_GROUP --------\");\n };\n\n render() {\n const {\n serverInfo,\n pollRates,\n isDisable,\n fetchedMqttBroker,\n userSessionIp,\n mapImages,\n strings,\n } = this.props;\n\n const { worker } = pollRates;\n const { isLightControlSim, lightControlSimRate } = this.state;\n\n const settingsWebworker = {\n start: worker / 1000,\n min: 0.5,\n max: 16,\n step: 0.5,\n onChange: (value) => {\n this.props.SetPokeTheWorkerPollRate(value * 1000); // in milliseconds\n //\n this.setState({\n workerPollRate: value * 1000,\n });\n },\n };\n\n const settingsLightControlSim = {\n start: 5000 / 1000,\n min: 0.5,\n max: 16,\n step: 0.5,\n onChange: (value) => {\n this.setState({\n lightControlSimRate: value * 1000,\n });\n },\n };\n\n const imageContent = mapImages.map((image) => (\n \n \n \"\"\n \n \n ));\n\n // e.g. const date = DateTime.fromISO(\"2010-10-22T21:38:00\");\n const humanReadable = DateTime.now().toLocaleString(DateTime.DATETIME_MED);\n\n return (\n
\n \n \n \n \n
{strings?.[\"System Tools\"]}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n \n \n {strings?.[\"Administrator Use Only\"]}\n \n {strings?.[\"ADMIN_ONLY_MESSAGE\"]}\n \n \n\n \n \n \n \n
{strings?.[\"Server Operations\"]}
\n \n \n \n \n \n \n }\n />\n
\n Clear all lighting events\n
\n \n \n \n \n \n \n }\n />\n
\n Clear all device fault database\n
\n \n \n \n \n \n }\n />\n
\n Clear all device fault messages\n
\n \n {true && (\n \n \n \n \n }\n />\n
\n Clear all Event Log messages\n
\n \n )}\n \n \n \n \n }\n />\n
\n Clear all Event Jobs\n
\n \n {/* #DEBUG #TESTING - \"Report lighting events info\" was setup for testing event clear and propogation. \n This is left in place for future use. */}\n {false && (\n \n \n \n \n }\n />\n
\n Report lighting events info\n
\n \n )}\n
\n
\n
\n \n \n
MQTT/Webworker Message Collection
\n \n this.onChangeCheckbox(evt, data)\n }\n />\n }\n />\n
\n Poll rate {this.state.workerPollRate / 1000} seconds\n
\n \n
\n
\n {false && (\n \n \n \n
Area Map Images
\n \n {imageContent}\n \n
\n
\n
\n )}\n {/* \n \n
Light Control Simulator
\n \n this.onChangeLightControlSimCheckbox(evt, data)\n }\n />\n }\n />\n
\n {`Button cycle rate ${\n this.state.lightControlSimRate / 1000\n } seconds`}\n
\n \n
\n
*/}\n
\n \n \n \n
{strings?.[\"MQTT Information\"]}
\n \n \n {\"broker\"}\n
\n {JSON.stringify(fetchedMqttBroker)}\n
\n
\n
\n
\n \n \n
{strings?.[\"Session Information\"]}
\n \n \n {\"current local time\"}\n
\n {humanReadable}\n
\n \n {\"username and client IP\"}\n
\n {JSON.stringify(userSessionIp)}\n
\n
\n
\n
\n \n \n
{strings?.[\"Server Information\"]}
\n {Object.keys(serverInfo).map((key, idx) => {\n return (\n
\n {key}\n

{JSON.stringify(serverInfo[key])}

\n
\n );\n })}\n
\n
\n
\n
\n
\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n //\n\n return {\n faults: getFaults(state),\n serverInfo: getServerInfo(state),\n isPokeTheWorker: isOnOffPokeTheWorker(state),\n pollRates: getPollRates(state),\n isDisable: isDisabledPokeTheWorker(state),\n fetchedMqttBroker: getMqttBroker(state),\n userSessionIp: getUserSessionIp(),\n mapImages: getMapImages(state),\n //\n allNamedAreaEvents: getAllNamedAreaEvents(state),\n namedAreaEventsByAreaId: getNamedAreaEventsByAreaId(state, \"test_area\"),\n namedAreaGroupButtons: getButtonPrioritysInNamedAreaGroupByAreaId(\n state,\n \"test_area\"\n ),\n namedAreaEventButtonGroupState: getNamedAreaEventButtonGroupState(state),\n buttonGroupStates: getNamedAreaEventButtonGroupState(state),\n prevNamedAreaGroups: getPrevNamedAreaGroups(state),\n prevNamedAreaGroupButtonStates: getPrevNamedAreaGroupButtonStates(state),\n };\n};\n\nexport default connect(mapStateToProps, {\n mqttPublish,\n ClearFaults,\n TurnOnOffPokeTheWorker,\n DisablePokeTheWorker,\n SetPokeTheWorkerPollRate,\n fetchServerInfo,\n updateRemoteButtonClick,\n //\n saveNewNamedAreaEvent,\n //\n activateNamedAreaEvent,\n cancelNamedAreaEvent,\n activateNamedAreaEventSingle,\n updateButtonGroupState,\n deleteEventLog,\n deleteScheduledEventJobs,\n})(ToolsSystem);\n","export function UpdateMqttMsg(mqttMsg) {\n return { type: \"MQTT_MSG_UPDATE\", payload: mqttMsg };\n}\n\nexport function ClearMqttMsg() {\n return { type: \"MQTT_MSG_CLEAR\" };\n}\n\n// #NOTE - same as above.\n// Transitioning from \"mqttMsg\" to \"faults\"\nexport function ClearFaults() {\n return { type: \"MQTT_MSG_CLEAR\" };\n}\n","// see - https://codesandbox.io/s/04lz4580pl?file=/src/index.js\n// - https://stackoverflow.com/questions/62420839/reading-multiple-files-cotents-react-js\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport { Button, Popup, Icon } from \"semantic-ui-react\";\n\nimport {\n saveFolderFile,\n fetchFolderFilesListByFolder,\n} from \"components/Settings/actions\";\n\nclass _Upload extends Component {\n constructor() {\n super();\n this.state = {\n isFileUploaded: false,\n show: false,\n //\n file: null,\n fileName: \"\",\n fileType: \"\",\n //\n //\n uploadButton: { disabled: false },\n };\n }\n\n fileInputRef = React.createRef();\n\n requestAction = (action) => {\n const { file } = this.state;\n\n const { saveFolderFile } = this.props;\n\n let promiseArray = [];\n\n if (action === \"save\") {\n //for (var key in selections) {\n //const selection = key; // mac address\n\n //console.log(\"saveFolderFile file \", file);\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n saveFolderFile({\n values: {\n filename: \"filenameblah\", // #WIP #REVIEW - ATM we do not pass the filename and folder. These default\n folder: \"folderblah\",\n file: file,\n },\n resolve,\n reject,\n })\n )\n );\n //}\n }\n\n //console.log(\"saveFolderFile file promiseArray \", promiseArray);\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\" .... processed request\", results);\n })\n .then(\n () => {\n this.props.fetchFolderFilesListByFolder(\"backups\"); // #FETCHS\n //this.props.push(`/tools/backup-restore`);\n },\n (errorMsg) => {\n console.log(\"action failed\", errorMsg); // #TODO probs should show this?\n }\n );\n };\n\n fileChange = (e) => {\n this.setState({ file: e.target.files[0] }, () => {\n //console.log(\"fileupload File chosen --->\", this.state.file);\n\n this.requestAction(\"save\");\n\n // set a timer so the user does not pound the upload button,\n // as the upload takes a few seconds to be processed\n this.setState({\n uploadButton: { disabled: true },\n });\n setTimeout(() => {\n this.setState({\n uploadButton: { disabled: false },\n });\n }, 4000); // wait for a timeout before making button active\n });\n };\n\n render() {\n const {\n popup = \"\",\n label = \"\",\n fileType = \".zip\",\n disabled = false,\n } = this.props;\n return (\n <>\n this.fileInputRef.current.click()}\n disabled={this.state.uploadButton.disabled || disabled}\n loading={this.state.uploadButton.disabled}\n >\n }\n />\n \n \n );\n }\n}\n\nexport const Upload = connect(null, {\n saveFolderFile,\n fetchFolderFilesListByFolder,\n})(_Upload);\n","import React, { Component } from \"react\";\nimport { push } from \"react-router-redux\";\n\nimport { connect } from \"react-redux\";\nimport { Link } from \"react-router-dom\";\n\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Popup,\n Icon,\n Checkbox,\n Message,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\nimport { getFolderFilesListById } from \"components/Settings/reducer\";\nimport {\n deleteFolderFile,\n fetchFolderFilesListByFolder,\n} from \"components/Settings/actions\";\n\nimport GenericButton from \"admin/GenericButton\";\nimport { Upload } from \"admin/UploadButton\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport _every from \"lodash/every\";\nimport _has from \"lodash/has\";\nimport _size from \"lodash/size\";\nimport hash from \"object-hash\";\n\n// #REVIEW - only use of this immute helper -consider replacing for consistency when time\nimport update from \"immutability-helper\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { callRunScript } from \"components/Tools/actions\";\n\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\nimport { getUserData } from \"auth/reducer\";\nimport { isSystemRestore } from \"components/Settings/reducer\";\n\nfunction _derivedState(incomingState) {\n // Sets derived state based on new selections\n return Object.assign({}, incomingState, {\n areAnySelected: !_isEmpty(incomingState.selections),\n selectedCount: _size(incomingState.selections),\n });\n}\n\nclass ToolsBackupRestore extends Component {\n constructor(props) {\n super(props);\n this.state = {\n // initialise data list sort columns\n column: null,\n data: props.data,\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n id: \"\",\n fileDateStr: \"\",\n fileSize: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n // manage row checkbox enabledDisable selections\n areAnySelected: false,\n selectedCount: 0,\n selections: {},\n //\n backupButton: { disabled: false },\n };\n }\n\n componentDidMount() {\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"backupfilenameList\"\n );\n\n if (!_.isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n }\n\n this.props.fetchFolderFilesListByFolder(\"backups\"); // #FETCHS\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"backupfilenameList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { filterInput: match } = this.state;\n\n if (\n JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n JSON.stringify(this.props.data) !== JSON.stringify(prevProps.data) // if original props data changes\n ) {\n let newData = [...this.props?.data]; // original data\n\n newData = newData.filter(function (item) {\n let checkMatch = true; // assume all included as default \"\" is always included\n\n for (var key in match) {\n checkMatch =\n checkMatch &&\n item[key]?.toLowerCase().includes(match[key].toLowerCase()); // remove item which don't match\n }\n return checkMatch;\n });\n\n this.setState({\n data: newData,\n });\n\n // restore sort\n const { column, direction } = this.state;\n\n // #REVIEW - decide if need a default sort column\n // column is initially undefined. i.e. no default sort column\n if (column) {\n newData = newData.slice().sort((a, b) =>\n a[column].localeCompare(b[column], \"en\", {\n numeric: true,\n })\n );\n }\n\n // newData = _.sortBy(newData, [column]);\n\n if (direction === \"descending\") {\n newData = newData.reverse();\n }\n this.setState({\n data: newData,\n });\n }\n }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n handleClearAll = () => {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n };\n\n handleSelect = (id) => {\n this.setState((prevState) => {\n if (_has(prevState.selections, id)) {\n // { 1: true } -> {}\n return _derivedState(\n update(prevState, {\n selections: { $unset: [id] },\n })\n );\n }\n // {} -> { 1: true }\n return _derivedState(\n update(prevState, {\n selections: { [id]: { $set: true } },\n })\n );\n });\n };\n\n handleSelectAll = (items) => {\n if (_isEmpty(this.state.selections)) {\n const newSelections = {};\n items.forEach((item) => {\n if (!item.disableUnassign) newSelections[item.id] = true;\n });\n this.setState(\n _derivedState({\n selections: newSelections,\n })\n );\n } else {\n this.setState(\n _derivedState({\n selections: {},\n })\n );\n }\n };\n\n areAllIndeterminate = (items) =>\n !_isEmpty(this.state.selections) && !this.areAllSelected(items);\n areAllSelected = (items) =>\n _every(items, (item) => _has(this.state.selections, item.id));\n isItemSelected = (id) => _has(this.state.selections, id);\n\n backup = () => {\n this.props.callRunScript({\n folder: \"backups\",\n action: \"backup\",\n id: \"\",\n });\n\n // set a timer so the user does not pound the backup button,\n // as the backup takes a few seconds to be processed\n this.setState({\n backupButton: { disabled: true },\n });\n setTimeout(() => {\n this.props.fetchFolderFilesListByFolder(\"backups\");\n this.setState({\n backupButton: { disabled: false },\n });\n }, 4000); // wait for a timeout before making button active\n };\n\n restore = (filenames) => {\n console.log(\"RESTORE ZIP FILENAME \", filenames.replace(/\\.[^/.]+$/, \"\"));\n\n this.props.callRunScript({\n folder: \"backups\",\n action: \"restore\",\n id: filenames.replace(/\\.[^/.]+$/, \"\"),\n });\n };\n\n requestAction = (action) => {\n const { selections } = this.state;\n\n const { deleteFolderFile } = this.props;\n\n let promiseArray = [];\n\n if (action === \"delete\") {\n for (var key in selections) {\n const selection = key; // mac address\n\n //console.log(\"deleteFolderFile selection \", selection);\n\n promiseArray.push(\n new Promise((resolve, reject) =>\n deleteFolderFile({\n values: { filename: selection, folder: \"backups\" },\n resolve,\n reject,\n })\n )\n );\n }\n }\n\n return Promise.all(promiseArray)\n .then((results) => {\n console.log(\" .... processed request\", results);\n })\n .then(\n () => {\n this.props.fetchFolderFilesListByFolder(\"backups\"); // #FETCHS\n this.props.push(`/tools/backup-restore`);\n },\n (errorMsg) => {\n console.log(\"action failed\", errorMsg); // #TODO probs should show this?\n }\n );\n };\n\n render() {\n const { isLoading, error, strings } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n const includeTitles = this.props.includeTitles === \"true\";\n const title = includeTitles ? (\n
{strings?.[\"Backup and Restore\"]}
\n ) : (\n
\n );\n\n // APP_TERMINOLOGY\n let strFile = strings?.[\"File\"];\n let strFiles = strings?.[\"Files\"];\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n // if enough faults display paginationSelect items in the table below to apply an action.\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const areAnySelected = !_isEmpty(this.state.selections);\n const selectedCount = _size(this.state.selections);\n const selections = this.state.selections;\n\n const { data: allData } = this.props; // get unfiltered data\n const filenameFromDataById = (id) => allData.find((item) => item.id == id); // falsey\n\n const sortAlphaNum = (a, b) => a.localeCompare(b, \"en\", { numeric: true });\n\n let updateButton;\n let backupButton;\n let uploadButton;\n let deleteButton;\n let restoreButton;\n let isRestoreMessage = false;\n let filenameSelectedList;\n\n updateButton = (\n this.props.fetchFolderFilesListByFolder(\"backups\")}\n size=\"large\"\n disabled={this.props.isSystemRestore}\n >\n {strings?.[\"Update\"]}\n \n }\n />\n );\n\n backupButton = (\n this.backup()}\n >\n {strings?.[\"Backup\"]}\n \n }\n />\n );\n\n uploadButton = (\n \n );\n\n if (selectedCount > 0) {\n let filenames = [];\n\n // #REVIEW - WIP\n for (var key in selections) {\n if (filenameFromDataById(key) !== undefined) {\n let filename = filenameFromDataById(key).id;\n filenames.push(filename);\n }\n }\n\n filenames.sort(sortAlphaNum);\n filenames = filenames.join(\", \"); // separate by commas\n\n deleteButton = (\n this.requestAction(\"delete\")}\n size=\"large\"\n disabled={this.props.isSystemRestore}\n />\n );\n\n restoreButton = (\n this.restore(filenames)}\n disabled={selectedCount !== 1 || this.props.isSystemRestore}\n size=\"large\"\n >\n {strings?.[\"Restore\"]}\n \n }\n />\n );\n\n isRestoreMessage = selectedCount === 1;\n\n filenameSelectedList = (\n \n {`${strFiles} selected ...`} \n {filenames}\n \n );\n }\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n return (\n
\n \n \n \n \n
{title}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n {!areAnySelected && (\n <>\n \n {updateButton}\n {true && }\n {backupButton}\n {true && }\n {uploadButton}\n \n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n \n )}\n \n \n {selectedCount} selected\n \n \n \n {strings?.[\"Clear\"]}\n \n \n {deleteButton}\n \n {restoreButton}\n \n
\n \n {viewablesPage.length} items displayed. {selectedCount} selected\n \n \n {filenameSelectedList}\n \n\n {/* \n \n {!areAnySelected && (\n \n {\n strings?.[\n \"Select items in the table below to apply an action\"\n ]\n }\n \n )}\n \n \n {selectedCount} selected\n \n \n \n {deleteButton}\n \n {restoreButton}\n \n \n
\n {viewablesPage.length} items displayed.\n
\n
\n {filenameSelectedList}\n
*/}\n {isRestoreMessage && (\n \n \n \n \n {strings?.[\"Restore Warning Message Header\"]}\n \n {strings?.[\"Restore Warning Message Content\"]}\n \n \n )}\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n this.handleSelectAll(viewablesPage)}\n />\n \n \n {strings?.[\"File Name\"]}\n \n \n {strings?.[\"File Date\"]}\n \n \n {strings?.[\"File Size\"]}\n \n \n \n \n {_.map(\n viewablesPage,\n ({ id, idLink, fileDate, fileSize, fileDateStr }) => (\n \n \n this.handleSelect(id)}\n //disabled={disableUnassign}\n />\n \n {idLink}\n {fileDateStr}\n {fileSize}\n \n )\n )}\n \n \n
\n {pagination}\n \n \n \n );\n }\n}\n\nconst _prepData = (elements, userLanguage) => {\n let filteredElements = [];\n\n // only need a subset of data\n elements.forEach((element, idx) => {\n const link = (\n \n {element?.filename}\n \n );\n\n const dateStr = new Date(Number(element?.filedate) * 1000).toLocaleString(\n userLanguage,\n {\n weekday: \"short\",\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n hour12: false,\n }\n );\n\n // compose new data set\n filteredElements[idx] = {\n id: element?.filename,\n idLink: link,\n fileDate: `${element?.filedate}`,\n fileDateStr: dateStr,\n fileSize: `${element?.filesize}`,\n };\n });\n\n // sort newest - oldest\n return [...filteredElements].sort((a, b) => b.fileDate - a.fileDate);\n};\n\nfunction mapStateToProps(state, props) {\n const folderFilesList = getFolderFilesListById(state, \"backups\") || [];\n\n const userLanguage = getUserData(state)?.language || \"en-US\";\n const data = _prepData(folderFilesList, userLanguage);\n\n return {\n data,\n userLanguage,\n isSystemRestore: isSystemRestore(state),\n };\n}\n\nexport default withComponentStateCache(\n connect(mapStateToProps, {\n push,\n callRunScript,\n deleteFolderFile,\n fetchFolderFilesListByFolder,\n saveUserSettingsComponentState,\n })(ToolsBackupRestore)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport {\n Table,\n Container,\n Button,\n Header,\n Grid,\n Input,\n Pagination,\n Dropdown,\n Segment,\n Icon,\n Popup,\n Label,\n} from \"semantic-ui-react\";\nimport { TrailingContent } from \"components/TableTrailingContent\";\nimport FlashMessagesList from \"FlashMessages\";\n\nimport { timeConverter } from \"../../utils/format-time\";\nimport { formatDate } from \"utils/format-date\";\n\nimport _ from \"lodash\";\nimport _isEmpty from \"lodash/isEmpty\";\n\nimport { ClearLog } from \"components/Logger/actions\";\n\nimport { DebugPagePropsMessages } from \"components/Debug/propsMessages\";\n\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { saveUserSettingsComponentState } from \"components/UserAdmin/actions\";\n\nimport { mqttTopicOptions as _mqttTopicOptions } from \"components/ConfigJs\";\n\nimport { getMqttBroker } from \"components/Settings/reducer\";\n\nimport Paho from \"paho-mqtt\"; // npm install paho-mqtt --save\n\n// XLSL 'react-export-excel' IMPLEMENTATION\n// click button to download report\n// uses https://www.npmjs.com/package/react-export-excel\n// see ex - https://github.com/rdcalle/react-export-excel/blob/HEAD/examples/with_custom_download_element.md\nimport ReactExport from \"react-export-excel\";\nconst ExcelFile = ReactExport.ExcelFile;\nconst ExcelSheet = ReactExport.ExcelFile.ExcelSheet;\nconst ExcelColumn = ReactExport.ExcelFile.ExcelColumn;\n\nclass Download extends React.Component {\n render() {\n const { data } = this.props;\n const filename = `mqtt_messages_report_${formatDate(\n new Date(Date.now()),\n \"dd-MMM-yy-HH-mm-ss\"\n )}`;\n\n return (\n \n \n \n }\n />\n }\n >\n \n \n \n \n \n \n );\n }\n}\n\n// var network = {\n// //\n// protocol: \"ws\",\n// address: \"192.168.1.99\",\n// port: \"1885\",\n// //\n// subscribe: \"firefly/+/lightingstatus\", //\"ups/+/status\",\n// consoleTopic: true,\n// consoleMessage: true,\n// };\n\n// const {\n// rejectUnauthorized,\n// protocol,\n// address,\n// port,\n// subscribe,\n// consoleTopic,\n// consoleMessage,\n// } = network;\n\n// const options = {\n// port: port || \"1884\",\n// host: address || \"192.168.1.99\",\n// protocol: protocol || \"wss\",\n// };\n\n// const topic = subscribe || \"firefly/+/lightingstatus\";\n\n// Create a client instance\n// var client = new Paho.Client(options.host, Number(options.port), \"clientId\");\n// secure websocket connection\n// https://pi3g.com/2019/05/17/correct-way-to-instantiate-paho-client-in-javascript-for-wss-secure-websocket/\n\nvar toolsMqttListClient;\n\nconst connectWS = (protocol, address, port) => {\n return new Promise(function (resolve, reject) {\n let server = new WebSocket(`${protocol}://${address}:${port}/`);\n server.addEventListener(\"error\", function (event) {\n console.log(\"MQTT List - DEBUG: WebSocket error:\", event);\n });\n server.onopen = function () {\n console.log(`MQTT List - connectWS onopen `, server);\n resolve(server);\n };\n server.onerror = function (err) {\n console.log(`MQTT List - connectWS onerror `, err);\n\n reject(err);\n };\n });\n};\n\nconst mqttTopicOptions = _mqttTopicOptions();\n\nconst messageTxt = (msg) =>\n JSON.stringify(msg, null, 2).replace(/\\\\n/g, \"\\n\").replace(/\\\\\"/g, '\"');\n\nclass ToolsMqttList extends Component {\n constructor(props) {\n super(props);\n const downloadData = [];\n this.state = {\n downloadData,\n // initialise data list sort columns\n column: null,\n data: [],\n direction: null,\n // intialise filter input strings\n filterInput: {\n // called \"filterInput\" to avoid reserved word .filter\n // #NOTE - some list page versions of filtering have e.g. { strings: ..., include: true}\n // this is used when there is a dropdown list to remove the whole group from the data search\n time: \"\",\n message: \"\",\n topic: \"\",\n },\n // intialise pagination of data list items\n page: 1,\n itemsPerPage: 10,\n\n // mqtt\n topic: \"firefly/+/lightingstatus\",\n isClientConnected: false,\n upsFFCount: {},\n topicSelect: 1,\n };\n }\n\n // called when a message arrives\n onMessageArrived = (message) => {\n //that.setState({ message: message.payloadString });\n // that.setState({ message: message.topic });\n\n const timestamp = new Date().getTime();\n\n let newMessage = [...(this.state?.data || [])]; // if undefined return empty array\n\n newMessage.unshift({\n topic: messageTxt(message.topic),\n message: messageTxt(message.payloadString),\n time: timestamp > 0 ? timeConverter(timestamp) : \"-\",\n });\n\n this.setState({ data: newMessage });\n };\n\n unSubscribe = (topic) => {\n console.log(\"MQTT List - unsubscribe to \", topic);\n\n toolsMqttListClient.unsubscribe(topic, function (err) {\n if (err) {\n console.log(\n \"MQTT - Error - could not unsubscribe \" +\n topic +\n \": \" +\n err.toString()\n );\n }\n });\n };\n\n // called when subscribed to topic\n onSubscribe = () => {\n console.log(\"MQTT List - onSubscribe!\");\n this.setState({ isClientConnected: true });\n };\n\n // called when the client loses its connection\n onConnectionLost = (responseObject) => {\n this.setState({ isClientConnected: false });\n if (responseObject.errorCode !== 0) {\n console.log(\n \"MQTT List - onConnectionLost:\" + responseObject.errorMessage\n );\n }\n };\n\n // called when the client connects\n onConnect = () => {\n // Once a connection has been made, make a subscription and send a message.\n console.log(\"MQTT List - onConnect subscribe to topic \", this.state.topic);\n\n toolsMqttListClient.subscribe(this.state.topic, {\n onSuccess: this.onSubscribe,\n });\n //var message = new Paho.Message(\"Hello\");\n //message.destinationName = \"World\";\n //client.send(message);\n };\n\n // _OLD\n //\n _setupMQTT = () => {\n let that = this;\n\n // set callback handlers\n toolsMqttListClient.onConnectionLost = onConnectionLost;\n toolsMqttListClient.onMessageArrived = onMessageArrived;\n\n // connect the client\n toolsMqttListClient.connect({ onSuccess: onConnect });\n\n // called when the client connects\n function onConnect() {\n // Once a connection has been made, make a subscription and send a message.\n console.log(\"Connect to topic \", that.state.topic);\n toolsMqttListClient.subscribe(that.state.topic, {\n onSuccess: onSubscribe,\n });\n //var message = new Paho.Message(\"Hello\");\n //message.destinationName = \"World\";\n //client.send(message);\n }\n\n // called when subscribed to topic\n function onSubscribe() {\n console.log(\"onSubscribe\");\n that.setState({ isClientConnected: true });\n }\n // called when the client loses its connection\n function onConnectionLost(responseObject) {\n if (responseObject.errorCode !== 0) {\n console.log(\"onConnectionLost:\" + responseObject.errorMessage);\n }\n }\n\n // called when a message arrives\n function onMessageArrived(message) {\n //that.setState({ message: message.payloadString });\n // that.setState({ message: message.topic });\n\n const timestamp = new Date().getTime();\n\n let newMessage = that.state.data;\n\n newMessage.unshift({\n topic: messageTxt(message.topic),\n message: messageTxt(message.payloadString),\n time: timestamp > 0 ? timeConverter(timestamp) : \"-\",\n });\n\n that.setState({ data: newMessage });\n }\n };\n\n componentDidMount() {\n const { fetchedMqttBroker } = this.props;\n\n const { address, port, protocol } = fetchedMqttBroker;\n\n const filterInput = this.props.componentstate.get(\n \"filterInput\",\n \"mqttMessageList\"\n );\n\n if (!_isEmpty(filterInput)) {\n this.setState({ filterInput: filterInput });\n }\n\n console.log(`MQTT List - connect to ${protocol}://${address}:${port}/mqtt`);\n\n // setup paho client\n const clientId = `mqttjs_${Math.random().toString(16).substr(2, 8)}`;\n\n toolsMqttListClient = new Paho.Client(\n `${protocol}://${address}:${port}/mqtt`,\n clientId\n );\n\n // load topic from the options list\n const newTopic = mqttTopicOptions.find(\n (option) => option.value === this.state.topicSelect\n )?.text;\n\n this.setState({ topic: newTopic });\n\n // # DEBUG TESTS - CONNECT MQTT WITHOUT TESTING connectWS\n if (false) {\n // set callback handlers\n toolsMqttListClient.onConnectionLost = this.onConnectionLost;\n toolsMqttListClient.onMessageArrived = this.onMessageArrived;\n\n // connect the client\n toolsMqttListClient.connect({ onSuccess: this.onConnect });\n }\n\n // check WS connection and connect\n true &&\n connectWS(protocol, address, port)\n .then((server) => {\n server.close(); // OK!, so close the test connection\n console.log(\"MQTT List - WSS connection checked OK!\");\n\n //_this.setupMQTT();\n\n // set callback handlers\n toolsMqttListClient.onConnectionLost = this.onConnectionLost;\n toolsMqttListClient.onMessageArrived = this.onMessageArrived;\n\n // connect the client\n toolsMqttListClient.connect({ onSuccess: this.onConnect });\n })\n .catch((error) => {\n console.log(\"connectWS error\", error);\n });\n }\n\n componentWillUnmount() {\n const settings = {\n section: \"filterInput\",\n key: \"mqttMessageList\",\n data: { ...this.state.filterInput },\n };\n\n this.props.componentstate.set(\n settings.section,\n settings.key,\n settings.data\n );\n\n this.props.saveUserSettingsComponentState({ settings });\n\n if (this.state.isClientConnected) {\n this.unSubscribe(\"#/#/#\"); // may not be necessary\n toolsMqttListClient.disconnect();\n }\n }\n\n // #TODO - Fix filtering.\n // The problem is that filtering is destructive. It filters the State data and re-writes it.\n // When data comes from Props this is not a problem as we just get Props again,\n // however on this page the MQTT data is rx directly to state.\n // Consequently when the data after the data is filtered the original data no longer exists.\n //\n\n // componentDidUpdate(prevProps, prevState) {\n // const { data, filterInput: match } = this.state;\n\n // if (\n // JSON.stringify(match) !== JSON.stringify(prevState.filterInput) ||\n // JSON.stringify(data) !== JSON.stringify(prevState.data)\n // ) {\n // let newData = [...this.props.data]; // original data\n\n // newData = newData.filter(function (item) {\n // let checkMatch = true; // assume all included as default \"\" is always included\n // for (var key in match) {\n // checkMatch =\n // checkMatch &&\n // item[key]?.toLowerCase()?.includes(match[key]?.toLowerCase()); // remove item which don't match\n // }\n // return checkMatch;\n // });\n\n // this.setState({\n // data: newData,\n // });\n\n // // restore sort\n // const { column, direction } = this.state;\n\n // // #REVIEW - decide if need a default sort column\n // // column is initially undefined. i.e. no default sort column\n // if (column) {\n // newData = newData.slice().sort((a, b) =>\n // a[column].localeCompare(b[column], \"en\", {\n // numeric: true,\n // })\n // );\n // }\n\n // // newData = _.sortBy(newData, [column]);\n\n // if (direction === \"descending\") {\n // newData = newData.reverse();\n // }\n // this.setState({\n // data: newData,\n // });\n // }\n // }\n\n handleSort = (clickedColumn) => () => {\n const { column, data, direction } = this.state;\n\n if (column !== clickedColumn) {\n this.setState({\n column: clickedColumn,\n //data: _.sortBy(data, [clickedColumn]),\n data: data.slice().sort((a, b) =>\n a[clickedColumn].localeCompare(b[clickedColumn], \"en\", {\n numeric: true,\n })\n ),\n direction: \"ascending\",\n });\n return;\n }\n\n this.setState({\n data: data.reverse(),\n direction: direction === \"ascending\" ? \"descending\" : \"ascending\",\n });\n };\n\n handleFilterChange = (e) => {\n const target = e.target;\n const { name, value } = target;\n let match = JSON.parse(JSON.stringify(this.state?.filterInput));\n\n // update match value with most recent filter entry\n match[name] = value;\n\n this.setState({\n filterInput: { ...match },\n });\n };\n\n handleDropdownItemsPerPage = (e, data) => {\n this.setState({ itemsPerPage: data.value, page: 1 });\n };\n\n setPageNum = (event, { activePage }) => {\n this.setState({ page: activePage });\n };\n\n onClickStart = () => {\n // stop current subscription\n this.unSubscribe(this.state.topic);\n // make selection the new topic\n const newTopic = mqttTopicOptions.find(\n (option) => option.value === this.state.topicSelect\n )?.text;\n // connect to the new topic\n this.setState({ topic: newTopic }, () => {\n this.onConnect();\n });\n };\n\n onClickClear = () => {\n this.setState({ data: [] });\n };\n\n onClickStop = () => {\n this.unSubscribe(this.state.topic);\n };\n\n handleDropdownMqttTopic = (e, data) => {\n console.log(\"select event\", data.value);\n this.setState({ topicSelect: data.value });\n };\n\n render() {\n const includeTitles = this.props.includeTitles === \"true\";\n const title = includeTitles ? (\n
MQTT Messages
\n ) : (\n
\n );\n\n const { isLoading, error } = this.props;\n const { column, data, direction, filterInput } = this.state;\n\n // total # of items to display\n let itemsCount = 0;\n // setup variable to display viewable items per page\n let viewablesPage = [];\n // check data exists. May not happen on initial startup when redux state not setup\n if (data !== undefined) {\n itemsCount = data.length;\n viewablesPage = [...data];\n }\n // if enough faults display pagination\n let pagination;\n const { page, itemsPerPage } = this.state;\n\n if (itemsCount > itemsPerPage) {\n const totalPages = itemsCount / itemsPerPage;\n viewablesPage = data.slice(\n (page - 1) * itemsPerPage,\n (page - 1) * itemsPerPage + itemsPerPage\n );\n pagination = (\n
\n \n \n items per page. Found {itemsCount} items.\n
\n );\n }\n\n const headerCellStyle = {\n borderBottom: \"1px solid rgba(34,36,38,.1)\",\n };\n\n const segmentStyle = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n };\n\n return (\n
\n \n \n \n \n
{title}
\n
\n \n \n \n
\n {/* dummy row for spacing consistency */}\n
\n \n
\n \n {/* */}\n \n
\n {/* label and button *will not* go to same height as depends on font sizes. \n Fudge by vertical centering the button and label in same div. */}\n
\n \n \n Start\n \n }\n />\n \n {itemsCount}\n \n }\n />\n \n Stop\n \n }\n />\n
\n
\n\n \n \n {/* #TODO - Fix filtering. See notes above */}\n {/* \n \n \n \n \n \n \n \n \n \n */}\n \n \n Time\n \n \n Topic\n \n \n Message\n \n \n \n \n {_.map(viewablesPage, ({ time, topic, message }) => (\n \n {time}\n {topic}\n {message}\n \n ))}\n \n \n
\n {pagination}\n \n
\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n return {\n fetchedMqttBroker: getMqttBroker(state),\n };\n};\n\nexport default withComponentStateCache(\n connect(mapStateToProps, { ClearLog, saveUserSettingsComponentState })(\n ToolsMqttList\n )\n);\n","export const callRunScript = (action) => {\n return { type: \"SERVER_RUN_SCRIPT_REQUESTED\", payload: action };\n};\n","// see main reducer at src/reducers.js\n//\n\nimport Immutable from \"seamless-immutable\";\n\n// let initialState = Immutable({\n// // displayed message list\n// mqttMsg: [],\n// });\n\nconst initialState = Immutable([]);\n\nexport default function reduce(state = initialState, action = {}) {\n const { type, payload } = action;\n switch (type) {\n case \"MQTT_TEST\":\n console.log(\"zzz TestWorker Reducer MQTT_TEST Payload - \", payload);\n return state.concat([action.payload]);\n case \"ADD_MQTT_MESSAGE\":\n //console.log(\"ADD_MQTT_MESSAGE\");\n return state.concat([action.payload]);\n case \"REMOVE_MQTT_MESSAGE\":\n console.log(\"zzz REMOVE_FLASH_MESSAGE\");\n return Immutable(\n // state.asMutable().filter(({ id }) => id !== action.payload.id)\n state.asMutable().filter(({ id }) => !id.includes(action.payload.id))\n );\n case \"CLEAR_MQTT_MESSAGES\":\n console.log(\"zzz CLEAR_MQTT_MESSAGES\");\n return initialState;\n // case \"MQTT_NAMED_AREA_NEW\":\n // console.log(\n // \"zzz TestWorker Reducer MQTT_NAMED_AREA_NEW Payload - \",\n // payload\n // );\n // return newState; /// do nothing for now\n default:\n return state;\n }\n}\n\nexport function getAllMqttMessages(state) {\n return state.mqttMessages;\n}\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport myWorker from \"./mqtt.worker\";\nimport Heartbeat from \"utils/Heartbeat\";\n\nimport {\n addWarningFlashMessageIdColor,\n removeFlashMessage,\n} from \"FlashMessages/actions\";\n\nimport { LogIt } from \"components/Logger/actions\";\n\nimport { removeMqttMessage, clearMqttMessages } from \"./actions\";\nimport { getAllMqttMessages } from \"./reducer\";\n\nimport { isConfigJs, mqttBroker, NetworkTimeout } from \"components/ConfigJs\";\nimport cuid from \"cuid\";\n\n// ***************\n// NOTE THIS IS OUTSIDE OF THE Component\n//\nvar promiseWorker = null; // initialize variable\nvar worker = null; // initialize variable\n//\n// ***************\n\nclass Worker extends Component {\n constructor(props) {\n super(props);\n this.state = {\n mqttConnected: false,\n mqttErrors: [],\n mqttMsg: [],\n mqttMessages: props.mqttMessages,\n };\n }\n\n setupWorker = (address, port, networkTimeout) => {\n // First check whether Web Workers are supported\n if (typeof Worker !== \"undefined\") {\n // Check whether Web Worker has been created. If not, create a new Web Worker\n if (promiseWorker == null) {\n var PromiseWorker = require(\"promise-worker\");\n worker = new myWorker();\n promiseWorker = new PromiseWorker(worker);\n\n var msg = {\n address,\n port,\n networkTimeout,\n type: \"SETUP_MQTT\",\n };\n console.log(\n \"MQTT - Sending start message to worker: \" + JSON.stringify(msg)\n );\n promiseWorker\n .postMessage(msg)\n .then(function (response) {\n //console.log(\"zzz Worker response: \" + response);\n })\n .catch(function (error) {\n console.log(\"Worker error: \" + error);\n // this.displayErrors(\"WORKER_SETUP_ERROR\", error); // <-------------- #REVIEW - displayErrors is not accessible from here!? why. Fix here and elsewhere\n });\n }\n } else {\n // Web workers are not supported by your browser\n // <-------------- #REVIEW - displayErrors is not accessible from here!? why. Fix here and elsewhere\n this.displayErrors(\n \"WORKER_SETUP_ERROR\",\n \"Sorry, your browser does not support Web Workers ...\"\n );\n console.log(\"zzz Sorry, your browser does not support Web Workers ...\");\n }\n };\n\n // pre-process the workerResponse.\n // Split the errors and pass them on for display\n //\n prepErrors = (workerResponse, errorCase) => {\n //console.log(\"zzz workerResponse - errorCase\", workerResponse, errorCase);\n // could be more than one error accumulated. Thus error'S'.\n const { mqttErrors } = this.state;\n // push the spread array\n mqttErrors.push(...workerResponse);\n // save it\n // console.log(\"zzz check 4\", Date.now());\n\n this.setState({ mqttErrors: mqttErrors }, function () {\n // console.log(\"zzz check 5\", Date.now());\n\n // log it. Could be multiple errors........\n mqttErrors.forEach((error) => this.displayErrors(errorCase, error));\n });\n\n // clear the errors after they have been displayed\n // no reason to keep errors as we poll for updated status\n this.setState({ mqttErrors: [] });\n };\n\n // loads header and message to display on control screen page\n // depending on significance of the error\n // All cases go to the Browser Logger page\n //\n displayErrors(errorType, extraMessage) {\n let header;\n let message;\n let displayOnPageHeader = false;\n let color;\n\n let id = cuid();\n\n // console.log(\"check 6\", Date.now());\n\n switch (errorType) {\n case \"CONFIG_JSON_ERROR\":\n header = \"MQTT Setup Error\";\n message = \"Problem loading ./config.json\";\n color = \"red\";\n displayOnPageHeader = true;\n break;\n case \"WEBSOCKET_CONNECTION_ERROR\":\n header = \"MQTT Setup Issue\";\n message =\n \"Could not establish websocket connection to \" +\n extraMessage +\n \". Check the network connections and refresh the browser page.\";\n color = \"red\";\n displayOnPageHeader = true;\n break;\n case \"WORKER_SETUP_ERROR\":\n header = \"MQTT Web Worker Setup Issue\";\n message = \"Could not setup worker. \" + extraMessage;\n color = \"red\";\n displayOnPageHeader = true;\n break;\n case \"MQTT_WORKER\":\n header = \"MQTT Web Worker Issue\";\n message = extraMessage;\n\n displayOnPageHeader = false;\n break;\n case \"NETWORK_RECONNECTED\":\n header = \"Network Reconnected\";\n message = \"The computer network has been reconnected to the server.\";\n\n // only clear 'NETWORK_DISCONNECTED' message when connection restored\n this.props.removeFlashMessage(\"NETWORK_DISCONNECTED\");\n displayOnPageHeader = false;\n break;\n case \"NETWORK_DISCONNECTED\":\n header = \"Network Disconnected\";\n message = \"The computer has been disconnected from the server network.\";\n color = \"red\";\n displayOnPageHeader = true;\n\n // include errorType in id so can find and remove later (see above)\n id = id + \"-NETWORK_DISCONNECTED\";\n\n break;\n default:\n break;\n }\n if (displayOnPageHeader) {\n this.props.addWarningFlashMessageIdColor(\n id,\n color,\n header,\n message || \"Unknown problem\"\n );\n }\n this.props.LogIt(`${errorType} - ${message}`);\n //console.log(\"displayErrors - \" + header + \"-\" + message);\n }\n\n componentDidMount() {\n //console.log(\"zzz mounted src/pages/Test/TestMQTT/testMqttWorker.js\");\n // function to connect to websocket\n // used to establish a test connection before proceed with mqtt_websocket\n // allows reporting of conditions of the websocket\n const connectWS = (address, port) => {\n return new Promise(function (resolve, reject) {\n let server = new WebSocket(\"wss://\" + address + \":\" + port + \"/\");\n server.onopen = function () {\n resolve(server);\n };\n server.onerror = function (err) {\n reject(err);\n };\n });\n };\n\n // check if the config.json file and broker object exists\n if (isConfigJs() && mqttBroker() && NetworkTimeout()) {\n const { address, port } = mqttBroker();\n const networkTimeout = NetworkTimeout();\n // console.log(\n // \"zzz MQTT - Connect to mqttBroker \",\n // JSON.stringify(mqttBroker())\n // );\n\n // (2) ...........\n // check if can connect to websocket\n connectWS(address, port)\n .then((server) => {\n server.close(); // OK!, so close the test connection\n console.log(\"MQTT - WSS connection checked OK!\");\n\n // (3) ...........\n // and setup MQTT when component mounts and has found IP and PORT\n this.setupWorker(address, port, networkTimeout);\n\n // old.....#REVIEW ............\n // // (4) ...........\n // // then a heartbeat manages the worker, collecting msgs, checking errors etc.\n // .then(this.heartbeat)\n // .catch(error => {\n // this.displayErrors(\"WORKER_SETUP_ERROR\");\n // });\n })\n .catch((error) => {\n this.displayErrors(\n \"WEBSOCKET_CONNECTION_ERROR\",\n \"wss://\" + address + \":\" + port + \"/\"\n );\n });\n } else {\n this.displayErrors(\"CONFIG_JSON_ERROR\");\n }\n }\n\n componentDidUpdate({ mqttMessages }) {\n console.log(\n \"zzz componentDidUpdate - /home/hugh/iot_server_web_v2/src/pages/Test/TestMQTT/testMqttWorker.js\"\n );\n if (this.props.mqttMessages !== mqttMessages) {\n console.log(\"zzz this.props.mqttMessages\", mqttMessages);\n\n mqttMessages.forEach((mqttMessage, index, arr) => {\n this.askWebWorker(\"sendMqttMsg\", mqttMessage);\n });\n\n this.props.clearMqttMessages();\n }\n }\n\n // ask the web worker for information\n askWebWorker = (action, message) => {\n if (promiseWorker !== null) {\n let msg; // data requested by message\n switch (action) {\n case \"getMqttMsg\":\n msg = { type: \"GET_MQTT_MSG\" };\n break;\n case \"sendMqttMsg\":\n console.log(\"zzz sendMqttMsg--->\", JSON.stringify(message));\n msg = { type: \"SEND_MQTT_MSG\", payload: message };\n break;\n case \"getConnectStatus\":\n msg = { type: \"GET_CONNECT_STATUS\" };\n break;\n case \"getErrors\":\n msg = { type: \"GET_ERRORS\" };\n break;\n // not used ATM\n case \"clearErrors\":\n msg = { type: \"CLEAR_ERRORS\" };\n break;\n default:\n break;\n }\n\n // post message type and process callback from web worker\n promiseWorker\n .postMessage(msg)\n .then((response) => {\n const workerResponse = JSON.parse(response.toString()); // <---{object}\n //console.log(\"zzz workerResponse\", workerResponse);\n })\n .catch((error) => {\n // #REVIEW - need to catch errors.........?!\n console.log(\"zzz Got error fetchWebWorker: \" + error);\n });\n }\n };\n\n // called by the heartbeat to periodically check on the state of the worker\n pokeTheWorker = () => {\n // console.log(\n // \"zzz pokeTheWorker this.state.mqttMessages\",\n // this.state.mqttMessages\n // );\n this.askWebWorker(\"getMqttMsg\", \"\");\n this.askWebWorker(\"getConnectStatus\", \"\");\n };\n\n render() {\n return (\n \n );\n }\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n removeFlashMessage: (id) => {\n dispatch(removeFlashMessage(id));\n },\n addWarningFlashMessageIdColor: (id, color, header, message) => {\n dispatch(addWarningFlashMessageIdColor(id, color, header, message));\n },\n LogIt: (message) => {\n dispatch(LogIt(message));\n },\n clearMqttMessages: () => {\n dispatch(clearMqttMessages());\n },\n removeMqttMessage: (id) => {\n dispatch(removeMqttMessage(id));\n },\n});\n\nconst mapStateToProps = (state) => {\n const mqttMessages = getAllMqttMessages(state);\n\n return {\n mqttMessages,\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(Worker);\n","export function mqttTest(mqttMsg) {\n return { type: \"MQTT_TEST\", payload: mqttMsg };\n}\n\nexport function removeMqttMessage(id) {\n return { type: \"REMOVE_MQTT_MESSAGE\", payload: { id } };\n}\n\nexport function clearMqttMessages() {\n return { type: \"CLEAR_MQTT_MESSAGES\" };\n}\n\nexport function newNamedAreaMqtt(mqttMsg) {\n return { type: \"NEW_NAMED_AREA_MQTT\", payload: mqttMsg };\n}\n\nexport function deleteNamedAreaMqtt(mqttMsg) {\n return { type: \"DELETE_NAMED_AREA_MQTT\", payload: mqttMsg };\n}\n\nexport function infoNamedAreaMqtt(mqttMsg) {\n return { type: \"INFO_NAMED_AREA_MQTT\", payload: mqttMsg };\n}\n\nexport function changeNamedAreaMqtt(mqttMsg) {\n return { type: \"CHANGE_NAMED_AREA_MQTT\", payload: mqttMsg };\n}\n\nexport function membersNamedAreaMqtt(mqttMsg) {\n return { type: \"MEMBER_NAMED_AREA_MQTTS\", payload: mqttMsg };\n}\n\nexport function eventNamedAreaMqtt(mqttMsg) {\n return { type: \"EVENT_NAMED_AREA_MQTT\", payload: mqttMsg };\n}\n","// #WEBWORKER INDEX\n\nimport React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport _isEmpty from \"lodash/isEmpty\";\nimport cuid from \"cuid\";\nimport { getUserSessionIp } from \"utils/messageToken\";\n\nimport {\n UpdateMqttReset,\n //\n UpdateMapMsg, // used for stress tester _latlng\n UpdateMqttMsg,\n UpdateLatestFaultTs,\n //\n SetActiveArea,\n UpdateAreaInfos,\n UpdateAreaStatuses,\n //\n UpdateControllerCoordinates,\n UpdateControllerStatuses,\n\n //\n UpdateFireflyCoordinates,\n UpdateFireflyStatuses,\n //\n UpdateNamedAreaInfos,\n UpdateNamedAreaStatuses,\n UpdateNamedAreaEvents,\n //\n UpdateEmergencyEventSettings,\n UpdateTriggerEventSettings,\n //\n UpdateAcks,\n //\n UpdateDeviceTimestamps,\n //\n UpdateRecalcState,\n // railway_application\n UpdateMachineStatus,\n UpdateExternalTrigger,\n UpdateButtonTrigger,\n //\n clearMqttMessages,\n removeMqttMessage,\n removeMqttMessageByToken,\n\n // data loading\n UpdateDataLoadingResponseRequestQueue,\n\n // API data fetched\n clearDataFetched,\n\n // set flag to reload area images\n setAreaImageChanged,\n UpdateServerTimestamp,\n UpdateSystemProcessMsg,\n ClearSystemProcessMsg,\n} from \"components/WebWorker/actions\";\n\nimport {\n saveNewNamedAreaEvent,\n saveNewEmergencyEvent,\n} from \"NamedAreas/actions\";\n\nimport myWorker from \"components/WebWorker/mqtt.worker\";\nimport Heartbeat from \"utils/Heartbeat\";\n\nimport {\n addWarningFlashMessageIdColor,\n removeFlashMessage,\n} from \"FlashMessages/actions\";\n\nimport { LogIt } from \"components/Logger/actions\";\n\nimport {\n getAllMqttMessages,\n getMqttReset,\n getMqttDataLoading,\n getMqttDataLoadingResponseRequestMessageQueue,\n //\n getAllData,\n getDataFetched,\n getActiveArea,\n} from \"components/WebWorker/reducer\";\n\nimport {\n isConfigJs,\n mqttBroker,\n NetworkTimeout,\n BoomgateControllerIp, // railway_application\n TemplateAllAreasButtons,\n TemplateDefaultArea,\n deviceCheckTimeout,\n isDemoMode,\n isTagTracking,\n isMqttDebugToConsole,\n lightingEventPriority,\n} from \"components/ConfigJs\";\n\nimport { getSettingsDataLoading } from \"components/Settings/reducer\";\nimport { fetchServerOk } from \"components/Settings/actions\";\nimport { fetchFireflyAreaLightingplan } from \"UPSPanelControllers/actions\";\nimport { fetchUPSs, fetchFireflys } from \"UPSPanelControllers/actions\";\n\nimport {\n isDisabledPokeTheWorker,\n isOnOffPokeTheWorker,\n getPollRates,\n getMqttBroker,\n} from \"components/Settings/reducer\";\n\nimport { makeAllDataForWorkerState } from \"components/WebWorker/makeAllDataForWorkerState\";\nimport { fetchTags } from \"components/Tags/actions\";\n\nimport { isMqttNotApiPost } from \"components/ConfigJs\";\n\nimport { getUserSettings } from \"auth/reducer\";\n\nconst makeGeoJson = (object) => {\n return { type: \"FeatureCollection\", features: Object.values(object) };\n};\n\n// ***************\n// NOTE THIS IS OUTSIDE OF THE Component\n//\nvar promiseWorker = null; // initialize variable\nvar worker = null; // initialize variable\n//\n// ***************\n\nclass Worker extends Component {\n constructor(props) {\n super(props);\n this.state = {\n mqttConnected: false,\n mqttErrors: [],\n mqttMsg: [],\n defaultAreaStatuses: { set: false, response: {} },\n //\n workerSetup: false, // indicated worker is setup OK\n dataFetched: false, // tracks if data has been fetched\n isMqttDebugToConsole: false, // output debugs to console\n isMqttNotApiPost: false, // default to send api POST\n isTagTracking: false,\n lightingEventPriority: { emergency: 9900, levelWide: 9800, forced: 5000 },\n workerJobId: 0,\n };\n }\n\n terminateWorker = () => {\n if (worker !== null) {\n // worker does not exist. This could happen if connectWS connection failed\n worker.terminate();\n this.setState({ workerSetup: false });\n }\n promiseWorker = null;\n };\n\n setupWorker = (\n address,\n port,\n protocol,\n networkTimeout,\n boomgateControllerIp,\n userSessionIp,\n templateAllAreasButtons,\n templateDefaultArea,\n deviceCheckTimeoutSetup,\n isDemoMode, \n isMqttDebugToConsole,\n lightingEventPriority\n ) => {\n // First check whether Web Workers are supported\n if (typeof Worker !== \"undefined\") {\n // Check whether Web Worker has been created. If not, create a new Web Worker\n if (promiseWorker == null) {\n var PromiseWorker = require(\"promise-worker\");\n worker = new myWorker();\n promiseWorker = new PromiseWorker(worker);\n\n var msg = {\n address,\n port,\n protocol,\n networkTimeout,\n type: \"SETUP_MQTT\",\n boomgateControllerIp,\n\n userSessionIp,\n templateAllAreasButtons,\n templateDefaultArea,\n\n deviceCheckTimeoutSetup,\n isDemoMode,\n isMqttDebugToConsole,\n lightingEventPriority,\n };\n console.log(\n \"MQTT - Sending start message to worker: \" + JSON.stringify(msg)\n );\n promiseWorker\n .postMessage(msg)\n .then((response) => {\n console.log(\"WORKER RESPONSE: \" + response);\n //\n this.setState({ workerSetup: true });\n })\n .catch((error) => {\n console.log(\"WORKER ERROR: \" + error);\n this.displayErrors(\"WORKER_SETUP_ERROR\", error);\n });\n }\n } else {\n // Web workers are not supported by your browser\n this.displayErrors(\n \"WORKER_SETUP_ERROR\",\n \"Sorry, your browser does not support Web Workers ...\"\n );\n console.log(\"Sorry, your browser does not support Web Workers ...\");\n }\n };\n\n // pre-process the workerResponse.\n // Split the errors and pass them on for display\n //\n prepErrors = (workerResponse, errorCase) => {\n // don't debug for default case\n if (workerResponse.length !== 1 && workerResponse !== \"NO_ERRORS\") {\n console.log(\n \"askWebWorker errorCase: \",\n errorCase,\n \"workerResponse: \",\n workerResponse\n );\n }\n\n // could be more than one error accumulated. Thus error'S'.\n const { mqttErrors } = this.state;\n\n mqttErrors.push(...workerResponse);\n\n this.setState({ mqttErrors: mqttErrors }, function () {\n // log it. Could be multiple errors........\n mqttErrors.forEach((error) => this.displayErrors(errorCase, error));\n });\n\n // clear the errors after they have been displayed\n // no reason to keep errors as we poll for updated status\n this.setState({ mqttErrors: [] });\n };\n\n // loads header and message to display on control screen page\n // depending on significance of the error\n // All cases go to the Browser Logger page\n //\n displayErrors(errorType, extraMessage) {\n let header;\n let message;\n let displayOnPageHeader = false;\n let color;\n\n let id = cuid();\n\n // console.log(\"check 6\", Date.now());\n\n switch (errorType) {\n case \"CONFIG_JS_ERROR\":\n header = \"MQTT Setup Error\";\n message = \"Problem loading data from ./network.js\";\n color = \"red\";\n displayOnPageHeader = true;\n break;\n case \"WEBSOCKET_CONNECTION_ERROR\":\n header = \"MQTT Setup Issue\";\n message =\n \"Could not establish websocket connection to \" +\n extraMessage +\n \". Check the network connections and refresh the browser page.\";\n color = \"red\";\n displayOnPageHeader = true;\n break;\n case \"WORKER_SETUP_ERROR\":\n header = \"MQTT Web Worker Setup Issue\";\n message = \"Could not setup worker. \" + extraMessage;\n color = \"red\";\n displayOnPageHeader = true;\n break;\n case \"MQTT_WORKER\":\n header = \"MQTT Web Worker Issue\";\n message = extraMessage;\n\n displayOnPageHeader = false;\n break;\n case \"NETWORK_RECONNECTED\":\n header = \"Network Reconnected\";\n message = \"The computer network has been reconnected to the server.\";\n\n // only clear 'NETWORK_DISCONNECTED' message when connection restored\n this.props.removeFlashMessage(\"NETWORK_DISCONNECTED\");\n displayOnPageHeader = false;\n break;\n case \"NETWORK_DISCONNECTED\":\n header = \"Network Disconnected\";\n message = \"The computer has been disconnected from the server network.\";\n color = \"red\";\n displayOnPageHeader = true;\n\n // include errorType in id so can find and remove later (see above)\n id = id + \"-NETWORK_DISCONNECTED\";\n\n break;\n default:\n break;\n }\n if (displayOnPageHeader) {\n this.props.addWarningFlashMessageIdColor(\n id,\n color,\n header,\n message || \"Unknown problem\"\n );\n }\n if (message !== \"NO_ERRORS\") {\n //this.props.LogIt(`${errorType} - ${message}`);\n //console.log(\"displayErrors - \" + header + \"-\" + message);\n }\n }\n\n initialiseWorker = () => {\n // function to connect to websocket\n // used to establish a test connection before proceed with mqtt_websocket\n // allows reporting of conditions of the websocket\n const connectWS = (address, port, protocol) => {\n console.log(\"MQTT Debug initialiseWorker > connectWS() \");\n return new Promise(function (resolve, reject) {\n let server = new WebSocket(\n protocol + \"://\" + address + \":\" + port + \"/\"\n );\n\n // #DEBUG MESSAGES FOR connectWS\n if (true) {\n console.log(\n \"MQTT Debug initialiseWorker > connectWS > new Promise() \",\n protocol + \"://\" + address + \":\" + port + \"/\"\n );\n console.log(\n \"MQTT Debug initialiseWorker > connectWS > server \",\n server\n );\n console.log(\n \"MQTT Debug initialiseWorker > connectWS > onopen()\",\n server.onerror\n );\n console.log(\n \"MQTT Debug initialiseWorker > connectWS > onerror response\",\n server.onerror\n );\n }\n\n server.onopen = () => {\n console.log(\n \"MQTT Debug initialiseWorker > connectWS > onopen response\"\n );\n resolve(server);\n };\n\n server.onerror = (err) => {\n console.log(\n \"MQTT Debug initialiseWorker > connectWS > onerror response\"\n );\n reject(err);\n };\n });\n };\n\n // check if the config.json file and broker object exists\n if (\n isConfigJs() &&\n //mqttBroker() && // #NOTE #TODO - no longer using network.js remove from code!\n NetworkTimeout() &&\n TemplateAllAreasButtons() &&\n TemplateDefaultArea() &&\n deviceCheckTimeout()\n ) {\n const fetchedMqttBroker = this.props.fetchedMqttBroker;\n const { address, addressSecondary, port, protocol } = fetchedMqttBroker; // mqttBroker(); // fetchedMqttBroker\n const networkTimeout = NetworkTimeout();\n\n //console.log(\"MQTT - Connected to Broker (network.js): \", mqttBroker());\n console.log(\n \"MQTT - CONNECTED TO BROKER: \",\n JSON.stringify(fetchedMqttBroker)\n );\n\n // railway_application\n const boomgateControllerIP = BoomgateControllerIp();\n\n // get template for ALL_AREAS and level wide AREA button groups\n const templateAllAreasButtons = TemplateAllAreasButtons();\n\n // set default AREA so system starts even if no mqtt responses\n const templateDefaultArea = TemplateDefaultArea();\n const defaultAreaStatuses = {};\n defaultAreaStatuses[templateDefaultArea.id] = templateDefaultArea;\n\n this.setState({\n defaultAreaStatuses: { set: false, response: defaultAreaStatuses },\n });\n //this.props.UpdateAreaStatuses(defaultAreaStatuses);\n\n const deviceCheckTimeoutSetup = deviceCheckTimeout();\n\n const userSessionIp = this.props.userSessionIp;\n\n const demoMode =\n this.props.userSettings?.feature?.includes(\"showDemoMode\") ||\n isDemoMode();\n //const mqttDebugToConsole = isMqttDebugToConsole();\n\n // (2) ...........\n // check if can connect to websocket\n\n // try primary and secondary addresses\n connectWS(address, port, protocol)\n .then(\n (server) => {\n console.log(\n \"MQTT - WEBSOCKET CONNECTION CHECKED OK! Server: \",\n server\n );\n server.close(); // OK!, so close the test connection\n\n // (3) ...........\n // and setup MQTT when component mounts and has found IP and PORT\n this.setupWorker(\n address,\n port,\n protocol,\n networkTimeout,\n boomgateControllerIP,\n userSessionIp,\n templateAllAreasButtons,\n templateDefaultArea,\n deviceCheckTimeoutSetup,\n demoMode,\n this.state.isMqttDebugToConsole,\n this.state.lightingEventPriority\n );\n },\n (error) => {\n console.log(\n \"MQTT - WS CHECK CONNECTION TO '\",\n address,\n \"' FAILED. ERROR : \",\n error\n );\n\n if (addressSecondary !== undefined) {\n console.log(\n \"MQTT - WS CHECK CONNECTION TO '\",\n address,\n \"' FAILED. ATTEMPTING CONNECTION TO SECONDARY ADDRESS '\",\n addressSecondary,\n \"'\"\n );\n console.log(\"MQTT - WS CHECK CONNECTION ERROR \", error);\n // attempt connection to secondary address\n connectWS(addressSecondary, port, protocol).then(\n (server) => {\n console.log(\n \"MQTT - WS CHECK CONNECTION TO SECONDARY ADDRESS CHECKED OK! SERVER:\",\n server\n );\n server.close(); // OK!, so close the test connection\n\n // (3) ...........\n // and setup MQTT when component mounts and has found IP and PORT\n this.setupWorker(\n addressSecondary,\n port,\n protocol,\n networkTimeout,\n boomgateControllerIP,\n userSessionIp,\n templateAllAreasButtons,\n templateDefaultArea,\n deviceCheckTimeoutSetup,\n demoMode,\n this.state.isMqttDebugToConsole,\n this.state.lightingEventPriority\n );\n },\n (error) => {\n console.log(\n \"MQTT - WS CHECK CONNECTION TO SECONDARY ADDRESS '\",\n addressSecondary,\n \"' ALSO FAILED.\"\n );\n console.log(\n \"MQTT - WS CHECK CONNECTION TO SECONDARY ADDRESS ERROR: \",\n error\n );\n this.displayErrors(\n \"MQTT WEBSOCKET_CONNECTION_ERROR\",\n \"primary address \" +\n protocol +\n \"://\" +\n address +\n \":\" +\n port +\n \"/ or secondary address \" +\n protocol +\n \"://\" +\n addressSecondary +\n \":\" +\n port +\n \"/\"\n );\n }\n );\n } else {\n console.log(\n \"MQTT - WS CHECK CONNECTION TO SECONDARY ADDRESS '\",\n addressSecondary,\n \"' ALSO FAILED.\"\n );\n console.log(\n \"MQTT - WS CHECK CONNECTION TO SECONDARY ADDRESS ERROR: \",\n error\n );\n this.displayErrors(\n \"WEBSOCKET_CONNECTION_ERROR\",\n \" address \" + protocol + \"://\" + address + \":\" + port + \"/\"\n );\n }\n }\n )\n .catch((error) => {\n console.log(\"MQTT - WS CHECK CONNECTION ERROR \", error);\n this.displayErrors(\n \"WEBSOCKET_CONNECTION_ERROR\",\n \"primary: \" +\n protocol +\n \"://\" +\n address +\n \":\" +\n port +\n \"/, secondary :\" +\n protocol +\n \"://\" +\n addressSecondary +\n \":\" +\n port +\n \"/\"\n );\n });\n } else {\n this.displayErrors(\"CONFIG_JS_ERROR\");\n }\n };\n\n componentDidMount() {\n const { UpdateMqttReset, isSettingsDataLoading, userSettings } = this.props;\n\n // disable mqttReset before proceeding\n UpdateMqttReset(false);\n\n // don't startup unless the settings data is loaded (particularly mqttBroker data)\n if (!isSettingsDataLoading) {\n this.initialiseWorker();\n }\n\n this.setState({ isMqttDebugToConsole: isMqttDebugToConsole() });\n this.setState({ isMqttNotApiPost: isMqttNotApiPost() });\n this.setState({\n isTagTracking:\n userSettings?.application?.includes(\"tagTracking\") || isTagTracking(),\n });\n this.setState({ lightingEventPriority: lightingEventPriority() });\n }\n\n componentDidUpdate(prevProps) {\n const {\n mqttReset,\n mqttMessages,\n clearMqttMessages,\n removeMqttMessageByToken,\n allData,\n dataFetchedList,\n //\n isSettingsDataLoading,\n //\n saveNewNamedAreaEvent,\n saveNewEmergencyEvent,\n //\n activeArea,\n } = this.props;\n\n if (\n !isSettingsDataLoading &&\n prevProps.isSettingsDataLoading !== isSettingsDataLoading\n ) {\n this.initialiseWorker();\n }\n\n // if reset true -> false (i.e. re-login) restart webworker\n if (prevProps.mqttReset === true && mqttReset === false) {\n // #DEBUG\n if (false) {\n console.log(\"mqttReset prevProps.mqttReset\", prevProps.mqttReset);\n console.log(\"mqttReset mqttReset\", mqttReset);\n console.log(\"mqttReset initialiseWorker\");\n }\n // #WIP _ not implemented. Review as necessary, especially as it has never been used!\n //this.initialiseWorker();\n }\n\n // if reset false -> true (i.e. logout ) terminate web worker\n if (prevProps.mqttReset === false && mqttReset === true) {\n // #DEBUG\n if (false) {\n console.log(\"mqttReset prevProps.mqttReset\", prevProps.mqttReset);\n console.log(\"mqttReset mqttReset\", mqttReset);\n console.log(\"mqttReset terminateWorker\");\n }\n this.terminateWorker();\n }\n\n // set default areaStatuses\n let defaultAreaStatuses = { ...this.state.defaultAreaStatuses };\n if (!defaultAreaStatuses.set && !_isEmpty(defaultAreaStatuses.response)) {\n // deep clone to remove methods before passing\n this.props.UpdateAreaStatuses(\n JSON.parse(JSON.stringify(defaultAreaStatuses.response))\n );\n defaultAreaStatuses.set = true;\n this.setState({ defaultAreaStatuses });\n }\n\n let promiseArray = [];\n //\n // PUBLISH EVENTS and other messages\n //\n // if publish message prop has changed & there are some ...\n if (mqttMessages !== prevProps.mqttMessages && !_isEmpty(mqttMessages)) {\n // loop through and publish each one\n mqttMessages.forEach((mqttMessage, index, arr) => {\n //console.log(`_PUBLISH `, index, `->`, mqttMessage);\n\n if (this.state.isMqttNotApiPost) {\n console.log(`_PUBLISH Message via MQTT askWebWorker `, mqttMessage);\n this.askWebWorker(\"sendMqttMsg\", mqttMessage);\n } else {\n //console.log(`_PUBLISH`, mqttMessage);\n\n const { topic } = mqttMessage;\n if (topic.includes(\"named_area/\") && topic.includes(\"/event\")) {\n console.log(\n `_PUBLISH Message via API saveNewNamedAreaEvent `,\n mqttMessage\n );\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveNewNamedAreaEvent({\n values: mqttMessage,\n resolve,\n reject,\n });\n })\n );\n } else if (topic.includes(\"emergency/\") && topic.includes(\"/event\")) {\n //console.log(`_PUBLISH - emergency event!!`);\n promiseArray.push(\n new Promise((resolve, reject) => {\n saveNewEmergencyEvent({\n values: mqttMessage,\n resolve,\n reject,\n });\n })\n );\n } else {\n console.log(\n `_PUBLISH *** ADD API SUPPORT FOR THIS _PUBLISH ??`,\n mqttMessage\n );\n this.askWebWorker(\"sendMqttMsg\", mqttMessage);\n }\n }\n // remove the message from the queue after it's been processed\n removeMqttMessageByToken(mqttMessage.message.token);\n });\n\n // and clear the redux list\n //clearMqttMessages();\n }\n\n if (promiseArray.length > 0) {\n Promise.all(promiseArray).then((results) => {\n console.log(\"SUCCESS _PUBLISH - mqttMessages\", results);\n });\n }\n\n //if data has been fetched directly from the server, update the web worker data\n //console.log(`_FETCH SET_ALL_DATA allData`, allData);\n //console.log(`_FETCH SET_ALL_DATA dataFetchedList`, dataFetchedList);\n //console.log(\n // `_FETCH SET_ALL_DATA prevProps.dataFetchedList`,\n // prevProps.dataFetchedList\n //);\n\n // keep track of whether data has been fetched in case can't render ATM\n if (dataFetchedList !== prevProps.dataFetchedList) {\n this.setState({ dataFetched: true });\n }\n\n if (\n !_isEmpty(allData) &&\n // dataFetchedList - array listing data that's been fetched\n !_isEmpty(dataFetchedList) &&\n this.state.workerSetup &&\n this.state.dataFetched\n ) {\n // reset fetch flag\n this.setState({ dataFetched: false });\n\n // #REVIEW\n //#NOTE\n // make sure data fetch is complete before sending the data to the worker.\n // Check is any key is empty\n const isAllDataSomeEmpty = Object.values(allData)?.some((data) =>\n _isEmpty(data)\n );\n\n //console.log(`SET_ALL_DATA isAllDataSomeEmpty`, isAllDataSomeEmpty);\n\n // if (isAllDataSomeEmpty) {\n // console.log(`SET_ALL_DATA isAllDataSomeEmpty allData`, allData);\n // }\n\n if (true) {\n // prepare allData to send to webworker\n // * geoJson is stripped to send only features in a keyed array\n // * methods are stripped from objects. Esp. areaInfos.\n //\n\n const allDataForWorkerState = makeAllDataForWorkerState(allData);\n\n console.log(`SET_ALL_DATA dataFetchedList`, dataFetchedList);\n console.log(`SET_ALL_DATA allData`, allDataForWorkerState);\n\n dataFetchedList.forEach((item) => {\n switch (item) {\n case \"MINE_LEVELS_FETCH_SUCCEEDED\":\n const { areaStatuses, areaInfos } = allDataForWorkerState;\n\n // don't send empty data\n if (!_isEmpty(areaStatuses) && !_isEmpty(areaInfos)) {\n console.log(\n `SET_ALL_DATA >>>> Tx fetched data to worker`,\n item,\n areaStatuses,\n areaInfos\n );\n\n this.askWebWorker(\"setAllData\", {\n areaStatuses,\n areaInfos,\n });\n this.props.clearDataFetched(\"MINE_LEVELS_FETCH_SUCCEEDED\");\n }\n\n break;\n case \"UPS_FETCH_SUCCEEDED\":\n const { controllerStatuses, controllerCoordinates } =\n allDataForWorkerState;\n\n if (\n !_isEmpty(controllerStatuses) &&\n !_isEmpty(controllerCoordinates)\n ) {\n console.log(\n `SET_ALL_DATA >>>> Tx fetched data to worker`,\n item,\n controllerStatuses,\n controllerCoordinates\n );\n\n // set web worker data to fetched data\n this.askWebWorker(\"setAllData\", {\n controllerStatuses,\n controllerCoordinates,\n });\n this.props.clearDataFetched(\"UPS_FETCH_SUCCEEDED\");\n\n // #WIP - is the local state already set on fetch?\n //\n // // set local state to fetched data\n // const getControllerCoordinates = makeGeoJson(\n // controllerCoordinates\n // );\n // const getControllerStatuses = controllerStatuses;\n // this.props.UpdateControllerCoordinates(\n // getControllerCoordinates\n // );\n // this.props.UpdateControllerStatuses(getControllerStatuses);\n }\n break;\n case \"FIREFLY_FETCH_SUCCEEDED\":\n const { fireflyStatuses, fireflyCoordinates } =\n allDataForWorkerState;\n\n if (!_isEmpty(fireflyStatuses) && !_isEmpty(fireflyCoordinates)) {\n console.log(\n `SET_ALL_DATA >>>> Tx fetched data to worker`,\n item,\n fireflyStatuses,\n fireflyCoordinates\n );\n\n this.askWebWorker(\"setAllData\", {\n fireflyStatuses,\n fireflyCoordinates,\n });\n this.props.clearDataFetched(\"FIREFLY_FETCH_SUCCEEDED\");\n }\n break;\n case \"NAMED_AREA_FETCH_SUCCEEDED\":\n const { namedAreaInfos, namedAreaStatuses, namedAreaEvents } =\n allDataForWorkerState;\n if (\n !_isEmpty(namedAreaInfos) &&\n !_isEmpty(namedAreaStatuses) &&\n !_isEmpty(namedAreaEvents)\n ) {\n console.log(\n `SET_ALL_DATA >>>> Tx fetched data to worker`,\n item,\n namedAreaInfos,\n namedAreaStatuses,\n namedAreaEvents\n );\n\n this.askWebWorker(\"setAllData\", {\n namedAreaInfos,\n namedAreaStatuses,\n namedAreaEvents,\n });\n this.props.clearDataFetched(\"NAMED_AREA_FETCH_SUCCEEDED\");\n }\n break;\n\n default:\n break;\n }\n });\n }\n }\n\n // if activeArea has changed, change the MQTT subscriptions ...\n if (prevProps.activeArea !== activeArea) {\n //console.log(\"XXX activeArea changed\", activeArea);\n this.askWebWorker(\"setActiveArea\", activeArea);\n }\n }\n\n processGetConnectStatus = (workerResponse) => {\n if (workerResponse[0] === \"TRUE\") {\n // if was previously not connected (false) show reconnected message\n // message in setState callback so happens after state change\n if (!this.state.mqttConnected) {\n this.setState({ mqttConnected: true }, function () {\n this.prepErrors([\"NETWORK_RECONNECTED\"], \"NETWORK_RECONNECTED\");\n });\n }\n } else if (workerResponse[0] === \"FALSE\") {\n // if was previously connected (true) show disconnected message\n // message in setState callback so happens after state change\n if (this.state.mqttConnected) {\n this.setState({ mqttConnected: false }, function () {\n this.prepErrors([\"NETWORK_DISCONNECTED\"], \"NETWORK_DISCONNECTED\");\n });\n }\n }\n };\n\n // ask the web worker for information\n askWebWorker = (action, message) => {\n if (promiseWorker !== null) {\n \n let jobId = this.state.workerJobId + 1;\n this.setState({ workerJobId: jobId});\n\n if (this.state.isMqttDebugToConsole) {\n console.log(`COLLECTING DATA ${jobId} .... asking for ${action}`);\n }\n\n const pokeTheWorkerStart = Date.now();\n\n let msg; // data requested by message\n switch (action) {\n // tx data\n case \"sendMqttMsg\": //publish\n // console.log(\n // \"zzz MQTT_PUBLISH sendMqttMsg--->\",\n // JSON.stringify(message)\n // );\n msg = { type: \"SEND_MQTT_MSG\", payload: message };\n break;\n\n // sets the state of the worker\n // Used to match the API fetch state with the Worker state\n case \"setAllData\":\n //console.log(`SET_ALL_DATA this.props.allData`, message);\n msg = { type: \"SET_ALL_DATA\", payload: message };\n break;\n\n // rx data\n case \"getAllData\":\n msg = { type: \"GET_ALL_DATA\" };\n break;\n\n // individual messages\n case \"getMqttMsg\":\n msg = { type: \"GET_MQTT_MSG\" };\n break;\n case \"getLatestFaultTs\":\n msg = { type: \"GET_LATEST_FAULT_TS\" };\n break;\n case \"getConnectStatus\":\n msg = { type: \"GET_CONNECT_STATUS\" };\n break;\n case \"getErrors\":\n msg = { type: \"GET_ERRORS\" };\n break;\n // not used ATM\n case \"clearErrors\":\n msg = { type: \"CLEAR_ERRORS\" };\n break;\n // railway_application\n case \"getExternalTrigger\":\n msg = { type: \"GET_EXTERNAL_TRIGGER\" };\n break;\n case \"getButtonTrigger\":\n msg = { type: \"GET_BUTTON_TRIGGER\" };\n break;\n case \"getMachineStatus\":\n msg = { type: \"GET_MACHINE_STATUS\" };\n break;\n\n // testing map positions stress\n case \"getMapMsg\":\n msg = { type: \"GET_MAP_MSG\" };\n break;\n //\n case \"getControllerCoordinates\":\n msg = { type: \"GET_CONTROLLER_COORDINATES\" };\n break;\n case \"getControllerStatuses\":\n msg = { type: \"GET_CONTROLLER_STATUSES\" };\n break;\n //\n case \"getFireflyCoordinates\":\n msg = { type: \"GET_FIREFLY_COORDINATES\" };\n break;\n case \"getFireflyStatuses\":\n msg = { type: \"GET_FIREFLY_STATUSES\" };\n break;\n //\n case \"setActiveArea\":\n msg = { type: \"SET_ACTIVE_AREA\", payload: message };\n break;\n case \"getAreaInfos\":\n msg = { type: \"GET_AREA_INFOS\" };\n break;\n case \"getAreaStatuses\":\n msg = { type: \"GET_AREA_STATUSES\" };\n break;\n //\n case \"getNamedAreaInfos\":\n msg = { type: \"GET_NAMED_AREA_INFOS\" };\n break;\n case \"getNamedAreaStatuses\":\n msg = { type: \"GET_NAMED_AREA_STATUSES\" };\n break;\n case \"getNamedAreaEvents\":\n msg = { type: \"GET_NAMED_AREA_EVENTS\" };\n break;\n //\n case \"getEmergencyEventSettings\":\n msg = { type: \"GET_EMERGENCY_EVENT_SETTINGS\" };\n break;\n case \"getTriggerEventSettings\":\n msg = { type: \"GET_TRIGGER_EVENT_SETTINGS\" };\n break;\n\n //\n case \"getAcks\":\n msg = { type: \"GET_ACKS\" };\n break;\n\n //\n case \"getDeviceTimestamps\":\n msg = { type: \"GET_DEVICE_TIMESTAMPS\" };\n break;\n\n //\n case \"getRecalcState\":\n msg = { type: \"GET_RECALC_STATE\" };\n break;\n\n //\n case \"getServerTimestamp\":\n msg = { type: \"GET_SERVER_TIMESTAMP\" };\n break;\n\n case \"getSystemProcessMsg\":\n msg = { type: \"GET_SYSTEM_PROCESS_MSG\" };\n break;\n\n case \"clearSystemProcessMsg\":\n msg = { type: \"CLEAR_SYSTEM_PROCESS_MSG\", payload: message };\n break;\n\n default:\n msg = { type: \"DO_NOTHING\" };\n break;\n }\n\n // post message type and process callback from web worker\n promiseWorker\n .postMessage(msg)\n .then((response) => {\n // debug\n //console.log(\"dataLoading promiseWorker response\", response);\n\n const workerRequest = JSON.parse(response).request;\n //console.log(\"dataLoading promiseWorker request\", workerRequest);\n\n // data loading request message queue\n const newRequest = workerRequest\n .split(\"_\")\n .map((w) => w[0].toUpperCase() + w.substr(1).toLowerCase())\n .join(\" \")\n .replace(\"Get\", \"Received\");\n\n //console.log(\"COLLECTING DATA .... \", newRequest);\n\n // limit queue to 5 items\n let responseRequestMessageQueue = JSON.parse(\n JSON.stringify(this.props.dataLoadingResponseRequestMessageQueue)\n );\n\n // console.log(\n // \"dataLoading this.props.dataLoadingResponseRequestMessageQueue\",\n // this.props.dataLoadingResponseRequestMessageQueue\n // );\n\n // console.log(\n // \"dataLoading responseRequestMessageQueue\",\n // responseRequestMessageQueue\n // );\n\n responseRequestMessageQueue.unshift(newRequest);\n if (responseRequestMessageQueue.length > 5) {\n responseRequestMessageQueue.pop();\n }\n\n // console.log(\n // \"dataLoading responseRequestMessageQueue\",\n // responseRequestMessageQueue\n // );\n\n // #NOTE\n // #WIP - if not using this as feedback could remove?\n //\n if (false) {\n this.props.UpdateDataLoadingResponseRequestQueue(\n responseRequestMessageQueue\n );\n }\n\n const workerResponse = JSON.parse(response).response;\n\n if (workerResponse === null) {\n console.log(\"workerResponse is NULL\");\n }\n\n // console.log(\n // `WebWorker workerResponse`,\n // action,\n // \" -> \",\n // workerResponse\n // );\n\n switch (action) {\n // tx data\n case \"sendMqttMsg\":\n // nothing to do here ...\n break;\n\n case \"setAllData\":\n // nothing to do here ...\n break;\n\n // rx data\n\n // -----------------------------------------\n //\n // get all data in one called to web worker\n //\n // -----------------------------------------\n\n case \"getAllData\":\n if (this.state.isMqttDebugToConsole) {\n console.log(\n `COLLECTING DATA - GET_ALL_DATA WORKER RX getAllData `,\n workerResponse\n );\n }\n\n const {\n getMqttMessages,\n getLatestFaultTs,\n getConnectedStatus,\n //getErrors, // #NOTE = see individual message processing\n //getClearErrors, // #NOTE = see individual message processing\n getExternalTrigger,\n getButtonTrigger,\n getMachineStatus,\n getMapMsg,\n getControllerCoordinates,\n getControllerStatuses,\n getFireflyCoordinates,\n getFireflyStatuses,\n getAreaInfos,\n getAreaStatuses,\n getNamedAreaInfos,\n getNamedAreaStatuses,\n getNamedAreaEvents,\n getEmergencyEventSettings,\n getTriggerEventSettings,\n //getAcks, // #NOTE = see individual message processing\n getDeviceTimestamps,\n getServerTimestamp,\n getSystemProcessMsg,\n // getRecalcState, // #NOTE = see individual message processing\n } = workerResponse;\n\n // #NOTE\n // Only process data if there is areaInfos has a feature.\n // This is/was to prevent updating data which refers to a non-existant area.\n // i.e. on startup of a new project messages from another system may be received when no area/info\n // data has been setup on this client.\n //\n // There should always be an area, albeit that area may be 'defaultArea'.\n //\n // Note that when deleting all areas 'areaStatuses' contains defaultArea (so not empty),\n // but 'areaInfos?.features' is empty.\n\n if (!_isEmpty(getAreaStatuses)) {\n // check for changes to the Area Images\n // If changed, set action and trigger reload on header\n //\n\n let isAreaImageChanged = false;\n for (const key in this.props.allData?.areaStatuses) {\n if (\n this.props.allData?.areaStatuses?.[key]?.image_filename !==\n getAreaStatuses?.[key]?.image_filename\n )\n isAreaImageChanged = true;\n }\n if (isAreaImageChanged) {\n // sent CHANGED message to reload images into state\n this.props.setAreaImageChanged(true);\n }\n\n // process data to state\n this.props.UpdateMqttMsg(getMqttMessages);\n this.props.UpdateLatestFaultTs(getLatestFaultTs);\n this.processGetConnectStatus(getConnectedStatus);\n this.props.UpdateExternalTrigger(getExternalTrigger);\n this.props.UpdateButtonTrigger(getButtonTrigger);\n this.props.UpdateMachineStatus(getMachineStatus);\n this.props.UpdateMapMsg(getMapMsg);\n this.props.UpdateControllerCoordinates(\n getControllerCoordinates\n );\n this.props.UpdateControllerStatuses(getControllerStatuses);\n this.props.UpdateFireflyCoordinates(\n getFireflyCoordinates,\n this.props.userSettings\n );\n this.props.UpdateFireflyStatuses(getFireflyStatuses);\n this.props.UpdateAreaInfos(getAreaInfos);\n this.props.UpdateAreaStatuses(getAreaStatuses);\n this.props.UpdateNamedAreaInfos(getNamedAreaInfos);\n this.props.UpdateNamedAreaStatuses(getNamedAreaStatuses);\n this.props.UpdateNamedAreaEvents(getNamedAreaEvents);\n this.props.UpdateEmergencyEventSettings(\n getEmergencyEventSettings\n );\n this.props.UpdateTriggerEventSettings(getTriggerEventSettings);\n this.props.UpdateDeviceTimestamps(getDeviceTimestamps);\n this.props.UpdateServerTimestamp(getServerTimestamp);\n this.props.UpdateSystemProcessMsg(getSystemProcessMsg);\n }\n\n break;\n\n // -----------------------------------------\n //\n // individual messages\n //\n // -----------------------------------------\n\n case \"getMqttMsg\":\n this.props.UpdateMqttMsg(workerResponse);\n break;\n case \"getLatestFaultTs\":\n this.props.UpdateLatestFaultTs(workerResponse);\n break;\n case \"getConnectStatus\":\n this.processGetConnectStatus(workerResponse);\n // if (workerResponse[0] === \"TRUE\") {\n // // if was previously not connected (false) show reconnected message\n // // message in setState callback so happens after state change\n // if (!this.state.mqttConnected) {\n // this.setState({ mqttConnected: true }, function () {\n // this.prepErrors(\n // [\"NETWORK_RECONNECTED\"],\n // \"NETWORK_RECONNECTED\"\n // );\n // });\n // }\n // } else if (workerResponse[0] === \"FALSE\") {\n // // if was previously connected (true) show disconnected message\n // // message in setState callback so happens after state change\n // if (this.state.mqttConnected) {\n // this.setState({ mqttConnected: false }, function () {\n // this.prepErrors(\n // [\"NETWORK_DISCONNECTED\"],\n // \"NETWORK_DISCONNECTED\"\n // );\n // });\n // }\n // }\n\n break;\n case \"getErrors\":\n this.prepErrors(workerResponse, \"MQTT_WORKER\");\n break;\n\n // railway_application\n case \"getExternalTrigger\":\n this.props.UpdateExternalTrigger(workerResponse);\n break;\n case \"getButtonTrigger\":\n this.props.UpdateButtonTrigger(workerResponse);\n break;\n case \"getMachineStatus\":\n this.props.UpdateMachineStatus(workerResponse);\n break;\n\n case \"getMapMsg\":\n this.props.UpdateMapMsg(workerResponse);\n break;\n //\n case \"getControllerCoordinates\":\n this.props.UpdateControllerCoordinates(workerResponse);\n break;\n case \"getControllerStatuses\":\n this.props.UpdateControllerStatuses(workerResponse);\n break;\n //\n case \"getFireflyCoordinates\":\n this.props.UpdateFireflyCoordinates(workerResponse);\n break;\n case \"getFireflyStatuses\":\n this.props.UpdateFireflyStatuses(workerResponse);\n break;\n //\n case \"getActiveArea\":\n // #WIP - confirm active area has been changed????????\n //this.props.SetActiveArea(workerResponse);\n break;\n case \"getAreaInfos\":\n this.props.UpdateAreaInfos(workerResponse);\n break;\n case \"getAreaStatuses\":\n this.props.UpdateAreaStatuses(workerResponse);\n break;\n //\n case \"getNamedAreaInfos\":\n this.props.UpdateNamedAreaInfos(workerResponse);\n break;\n case \"getNamedAreaStatuses\":\n this.props.UpdateNamedAreaStatuses(workerResponse);\n break;\n case \"getNamedAreaEvents\":\n this.props.UpdateNamedAreaEvents(workerResponse);\n break;\n //\n case \"getEmergencyEventSettings\":\n this.props.UpdateEmergencyEventSettings(workerResponse);\n break;\n case \"getTriggerEventSettings\":\n this.props.UpdateTriggerEventSettings(workerResponse);\n break;\n //\n case \"getAcks\":\n // #NOTE\n // #WIP - review. Why are they passed as strings?????\n //\n // acks are passed as a string, not an object so parse it 1st\n const acks = JSON.parse(workerResponse);\n const userSessionIp = getUserSessionIp();\n\n //console.log(\"getAcks workerResponse\", acks);\n\n acks.forEach((ack) => {\n console.log(\"getAcks workerResponse ack\", ack);\n const tokenArray = ack.token.split(\",\");\n //const timeStamp = tokenArray[0];\n\n console.log(\"getAcks tokenArray\", tokenArray);\n\n const user = tokenArray[1];\n const sessionIp = tokenArray[2];\n const isSameSession = userSessionIp === `${user},${sessionIp}`; // make this check if same session\n\n console.log(\"getAcks isSameSession\", isSameSession);\n\n console.log(\n \"getAcks UpdateAcks ack\",\n userSessionIp,\n \" vs \",\n user,\n \",\",\n sessionIp,\n userSessionIp === `${user},${sessionIp}`\n );\n\n if (isSameSession) {\n console.log(\n \"getAcks UpdateAcks ack isSameSession UpdateAcks\",\n ack\n );\n this.props.UpdateAcks(ack);\n }\n });\n break;\n case \"getDeviceTimestamps\":\n this.props.UpdateDeviceTimestamps(workerResponse);\n break;\n case \"getRecalcState\":\n this.props.UpdateRecalcState(workerResponse);\n break;\n case \"getServerTimestamp\":\n this.props.UpdateServerTimestamp(workerResponse);\n break;\n case \"getSystemProcessMsg\":\n this.props.UpdateSystemProcessMsg(workerResponse);\n break;\n\n default:\n break;\n }\n\n if (this.state.isMqttDebugToConsole) {\n const pokeTheWorkerEnd = Date.now();\n console.log(`COLLECTING DATA ${jobId} .... done with ${action} execution time: ${pokeTheWorkerEnd - pokeTheWorkerStart} ms`);\n }\n })\n .catch((error) => {\n // #REVIEW - need to catch errors.........?!\n console.log(\n \"askWebWorker action '\",\n action,\n \"' returned error: \" + error\n );\n });\n }\n };\n\n // called by the heartbeat to periodically check on the state of the worker\n pokeTheWorkerEssentials = () => {\n // get any errors\n this.askWebWorker(\"getErrors\", \"\");\n // get acks\n this.askWebWorker(\"getAcks\", \"\");\n // Turn on/off the collection of new data (webworker state) as necessary.\n // This disabled the significant CPU load initiated by the redux messages sent to update various states.\n //\n // Note ACKS, ERRORS etc need to be collected ASAP and the browser load here is a lot less.\n //\n // get server timestamp\n this.askWebWorker(\"getServerTimestamp\", \"\");\n this.askWebWorker(\"getSystemProcessMsg\", \"\");\n };\n\n // Called by the heartbeat to periodically check on the state of the worker\n pokeTheWorker = () => {\n const { isPokeTheWorker, isDisabled } = this.props;\n if (!isPokeTheWorker || isDisabled) {\n return\n }\n \n if (true) {\n // get all messages\n this.askWebWorker(\"getAllData\", \"\");\n } else {\n // get the latest mqtt messages\n this.askWebWorker(\"getMqttMsg\", \"\");\n\n // get the times for the latest faults\n this.askWebWorker(\"getLatestFaultTs\", \"\");\n\n // separately check on the connection status\n this.askWebWorker(\"getConnectStatus\", \"\");\n\n // railway_application\n this.askWebWorker(\"getExternalTrigger\");\n this.askWebWorker(\"getButtonTrigger\");\n this.askWebWorker(\"getMachineStatus\");\n\n // get updates map marker locations <-- stress testing\n this.askWebWorker(\"getMapMsg\", \"\");\n\n // get controller status messages\n this.askWebWorker(\"getControllerStatuses\", \"\");\n // get controller map marker locations\n this.askWebWorker(\"getControllerCoordinates\", \"\");\n\n // get firefly status messages\n this.askWebWorker(\"getFireflyStatuses\", \"\");\n // get firefly map marker locations\n this.askWebWorker(\"getFireflyCoordinates\", \"\");\n\n // get updates areas\n this.askWebWorker(\"getAreaInfos\", \"\");\n // get updates areas status\n this.askWebWorker(\"getAreaStatuses\", \"\");\n\n // get updates named areas\n this.askWebWorker(\"getNamedAreaInfos\", \"\");\n // get updates named areas status\n this.askWebWorker(\"getNamedAreaStatuses\", \"\");\n // get updates named area events\n this.askWebWorker(\"getNamedAreaEvents\", \"\");\n\n // get emergency event settings\n this.askWebWorker(\"getEmergencyEventSettings\", \"\");\n // get emergency event settings\n this.askWebWorker(\"getTriggerEventSettings\", \"\");\n\n // get device timestamps\n this.askWebWorker(\"getDeviceTimestamps\", \"\");\n }\n\n // Function getRecalcState() gets a boolean flag.\n // Used to trigger recalculation of transforms etc.\n // Particularly when an Area is updated, since all FFs and Controller coords\n // need to be recalculated.\n // Only need to process this if Area is updated in getAllData above.\n this.askWebWorker(\"getRecalcState\", \"\");\n };\n\n // called by the heartbeat to periodically check on the state of the server\n pokeTheServer = () => {\n // get the system info - this is used to monitor server uptime\n this.props.fetchServerOk();\n };\n\n pokeTheDemoModeFetchData = () => {\n // #TODO #WIP\n // if this works need to loop over the `active` Areas\n //console.log(\"xxx fetchFireflyAreaLightingplan \");\n //this.props.fetchFireflyAreaLightingplan({ id: \"GBC_Extraction\" });\n\n this.props.fetchFireflys({ userSettings: this.props.userSettings }); // #FETCHS\n };\n\n render() {\n const { isDataLoading, pollRates } = this.props;\n\n // #NOTE - default rates if necessary\n const {\n disable = false, // disables data collection via web worker\n worker: pollingRateWorker = 10 * 1000,\n workerEssentials: pollingRateWorkerEssentials = 1 * 1000,\n server: pollingRateServer = 30 * 1000,\n tagTracking: pollingRateTagTracking = 30 * 1000,\n } = pollRates;\n\n // #NOTE -\n // #WIP - not used any more as now fetch everything, remove this and all\n // infrastructure for isDataLoading\n //\n // if (isDataLoading) {\n // pollingRateWorker = (this.props.pollRate * 1000) / 2; // half normal rate??\n // }\n\n return (\n <>\n \n\n \n \n {\n // also see - src/components/WebWorker/reducer.js\n // search `isFireflyPropertyChanged = true;`\n //\n\n // #NOTE - *experimental* if the demo mode is set, poll for firefly messages.\n // this is similar to processing the received /lightingplan, but has the benefit\n // of \"seeming\" like the FireFly data is recent.\n //\n // #REVIEW - this may be overwhelming if a lot of FFs are being simulated.\n // NEEDS TESTING!!!!!!!!!!!!!!!!\n\n // #NOTE - this is set to FALSE and does not work ATM\n this.state.isDemoMode && false && (\n \n )\n }\n \n );\n }\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n //\n UpdateMqttReset: (bool) => {\n dispatch(UpdateMqttReset(bool));\n }, //\n\n clearMqttMessages: () => {\n dispatch(clearMqttMessages());\n },\n removeMqttMessageByToken: (token) => {\n dispatch(removeMqttMessageByToken(token));\n },\n UpdateMapMsg: (mqttMsg) => {\n dispatch(UpdateMapMsg(mqttMsg));\n },\n UpdateMqttMsg: (mqttMsg) => {\n dispatch(UpdateMqttMsg(mqttMsg));\n },\n //\n UpdateControllerCoordinates: (mqttMsg) => {\n dispatch(UpdateControllerCoordinates(mqttMsg));\n },\n UpdateControllerStatuses: (mqttMsg) => {\n dispatch(UpdateControllerStatuses(mqttMsg));\n },\n //\n SetActiveArea: (msg) => {\n dispatch(SetActiveArea(msg));\n },\n UpdateAreaInfos: (mqttMsg) => {\n dispatch(UpdateAreaInfos(mqttMsg));\n },\n UpdateAreaStatuses: (mqttMsg) => {\n dispatch(UpdateAreaStatuses(mqttMsg));\n },\n //\n UpdateFireflyCoordinates: (mqttMsg, userSettings) => {\n dispatch(UpdateFireflyCoordinates(mqttMsg, userSettings));\n },\n UpdateFireflyStatuses: (mqttMsg) => {\n dispatch(UpdateFireflyStatuses(mqttMsg));\n },\n //\n UpdateNamedAreaInfos: (mqttMsg) => {\n dispatch(UpdateNamedAreaInfos(mqttMsg));\n },\n UpdateNamedAreaStatuses: (mqttMsg) => {\n dispatch(UpdateNamedAreaStatuses(mqttMsg));\n },\n UpdateNamedAreaEvents: (mqttMsg) => {\n dispatch(UpdateNamedAreaEvents(mqttMsg));\n },\n //\n UpdateEmergencyEventSettings: (mqttMsg) => {\n dispatch(UpdateEmergencyEventSettings(mqttMsg));\n },\n UpdateTriggerEventSettings: (mqttMsg) => {\n dispatch(UpdateTriggerEventSettings(mqttMsg));\n },\n //\n UpdateAcks: (mqttMsg) => {\n dispatch(UpdateAcks(mqttMsg));\n },\n //\n UpdateDeviceTimestamps: (mqttMsg) => {\n dispatch(UpdateDeviceTimestamps(mqttMsg));\n },\n //\n UpdateServerTimestamp: (mqttMsg) => {\n dispatch(UpdateServerTimestamp(mqttMsg));\n },\n UpdateSystemProcessMsg: (msg) => {\n dispatch(UpdateSystemProcessMsg(msg));\n },\n ClearSystemProcessMsg: (msg) => {\n dispatch(ClearSystemProcessMsg(msg));\n },\n //\n UpdateRecalcState: (mqttMsg) => {\n dispatch(UpdateRecalcState(mqttMsg));\n },\n //\n UpdateLatestFaultTs: (latestFaultTs) => {\n dispatch(UpdateLatestFaultTs(latestFaultTs));\n },\n removeFlashMessage: (id) => {\n dispatch(removeFlashMessage(id));\n },\n addWarningFlashMessageIdColor: (id, color, header, message) => {\n dispatch(addWarningFlashMessageIdColor(id, color, header, message));\n },\n LogIt: (message) => {\n dispatch(LogIt(message));\n },\n // railway_application\n UpdateMachineStatus: (machineStatus) => {\n dispatch(UpdateMachineStatus(machineStatus));\n },\n UpdateExternalTrigger: (externalTrigger) => {\n dispatch(UpdateExternalTrigger(externalTrigger));\n },\n UpdateButtonTrigger: (buttonTrigger) => {\n dispatch(UpdateButtonTrigger(buttonTrigger));\n },\n\n // data loading\n UpdateDataLoadingResponseRequestQueue: (array) => {\n dispatch(UpdateDataLoadingResponseRequestQueue(array));\n },\n // server Ok info\n fetchServerOk: () => {\n dispatch(fetchServerOk());\n },\n // tag tracking info\n fetchTags: () => {\n dispatch(fetchTags());\n },\n\n // clears API data fetched flag\n clearDataFetched: (key) => {\n dispatch(clearDataFetched(key));\n },\n\n // sends events\n saveNewNamedAreaEvent: (values) => {\n dispatch(saveNewNamedAreaEvent(values));\n },\n saveNewEmergencyEvent: (values) => {\n dispatch(saveNewEmergencyEvent(values));\n },\n\n setAreaImageChanged: (values) => {\n dispatch(setAreaImageChanged(values));\n },\n\n // server Ok info\n fetchFireflyAreaLightingplan: (area) => {\n dispatch(fetchFireflyAreaLightingplan(area));\n },\n // server Ok info\n fetchFireflys: (data) => {\n dispatch(fetchFireflys(data));\n },\n});\n\nconst mapStateToProps = (state) => {\n // #REVIEW - could be renamed to e.g. getAllPublishMessages() - legacy of very early code.\n //\n const mqttMessages = getAllMqttMessages(state); // returns list of messages to publish (state.webWorker.general.publish)\n\n //console.log(\"MQTT_PUBLISH mqttMessages\", mqttMessages);\n const userSessionIp = getUserSessionIp();\n\n const mqttReset = getMqttReset(state);\n\n const isDataLoading = getMqttDataLoading(state);\n\n const dataLoadingResponseRequestMessageQueue =\n getMqttDataLoadingResponseRequestMessageQueue(state);\n\n const isPokeTheWorker = isOnOffPokeTheWorker(state);\n const isDisabled = isDisabledPokeTheWorker(state);\n\n const pollRates = getPollRates(state);\n\n const allData = getAllData(state);\n\n const dataFetchedList = getDataFetched(state) || false;\n\n const fetchedMqttBroker = getMqttBroker(state);\n\n // #NOTE -\n // mqttBroker was set in network.js, this was later moved to a GET from the server.\n // 'mqttBroker' - means from network.js\n // 'fetchedMqttBroker' - means fetched from the server\n\n return {\n mqttMessages,\n userSessionIp,\n mqttReset,\n isDataLoading,\n dataLoadingResponseRequestMessageQueue,\n isPokeTheWorker,\n isDisabled,\n pollRates,\n //\n allData,\n dataFetchedList, // array of *_SUCCESSFUL indicating which fetch data has been received\n fetchedMqttBroker,\n isSettingsDataLoading: getSettingsDataLoading(state),\n userSettings: getUserSettings(state) || {},\n activeArea: getActiveArea(state),\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(Worker);\n","export const makeAllDataForWorkerState = (allData) => {\n const {\n areaStatuses, // not used. recreated from areaInfos\n areaInfos,\n controllerCoordinates,\n controllerStatuses,\n fireflyCoordinates,\n fireflyStatuses,\n namedAreaInfos,\n namedAreaStatuses,\n namedAreaEvents,\n } = allData;\n\n const toObject = (arr, key) =>\n arr?.reduce((a, b) => ({ ...a, [b[key]]: b }), {});\n\n // remove functions, like transforms, before sending data\n let rawAreaInfos = {};\n let rawAreaStatuses = {};\n\n if (areaInfos.features) {\n Object.values(areaInfos.features).forEach((feature) => {\n const {\n id,\n geometry,\n properties: {\n //id: propId,\n ceiling,\n coordinatesUtm,\n default_color,\n default_state,\n floor,\n image_filename,\n image_info,\n name,\n namedAreaGroup,\n ref_coord,\n slug,\n status = \"api\",\n },\n } = feature;\n\n const properties = {\n id,\n ceiling,\n coordinatesUtm,\n default_color,\n default_state,\n floor,\n image_filename,\n image_info,\n name,\n namedAreaGroup,\n ref_coord,\n slug,\n status,\n };\n\n rawAreaInfos[id] = {\n geometry,\n properties: properties,\n };\n rawAreaStatuses[id] = properties;\n });\n }\n\n let rawFireflyCoordinates = {};\n\n if (fireflyCoordinates?.features) {\n const cloneFireflyCoordinatesFeatures = JSON.parse(\n JSON.stringify(fireflyCoordinates.features)\n );\n\n cloneFireflyCoordinatesFeatures.map((feature) => {\n const { id, properties, geometry } = feature;\n const { coordinates, type } = geometry;\n const { easting, northing } = properties;\n\n let newFeature = feature;\n newFeature.geometry = { coordinates: [easting, northing], type: type };\n rawFireflyCoordinates[id] = newFeature;\n });\n }\n\n let rawControllerCoordinates = {};\n\n if (controllerCoordinates?.features) {\n const cloneControllerCoordinates = JSON.parse(\n JSON.stringify(controllerCoordinates.features)\n );\n\n cloneControllerCoordinates.map((feature) => {\n const { id, properties, geometry } = feature;\n const { coordinates, type } = geometry;\n const { easting, northing } = properties;\n\n let newFeature = feature;\n newFeature.geometry = { coordinates: [easting, northing], type: type };\n rawControllerCoordinates[id] = newFeature;\n });\n }\n\n return {\n areaInfos: rawAreaInfos,\n areaStatuses: rawAreaStatuses,\n controllerCoordinates: rawControllerCoordinates, // toObject(controllerCoordinates?.features, \"id\") || {},\n controllerStatuses: controllerStatuses || {},\n fireflyCoordinates: rawFireflyCoordinates, // toObject(fireflyCoordinates?.features, \"id\") || {},\n fireflyStatuses: fireflyStatuses || {},\n namedAreaInfos: toObject(namedAreaInfos?.features, \"id\") || {},\n namedAreaStatuses: namedAreaStatuses || {},\n namedAreaEvents: namedAreaEvents || {},\n };\n};\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport {\n Table,\n Button,\n Checkbox,\n Message,\n Segment,\n Divider,\n} from \"semantic-ui-react\";\n\n// import Worker from \"./testMqttWorker\";\n//import { mqttPublish } from \"./actions\";\n\nimport {\n mqttPublish,\n removeAcks,\n isAcksReceived,\n} from \"components/WebWorker/actions\";\n\nimport { getAllAreaStatuses, getAcks } from \"components/WebWorker/reducer\";\n\nimport { getUserSessionIp, messageToken } from \"utils/messageToken\";\n\nimport { confirmTokenRxWithRetryAndTimeout } from \"utils/confirmTokenRxWithRetryAndTimeout\";\n\nimport * as Api from \"api/apiAck\";\nimport { downloadFileChannel, channelBufferPublishMsg } from \"apiSaga\";\n\nimport {\n testLedFF,\n testFF,\n testArea,\n testNamedArea,\n testNamedAreaEvent,\n officeFireflies,\n testController,\n officeControllers,\n} from \"pages/Test/TestMQTT/mqttMessages\";\n\nimport { cloneDeep } from \"lodash\";\n\nclass TestMqttSimpleTable extends Component {\n constructor(props) {\n super(props);\n this.state = {\n eventMsg: \"\",\n toggleActive: {},\n groupActive: {},\n que1: \"\",\n que2: \"\",\n que3: false,\n };\n }\n\n // ----------NAMED_AREA MESSAGES -----------------\n newNamedArea = () => {\n console.log(\"qqq click new\");\n\n const newMsg = cloneDeep(testNamedArea);\n console.log(\"qqq newNamedArea\", newMsg);\n this.props.mqttPublish({\n topic: `named_area/${newMsg.id}/new`,\n qos: 0,\n message: newMsg,\n retained: false,\n });\n };\n\n changeNamedArea = () => {\n console.log(\"qqq click change\");\n\n const changeButton = {\n clickable: true,\n icon: \"travelway_button.png\",\n priority: 2,\n title: \"Travelway\",\n alt: \"Area A - Travelway\",\n state: \"on\",\n color: \"yelllow\",\n on_time: 0,\n off_time: 0,\n };\n\n let changeMsg = cloneDeep(testNamedArea);\n changeMsg.button.push(changeButton);\n console.log(\"qqq changeNamedArea\", changeMsg);\n this.props.mqttPublish({\n topic: `named_area/${changeMsg.id}/change`,\n qos: 0,\n message: changeMsg,\n retained: false,\n });\n };\n\n deleteNamedArea = () => {\n console.log(\"qqq click delete\");\n\n // test\n const deleteMsg = {\n id: testNamedArea.id,\n delete: true,\n };\n\n console.log(\"qqq deleteNamedArea\", deleteMsg);\n this.props.mqttPublish({\n topic: `named_area/${testNamedArea.id}/delete`,\n qos: 0,\n message: deleteMsg,\n retained: false,\n });\n };\n\n eventNamedArea = (active) => {\n console.log(\"qqq click event\");\n\n let changeMsg = cloneDeep(testNamedAreaEvent);\n changeMsg.active = active;\n\n console.log(\"qqq eventNamedArea\", changeMsg);\n this.props.mqttPublish({\n topic: `named_area/${changeMsg.id}/event`,\n qos: 0,\n message: changeMsg,\n retained: true,\n });\n };\n\n // -----AREA MESSAGES-------------------------------------------------------\n\n newArea = () => {\n console.log(\"qqq click new\");\n\n // const token = messageToken();\n // const newMsg = {\n // id: testArea.id,\n // image_filename: testArea.image_filename,\n // token: token,\n // };\n // console.log(\"qqq newArea\", newMsg);\n // this.props.mqttPublish({\n // topic: `area/${testArea.id}/new`,\n // qos: 0,\n // message: newMsg,\n // retained: false,\n // });\n\n // prepare message token\n const userSessionIp = getUserSessionIp();\n const token = messageToken(userSessionIp);\n\n this.setState({ eventMsg: `newArea - token (${token})` });\n\n const newMsg = {\n id: testArea.id,\n image_filename: testArea.image_filename,\n token: token,\n };\n const payload = {\n topic: `area/${testArea.id}/new`,\n qos: 0,\n message: newMsg,\n retained: false,\n };\n\n // const channelBufferPublishMsg = (payload) => {\n // console.log(\n // \"newArea sent mqtt publish msg to channel buffer ....\",\n // payload\n // );\n // downloadFileChannel.put({\n // type: \"MQTT_PUBLISH\",\n // payload: payload,\n // });\n // };\n\n channelBufferPublishMsg(payload, \"MQTT_PUBLISH\");\n\n // after message sent get confirmation of action (ACK) by comparing with token returned\n\n console.log(\"newArea ACK sent message with token:\", token);\n\n // wait for ack message with promise message timer\n // waits time is 1000 mS between retries\n const retries = 2;\n\n const checkToken = async (token) => {\n return await confirmTokenRxWithRetryAndTimeout(token, retries);\n };\n\n checkToken(token)\n .then((result) =>\n console.log(\"newArea found the Ack at index: \" + result)\n ) // found matching ack\n .then(() => Api.removeAckToken(token)) // delete it\n .catch(console.log);\n\n // #REVIEW - move this to form submit action\n };\n\n changeArea = () => {\n console.log(\"qqq click change\");\n\n const changeMsg = cloneDeep(testArea);\n\n console.log(\"qqq changeArea\", changeMsg);\n this.props.mqttPublish({\n topic: `area/${changeMsg.id}/change`,\n qos: 0,\n message: changeMsg,\n retained: false,\n });\n };\n\n deleteArea = () => {\n console.log(\"qqq click delete\");\n\n const id = `Two`; //`DMLZ_Undercut`; //testArea.id; //\n\n // sdkfjshdkfh\n\n const deleteMsg = {\n id: id,\n delete: true,\n token: messageToken(),\n };\n\n console.log(\"qqq deleteArea\", deleteMsg);\n this.props.mqttPublish({\n topic: `area/${id}/delete`,\n qos: 0,\n message: deleteMsg,\n retained: false,\n });\n };\n\n // -----CONTROLLER MESSAGES-------------------------------------------------------\n\n newController = () => {\n console.log(\"qqq click new Controller\");\n\n const newMsg = cloneDeep(testController);\n\n console.log(\"qqq newController\", newMsg);\n\n this.props.mqttPublish({\n topic: `controller/${newMsg.id}/new`,\n qos: 0,\n message: newMsg,\n retained: false,\n });\n };\n\n changeController = () => {\n console.log(\"qqq click change\");\n\n const changeMsg = cloneDeep(testController);\n\n console.log(\"qqq changeController\", changeMsg);\n this.props.mqttPublish({\n topic: `controller/${changeMsg.id}/change`,\n qos: 0,\n message: changeMsg,\n retained: false,\n });\n };\n\n deleteController = () => {\n console.log(\"qqq click delete\");\n\n const deleteMsg = {\n id: testController.id,\n delete: true,\n token: messageToken(),\n };\n\n console.log(\"qqq deleteController\", deleteMsg);\n this.props.mqttPublish({\n topic: `controller/${deleteMsg.id}/delete`,\n qos: 0,\n message: deleteMsg,\n retained: false,\n });\n };\n\n newOfficeControllers = () => {\n console.log(\"qqq click newOfficeControllers\");\n\n const changeMsg = cloneDeep(officeControllers);\n console.log(\"qqq newOfficeControllers\", changeMsg);\n\n changeMsg.forEach((controller) => {\n console.log(\"qqq controller change\", controller);\n this.props.mqttPublish({\n topic: `controller/${controller.id}/change`,\n qos: 0,\n message: controller,\n retained: false,\n });\n });\n };\n\n // -----FF MESSAGES-------------------------------------------------------\n\n newFF = () => {\n console.log(\"qqq click new change\");\n\n const changeMsg = cloneDeep(testFF);\n\n console.log(\"qqq newFF\", changeMsg);\n this.props.mqttPublish({\n topic: `firefly/${changeMsg.id}/change`,\n qos: 0,\n message: changeMsg,\n retained: false,\n });\n };\n changeFF = () => {\n this.newFF();\n };\n\n deleteFF = () => {\n console.log(\"qqq click delete\");\n\n const deleteMsg = {\n id: testFF.id,\n delete: true,\n token: messageToken(),\n };\n\n console.log(\"qqq deleteFF\", deleteMsg);\n this.props.mqttPublish({\n topic: `firefly/${testFF.id}/delete`,\n qos: 0,\n message: deleteMsg,\n retained: false,\n });\n };\n\n ledFF = () => {\n console.log(\"qqq click led\");\n\n const changeMsg = cloneDeep(testLedFF);\n const id = `${changeMsg.location}:${changeMsg.position}`;\n\n console.log(\"qqq ledFF\", id, changeMsg);\n this.props.mqttPublish({\n topic: `firefly/${id}/led`,\n qos: 0,\n message: changeMsg,\n retained: true,\n });\n };\n\n // newOfficeFireflies;\n\n newOfficeFFs = () => {\n console.log(\"qqq click newOfficeFFs\");\n\n const changeMsg = cloneDeep(officeFireflies);\n console.log(\"qqq newOfficeFFs\", changeMsg);\n\n changeMsg.forEach((firefly) => {\n console.log(\"qqq firefly change\", firefly);\n this.props.mqttPublish({\n topic: `firefly/${firefly.id}/change`,\n qos: 0,\n message: firefly,\n retained: false,\n });\n });\n };\n\n componentDidMount() {\n //console.log(\"qqq mounted src/pages/Test/TestMQTT/TestSimpleTable.js\");\n }\n\n handleClick = () =>\n this.setState((prevState) => ({ toggleActive: !prevState.toggleActive }));\n handleGroupClick = () =>\n this.setState((prevState) => ({ toggleActive: !prevState.toggleActive }));\n\n handleClickDataKeyQue1 = (event) => {\n this.setState(\n {\n que1: event.target.attributes.getNamedItem(\"data-key\").value,\n },\n () => {\n console.log(this.state.que1);\n }\n );\n };\n\n isButtonActiveQue1 = (dataKey) => {\n if (dataKey === this.state.que1) {\n return true;\n } else {\n return false;\n }\n };\n\n handleClickDataKeyQue2 = (event) => {\n this.setState(\n {\n que2: event.target.attributes.getNamedItem(\"data-key\").value,\n },\n () => {\n console.log(this.state.que2);\n }\n );\n };\n\n isButtonActiveQue2 = (dataKey) => {\n if (dataKey === this.state.que2) {\n return true;\n } else {\n return false;\n }\n };\n\n handleClickDataKeyQue3 = (event) => {\n this.setState((prevState) => ({ que3: !prevState.que3 }));\n\n // this.setState(\n // {\n // que3: event.target.attributes.getNamedItem(\"data-key\").value,\n // },\n // () => {\n // console.log(this.state.que3);\n // }\n // );\n };\n\n isButtonActiveQue3 = (dataKey) => {\n // if (dataKey === this.state.que3) {\n // return true;\n // } else {\n // return false;\n // }\n return this.state.que3;\n };\n\n render() {\n const { allAreas } = this.props;\n const { eventMsg } = this.state;\n\n const { toggleActive } = this.state;\n\n return (\n <>\n {/*
\n \n
*/}\n
\n \n \n \n Console filter \"qqq\"\n {/* new\n delete */}\n \n \n \n {/* -------------NAMED_AREA--------------------- */}\n \n named_area\n \n \n \n \n \n \n \n \n \n \n this.eventNamedArea(true)}\n >\n event on\n \n \n \n this.eventNamedArea(false)}\n >\n event off\n \n \n \n {/* -------------AREA--------------------- */}\n \n area\n \n \n \n \n \n \n \n \n \n \n {/* -------------CONTOLLER--------------------- */}\n \n controller\n \n \n \n \n \n \n \n \n \n \n \n \n \n {/* -------------FIREFLY--------------------- */}\n \n firefly\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n {/* \n \n \n \n \n */}\n
\n
\n \n \n \n
\n
\n \n \n \n Never\n \n \n Occassionally\n \n \n Often\n \n \n Very Often\n \n \n Always\n \n \n \n \n \n Never\n \n \n Occassionally\n \n \n \n \n \n Never\n \n \n \n\n \n \n Click event:\n
{eventMsg}
\n
\n
\n \n \n Page props:\n
Props {JSON.stringify(allAreas, null, 2)}
\n {/*
State {JSON.stringify(this.state, null, 2)}
*/}\n
\n
\n
\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n const allAreas = getAllAreaStatuses(state);\n\n // ack mqtt messages\n const acks = getAcks(state);\n\n // get unique ip of the client\n //const userSessionIp = getUserSessionIp(state);\n\n return {\n allAreas,\n acks,\n //userSessionIp,\n };\n};\n\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n removeAcks: (token) => {\n dispatch(removeAcks(token));\n },\n isAcksReceived: (token) => {\n dispatch(isAcksReceived(token));\n },\n // LogIt: (thingsLogged) => {\n // dispatch(LogIt(thingsLogged));\n // },\n };\n}\n\nexport default connect(\n mapStateToProps,\n mapDispatchToProps\n)(TestMqttSimpleTable);\n","// TestTable-working-preComponentize-10Jun1219.js\n// https://medium.com/@subalerts/create-dynamic-table-from-json-in-react-js-1a4a7b1146ef\n// draggable row - https://codesandbox.io/s/4jw25r7l19?file=/src/index.js:1333-1353\n// hooks parent to children- https://stackoverflow.com/questions/55726886/react-hook-send-data-from-child-to-parent-component\n\nimport React, { Component, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { Table, Checkbox, Icon, Button, Input } from \"semantic-ui-react\";\n\nimport DraggableTableRow from \"./DraggableTableRow\";\n\nimport { testNamedAreas } from \"./mqttMessages\";\n\nimport { mqttPublish } from \"components/WebWorker/actions\";\n\nclass TableMade extends Component {\n constructor(props) {\n super(props);\n this.state = {\n data: props.data,\n rows: [],\n };\n }\n\n swap = (a, b) => {\n let { data } = this.state;\n data[a] = data.splice(b, 1, data[a])[0];\n this.setState({\n ...this.state,\n data,\n });\n };\n\n getKeys = () => {\n return Object.keys(this.state.data[0]);\n };\n\n getHeader = () => {\n // var keys = this.getKeys();\n // return keys.map((key, index) => {\n // return {key.toUpperCase()};\n // });\n\n return (\n \n Console filter \"qqq\"\n \n );\n };\n\n onClickColor = (props) => {\n //console.log(\"qqq onClickColor \", props);\n\n const { row, column } = props;\n\n const { data } = this.state;\n // // #REVIEW - why need to deepClone here?\n // // replace lodash deepClone option elsewhere\n let newData = JSON.parse(JSON.stringify(data)); /// <---deepClone\n\n const colors = [\"green\", \"amber\", \"blue\", \"red\", \"off\"];\n const currentColor = newData[row].button[column].color;\n const index = colors.findIndex((x) => x === currentColor);\n let newColor;\n index + 1 > colors.length - 1\n ? (newColor = colors[0])\n : (newColor = colors[index + 1]);\n\n //console.log(\"qqq newData\", newData);\n newData[row].button[column].color = newColor;\n\n this.setState({ data: newData });\n };\n\n onEventClick = (col, active) => {\n //console.log(\"qqq click event\", col);\n\n const { data } = this.state;\n\n let newData = JSON.parse(JSON.stringify(data)); /// <---deepClone so that reverse (see below) does not alter data object\n\n // NOTE: named areas are published in reverse so the 'top' in the list\n // comes out last so sets highest lighting priority\n newData.reverse().forEach((namedArea, index) => {\n const eventMsg = {\n id: namedArea.id,\n // this is the priority of the button. 0 is base level of lights priority, so start from 1...\n // <----#REVIEW - should get this from the button setup\n priority: col + 1,\n active: active,\n active_color: namedArea.button[col].color,\n active_state: \"ON\",\n timestamp: new Date().getTime(),\n token: \"token-\" + new Date().getTime().toString(),\n precanned: 0,\n };\n //console.log(\"qqq eventNamedArea row \", col, \"msg \", eventMsg);\n\n this.props.onSendMqtt({\n topic: `named_area/${eventMsg.id}/event`,\n qos: 0,\n message: eventMsg,\n retained: true,\n });\n });\n };\n\n getRowsData = () => {\n const items = this.state.data;\n\n // items sorted by \"priority\"\n // priority may be integer or string.\n // #REVIEW - force to integer for now\n // const items = this.state.data.sort((a, b) => {\n // return a.priority.toString().localeCompare(b.priority);\n // });\n\n const keys = this.getKeys();\n const itemsLength = items.length;\n\n return items.map((row, index) => {\n return (\n \n \n \n );\n });\n };\n\n sendNamedAreaSetupMqtt = () => {\n console.log(\"qqq sendMqtt\");\n // console.log(\"qqq this.state.data\", this.state.data);\n\n const namedAreas = this.state.data;\n\n namedAreas.forEach((namedArea) => {\n console.log(\"qqq changeArea\", namedArea);\n this.props.onSendMqtt({\n topic: `named_area/${namedArea.id}/change`,\n qos: 0,\n message: namedArea,\n retained: false,\n });\n });\n };\n\n newNamedArea = (col) => {\n //console.log(\"qqq click new \", col);\n\n const testNamedAreas = this.state.data;\n\n const namedArea = testNamedAreas[col - 1];\n\n console.log(\"qqq changeArea\", namedArea);\n this.props.onSendMqtt({\n topic: `named_area/${namedArea.id}/change`,\n qos: 0,\n message: namedArea,\n retained: false,\n });\n };\n\n deleteNamedArea = (col) => {\n //console.log(\"qqq click delete \", col);\n\n let testNamedAreaId;\n switch (col) {\n case 1:\n testNamedAreaId = \"DMLZ_Extraction:AREA_46_1\";\n break;\n case 2:\n testNamedAreaId = \"DMLZ_Extraction:AREA_46_2\";\n break;\n case 3:\n testNamedAreaId = \"DMLZ_Extraction:AREA_46_3\";\n break;\n case 4:\n testNamedAreaId = \"DMLZ_Extraction:AREA_46_4\";\n break;\n default:\n break;\n }\n // test\n const deleteMsg = {\n id: testNamedAreaId,\n delete: true,\n };\n\n console.log(\"qqq deleteNamedArea\", deleteMsg);\n this.props.onSendMqtt({\n topic: `named_area/${testNamedAreaId}/delete`,\n qos: 0,\n message: deleteMsg,\n retained: false,\n });\n };\n\n render() {\n return (\n
\n \n \n {this.getHeader()}\n {this.getRowsData()}\n\n \n \n \n \n \n Event button # column {`>`}\n \n \n this.onEventClick(0, false)}\n >\n off 1\n \n \n \n \n this.onEventClick(1, false)}\n >\n off 2\n \n \n \n \n this.onEventClick(2, false)}\n >\n off 3\n \n \n \n \n this.onEventClick(3, false)}\n >\n off 4\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n );\n }\n}\n\nconst RenderRow = (props) => {\n //console.log(\"qqq props\", props);\n const [open, setOpen] = useState(true); // declare new state variable \"open\" with setter\n\n const color = \"black\";\n\n const isItemSelected = (e) => {\n //console.log(\"qqq e\", e);\n };\n\n const handleSelect = (e) => {\n //console.log(\"qqq e\", e);\n };\n\n const handleClick = (e, key) => {\n //console.log(\"qqq key\", key);\n\n e.preventDefault();\n setOpen(!open);\n };\n\n const eyeIcon = open ? \"eye\" : \"eye slash\";\n const gripIcon = (index, length) => {\n //console.log(\"qqq length, index\", length, index);\n switch (index) {\n case 0:\n return \"sort down\";\n case length - 1:\n return \"sort up\";\n default:\n return \"sort\";\n }\n };\n\n const iconButtons = {\n //padding: \"0.5em\",\n };\n\n return (\n
\n {props.data.priority}\n \n handleClick(e, props.index)}\n >\n \n \n \n \n handleSelect(e, props.index)}\n />\n \n \n \n \n \n \n \n \n
\n );\n};\n\n// priority: integer - order of items in list <-- or just sort the object?\n// active: boolean - checkbox status\n// show: boolean - show/hide on map (eye icon)\n// name: string - named area polygon shape name <-- could be generated\n// button: array of button color settings\n\nconst RenderRowColorBox = (props) => {\n //console.log(\"qqq RenderRowColorBox props\", props);\n\n const [open, setOpen] = useState(true); // declare new state variable \"open\" with setter\n\n const handleClick = (e, key) => {\n e.preventDefault();\n\n //let data = props.data;\n const row = props.index;\n const column = key;\n\n // console.log(\"qqq RenderRowColorBox index\", buttonIndex);\n // console.log(\"qqq RenderRowColorBox key\", key);\n // //console.log(\"qqq RenderRowColorBox data\", data);\n\n // console.log(\"qqq currentColor\", data.button[key].color);\n // const colors = [\"green\", \"amber\", \"blue\", \"red\"];\n // const currentColor = data.button[key].color;\n // const index = colors.findIndex((x) => x === currentColor);\n // let newColor;\n // index + 1 > colors.length - 1\n // ? (newColor = colors[0])\n // : (newColor = colors[index + 1]);\n\n // console.log(\"qqq newColor\", newColor);\n\n // update data!\n props.onClickColor({ row, column });\n\n setOpen(!open);\n };\n\n const greenBox = {\n // backgroundColor: \"green\",\n borderRadius: 0,\n border: \"1px outset black\",\n height: \"100%\",\n margin: \".25em\",\n };\n\n const buttons = props.data.button;\n\n return buttons.map((button, index) => {\n //console.log(\"qqq buttons index\", button, index);\n\n let buttonColor = \"green\";\n switch (button.color) {\n case \"amber\":\n buttonColor = \"yellow\";\n break;\n case \"no_change\":\n buttonColor = \"grey\";\n break;\n case \"off\":\n buttonColor = \"black\";\n break;\n default:\n buttonColor = button.color;\n break;\n }\n return (\n \n handleClick(e, index)}\n >\n \n \n \n );\n });\n};\n\nclass TestNamedAreaTable extends Component {\n constructor(props) {\n super(props);\n this.state = {\n tableData: testNamedAreas,\n };\n }\n\n // sendMqtt = (mqttMsg) => {\n // console.log(\"qqq onSendMqtt\", mqttMsg);\n // };\n\n render() {\n console.log(\"qqq testNamedAreas\", testNamedAreas);\n return (\n
\n this.props.mqttPublish(mqttMsg)}\n />\n
\n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n return {};\n};\n\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n mqttPublish: (mqttMsg) => {\n dispatch(mqttPublish(mqttMsg));\n },\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(TestNamedAreaTable);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport Worker from \"./testMqttWorker\";\nimport WebWorker from \"components/WebWorker\";\n\nimport { mqttTest } from \"./actions\";\n\nimport TestMqttSimpleTable from \"./TestMqttSimpleTable\";\nimport TestMqttNamedAreasTable from \"./TestMqttNamedAreasTable\";\n\nclass TestMqttControl extends Component {\n constructor(props) {\n super(props);\n this.state = {};\n }\n\n componentDidMount() {\n // console.log(\"qqq mounted src/pages/Test/TestMQTT/index.js\");\n }\n\n render() {\n return (\n <>\n
\n {/* */}\n {/* */}\n \n \n
\n \n );\n }\n}\n\nconst mapStateToProps = (state, props) => {\n return {};\n};\n\nexport function mapDispatchToProps(dispatch, ownProps) {\n return {\n mqttTest: (mqttMsg) => {\n dispatch(mqttTest(mqttMsg));\n },\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(TestMqttControl);\n","import React, { useState, useEffect } from \"react\";\nimport { connect } from \"react-redux\";\nimport { GetLocalMap } from \"components/Map/reducer\";\n\nimport {\n Header,\n Table,\n Button,\n Checkbox,\n Grid,\n Container,\n Form,\n Radio,\n} from \"semantic-ui-react\";\n\nimport Map from \"pages/Test/TestMqttGeoJsonMap\";\n//import Map from \"components/Map/mapBase.js\";\n//import MapMini from \"./TestMqttGeoJsonMapMini\";\n\n// based on\n// - https://embed.plnkr.co/Gvei5I0S9yEo6fCYXPuy/\n// see -> from \"./TestMapTilesMap\";\n\n// --------------------------------------\n// Marker not appearing for Simple Example\n// Fix - https://github.com/PaulLeCam/react-leaflet/issues/453\n//\nimport \"leaflet/dist/leaflet.css\";\nimport L from \"leaflet\";\n\ndelete L.Icon.Default.prototype._getIconUrl;\n\nL.Icon.Default.mergeOptions({\n iconRetinaUrl: require(\"leaflet/dist/images/marker-icon-2x.png\"),\n iconUrl: require(\"leaflet/dist/images/marker-icon.png\"),\n shadowUrl: require(\"leaflet/dist/images/marker-shadow.png\"),\n});\n// --------------------------------------\n// HACKfix: Use zIndex to stop leaflet map from being above the Semantic-UI dropdown menus!\nconst DEFAULT_MAP_STYLE = {\n height: \"800px\",\n width: \"100%\",\n position: \"relative\",\n zIndex: 0,\n};\n\nconst TAG_MARKER_ICONS = [\n \"TagUnknownMarker\",\n \"TagHardHat\",\n \"TagTruckPickupMarker\",\n \"TagAmbulanceMarker\",\n \"TagLightVehicleMarker\",\n \"TagLoaderMarker\",\n \"TagTruckMarker\",\n \"TagJumboMarker\",\n];\n\nclass TestMarkerIcons extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n isCheckboxMarker: false,\n isCheckboxRefMarker: false,\n isCheckboxFireflies: false,\n isCheckboxPolyline: false,\n isAddPolygonClicked: false,\n //\n // tag icon demo - radio buttons\n iconSelection: \"\",\n };\n }\n\n isAddPolygonClicked = () => {\n this.setState({\n isAddPolygonClicked: !this.state.isAddPolygonClicked,\n });\n };\n\n onClickCheckbox = (name) => {\n console.log(\"onClickCheckbox\", name);\n this.setState({\n [name]: !this.state[name],\n });\n\n // uiseful - https://hallister.github.io/semantic-react/#!/Checkbox\n\n // via REDUX map the state of the controls\n // within the Map component, catch updates and alter layers etc. based on\n // STATE messages.\n\n // _alt_\n // pass down the state to child component (as below)\n\n // see\n // https://gis.stackexchange.com/questions/186131/placing-controls-outside-map-container-with-leaflet\n };\n\n onClickRadioButton = (name) => {\n this.setState({ iconSelection: name });\n };\n\n render() {\n let {\n isCheckboxMarker,\n isCheckboxRefMarker,\n isCheckboxFireflies,\n isCheckboxPolyline,\n //\n isCheckboxTagPersonnel,\n } = this.state;\n\n const { localMapState } = this.props;\n // console.log(\n // \"localMapState namedAreas\",\n // JSON.stringify(localMapState.namedAreas)\n // );\n\n // #REVIEW - replace with object search\n // https://stackoverflow.com/questions/2631001/test-for-existence-of-nested-javascript-object-key\n function getNested(obj, ...args) {\n return args.reduce((obj, level) => obj && obj[level], obj);\n }\n\n const tempArray = getNested(localMapState, \"namedAreas\", \"features\") || [];\n // console.log(\"tempArray\", tempArray);\n\n return (\n <>\n
\n \n \n \n \n
Test Marker Icons
\n
\n \n
\n {/* dummy row for spacing consistency */}\n
\n \n \n \n
\n {/* \n
\n */}\n {/* \n \n */}\n {/* \n \n */}\n {/* \n \n */}\n {/* \n \n */}\n {/* \n \n */}\n \n
Select the icon type
\n
\n {/* \n Selected value: {this.state.iconSelection}\n */}\n {TAG_MARKER_ICONS.map((option) => {\n return (\n \n {\n this.onClickRadioButton(data.value);\n }}\n />\n \n );\n })}\n
\n
\n \n
\n To do:\n
* change marker size (stepper?)\n
* option to select area background\n
* modify dimensions of the marker ??\n
* setup marker type as ConfigJs\n
* add clustering to demo?\n
* offset pointer? I wonder if this is necessary.\n Position is not exact.\n
\n
\n \n \n {/* */}\n \n
\n
\n
\n
\n \n );\n }\n}\n\nfunction mapStateToProps(state, props) {\n const localMapState = GetLocalMap(state);\n\n return {\n localMapState,\n };\n}\n\nexport default connect(mapStateToProps, null)(TestMarkerIcons);\n","// HB_15Mar22 - #OLD_CODE review file pending review and removal.\n//\n// This old code is still being used and should be rewritten.\n//\n// After re-write remove -src/UPSPanelControllers/reducer.js\n//\n\nimport { Component } from \"react\";\nimport { connect } from \"react-redux\";\n\nimport {\n addWarningFlashMessageIdColor,\n removeFlashMessage,\n} from \"FlashMessages/actions\";\n\nimport {\n isConfigJs,\n faultMessageBannerDisplay,\n faultMessageBannerText,\n} from \"components/ConfigJs\";\n\nimport { SetMessageBanner } from \"../AlarmButton/actions\";\n\nimport { LogIt } from \"components/Logger/actions\";\n\nimport cuid from \"cuid\";\nimport uniq from \"lodash/uniq\";\nimport reduce from \"lodash/reduce\";\n\nimport { getAllUPSs } from \"UPSPanelControllers/reducer\";\n//import { getFirefliesForUPSId } from \"UPSPanelControllers/reducer\";\n\nimport { getAllFireflys } from \"UPSPanelControllers/reducer\";\nimport { hasTopologyChanged } from \"UPSPanelControllers/reducer\";\n\nimport { UpdateConflicts } from \"components/StatusChecks/actions\";\nimport { getAllConflicts } from \"components/StatusChecks/reducer\";\n\n// StatusChecks\n//\n// Runs checks on map data and reports problems to alarm banner.\n//\n//\nclass StatusChecks extends Component {\n constructor(props) {\n super(props);\n this.state = {\n controllersNeedingDiscovering: [],\n };\n }\n\n checkAllControllers = () => {\n const { controllers } = this.props;\n const { fireflies } = this.props;\n\n let controllersNeedingDiscovering = [];\n\n // check all FFs connected to each controller for duplicates topology.positions\n controllers.forEach(function (controller, idx) {\n const { id: upsId, name: upsName } = controller;\n let name = upsName;\n if (controller?.lastStatusReport?.topology?.network_name !== undefined) {\n name = controller.lastStatusReport.topology.network_name;\n }\n\n const firefliesForController = fireflies.filter(\n (ff) => ff.topology.upsId === upsId\n );\n\n // do this for each controller ....\n // see - src/admin/bulk-positioning/UPSPortSummary.js\n // Controllers have 4 ports\n const portNum = [1, 2, 3, 4].map((i) => String(i));\n portNum.map((pi) => {\n let totalCount = 0;\n let uncommissionedCount = 0;\n const atEachOrdinal = {};\n\n firefliesForController.forEach((ff) => {\n if (ff.getIn([\"topology\", \"portNumber\"]) === pi) {\n const topoPos = ff.getIn([\"topology\", \"position\"]);\n\n // create a list ordered of ff mac addresses by topology position i.e. position in mine panel\n atEachOrdinal[topoPos] = [ff.id]\n .concat(atEachOrdinal[topoPos])\n .filter(Boolean); // truthy values only\n\n totalCount += 1;\n\n // if there is no previously assigned geographic position (i.e. latlng) it's uncommissioned\n if (ff.position === null) {\n uncommissionedCount += 1;\n }\n }\n });\n\n const likelyReplacements = reduce(\n atEachOrdinal,\n (result, value, key) => {\n if (uniq(value).length > 1) {\n result.push({ position: key, fireflyIps: value });\n //console.log(\"xxx likelyReplacements key value\", key, value);\n }\n return result;\n },\n []\n );\n\n if (likelyReplacements.length > 0) {\n for (let i = 0; i < likelyReplacements.length; i++) {\n controllersNeedingDiscovering.push({\n name: name,\n port: pi,\n position: likelyReplacements[i].position,\n fireflyIps: likelyReplacements[i].fireflyIps.toString(),\n });\n }\n\n // console.log(\n // \"likelyReplacements controllersNeedingDiscovering\",\n // controllersNeedingDiscovering\n // );\n // console.log(\"likelyReplacements\", likelyReplacements);\n // console.log(\n // \"xxx startup message to notify run discovery on controller \",\n // name,\n // \"because of likely replacement FF at port\",\n // pi,\n // \"position\",\n // likelyReplacements[0].position,\n // \"firefly IPs \",\n // likelyReplacements[0].fireflyIps\n // );\n }\n });\n });\n\n return controllersNeedingDiscovering;\n };\n\n // #REVIEW - note similar code to src/admin/firefly/FireflyList.js\n checkAllFireflies = () => {\n const { fireflies } = this.props;\n\n // ... is there another FF in same position?\n let samePosition = [];\n\n // ... has a FF changed topology\n // i.e. moved from a previous position and recommissioned\n\n let changedTopology = [];\n\n // compare the position of every firefly with every other firefly\n fireflies.forEach(function (firefly, idx) {\n // #REVIEW - code similar to src/admin/firefly/FireflyList.js\n const {\n id,\n position,\n topology: { area },\n lastStatusReport,\n } = firefly;\n\n // do this for each firefly ....\n\n // ... has it moved?\n if (lastStatusReport !== null) {\n if (\n firefly.topology &&\n firefly.topology !== null &&\n lastStatusReport.topology &&\n lastStatusReport.topology !== null\n ) {\n if (hasTopologyChanged(firefly, lastStatusReport)) {\n changedTopology.push(firefly.name);\n }\n }\n }\n\n // compare this firefly with every other firefly\n fireflies.map((ff) => {\n // some fireflies do not have a position assigned\n // and ignore comparing to self\n // ignore if in different area\n if (\n position &&\n ff.position &&\n ff.id !== id &&\n ff.topology.area !== area\n ) {\n // elsewhere the positional data is changed from ~12 dec points\n // to longer some have to fix to set # of decimal places before comparison\n const decPlaces = 12;\n const fixedPosition = {\n lat: position.lat.toFixed(decPlaces),\n lng: position.lng.toFixed(decPlaces),\n };\n const fixedFFPosition = {\n lat: ff.position.lat.toFixed(decPlaces),\n lng: ff.position.lng.toFixed(decPlaces),\n };\n\n if (\n JSON.stringify(fixedPosition) === JSON.stringify(fixedFFPosition)\n ) {\n samePosition.push(ff.name);\n }\n }\n });\n });\n\n //this.displayChangedTopologyMessage(changedTopology);\n //this.displaySamePositionMessage(samePosition);\n };\n\n // checkChangedTopology = () => {\n // const { fireflies } = this.props;\n\n // // ... has a FF changed topology\n // // i.e. moved from a previous position and recommissioned\n\n // let changedTopology = [];\n\n // // compare the position of every firefly with every other firefly\n // fireflies.forEach(function (firefly, idx) {\n // const { lastStatusReport } = firefly;\n\n // // #REVIEW - code similar to src/admin/firefly/FireflyList.js\n // // ... has it moved?\n\n // console.log(\"xxx firefly\", firefly);\n // console.log(\"xxx lastStatusReport\", lastStatusReport);\n\n // if (lastStatusReport !== null) {\n // if (\n // firefly.topology &&\n // firefly.topology !== null &&\n // lastStatusReport.topology &&\n // lastStatusReport.topology !== null\n // ) {\n // // if (hasTopologyChanged(firefly, lastStatusReport)) {\n // // changedTopology.push(firefly.name);\n // // }\n // }\n // }\n // });\n\n // console.log(\"changedTopology\", changedTopology);\n // this.displayChangedTopologyMessage(changedTopology);\n // };\n\n displaySamePositionMessage = (samePosition) => {\n if (samePosition.length) {\n let positions;\n samePosition.forEach(function (position, idx) {\n if (idx === 0) {\n positions = position;\n } else {\n positions = positions + \", \" + position;\n }\n });\n\n if (isConfigJs() && faultMessageBannerDisplay()) {\n const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n const messageBanners = this.props.messageBanners; // from redux state\n //#REVIEW - force to one type for now - this needs to be merged with AlarmButtons and other messaging\n const bannerDisplayed = messageBanners[\"fireflySamePosition\"].display; // deconstruct to a simpler obj\n\n // if this fault type allows message banner display (in config)\n // and there hasn't been a message banner displayed previously\n\n //#REVIEW - need to check fault type as per review comment above\n if (\n isMessageBannerForFaultType[\"fireflySamePosition\"] &&\n !bannerDisplayed\n ) {\n // create a unique ID for the banner\n const id = cuid();\n\n // display a new banner\n this.displayErrors(id, \"fireflySamePosition\", positions);\n\n // record the update state of banner including the id (needed to delete this particular banner)\n let tmpObj = {};\n tmpObj.faultType = \"fireflySamePosition\"; // #REVIEW - force to one status check type for now\n tmpObj.display = true;\n tmpObj.id = id;\n\n this.props.SetMessageBanner(tmpObj);\n }\n }\n }\n };\n\n displayControllerRunDiscoverMessage = (controllersNeedingDiscovering) => {\n let controllers = [];\n\n // console.log(\n // \"xxx controllersNeedingDiscovering\",\n // controllersNeedingDiscovering\n // );\n\n if (controllersNeedingDiscovering.length) {\n controllersNeedingDiscovering.forEach(function (\n { name, port, position, fireflyIps, ip },\n idx\n ) {\n //const description = `${name}| Port: ${port} | Position: ${position} | FFs : ${fireflyIps.toString()} `;\n if (idx === 0) {\n controllers = `Check Bulk Positioning for : ${name.toUpperCase()} [Port ${port}] `;\n } else {\n controllers = `${controllers}, ${name.toUpperCase()} [Port ${port}]`;\n }\n });\n\n if (isConfigJs() && faultMessageBannerDisplay()) {\n const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n const messageBanners = this.props.messageBanners; // from redux state\n\n //#REVIEW - force to one type for now - this needs to be merged with AlarmButtons and other messaging\n const bannerDisplayed =\n messageBanners[\"controllerLikelyReplacement\"].display; // deconstruct to a simpler obj\n\n // if this fault type allows message banner display (in config)\n // and there hasn't been a message banner displayed previously\n\n //#REVIEW - need to check fault type as per review comment above\n if (\n isMessageBannerForFaultType[\"controllerLikelyReplacement\"] &&\n !bannerDisplayed\n ) {\n // create a unique ID for the banner\n const id = cuid();\n\n if (controllers.length) {\n // likely replacements exists\n // display a message banner if one doesn't already exist\n if (!this.faultMessageBannerId(\"controllerLikelyReplacement\")) {\n // display a new banner\n this.displayErrors(\n id,\n \"controllerLikelyReplacement\",\n controllers\n );\n\n // record the update state of banner including the id (needed to delete this particular banner)\n let tmpObj = {};\n tmpObj.faultType = \"controllerLikelyReplacement\"; // #REVIEW - force to one status check type for now\n tmpObj.display = true;\n tmpObj.id = id;\n\n this.props.SetMessageBanner(tmpObj);\n }\n }\n }\n }\n } // #REVIEW - manage removal of message banner by finding ID (if exists) BUT also log a message\n //\n else {\n // clear the banner message for 'controllerLikelyReplacement'\n // and log controllerLikelyReplacementCorrected\n this.displayErrors(\n 0, // dummy id\n \"controllerLikelyReplacementCorrected\",\n controllers\n );\n //\n }\n };\n\n displayChangedTopologyMessage = (changedTopology) => {\n if (changedTopology.length) {\n let locations;\n changedTopology.forEach(function (location, idx) {\n if (idx === 0) {\n locations = location;\n } else {\n locations = locations + \", \" + location;\n }\n });\n\n if (isConfigJs() && faultMessageBannerDisplay()) {\n const isMessageBannerForFaultType = faultMessageBannerDisplay(); // from config.js file\n\n const messageBanners = this.props.messageBanners; // from redux state\n //#REVIEW - force to one type for now - this needs to be merged with AlarmButtons and other messaging\n const bannerDisplayed =\n messageBanners[\"fireflyChangedTopology\"].display; // deconstruct to a simpler obj\n\n // if this fault type allows message banner display (in config)\n // and there hasn't been a message banner displayed previously\n\n //#REVIEW - need to check fault type as per review comment above\n if (\n isMessageBannerForFaultType[\"fireflyChangedTopology\"] &&\n !bannerDisplayed\n ) {\n // create a unique ID for the banner\n const id = cuid();\n\n // display a new banner\n this.displayErrors(id, \"fireflyChangedTopology\", locations);\n\n // record the update state of banner including the id (needed to delete this particular banner)\n let tmpObj = {};\n tmpObj.faultType = \"fireflyChangedTopology\"; // #REVIEW - force to one status check type for now\n tmpObj.display = true;\n tmpObj.id = id;\n\n this.props.SetMessageBanner(tmpObj);\n }\n }\n }\n };\n\n // get the text for the fault message banner from config.js or set default\n getFaultMessageBannerText = (faultType) => {\n let header;\n let message;\n let color;\n\n if (isConfigJs() && faultMessageBannerText()) {\n const messageBannerText = faultMessageBannerText(); // from config.js file\n\n //console.log(\"xxx faultType\", faultType);\n // console.log(\"xxx messageBannerText\", messageBannerText);\n // console.log(\n // \"xxx messageBannerText[faultType]\",\n // messageBannerText[faultType]\n // );\n\n header = messageBannerText[faultType].header;\n message = messageBannerText[faultType].message;\n color = messageBannerText[faultType].color;\n } else {\n // default messages if config.js object is stuffed\n switch (faultType) {\n case \"fireflySamePosition\":\n header = \"FireFly Same Position\";\n message = \"More than one FireFly in the same position.\";\n color = \"red\";\n break;\n case \"controllerLikelyReplacement\":\n header = \"Run Discovery\";\n message = \"Run discovery on controllers to correct FF positions. \";\n color = \"red\";\n break;\n default:\n break;\n }\n }\n\n return { header, message, color };\n };\n\n // loads header and message to display on control screen page\n displayErrors(id, faultType, extraMessage) {\n const {\n header: headerDefault,\n message: messageDefault,\n color: colorDefault,\n } = this.getFaultMessageBannerText(faultType);\n\n let header = \"\";\n let message = \"\";\n let color = \"red\";\n let displayOnPageHeader = false;\n let errorType;\n\n switch (faultType) {\n case \"fireflySamePosition\":\n header = headerDefault;\n message = messageDefault + \" \" + extraMessage;\n color = colorDefault;\n displayOnPageHeader = true;\n // include errorType in id so can find and remove later (see above)\n id = id + \"-SAME_POSITION\";\n errorType = \"SAME_POSITION\";\n break;\n\n // #REVIEW - move this to configJS too (or db entry)\n case \"fireflySamePositionCorrected\":\n header = headerDefault;\n message = messageDefault + \" \" + extraMessage;\n\n // only clear 'LIKELY_REPLACEMENT_CORRECTED' message if there is no problem\n this.clearFaultMessageBanner(\"fireflySamePosition\");\n errorType = \"SAME_POSITION_CORRECTED\";\n displayOnPageHeader = false;\n break;\n // controllerLikelyReplacement\n case \"controllerLikelyReplacement\":\n header = headerDefault;\n message = messageDefault + \" \" + extraMessage;\n color = colorDefault;\n displayOnPageHeader = true;\n // include errorType in id so can find and remove later (see above)\n id = id + \"-LIKELY_REPLACEMENT\";\n errorType = \"LIKELY_REPLACEMENT\";\n break;\n\n // #REVIEW - move this to configJS too (or db entry)\n case \"controllerLikelyReplacementCorrected\":\n header = headerDefault;\n message = messageDefault + \" \" + extraMessage;\n\n // only clear 'controllerLikelyReplacement' message if there is no problem\n this.clearFaultMessageBanner(\"controllerLikelyReplacement\");\n // this.props.removeFlashMessage(\"LIKELY_REPLACEMENT\");\n errorType = \"LIKELY_REPLACEMENT_CORRECTED\";\n displayOnPageHeader = false;\n break;\n\n default:\n break;\n }\n if (displayOnPageHeader) {\n this.props.addWarningFlashMessageIdColor(\n id,\n color,\n header,\n message || \"Unknown problem\"\n );\n }\n this.props.LogIt(`${errorType} - ${message}`);\n //console.log(\"displayErrors - \" + header + \"-\" + message);\n }\n\n // #REVIEW - from src/components/AlarmButton/index.js\n // move to common function\n\n clearFaultMessageBanner = (faultType) => {\n // NOTE - there are two ways these messages are cleared\n //\n // removeFlashMessage(\"something\");\n // ... clears anything with \"something\" in the id of the message\n // so it is possible to clear all messages of a specific type,\n // e.g.\n // id = id + \"-LIKELY_REPLACEMENT\";\n // removeFlashMessage(\"LIKELY_REPLACEMENT\")\n // or a specific message\n // removeFlashMessage(id)\n //\n\n // Aside - this.props.clearFlashMessages(); // clear off previous messages\n\n // get the id for the flash message\n const bannerId = this.faultMessageBannerId(faultType);\n if (bannerId) {\n this.props.removeFlashMessage(bannerId);\n\n //#REVIEW - make this a function..........\n // delete this banner message from state\n let tmpObj = {};\n tmpObj.faultType = faultType;\n tmpObj.display = false;\n tmpObj.id = \"\";\n\n this.props.SetMessageBanner(tmpObj);\n }\n };\n\n faultMessageBannerId = (faultType) => {\n // check if a message of this type exists\n\n // get the id for the flash message\n const messageBanners = this.props.messageBanners; // from redux state\n return messageBanners[faultType].id;\n };\n\n componentDidMount() {\n // #REVIEW - rewrite when have actual tests of faults coming and going\n // #REVIEW - had this at startup but not necessary????????????\n //\n //\n //\n // const controllersNeedingDiscovering = this.checkAllControllers();\n // // don't react to no-fault state at startup\n // if (controllersNeedingDiscovering.length !== 0) {\n // this.displayControllerRunDiscoverMessage(controllersNeedingDiscovering);\n // } else {\n // this.setState({\n // controllersNeedingDiscovering: controllersNeedingDiscovering,\n // });\n // }\n }\n\n componentDidUpdate(prevProps) {\n // only check if controller / firefly properties have changed\n // i.e. when FFs are added and removed\n\n // console.log(\n // \"xxx componentDidUpdate prevProps.controllers !== this.props.controllers\",\n // prevProps.controllers !== this.props.controllers\n // );\n // console.log(\"xxx this.props.messageBanners\", this.props.messageBanners);\n\n if (prevProps.controllers !== this.props.controllers) {\n // #REVIEW - rewrite when have actual tests of faults coming and going\n\n const controllersNeedingDiscovering = this.checkAllControllers();\n\n // DEBUGS FOR MESSAGE BANNER CHECKS\n // console.log(\n // \"xxx this.state.controllersNeedingDiscovering\",\n // JSON.stringify(this.state.controllersNeedingDiscovering)\n // );\n // console.log(\n // \"xxx controllersNeedingDiscovering\",\n // JSON.stringify(controllersNeedingDiscovering)\n // );\n\n // react if there is a change\n\n if (\n // #REVIEW - force both to strings before compare - super ugly????\n JSON.stringify(this.state.controllersNeedingDiscovering) !==\n JSON.stringify(controllersNeedingDiscovering)\n ) {\n this.displayControllerRunDiscoverMessage(controllersNeedingDiscovering);\n // update changed state\n this.setState({\n controllersNeedingDiscovering: controllersNeedingDiscovering,\n });\n }\n }\n }\n\n render() {\n return null;\n }\n}\n\nfunction mapStateToProps(state) {\n const { messageBanners } = state.alarmButton;\n const fireflies = getAllFireflys(state) || [];\n const controllers = getAllUPSs(state) || [];\n const conflicts = getAllConflicts(state) || [];\n return {\n messageBanners,\n fireflies,\n controllers,\n conflicts,\n };\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n // sets a State record that a banner has been set\n SetMessageBanner: (messageState) => {\n dispatch(SetMessageBanner(messageState));\n },\n // remove a particular message banner\n removeFlashMessage: (id) => {\n dispatch(removeFlashMessage(id));\n },\n // display a message banner\n addWarningFlashMessageIdColor: (id, color, header, message) => {\n dispatch(addWarningFlashMessageIdColor(id, color, header, message));\n },\n LogIt: (message) => {\n dispatch(LogIt(message));\n },\n UpdateConflicts: (message) => {\n dispatch(UpdateConflicts(message));\n },\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(StatusChecks);\n","export function UpdateConflicts(message) {\n //console.log(\"UPDATE_CONFLICTS - message - \", message);\n return { type: \"UPDATE_CONFLICTS\", payload: message };\n}\n\nexport function RemoveConflicts(id) {\n console.log(\"REMOVE_CONFLICTS action- Remove\");\n return { type: \"REMOVE_CONFLICTS\", payload: id };\n}\n\nexport function ClearConflicts() {\n console.log(\"CLEAR_CONFLICTS action- Clear\");\n return { type: \"CLEAR_CONFLICTS\" };\n}\n","export function fetchLocalisation() {\n return { type: \"LOCALISATION_FETCH_REQUESTED\" };\n}\n\nexport const changeLocalisation = (data) => {\n return { type: \"CHANGE_LOCALISATION\", payload: data };\n};\n","import { connect } from \"react-redux\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\n\nimport { fetchMineLevels } from \"MineLevels/actions\";\nimport { fetchUPSs } from \"UPSPanelControllers/actions\";\nimport { fetchFireflys } from \"UPSPanelControllers/actions\";\nimport {\n fetchNamedAreas,\n fetchNamedAreaEvents,\n fetchNamedAreaExtTriggerEventInfo,\n fetchNamedAreaTriggers,\n} from \"NamedAreas/actions\";\nimport { fetchLocalisation } from \"components/Localisation/actions\";\nimport { fetchFolderFilesListByFolder } from \"components/Settings/actions\";\nimport {\n fetchTags,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n} from \"components/Tags/actions\";\nimport { isTagTracking } from \"components/ConfigJs\";\n\nimport { checkAuth } from \"auth/actions\";\nimport { fetchAllUsers } from \"components/UserAdmin/actions\";\nimport { getUserSettings } from \"auth/reducer\";\n\nconst _FetchAllData = ({ ...props }) => {\n const {\n checkAuth,\n fetchAllUsers,\n fetchMineLevels,\n fetchUPSs,\n fetchFireflys,\n fetchNamedAreas,\n fetchNamedAreaEvents,\n fetchNamedAreaTriggers,\n fetchNamedAreaExtTriggerEventInfo,\n fetchFolderFilesListByFolder,\n fetchLocalisation,\n componentstate,\n fetchTags,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n //\n userSettings,\n } = props;\n\n const checkRefresh = componentstate.get(\"FETCH_ALL_DATA\", 1);\n\n // console.log(`XXXXXXXXXXXXXXXX FetchAllData get checkRefresh`, checkRefresh);\n\n if (checkRefresh === null) {\n // console.log(\n // `XXXXXXXXXXXXXXXX FetchAllData get checkRefresh == null`,\n // checkRefresh === null\n // );\n\n console.log(`_FETCH FetchAllData set FETCH_ALL_DATA, fetching data ....`);\n\n // #NOTE -\n // #WIP - at some stage may need to implement a process to wait\n // for the fetch of folder info to complete before the areas,\n // since area display depends on knowledge of folders\n //\n\n // #FETCH - get these first\n checkAuth(); // gets current login\n fetchAllUsers(); // gets all users for user admin\n //\n fetchLocalisation();\n fetchFolderFilesListByFolder(\"areas\");\n fetchFolderFilesListByFolder(\"documents\");\n fetchFolderFilesListByFolder(\"backups\");\n\n //#FETCHS\n fetchMineLevels(); //#FETCHS\n fetchUPSs(); //#FETCHS\n fetchFireflys({ userSettings }); // #FETCHS\n fetchNamedAreas(); //#FETCHS\n fetchNamedAreaEvents(); // #FETCHS\n fetchNamedAreaTriggers(); // #FETCHS\n fetchNamedAreaExtTriggerEventInfo();\n\n if (userSettings?.application?.includes(\"tagTracking\") || isTagTracking()) {\n fetchTags();\n fetchAllTagUsers();\n fetchAllTagVehicles();\n } // #FETCHS\n\n componentstate.set(\"FETCH_ALL_DATA\", 1, \"FETCHED\");\n\n console.log(`_FETCH FetchAllData cleared FETCH_ALL_DATA`);\n }\n\n return null;\n};\n\nconst mapStateToProps = (state, props) => {\n return {\n userSettings: getUserSettings(state) || {},\n };\n};\n\nexport const FetchAllData = withComponentStateCache(\n connect(mapStateToProps, {\n fetchMineLevels,\n fetchUPSs,\n fetchFireflys,\n fetchNamedAreas,\n fetchNamedAreaEvents,\n fetchNamedAreaTriggers,\n fetchNamedAreaExtTriggerEventInfo,\n //\n checkAuth,\n fetchAllUsers,\n fetchLocalisation,\n fetchFolderFilesListByFolder,\n fetchTags,\n fetchAllTagUsers,\n fetchAllTagVehicles,\n })(_FetchAllData)\n);\n","import { connect } from \"react-redux\";\n\nimport {\n SetNamedAreaDisplaySettings,\n SetPollRates,\n fetchMqttBroker,\n fetchCheckService,\n} from \"components/Settings/actions\";\n\nimport { NAMED_AREA_DISPLAY_SETTINGS } from \"cookies\";\nimport { isConfigJs, pollRates, checkService } from \"components/ConfigJs\";\nimport { withComponentStateCache } from \"react-component-state-cache\";\nimport { UpdateNamedAreaDisplaySettings } from \"components/Settings/actions\";\n\nfunction Settings({ ...props }) {\n // setup named area display settings\n props.SetNamedAreaDisplaySettings(NAMED_AREA_DISPLAY_SETTINGS);\n // get mqtt settings from the server\n props.fetchMqttBroker();\n\n const services = checkService() || [];\n\n //console.log(\"xxx services\", services);\n //console.log(\"xxx userSettings\", props?.userSettings);\n\n // application or features which require service checks:\n // - BackupRestore - iot-firefly-server-backup-monitor\n // - TagTracking - iot-tag-tracking\n\n // checkService for applications\n\n // checkService for features\n\n services.forEach((serv) => {\n // check if services required for features/applications are running OK\n\n const isApplication = props?.userSettings?.application?.includes(\n serv.application\n );\n const isFeature = props?.userSettings?.feature?.includes(serv.feature);\n\n if (isApplication || isFeature) {\n props.fetchCheckService({\n service: serv.service,\n check: \"status\",\n });\n }\n });\n\n // setup pollRates from config if available\n if (isConfigJs() && pollRates()) {\n const { disable, workerEssentials, worker, server, tagTracking } =\n pollRates();\n\n props.SetPollRates({\n disable: disable,\n worker: worker,\n workerEssentials,\n server: server,\n tagTracking: tagTracking,\n });\n }\n\n console.log(\"LOADED USER SETTINGS: \", JSON.stringify(props?.userSettings));\n\n // #NOTE - #USER_SETTINGS\n // reset componentStateCache from db settings records\n const componentState = props?.userSettings?.componentState || [];\n componentState.forEach((settings) => {\n props.componentstate.set(settings.section, settings.key, settings.data);\n });\n\n // #NOTE - #USER_SETTINGS\n const displaySettings = props?.userSettings?.display || [];\n props.UpdateNamedAreaDisplaySettings(displaySettings);\n\n return null;\n}\n\nexport default withComponentStateCache(\n connect(null, {\n SetNamedAreaDisplaySettings,\n SetPollRates,\n fetchMqttBroker,\n fetchCheckService,\n UpdateNamedAreaDisplaySettings,\n })(Settings)\n);\n","import React, { Component } from \"react\";\nimport { connect } from \"react-redux\";\nimport { SetMapImage } from \"components/Settings/actions\";\nimport { getMapImages } from \"components/Settings/reducer\";\nimport { getAllAreaStatuses } from \"components/WebWorker/reducer\";\nimport { getFolderFileNamesListById } from \"components/Settings/reducer\";\n\n// https://stackoverflow.com/questions/19183180/how-to-save-an-image-to-localstorage-and-display-it-on-the-next-page\n\n// You don't need the getBase64Image function.\n// Data urls are already base 64 so when you call reader.readAsDataURL\n// the e.target.result sent to the reader.onload handler will be all you need.\n\nfunction getBase64Image(img) {\n var canvas = document.createElement(\"canvas\");\n canvas.width = img.width;\n canvas.height = img.height;\n\n var ctx = canvas.getContext(\"2d\");\n ctx.drawImage(img, 0, 0);\n\n var dataURL = canvas.toDataURL(\"image/png\");\n\n return dataURL.replace(/^data:image\\/(png|jpg);base64,/, \"\");\n}\n\nclass AreaImages extends Component {\n render() {\n const { areaIds, areaImageFileNames, mapImagesFromState, SetMapImage } =\n this.props;\n\n const mapImageIds = [...mapImagesFromState.map((img) => img.id)];\n\n // #REVIEW #WIP\n //\n // #NOTE - this render is not limited _but_ because the browser/react checks that is not reloaded, and onload is not run again.\n //\n // If memory loading is down without putting the in the DOM the rendering will have to be\n // controlled based on state changes.\n //\n //\n // console.log(\n // `XXXXXXXXXXXXXXXX AreaImages render `,\n // areaImageFileNames,\n // mapImagesFromState\n // );\n\n const content = areaIds.map((areaId) => {\n //\n const imageFilename = areaImageFileNames.find?.(\n (item) => item.id === areaId\n )?.src;\n\n const imageSrc = process.env.PUBLIC_URL + \"/areas/\" + imageFilename;\n const images = (areaId, imageSrc) => {\n return (\n