From 847474546cf4514ddd284b7f2a7f12d622c60f48 Mon Sep 17 00:00:00 2001
From: Sukh <6563909+sukhpalp@users.noreply.github.com>
Date: Thu, 9 May 2024 08:58:09 -0700
Subject: [PATCH 001/184] Cloudfront CORS policy terraform (#1887)
* Add CORS Config for Cloudfront
* Test uses dev APIs
* Split header policies and use the non auth one for maps
* Add capacitor
* Add Android origin
* https instead of http
* Add localhost for old android
---
terraform/cloudfront.tf | 110 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 109 insertions(+), 1 deletion(-)
diff --git a/terraform/cloudfront.tf b/terraform/cloudfront.tf
index c66f55956..cbfddfac3 100644
--- a/terraform/cloudfront.tf
+++ b/terraform/cloudfront.tf
@@ -915,7 +915,7 @@ resource "aws_cloudfront_distribution" "wfnews_openmaps_cache" {
}
}
- response_headers_policy_id = aws_cloudfront_response_headers_policy.cache_control_response_headers.id
+ response_headers_policy_id = aws_cloudfront_response_headers_policy.cache_control_response_headers_no_auth_cors.id
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
@@ -1021,6 +1021,114 @@ output "wfnews_cloudfront_nginx_url" {
resource "aws_cloudfront_response_headers_policy" "cache_control_response_headers" {
name = "cache-control-response-headers-${var.target_env}"
+ custom_headers_config {
+ items {
+ header = "Cache-Control"
+ override = true
+ value = "stale-while-revalidate=600"
+ }
+ }
+
+ remove_headers_config {
+ items {
+ header = "X-Forwarded-Server"
+ }
+
+ items {
+ header = "X-Forwarded-Host"
+ }
+
+ items {
+ header = "X-Host"
+ }
+ }
+}
+
+resource "aws_cloudfront_response_headers_policy" "cache_control_response_headers_no_auth_cors" {
+ name = "cache-control-response-headers-no-auth-cor-${var.target_env}"
+ cors_config {
+ access_control_allow_credentials = false
+
+ access_control_allow_headers {
+ items = ["*"]
+ }
+
+ access_control_allow_methods {
+ items = ["*"]
+ }
+
+ access_control_allow_origins {
+ items = ["*"]
+ }
+
+ access_control_max_age_sec = 300
+
+ origin_override = true
+ }
+
+ custom_headers_config {
+ items {
+ header = "Cache-Control"
+ override = true
+ value = "stale-while-revalidate=600"
+ }
+ }
+
+ remove_headers_config {
+ items {
+ header = "X-Forwarded-Server"
+ }
+
+ items {
+ header = "X-Forwarded-Host"
+ }
+
+ items {
+ header = "X-Host"
+ }
+ }
+}
+
+resource "aws_cloudfront_response_headers_policy" "cache_control_response_headers_auth_cors" {
+ name = "cache-control-response-headers-auth-cor-${var.target_env}"
+ cors_config {
+ access_control_allow_credentials = true
+
+ access_control_allow_headers {
+ items = [
+ "Accept",
+ "Accept-Encoding",
+ "Accept-Language",
+ "Cache-Control",
+ "Origin",
+ "Pragma",
+ "Priority",
+ "Referer",
+ "Apikey",
+ "Authorization",
+ "Content-Type"
+ ]
+ }
+
+ access_control_allow_methods {
+ items = ["GET", "POST", "PUT", "HEAD", "OPTIONS", "PATCH", "DELETE"]
+ }
+
+ access_control_allow_origins {
+ items = [
+ "capacitor://localhost",
+ "http://localhost",
+ "https://localhost",
+ "https://wfnews-client.dev.bcwildfireservices.com",
+ "https://wfnews-client.test.bcwildfireservices.com",
+ "https://wildfiresituation.nrs.gov.bc.ca"
+ ]
+ }
+
+ access_control_max_age_sec = 300
+
+ origin_override = true
+ }
custom_headers_config {
items {
From a488a5f1b53256d376081549d6663bf59afa5836 Mon Sep 17 00:00:00 2001
From: Sukh <6563909+sukhpalp@users.noreply.github.com>
Date: Thu, 9 May 2024 09:23:17 -0700
Subject: [PATCH 002/184] WFNEWS-2147 : Storybook (#1892)
* Add storybook to project
* Add checkbox-button
* Add stories
* Clean up
* Reorganize stories
* Node version bump
* Remove google-services
---
.github/workflows/android.yml | 2 +-
.github/workflows/ios.yml | 2 +-
.vscode/settings.json | 3 +-
client/wfnews-war/pom.xml | 2 +-
client/wfnews-war/src/main/angular/.gitignore | 2 +
.../src/main/angular/.storybook/main.ts | 26 +
.../main/angular/.storybook/preview-head.html | 7 +
.../src/main/angular/.storybook/preview.ts | 17 +
.../main/angular/.storybook/tsconfig.doc.json | 10 +
.../src/main/angular/.storybook/tsconfig.json | 11 +
.../src/main/angular/.storybook/typings.d.ts | 4 +
.../wfnews-war/src/main/angular/angular.json | 58 +-
.../src/main/angular/documentation.json | 101839 +++++++++++++++
.../src/main/angular/package-lock.json | 17105 ++-
.../wfnews-war/src/main/angular/package.json | 22 +-
.../active-wildfire-map.component.html | 198 +-
.../alert-order-banner.stories.ts | 44 +
.../checkbox-button.stories.ts | 26 +
.../common/link-button/link-button.stories.ts | 52 +
.../map-toggle-button.stories.ts | 41 +
.../mobile-sliding-drawer.stories.ts | 49 +
.../unsaved-changes-dialog.stories.ts | 45 +
.../angular/src/assets/icons/icon-128x128.png | Bin 18265 -> 0 bytes
.../angular/src/assets/icons/icon-144x144.png | Bin 21821 -> 0 bytes
.../angular/src/assets/icons/icon-152x152.png | Bin 24115 -> 0 bytes
.../angular/src/assets/icons/icon-192x192.png | Bin 29394 -> 0 bytes
.../angular/src/assets/icons/icon-384x384.png | Bin 73274 -> 0 bytes
.../angular/src/assets/icons/icon-512x512.png | Bin 111600 -> 0 bytes
.../angular/src/assets/icons/icon-72x72.png | Bin 8411 -> 0 bytes
.../angular/src/assets/icons/icon-96x96.png | Bin 11919 -> 0 bytes
.../src/main/angular/src/globals.ts | 1 -
.../main/angular/src/stories/.eslintrc.json | 5 +
.../src/main/angular/src/stories/Readme.mdx | 243 +
.../wfnews-war/src/main/angular/tsconfig.json | 2 +-
34 files changed, 113276 insertions(+), 6540 deletions(-)
create mode 100644 client/wfnews-war/src/main/angular/.storybook/main.ts
create mode 100644 client/wfnews-war/src/main/angular/.storybook/preview-head.html
create mode 100644 client/wfnews-war/src/main/angular/.storybook/preview.ts
create mode 100644 client/wfnews-war/src/main/angular/.storybook/tsconfig.doc.json
create mode 100644 client/wfnews-war/src/main/angular/.storybook/tsconfig.json
create mode 100644 client/wfnews-war/src/main/angular/.storybook/typings.d.ts
create mode 100644 client/wfnews-war/src/main/angular/documentation.json
create mode 100644 client/wfnews-war/src/main/angular/src/app/components/common/alert-order-banner/alert-order-banner.stories.ts
create mode 100644 client/wfnews-war/src/main/angular/src/app/components/common/checkbox-button/checkbox-button.stories.ts
create mode 100644 client/wfnews-war/src/main/angular/src/app/components/common/link-button/link-button.stories.ts
create mode 100644 client/wfnews-war/src/main/angular/src/app/components/common/map-toggle-button/map-toggle-button.stories.ts
create mode 100644 client/wfnews-war/src/main/angular/src/app/components/common/mobile-sliding-drawer/mobile-sliding-drawer.stories.ts
create mode 100644 client/wfnews-war/src/main/angular/src/app/components/common/unsaved-changes-dialog/unsaved-changes-dialog.stories.ts
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-128x128.png
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-144x144.png
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-152x152.png
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-192x192.png
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-384x384.png
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-512x512.png
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-72x72.png
delete mode 100644 client/wfnews-war/src/main/angular/src/assets/icons/icon-96x96.png
delete mode 100644 client/wfnews-war/src/main/angular/src/globals.ts
create mode 100644 client/wfnews-war/src/main/angular/src/stories/.eslintrc.json
create mode 100644 client/wfnews-war/src/main/angular/src/stories/Readme.mdx
diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index 356b32828..e9f73eeb0 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -161,7 +161,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
- node-version: 16
+ node-version: 20
- name: Set up JDK 17
uses: actions/setup-java@v3
diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml
index 57af3bee6..772748a54 100644
--- a/.github/workflows/ios.yml
+++ b/.github/workflows/ios.yml
@@ -144,7 +144,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
- node-version: 16
+ node-version: 20
cache: 'npm'
cache-dependency-path: '**/package.json'
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e6eb93c47..3a2956af4 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,6 +2,7 @@
"java.configuration.updateBuildConfiguration": "automatic",
"files.maxMemoryForLargeFilesMB": 8192,
"java.compile.nullAnalysis.mode": "automatic",
- "java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx8G -Xms100m -javaagent:\"c:\\Users\\dhemsworth\\.vscode\\extensions\\vscjava.vscode-lombok-1.0.1\\server\\lombok.jar\""
+ "java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx8G -Xms100m -javaagent:\"c:\\Users\\dhemsworth\\.vscode\\extensions\\vscjava.vscode-lombok-1.0.1\\server\\lombok.jar\"",
+ "angular.enable-strict-mode-prompt": false
}
\ No newline at end of file
diff --git a/client/wfnews-war/pom.xml b/client/wfnews-war/pom.xml
index 9b96087c8..1fe23fe92 100644
--- a/client/wfnews-war/pom.xml
+++ b/client/wfnews-war/pom.xml
@@ -15,7 +15,7 @@
${env.BUILD_NUMBER}
UTF-8
$
- v16.20.0
+ v18.10.0
8.19.4
${user.home}/.node
src/main/angular
diff --git a/client/wfnews-war/src/main/angular/.gitignore b/client/wfnews-war/src/main/angular/.gitignore
index 93f3e6b78..bd21ae82e 100644
--- a/client/wfnews-war/src/main/angular/.gitignore
+++ b/client/wfnews-war/src/main/angular/.gitignore
@@ -45,3 +45,5 @@ Thumbs.db
# config
appConfig.*.json
+
+*storybook.log
\ No newline at end of file
diff --git a/client/wfnews-war/src/main/angular/.storybook/main.ts b/client/wfnews-war/src/main/angular/.storybook/main.ts
new file mode 100644
index 000000000..fb89255f2
--- /dev/null
+++ b/client/wfnews-war/src/main/angular/.storybook/main.ts
@@ -0,0 +1,26 @@
+import type { StorybookConfig } from "@storybook/angular";
+
+const config: StorybookConfig = {
+ stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
+ staticDirs: [
+ "../src/assets/icons",
+ "../src/assets/images",
+ "../src/assets/images/drivebc",
+ "../src/assets/images/logo",
+ "../src/assets/images/svg-icons",
+ ],
+ addons: [
+ "@storybook/addon-links",
+ "@storybook/addon-essentials",
+ "@chromatic-com/storybook",
+ "@storybook/addon-interactions",
+ ],
+ framework: {
+ name: "@storybook/angular",
+ options: {},
+ },
+ docs: {
+ autodocs: "tag",
+ },
+};
+export default config;
diff --git a/client/wfnews-war/src/main/angular/.storybook/preview-head.html b/client/wfnews-war/src/main/angular/.storybook/preview-head.html
new file mode 100644
index 000000000..fb093c626
--- /dev/null
+++ b/client/wfnews-war/src/main/angular/.storybook/preview-head.html
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/wfnews-war/src/main/angular/.storybook/preview.ts b/client/wfnews-war/src/main/angular/.storybook/preview.ts
new file mode 100644
index 000000000..3296c71ba
--- /dev/null
+++ b/client/wfnews-war/src/main/angular/.storybook/preview.ts
@@ -0,0 +1,17 @@
+import type { Preview } from "@storybook/angular";
+import { setCompodocJson } from "@storybook/addon-docs/angular";
+import docJson from "../documentation.json";
+setCompodocJson(docJson);
+
+const preview: Preview = {
+ parameters: {
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/i,
+ },
+ },
+ },
+};
+
+export default preview;
diff --git a/client/wfnews-war/src/main/angular/.storybook/tsconfig.doc.json b/client/wfnews-war/src/main/angular/.storybook/tsconfig.doc.json
new file mode 100644
index 000000000..22e282bd5
--- /dev/null
+++ b/client/wfnews-war/src/main/angular/.storybook/tsconfig.doc.json
@@ -0,0 +1,10 @@
+// This tsconfig is used by Compodoc to generate the documentation for the project.
+// If Compodoc is not used, this file can be deleted.
+{
+ "extends": "./tsconfig.json",
+ // Exclude all files that are not needed for documentation generation.
+ "exclude": ["../src/test.ts", "../src/**/*.spec.ts", "../src/**/*.stories.ts"],
+ // Please make sure to include all files from which Compodoc should generate documentation.
+ "include": ["../src/**/*"],
+ "files": ["./typings.d.ts"]
+}
diff --git a/client/wfnews-war/src/main/angular/.storybook/tsconfig.json b/client/wfnews-war/src/main/angular/.storybook/tsconfig.json
new file mode 100644
index 000000000..a0bfe369c
--- /dev/null
+++ b/client/wfnews-war/src/main/angular/.storybook/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../src/tsconfig.app.json",
+ "compilerOptions": {
+ "types": ["node"],
+ "allowSyntheticDefaultImports": true,
+ "resolveJsonModule": true
+ },
+ "exclude": ["../src/test.ts", "../src/**/*.spec.ts"],
+ "include": ["../src/**/*.stories.*", "./preview.ts"],
+ "files": ["./typings.d.ts"]
+}
diff --git a/client/wfnews-war/src/main/angular/.storybook/typings.d.ts b/client/wfnews-war/src/main/angular/.storybook/typings.d.ts
new file mode 100644
index 000000000..f73d61b39
--- /dev/null
+++ b/client/wfnews-war/src/main/angular/.storybook/typings.d.ts
@@ -0,0 +1,4 @@
+declare module '*.md' {
+ const content: string;
+ export default content;
+}
diff --git a/client/wfnews-war/src/main/angular/angular.json b/client/wfnews-war/src/main/angular/angular.json
index 7388ef4fd..18a7ffdd9 100644
--- a/client/wfnews-war/src/main/angular/angular.json
+++ b/client/wfnews-war/src/main/angular/angular.json
@@ -20,7 +20,9 @@
"outputPath": "dist/wfnews",
"index": "src/index.html",
"main": "src/main.ts",
- "polyfills": ["zone.js"],
+ "polyfills": [
+ "zone.js"
+ ],
"tsConfig": "src/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"preserveSymlinks": true,
@@ -161,7 +163,10 @@
"options": {
"main": "src/test.ts",
"karmaConfig": "./karma.conf.js",
- "polyfills": ["zone.js", "zone.js/testing"],
+ "polyfills": [
+ "zone.js",
+ "zone.js/testing"
+ ],
"tsConfig": "src/tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"scripts": [
@@ -194,7 +199,52 @@
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
- "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
+ "lintFilePatterns": [
+ "src/**/*.ts",
+ "src/**/*.html"
+ ]
+ }
+ },
+ "storybook": {
+ "builder": "@storybook/angular:start-storybook",
+ "options": {
+ "configDir": ".storybook",
+ "browserTarget": "WFNEWS:build",
+ "compodoc": true,
+ "compodocArgs": [
+ "-e",
+ "json",
+ "-d",
+ "."
+ ],
+ "styles": [
+ "src/styles/main.scss",
+ "node_modules/leaflet/dist/leaflet.css",
+ "node_modules/ng-pick-datetime/assets/style/picker.min.css",
+ "node_modules/lightgallery/scss/lightgallery.scss"
+ ],
+ "port": 6006
+ }
+ },
+ "build-storybook": {
+ "builder": "@storybook/angular:build-storybook",
+ "options": {
+ "configDir": ".storybook",
+ "browserTarget": "WFNEWS:build",
+ "compodoc": true,
+ "compodocArgs": [
+ "-e",
+ "json",
+ "-d",
+ "."
+ ],
+ "styles": [
+ "src/styles/main.scss",
+ "node_modules/leaflet/dist/leaflet.css",
+ "node_modules/ng-pick-datetime/assets/style/picker.min.css",
+ "node_modules/lightgallery/scss/lightgallery.scss"
+ ],
+ "outputDir": "storybook-static"
}
}
}
@@ -206,4 +256,4 @@
"enabled": true
}
}
-}
+}
\ No newline at end of file
diff --git a/client/wfnews-war/src/main/angular/documentation.json b/client/wfnews-war/src/main/angular/documentation.json
new file mode 100644
index 000000000..83cc27a8f
--- /dev/null
+++ b/client/wfnews-war/src/main/angular/documentation.json
@@ -0,0 +1,101839 @@
+{
+ "pipes": [
+ {
+ "name": "SafePipe",
+ "id": "pipe-SafePipe-714be3e3e3a8f68411d47e2bca994aa77e7a03bb59bca0112c937757bf1d3d249b8b0fec2271dbefc8c9ee390dc72b0e85cb7b1115df0dae5ab4ad27e43ec5ce",
+ "file": "src/app/pipes/safe.pipe.ts",
+ "type": "pipe",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "description": "",
+ "rawdescription": "\n",
+ "properties": [],
+ "methods": [
+ {
+ "name": "transform",
+ "args": [
+ {
+ "name": "url",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 10,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "url",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ }
+ ],
+ "standalone": false,
+ "ngname": "safe",
+ "sourceCode": "import { Pipe, PipeTransform } from '@angular/core';\r\nimport { DomSanitizer } from '@angular/platform-browser';\r\n\r\n@Pipe({\r\n name: 'safe',\r\n})\r\nexport class SafePipe implements PipeTransform {\r\n constructor(private sanitizer: DomSanitizer) {}\r\n\r\n transform(url) {\r\n return this.sanitizer.bypassSecurityTrustResourceUrl(url);\r\n }\r\n}\r\n"
+ }
+ ],
+ "interfaces": [
+ {
+ "name": "AgolOptions",
+ "id": "interface-AgolOptions-45e960f81ae10a923d8d2a8ab60d53c41df3ca39dab8c86410faaf0735ceb078ecba84502b8ff2a5160310ee2f3ce5d226e24a009acd193476868f5ae0d11b59",
+ "file": "src/app/services/AGOL-service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\nimport { Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\n\r\nexport interface AgolOptions {\r\n returnCentroid?: boolean;\r\n returnGeometry?: boolean;\r\n returnExtent?: boolean;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AGOLService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n protected http: HttpClient,\r\n ) {\r\n /* empty */\r\n }\r\n\r\n getFirePerimetre(fireNumber: string, options: AgolOptions = null) {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLperimetres'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n // append query. Only search for Fire events\r\n url += `query?where=FIRE_NUMBER='${fireNumber}'&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getEvacOrdersByEventNumber(\r\n eventNumber: string,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLevacOrders'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n // append query. Only search for Fire events\r\n url += `query?where=EVENT_NUMBER='${eventNumber}'&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getEvacOrders(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLevacOrders'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query. Only search for Fire events\r\n url += `query?where=EVENT_TYPE='Wildfire' OR EVENT_TYPE='fire'${\r\n where ? ' AND (' + where + ')' : ''\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n url = encodeURI(url).replaceAll(' ', '%20')\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(url, { headers });\r\n }\r\n\r\n getEvacOrdersByParam(where: string, options: AgolOptions = null): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLevacOrders'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n // append query. Only search for Fire events\r\n url += `query?where=${where}&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getAreaRestrictions(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLareaRestrictions'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=${\r\n where ? where : '1=1'\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getBansAndProhibitionsById(\r\n sysId: string,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLBansAndProhibitions'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=PROT_BAP_SYSID=${sysId}&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getBansAndProhibitions(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLBansAndProhibitions'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=${\r\n where ? where : '1=1'\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getAreaRestrictionsWfs() {\r\n const url =\r\n 'https://openmaps.gov.bc.ca/geo/pub/WHSE_LAND_AND_NATURAL_RESOURCE.PROT_RESTRICTED_AREAS_SP/ows?service=wfs&version=1.1.0&request=GetFeature&typename=WHSE_LAND_AND_NATURAL_RESOURCE.PROT_RESTRICTED_AREAS_SP&outputFormat=application/json&SRSName=urn:x-ogc:def:crs:EPSG:4326';\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n // Wont be needed when we point to our internal cache\r\n getActiveFireCount(): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLactiveFirest'].toString();\r\n url += `/query?f=json&where=FIRE_STATUS <> 'Out'&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&outStatistics=[{\\\"statisticType\\\":\\\"count\\\",\\\"onStatisticField\\\":\\\"OBJECTID\\\",\\\"outStatisticFieldName\\\":\\\"value\\\"}]`;\r\n return this.http.get(encodeURI(url));\r\n }\r\n\r\n getActiveFiresNoGeom(): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLactiveFirest'].toString();\r\n url += `/query?f=json&where=FIRE_STATUS <> 'Out'&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*`;\r\n return this.http.get(encodeURI(url));\r\n }\r\n\r\n getOutFiresNoGeom(): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLactiveFirest'].toString();\r\n url += `/query?f=json&where=FIRE_STATUS = 'Out'&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*`;\r\n return this.http.get(encodeURI(url));\r\n }\r\n\r\n getCurrentYearFireLastXDaysStats(lastXDays: number): Observable {\r\n const startdate = new Date();\r\n const enddate = new Date();\r\n startdate.setDate(startdate.getDate() - lastXDays);\r\n const sStartdate = `${startdate.getFullYear()}-${\r\n startdate.getMonth() + 1\r\n }-${startdate.getDate()} ${\r\n startdate.getHours() < 10 ? '0' : ''\r\n }${startdate.getHours()}:${\r\n startdate.getMinutes() < 10 ? '0' : ''\r\n }${startdate.getMinutes()}:${\r\n startdate.getSeconds() < 10 ? '0' : ''\r\n }${startdate.getSeconds()}`;\r\n const sEnddate = `${enddate.getFullYear()}-${\r\n enddate.getMonth() + 1\r\n }-${enddate.getDate()} ${\r\n enddate.getHours() < 10 ? '0' : ''\r\n }${enddate.getHours()}:${\r\n enddate.getMinutes() < 10 ? '0' : ''\r\n }${enddate.getMinutes()}:${\r\n enddate.getSeconds() < 10 ? '0' : ''\r\n }${enddate.getSeconds()}`;\r\n\r\n let url =\r\n `${\r\n this.appConfigService.getConfig().externalAppConfig['AGOLactiveFirest']\r\n }/query?f=json&` +\r\n `where=IGNITION_DATE<=timestamp '${sEnddate}' AND IGNITION_DATE>=timestamp '${sStartdate}'` +\r\n `&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*` +\r\n `&outStatistics=[{\\\"statisticType\\\":\\\"count\\\",\\\"onStatisticField\\\":\\\"OBJECTID\\\",\\\"outStatisticFieldName\\\":\\\"value\\\"}]`;\r\n url = encodeURI(url);\r\n return this.http.get(url);\r\n }\r\n\r\n getCurrentYearFireStats(): Observable {\r\n let url = `${\r\n this.appConfigService.getConfig().externalAppConfig['AGOLactiveFirest']\r\n }/query?f=json&where=1=1&returnGeometry=false&spatialRel=esriSpatialRelIntersects&\r\n outFields=*&outStatistics=[{\\\"statisticType\\\":\\\"count\\\",\\\"onStatisticField\\\":\\\"OBJECTID\\\",\\\"outStatisticFieldName\\\":\\\"value\\\"}]`;\r\n url = encodeURI(url);\r\n return this.http.get(url);\r\n }\r\n\r\n getDangerRatings(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLDangerRatings'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=${\r\n where ? where : '1=1'\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n}\r\n",
+ "properties": [
+ {
+ "name": "returnCentroid",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": true,
+ "description": "",
+ "line": 7
+ },
+ {
+ "name": "returnExtent",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": true,
+ "description": "",
+ "line": 9
+ },
+ {
+ "name": "returnGeometry",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": true,
+ "description": "",
+ "line": 8
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ApplicationState",
+ "id": "interface-ApplicationState-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "errorStates",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "ErrorStates",
+ "optional": false,
+ "description": "",
+ "line": 43
+ },
+ {
+ "name": "formStates",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "FormStates",
+ "optional": false,
+ "description": "",
+ "line": 44
+ },
+ {
+ "name": "loadStates",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "LoadStates",
+ "optional": false,
+ "description": "",
+ "line": 42
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "AreaRestrictionsOption",
+ "id": "interface-AreaRestrictionsOption-578a59039ac4654484d8e4be5fbd449d901a2d6cb9e741f267e162564117f8a272fcd258bbfc777cf74459f717c323464cbe9fd25dca73541ef16adf9822a5a4",
+ "file": "src/app/conversion/models.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface PagedCollection {\r\n pageNumber?: number;\r\n pageRowCount?: number;\r\n totalRowCount?: number;\r\n totalPageCount?: number;\r\n collection?: Array;\r\n}\r\n\r\nexport interface fireCentreOption {\r\n code?: string;\r\n fireCentreName?: string;\r\n}\r\n\r\nexport interface EvacOrderOption {\r\n eventName?: string;\r\n eventType?: string;\r\n orderAlertStatus?: string;\r\n issuingAgency?: string;\r\n preOcCode?: string;\r\n emrgOAAsysID?: number;\r\n centroid?: any;\r\n geometry?: any;\r\n dateModified?: Date;\r\n noticeType?: string;\r\n uri?: string;\r\n issuedOn?: string;\r\n externalUri?: boolean;\r\n eventNumber?: string;\r\n}\r\n\r\nexport interface AreaRestrictionsOption {\r\n protRsSysID?: number;\r\n name?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n noticeType?: string;\r\n}\r\n\r\nexport interface BansAndProhibitionsOption {\r\n protBsSysID?: number;\r\n type?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n accessProhibitionDescription?: string;\r\n noticeType?: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "accessStatusEffectiveDate",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Date",
+ "optional": true,
+ "description": "",
+ "line": 34
+ },
+ {
+ "name": "bulletinUrl",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 37
+ },
+ {
+ "name": "centroid",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 38
+ },
+ {
+ "name": "fireCentre",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 35
+ },
+ {
+ "name": "fireZone",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 36
+ },
+ {
+ "name": "geometry",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 39
+ },
+ {
+ "name": "name",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 33
+ },
+ {
+ "name": "noticeType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 40
+ },
+ {
+ "name": "protRsSysID",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 32
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "AudibleAlertState",
+ "id": "interface-AudibleAlertState-97e807b22dd48389a9e8795594d9abdbaae08bf80a89836e570a2fe1b3a1593a4106dda39fc3562d0e5caeb9a95fb68d68ba0c5ebbd89310aeb2f71c1564f685",
+ "file": "src/app/store/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { routerReducer } from '@ngrx/router-store';\r\nimport { Action, ActionReducer, ActionReducerMap } from '@ngrx/store';\r\nimport { searchReducer, SearchState, SortDirection } from '@wf1/core-ui';\r\nimport { storeLogger } from 'ngrx-store-logger';\r\nimport {\r\n ApplicationState,\r\n PagingSearchState,\r\n} from './application/application.state';\r\nimport { pageSearchReducer } from './common/page-search.reducer';\r\nimport { IncidentEffect } from './incident/incident.effect';\r\nimport { incidentReducer } from './incident/incident.reducer';\r\nimport { IncidentState } from './incident/incident.stats';\r\nimport { IncidentsEffect } from './incidents/incidents.effects';\r\n\r\nimport { incidentsReducer } from './incidents/incidents.reducer';\r\nimport {\r\n initialIncidentsSearchState,\r\n IncidentsState,\r\n} from './incidents/incidents.stats';\r\nimport { WildfiresListEffect } from './wildfiresList/wildfiresList.effects';\r\nimport { wildfiresListReducer } from './wildfiresList/wildfiresList.reducer';\r\nimport {\r\n initialWildfiresSearchState,\r\n WildfiresState,\r\n} from './wildfiresList/wildfiresList.stats';\r\n\r\nexport interface BaseRouterStoreState {\r\n url: string;\r\n}\r\n\r\nexport interface RouterState {\r\n state: BaseRouterStoreState;\r\n}\r\n\r\nexport const rootReducers: ActionReducerMap = {\r\n search: searchReducer,\r\n router: routerReducer,\r\n incidents: incidentsReducer,\r\n searchIncidents: pageSearchReducer,\r\n incident: incidentReducer,\r\n wildfires: wildfiresListReducer,\r\n searchWildfires: pageSearchReducer,\r\n};\r\n\r\nexport interface RootState {\r\n application?: ApplicationState;\r\n incidents?: IncidentsState;\r\n searchIncidents?: PagingSearchState;\r\n incident?: IncidentState;\r\n wildfires?: WildfiresState;\r\n searchWildfires?: PagingSearchState;\r\n}\r\n\r\nexport const initialRootState: RootState = {\r\n searchIncidents: initialIncidentsSearchState,\r\n searchWildfires: initialWildfiresSearchState,\r\n};\r\n\r\nexport const rootEffects: any[] = [\r\n // PlaceNameSearchEffects,\r\n IncidentsEffect,\r\n IncidentEffect,\r\n WildfiresListEffect,\r\n];\r\n\r\nexport function logger(reducer: ActionReducer): any {\r\n // default, no options\r\n return storeLogger({\r\n collapsed: true,\r\n level: 'log',\r\n filter: {\r\n blacklist: [],\r\n },\r\n })(reducer);\r\n}\r\n\r\nexport interface AudibleAlertState {\r\n enableUnacknowledged: boolean;\r\n enableReceivedFromPM: boolean;\r\n selectedZoneIds?: string[];\r\n}\r\n\r\nexport class SearchStateAndConfig implements SearchState {\r\n query: string;\r\n sortParam: string;\r\n sortDirection: SortDirection;\r\n sortModalVisible: boolean;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n hiddenFilters: {\r\n [param: string]: any[];\r\n };\r\n columns?: string[]; //ordered list of columns to display\r\n componentId?: string;\r\n audibleAlert?: AudibleAlertState;\r\n}\r\n\r\nexport function isEmpty(obj) {\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport interface LabeledAction extends Action {\r\n displayLabel: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "enableReceivedFromPM",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 79
+ },
+ {
+ "name": "enableUnacknowledged",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 78
+ },
+ {
+ "name": "selectedZoneIds",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": true,
+ "description": "",
+ "line": 80
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "BansAndProhibitionsOption",
+ "id": "interface-BansAndProhibitionsOption-578a59039ac4654484d8e4be5fbd449d901a2d6cb9e741f267e162564117f8a272fcd258bbfc777cf74459f717c323464cbe9fd25dca73541ef16adf9822a5a4",
+ "file": "src/app/conversion/models.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface PagedCollection {\r\n pageNumber?: number;\r\n pageRowCount?: number;\r\n totalRowCount?: number;\r\n totalPageCount?: number;\r\n collection?: Array;\r\n}\r\n\r\nexport interface fireCentreOption {\r\n code?: string;\r\n fireCentreName?: string;\r\n}\r\n\r\nexport interface EvacOrderOption {\r\n eventName?: string;\r\n eventType?: string;\r\n orderAlertStatus?: string;\r\n issuingAgency?: string;\r\n preOcCode?: string;\r\n emrgOAAsysID?: number;\r\n centroid?: any;\r\n geometry?: any;\r\n dateModified?: Date;\r\n noticeType?: string;\r\n uri?: string;\r\n issuedOn?: string;\r\n externalUri?: boolean;\r\n eventNumber?: string;\r\n}\r\n\r\nexport interface AreaRestrictionsOption {\r\n protRsSysID?: number;\r\n name?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n noticeType?: string;\r\n}\r\n\r\nexport interface BansAndProhibitionsOption {\r\n protBsSysID?: number;\r\n type?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n accessProhibitionDescription?: string;\r\n noticeType?: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "accessProhibitionDescription",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 52
+ },
+ {
+ "name": "accessStatusEffectiveDate",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Date",
+ "optional": true,
+ "description": "",
+ "line": 46
+ },
+ {
+ "name": "bulletinUrl",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 49
+ },
+ {
+ "name": "centroid",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 50
+ },
+ {
+ "name": "fireCentre",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 47
+ },
+ {
+ "name": "fireZone",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 48
+ },
+ {
+ "name": "geometry",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 51
+ },
+ {
+ "name": "noticeType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 53
+ },
+ {
+ "name": "protBsSysID",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 44
+ },
+ {
+ "name": "type",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 45
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "BaseRouterStoreState",
+ "id": "interface-BaseRouterStoreState-97e807b22dd48389a9e8795594d9abdbaae08bf80a89836e570a2fe1b3a1593a4106dda39fc3562d0e5caeb9a95fb68d68ba0c5ebbd89310aeb2f71c1564f685",
+ "file": "src/app/store/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { routerReducer } from '@ngrx/router-store';\r\nimport { Action, ActionReducer, ActionReducerMap } from '@ngrx/store';\r\nimport { searchReducer, SearchState, SortDirection } from '@wf1/core-ui';\r\nimport { storeLogger } from 'ngrx-store-logger';\r\nimport {\r\n ApplicationState,\r\n PagingSearchState,\r\n} from './application/application.state';\r\nimport { pageSearchReducer } from './common/page-search.reducer';\r\nimport { IncidentEffect } from './incident/incident.effect';\r\nimport { incidentReducer } from './incident/incident.reducer';\r\nimport { IncidentState } from './incident/incident.stats';\r\nimport { IncidentsEffect } from './incidents/incidents.effects';\r\n\r\nimport { incidentsReducer } from './incidents/incidents.reducer';\r\nimport {\r\n initialIncidentsSearchState,\r\n IncidentsState,\r\n} from './incidents/incidents.stats';\r\nimport { WildfiresListEffect } from './wildfiresList/wildfiresList.effects';\r\nimport { wildfiresListReducer } from './wildfiresList/wildfiresList.reducer';\r\nimport {\r\n initialWildfiresSearchState,\r\n WildfiresState,\r\n} from './wildfiresList/wildfiresList.stats';\r\n\r\nexport interface BaseRouterStoreState {\r\n url: string;\r\n}\r\n\r\nexport interface RouterState {\r\n state: BaseRouterStoreState;\r\n}\r\n\r\nexport const rootReducers: ActionReducerMap = {\r\n search: searchReducer,\r\n router: routerReducer,\r\n incidents: incidentsReducer,\r\n searchIncidents: pageSearchReducer,\r\n incident: incidentReducer,\r\n wildfires: wildfiresListReducer,\r\n searchWildfires: pageSearchReducer,\r\n};\r\n\r\nexport interface RootState {\r\n application?: ApplicationState;\r\n incidents?: IncidentsState;\r\n searchIncidents?: PagingSearchState;\r\n incident?: IncidentState;\r\n wildfires?: WildfiresState;\r\n searchWildfires?: PagingSearchState;\r\n}\r\n\r\nexport const initialRootState: RootState = {\r\n searchIncidents: initialIncidentsSearchState,\r\n searchWildfires: initialWildfiresSearchState,\r\n};\r\n\r\nexport const rootEffects: any[] = [\r\n // PlaceNameSearchEffects,\r\n IncidentsEffect,\r\n IncidentEffect,\r\n WildfiresListEffect,\r\n];\r\n\r\nexport function logger(reducer: ActionReducer): any {\r\n // default, no options\r\n return storeLogger({\r\n collapsed: true,\r\n level: 'log',\r\n filter: {\r\n blacklist: [],\r\n },\r\n })(reducer);\r\n}\r\n\r\nexport interface AudibleAlertState {\r\n enableUnacknowledged: boolean;\r\n enableReceivedFromPM: boolean;\r\n selectedZoneIds?: string[];\r\n}\r\n\r\nexport class SearchStateAndConfig implements SearchState {\r\n query: string;\r\n sortParam: string;\r\n sortDirection: SortDirection;\r\n sortModalVisible: boolean;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n hiddenFilters: {\r\n [param: string]: any[];\r\n };\r\n columns?: string[]; //ordered list of columns to display\r\n componentId?: string;\r\n audibleAlert?: AudibleAlertState;\r\n}\r\n\r\nexport function isEmpty(obj) {\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport interface LabeledAction extends Action {\r\n displayLabel: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "url",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 28
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "BoundingBox",
+ "id": "interface-BoundingBox-202e8b4af361065a5c9ff67e569650ac69ed946c07e7a48a5068feaedf798ecfd0374c037fcab52c70869343bbe242a22ac75f2d29027ce50db28f62b14d5fa9",
+ "file": "src/app/services/notification.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { CapacitorService } from '@app/services/capacitor-service';\r\nimport { CommonUtilityService } from '@app/services/common-utility.service';\r\nimport { CapacitorHttp } from '@capacitor/core';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface NotificationSettingRsrc {\r\n deviceType: string;\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n notifications: NotificationRsrc[];\r\n}\r\n\r\nexport interface NotificationRsrc {\r\n notificationName: string;\r\n notificationType: string;\r\n radius: number;\r\n point: VmGeometry;\r\n topics: string[];\r\n activeIndicator: boolean;\r\n}\r\n\r\nexport interface VmGeometry {\r\n type: string;\r\n coordinates: number[];\r\n crs: string;\r\n}\r\n\r\nexport interface VmNotificationPreferences {\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n deviceType: string;\r\n notificationDetails: VmNotificationDetail[];\r\n}\r\n\r\nexport interface VmNotificationDetail {\r\n name: string;\r\n type: string;\r\n radius: number;\r\n preferences: string[];\r\n locationCoords: VmCoordinates;\r\n active: boolean;\r\n mapConfig?: Promise;\r\n}\r\n\r\nexport interface VmCoordinates {\r\n long: number;\r\n lat: number;\r\n}\r\n\r\nexport interface BoundingBox {\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class NotificationService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private httpClient: HttpClient,\r\n private capacitorService: CapacitorService,\r\n private commonUtilityService: CommonUtilityService,\r\n ) {}\r\n\r\n public updateUserNotificationPreferences(\r\n notificationSettings,\r\n savedNotification,\r\n ): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n console.log('device properties:\\'', p);\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n const token = this.capacitorService.getNotificationToken();\r\n const notificationSettingRsrc =\r\n convertToNotificationSettingRsrc(notificationSettings);\r\n notificationSettingRsrc.subscriberGuid = p.deviceId;\r\n notificationSettingRsrc.notificationToken = token;\r\n notificationSettingRsrc.deviceType = p.isAndroidPlatform\r\n ? 'android'\r\n : 'ios';\r\n if (savedNotification.length) {\r\n savedNotification.forEach((notification) => {\r\n notificationSettingRsrc.notifications.push(notification);\r\n });\r\n }\r\n const notificationSettingsJSON: string = JSON.stringify(notificationSettingRsrc);\r\n if (this.commonUtilityService.hasSQLKeywords(notificationSettingsJSON)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n\r\n return this.httpClient\r\n .put(url, notificationSettingRsrc, { headers })\r\n .toPromise();\r\n });\r\n }\r\n\r\n public getUserNotificationPreferences(): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p?.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n return this.httpClient.get(url, { headers }).toPromise();\r\n });\r\n }\r\n\r\n public getFireCentreByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.DRP_MOF_FIRE_CENTRES_SP&outputformat=application/json&cql_filter=INTERSECTS(GEOMETRY,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n\r\n public getDangerRatingByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LAND_AND_NATURAL_RESOURCE.PROT_DANGER_RATING_SP&outputformat=application/json&cql_filter=INTERSECTS(SHAPE,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport function convertToNotificationSettingRsrc(\r\n np: any,\r\n): NotificationSettingRsrc {\r\n const notificationTopics = [];\r\n if (np?.pushNotificationsFireBans) {\r\n notificationTopics.push('British_Columbia_Bans_and_Prohibition_Areas');\r\n notificationTopics.push('British_Columbia_Area_Restrictions');\r\n }\r\n if (np?.pushNotificationsWildfires) {\r\n notificationTopics.push('BCWS_ActiveFires_PublicView');\r\n notificationTopics.push('Evacuation_Orders_and_Alerts');\r\n }\r\n return {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notificationSettings',\r\n notifications: np\r\n ? [\r\n {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notification',\r\n notificationName: np.notificationName,\r\n notificationType: 'nearme',\r\n radius: np.radius,\r\n point: {\r\n type: 'Point',\r\n coordinates: [np.longitude, np.latitude],\r\n crs: null,\r\n },\r\n activeIndicator: true,\r\n topics: notificationTopics,\r\n },\r\n ]\r\n : [],\r\n notificationToken: null,\r\n subscriberToken: 'subscriberTpken',\r\n subscriberGuid: null,\r\n deviceType: null,\r\n } as unknown as NotificationSettingRsrc;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "latitude",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 55
+ },
+ {
+ "name": "longitude",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 56
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "CheckUnsavedChanges",
+ "id": "interface-CheckUnsavedChanges-3ebb3685541a825e4dda6d8229cb2cf06e3f478432a9ec8d299f5b385fc64dfdaee470b614195abde181d48955706828fc1f7b1e7c1173303f1b7a4359f3ce20",
+ "file": "src/app/components/common/guards/unsaved-changes.guard.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Injectable } from '@angular/core';\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { CanDeactivate } from '@angular/router';\r\nimport { Observable, of } from 'rxjs';\r\n\r\nexport interface CheckUnsavedChanges {\r\n changesSaved: () => boolean | Observable;\r\n confirmDialog: () => boolean | Observable;\r\n}\r\n\r\n@Injectable()\r\nexport class CanDeactivateGuard implements CanDeactivate {\r\n constructor(public dialog: MatDialog) {}\r\n\r\n canDeactivate(component: CheckUnsavedChanges): boolean | Observable {\r\n if (!component.changesSaved()) {\r\n return component.confirmDialog();\r\n }\r\n\r\n return of(true);\r\n }\r\n}\r\n",
+ "properties": [
+ {
+ "name": "changesSaved",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "function",
+ "optional": false,
+ "description": "",
+ "line": 7
+ },
+ {
+ "name": "confirmDialog",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "function",
+ "optional": false,
+ "description": "",
+ "line": 8
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "CompassHeading",
+ "id": "interface-CompassHeading-8535ce51ccdad526d840669937c2863b8c4704ebacf2e5a788764298904f6dbe7761d1eb638a976f40486932cb843e69f3a4250037faa79d75e0a3680ed65ea9",
+ "file": "src/app/services/capacitor-service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { EventEmitter, Injectable, NgZone } from '@angular/core';\r\nimport { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';\r\nimport { Router } from '@angular/router';\r\nimport { FCM } from '@capacitor-community/fcm';\r\nimport { App, AppState } from '@capacitor/app';\r\nimport { AppLauncher } from '@capacitor/app-launcher';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Device } from '@capacitor/device';\r\nimport { Geolocation, Position } from '@capacitor/geolocation';\r\nimport {\r\n PushNotificationSchema,\r\n PushNotifications,\r\n} from '@capacitor/push-notifications';\r\nimport { Store } from '@ngrx/store';\r\nimport { BehaviorSubject, fromEvent } from 'rxjs';\r\nimport { environment } from '../../environments/environment';\r\nimport { RootState } from '../store';\r\nimport { ApplicationStateService } from './application-state.service';\r\nimport { EventEmitterService } from './event-emitter.service';\r\n\r\nimport { ResourcesRoutes } from '@app/utils';\r\nimport { NotificationSnackbarComponent } from '../components/notification-snackbar/notification-snackbar.component';\r\nimport { Preferences } from '@capacitor/preferences';\r\n\r\nexport interface CompassHeading {\r\n magneticHeading?: number; //The heading in degrees from 0-359.99 at a single moment in time. (Number)\r\n trueHeading?: number; //The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. A negative value indicates that the true heading can't be determined. (Number)\r\n headingAccuracy?: number; //The deviation in degrees between the reported heading and the true heading. (Number)\r\n timestamp?: string; //The time at which this heading was determined. (DOMTimeStamp)\r\n error?: string;\r\n}\r\n\r\nexport interface LocationNotification {\r\n latitude: number;\r\n longitude: number;\r\n radius: number;\r\n featureId: string;\r\n featureType: string;\r\n fireYear?: number;\r\n}\r\n\r\nexport interface ReportOfFireNotification {\r\n title: string;\r\n body: string;\r\n}\r\n\r\nexport interface DeviceProperties {\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n isMobilePlatform: boolean;\r\n deviceId: string;\r\n isTwitterInstalled: boolean;\r\n}\r\n\r\nconst UPDATE_AFTER_INACTIVE_MILLIS = 1000 * 60; // 1 minute\r\nconst REFRESH_INTERVAL_ACTIVE_MILLIS = 5 * 1000 * 60; // 5 minutes\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CapacitorService {\r\n resume: BehaviorSubject;\r\n initialized: Promise;\r\n fbAppInstalled: boolean;\r\n twitterAppInstalled: boolean;\r\n appState: AppState;\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n deviceId: string;\r\n pnNav = null;\r\n notificationToken = null;\r\n updateMainMapLayers = new EventEmitter();\r\n currentHeadingPromise: Promise;\r\n locationNotifications = new EventEmitter();\r\n rofNotifications = new EventEmitter();\r\n inactiveStart: number;\r\n refreshTimer;\r\n locationNotificationsDelay = 5000;\r\n rofNotificationsDelay = 5000;\r\n notificationSnackbarPromise = Promise.resolve();\r\n registeredForNotifications = false;\r\n private devicePropertiesPromise: Promise;\r\n\r\n constructor(\r\n private zone: NgZone,\r\n protected router: Router,\r\n protected store: Store,\r\n protected eventEmitterService: EventEmitterService,\r\n protected stateService: ApplicationStateService,\r\n protected snackbar: MatSnackBar,\r\n ) {\r\n this.resume = new BehaviorSubject(null);\r\n fromEvent(document, 'resume').subscribe((event) => {\r\n this.zone.run(() => {\r\n this.onResume();\r\n });\r\n });\r\n\r\n this.isIOSPlatform = false;\r\n this.isAndroidPlatform = false;\r\n this.isWebPlatform = false;\r\n this.fbAppInstalled = false;\r\n this.twitterAppInstalled = false;\r\n this.deviceId = '';\r\n\r\n this.initialized = this.checkDevice().then(() => {\r\n this.init();\r\n\r\n // use for testing notification at startup\r\n // this.emitLocationNotification( {\r\n // coords: '[48.463259,-123.312635]',\r\n // radius: '20',\r\n // messageID: 'V65055',\r\n // topicKey: 'BCWS_ActiveFires_PublicView',\r\n // } )\r\n });\r\n }\r\n\r\n init() {\r\n const startRefreshTimer = () => {\r\n stopRefreshTimer();\r\n\r\n this.refreshTimer = setTimeout(() => {\r\n this.updateMainMapLayers.emit();\r\n startRefreshTimer();\r\n }, REFRESH_INTERVAL_ACTIVE_MILLIS);\r\n };\r\n\r\n const stopRefreshTimer = () => {\r\n if (!this.refreshTimer) {\r\nreturn;\r\n}\r\n\r\n clearTimeout(this.refreshTimer);\r\n this.refreshTimer = null;\r\n };\r\n\r\n startRefreshTimer();\r\n\r\n App.addListener('appStateChange', (state) => {\r\n if (state.isActive) {\r\n startRefreshTimer();\r\n\r\n if (!this.inactiveStart) {\r\nreturn;\r\n}\r\n\r\n const inactiveDuration = Date.now() - this.inactiveStart;\r\n this.inactiveStart = null;\r\n\r\n if (inactiveDuration > UPDATE_AFTER_INACTIVE_MILLIS) {\r\n this.updateMainMapLayers.emit();\r\n }\r\n } else {\r\n if (!this.inactiveStart) {\r\nthis.inactiveStart = Date.now();\r\n}\r\n\r\n stopRefreshTimer();\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n if (this.isWebPlatform) {\r\n this.notificationToken = 'FakeForWeb';\r\n return;\r\n }\r\n\r\n this.checkInstalledApps();\r\n\r\n if (this.isAndroidPlatform) {\r\n App.addListener('backButton', (state) => {\r\n this.eventEmitterService.androidBackButtonPressed();\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n // Request permission to use push notifications\r\n this.registerForNotifications()\r\n .then((registered) => {\r\n console.log('registeredForNotifications', registered);\r\n this.registeredForNotifications = registered;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // On success, we should be able to receive notifications\r\n PushNotifications.addListener('registration', (token) => {\r\n console.log('PNN REgister success ' + token.value);\r\n if (this.isAndroidPlatform) {\r\n this.notificationToken = token.value;\r\n } else if (this.isIOSPlatform) {\r\n FCM.getToken()\r\n .then((response) => {\r\n this.notificationToken = response.token;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Some issue with our setup and push will not work\r\n PushNotifications.addListener('registrationError', (error) => {\r\n console.log('PNN REgister fail ' + error);\r\n }).catch((err) => {\r\n console.error(err);\r\n });\r\n\r\n // Show us the notification payload if the app is open on our device\r\n PushNotifications.addListener(\r\n 'pushNotificationReceived',\r\n (notification) => {\r\n console.log('pushNotificationReceived', notification);\r\n this.handleRofPushNotification(notification);\r\n },\r\n ).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Method called when tapping on a notification\r\n PushNotifications.addListener('pushNotificationActionPerformed', (ev) => {\r\n const data = ev.notification.data;\r\n console.log('pushNotificationActionPerformed', data);\r\n\r\n this.emitLocationNotification(data);\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n async registerForNotifications(): Promise {\r\n let status = await PushNotifications.checkPermissions();\r\n if (status.receive === 'prompt') {\r\n status = await PushNotifications.requestPermissions();\r\n }\r\n\r\n if (status.receive !== 'granted') {\r\n return false;\r\n }\r\n\r\n await PushNotifications.register();\r\n return true;\r\n }\r\n\r\n handleRofPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n this.emitLocationNotification(notification.body);\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitRofNotification(title, body) {\r\n setTimeout(() => {\r\n try {\r\n this.rofNotifications.emit({ title, body });\r\n\r\n this.rofNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, title + ': ' + body);\r\n }\r\n }, this.rofNotificationsDelay);\r\n }\r\n\r\n handleLocationPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n const c = JSON.parse(notification.data['coords']);\r\n const r = JSON.parse(notification.data['radius']);\r\n this.router.navigate([ResourcesRoutes.ACTIVEWILDFIREMAP], {\r\n queryParams: {\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: notification.data['messageID'],\r\n featureType: notification.data['topicKey'],\r\n identify: true,\r\n notification: true,\r\n time: Date.now(),\r\n },\r\n });\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitLocationNotification(data) {\r\n setTimeout(() => {\r\n try {\r\n const c = JSON.parse(data['coords']);\r\n const r = JSON.parse(data['radius']);\r\n\r\n this.locationNotifications.emit({\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: data['messageID'],\r\n featureType: data['topicKey'],\r\n });\r\n\r\n this.locationNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, data);\r\n }\r\n }, this.locationNotificationsDelay);\r\n }\r\n\r\n showNotificationSnackbar(notification: any) {\r\n const cfg: MatSnackBarConfig = {\r\n data: { notification },\r\n // need to change back to 10 sec. Using 60 sec for testing purpose in case QA missed it.\r\n duration: 60 * 1000,\r\n verticalPosition: 'top',\r\n };\r\n\r\n return this.snackbar.openFromComponent(NotificationSnackbarComponent, cfg);\r\n }\r\n\r\n checkDevice() {\r\n // const deviceInfo = \r\n return Device.getInfo()\r\n .then((devInfo) => {\r\n console.log(devInfo);\r\n if (!devInfo) {\r\nreturn;\r\n}\r\n\r\n this.isIOSPlatform = devInfo.platform === 'ios';\r\n this.isAndroidPlatform = devInfo.platform === 'android';\r\n this.isWebPlatform =\r\n devInfo.platform !== 'ios' && devInfo.platform !== 'android';\r\n\r\n return Device.getId();\r\n })\r\n .then((deviceId) => {\r\n console.log(deviceId);\r\n this.deviceId = deviceId.identifier;\r\n });\r\n }\r\n\r\n async getCurrentPosition(options?: PositionOptions): Promise {\r\n const coordinates = Geolocation.getCurrentPosition(options);\r\n return coordinates;\r\n }\r\n\r\n checkInstalledApps() {\r\n this.checkTwitterAppInstalled().then(\r\n (result) => {\r\n this.twitterAppInstalled = result;\r\n },\r\n (error) => {\r\n this.twitterAppInstalled = false;\r\n },\r\n );\r\n\r\n this.checkFbAppInstalled().then(\r\n (result) => {\r\n this.fbAppInstalled = result;\r\n },\r\n (error) => {\r\n this.fbAppInstalled = false;\r\n },\r\n );\r\n }\r\n\r\n onResume(): void {\r\n this.resume.next(true);\r\n }\r\n\r\n openLinkInAppBrowser(url: string) {\r\n Browser.open({\r\n url,\r\n toolbarColor: '#f7f7f9',\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n private async checkTwitterAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async checkFbAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'fb://' : 'com.facebook.katana';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async appIsInstalled(scheme: string): Promise {\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n\r\n initOfflinePageSettings() {\r\n App.addListener('appStateChange', (state: AppState) => {\r\n this.appState = state;\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n public isMobilePlatform(): boolean {\r\n if (this.isIOSPlatform || this.isAndroidPlatform) {\r\n return true;\r\n }\r\n return !!environment['is_mobile_platform'];\r\n }\r\n\r\n getPnUrl() {\r\n return this.pnNav;\r\n }\r\n\r\n public getNotificationToken() {\r\n return this.notificationToken;\r\n }\r\n\r\n public setNotificationToken(token: string) {\r\n this.notificationToken = token;\r\n }\r\n\r\n openUrlInApp(url: string) {\r\n let scheme;\r\n let schemeUrl;\r\n // twitter\r\n if (url.indexOf('twitter.com/') !== -1) {\r\n scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n schemeUrl = 'twitter://user?screen_name=' + url.split('twitter.com/')[1];\r\n }\r\n\r\n if (scheme && schemeUrl) {\r\n AppLauncher.openUrl({ url: schemeUrl }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }\r\n\r\n isAndroid() {\r\n return this.isAndroidPlatform;\r\n }\r\n\r\n isIOS() {\r\n return this.isIOSPlatform;\r\n }\r\n\r\n getCurrentHeading(): Promise {\r\n const compass = navigator['compass'];\r\n if (!compass) {\r\nreturn Promise.reject(Error('navigator.compass not available'));\r\n} else {\r\n const currentHeading = new Promise((res, rej) => {\r\n compass.getCurrentHeading(\r\n (heading: CompassHeading) => {\r\n res(heading);\r\n this.currentHeadingPromise = null;\r\n },\r\n (error) => {\r\n rej(Error('Failed to get heading: ' + JSON.stringify(error)));\r\n this.currentHeadingPromise = null;\r\n },\r\n );\r\n });\r\n\r\n this.currentHeadingPromise = currentHeading;\r\n\r\n return this.currentHeadingPromise;\r\n }\r\n }\r\n\r\n async checkDeviceSystem() {\r\n // const deviceInfo = \r\n try {\r\n const deviceInfo = await Device.getInfo();\r\n return deviceInfo;\r\n } catch (error) {\r\n console.error('Error getting device info:', error);\r\n }\r\n }\r\n\r\n get deviceProperties(): Promise {\r\n if (!this.devicePropertiesPromise) {\r\nthis.devicePropertiesPromise = Device.getInfo()\r\n .then((devInfo) => Device.getId().then((deviceId) => {\r\n\r\n const p = devInfo && devInfo.platform;\r\n const prop: DeviceProperties = {\r\n isIOSPlatform: p == 'ios',\r\n isAndroidPlatform: p == 'android',\r\n isWebPlatform: p != 'ios' && p != 'android',\r\n isMobilePlatform:\r\n p == 'ios' ||\r\n p == 'android' ||\r\n !!environment['is_mobile_platform'],\r\n deviceId: deviceId.identifier,\r\n isTwitterInstalled: false,\r\n };\r\n const scheme = prop.isIOSPlatform\r\n ? 'twitter://'\r\n : 'com.twitter.android';\r\n return AppLauncher.canOpenUrl({ url: scheme })\r\n .then((canOpen) => {\r\n prop.isTwitterInstalled = canOpen.value;\r\n return prop;\r\n })\r\n .catch((e) => {\r\n console.warn(e);\r\n return prop;\r\n });\r\n }))\r\n .catch((e) => {\r\n console.warn(e);\r\n return {\r\n isIOSPlatform: false,\r\n isAndroidPlatform: false,\r\n isWebPlatform: false,\r\n isMobilePlatform: false,\r\n deviceId: '',\r\n isTwitterInstalled: false,\r\n };\r\n });\r\n}\r\n\r\n return this.devicePropertiesPromise;\r\n }\r\n\r\n get isMobile(): Promise {\r\n return this.deviceProperties.then((p) => p.isMobilePlatform);\r\n }\r\n\r\n async saveData(key: string, value: string) {\r\n await Preferences.set({\r\n key: key,\r\n value: value\r\n });\r\n }\r\n \r\n async getData(key: string) {\r\n const response = await Preferences.get({ key: key });\r\n return response.value;\r\n }\r\n\r\n async removeData(key: string) {\r\n await Preferences.remove({ key: key })\r\n }\r\n}\r\n\r\n\r\n",
+ "properties": [
+ {
+ "name": "error",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 30
+ },
+ {
+ "name": "headingAccuracy",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 28
+ },
+ {
+ "name": "magneticHeading",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 26
+ },
+ {
+ "name": "timestamp",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 29
+ },
+ {
+ "name": "trueHeading",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 27
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "Coordinates",
+ "id": "interface-Coordinates-d8cb1d18422d250f08384df5fb2272408deadabdf142b0e8e533061fc252ade67243883d97c3593a89d8e2fe8e06ccc7606abc0ddfc637f2b10a34c331048a03",
+ "file": "src/app/services/common-utility.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { NumberFormatStyle } from '@angular/common';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Injectable, Injector } from '@angular/core';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\nimport { App } from '@capacitor/app';\r\nimport { Geolocation } from '@capacitor/geolocation';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\nimport { Observable } from 'rxjs';\r\nimport { ReportOfFireService } from './report-of-fire-service';\r\nimport { LocalStorageService } from './local-storage-service';\r\n\r\nconst MAX_CACHE_AGE = 30 * 1000;\r\n\r\nexport interface Coordinates {\r\n readonly accuracy: number;\r\n readonly altitude: number | null;\r\n readonly altitudeAccuracy: number | null;\r\n readonly heading: number | null;\r\n readonly latitude: number;\r\n readonly longitude: number;\r\n readonly speed: number | null;\r\n}\r\n\r\nexport interface Position {\r\n readonly coords: Coordinates;\r\n readonly timestamp: NumberFormatStyle;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CommonUtilityService {\r\n private myLocation;\r\n private locationTime;\r\n private location;\r\n private rofService;\r\n\r\n constructor(\r\n protected snackbarService: MatSnackBar,\r\n private http: HttpClient,\r\n private appConfigService: AppConfigService,\r\n private injector: Injector,\r\n private storageService: LocalStorageService\r\n ) {\r\n setTimeout(() => (this.rofService = injector.get(ReportOfFireService)));\r\n }\r\n\r\n getCurrentLocationPromise(): Promise {\r\n const self = this;\r\n const now = Date.now();\r\n if (this.locationTime && now - this.locationTime < MAX_CACHE_AGE) {\r\n return this.location;\r\n }\r\n\r\n this.locationTime = now;\r\n this.location = Geolocation.getCurrentPosition();\r\n return this.location;\r\n }\r\n\r\n getCurrentLocation(callback?: (p: Position) => void) {\r\n if (navigator && navigator.geolocation) {\r\n return Geolocation.getCurrentPosition().then(\r\n (position) => {\r\n this.myLocation = position ? position.coords : undefined;\r\n if (callback) {\r\n callback(position);\r\n }\r\n return position ? position.coords : undefined;\r\n },\r\n (error) => {\r\n this.snackbarService.open(\r\n 'Unable to retrieve the current location.',\r\n '',\r\n {\r\n duration: 5,\r\n },\r\n );\r\n },\r\n );\r\n } else {\r\n console.warn('Unable to access geolocation');\r\n this.snackbarService.open('Unable to access location services.', '', {\r\n duration: 5,\r\n });\r\n }\r\n }\r\n\r\n preloadGeolocation() {\r\n Geolocation.getCurrentPosition().then(\r\n (position) => {\r\n this.myLocation = position.coords;\r\n },\r\n (error) => {\r\n this.snackbarService.open(\r\n 'Unable to retrieve the current location',\r\n 'Cancel',\r\n {\r\n duration: 5000,\r\n },\r\n );\r\n },\r\n );\r\n }\r\n\r\n sortAddressList(results: any, value: string) {\r\n let address = null;\r\n let trimmedAddress = null;\r\n let valueLength = null;\r\n let valueMatch = null;\r\n results.forEach((result) => {\r\n address = this.getFullAddress(result);\r\n result.address = address.trim();\r\n trimmedAddress = result.address;\r\n valueLength = value.length;\r\n if (trimmedAddress != null) {\r\nvalueMatch = trimmedAddress.substring(0, valueLength);\r\n}\r\n\r\n if (\r\n address != null &&\r\n valueLength != null &&\r\n valueMatch != null &&\r\n (value.toUpperCase() === address.toUpperCase() ||\r\n value.toUpperCase() === valueMatch.toUpperCase())\r\n ) {\r\n const index = results.indexOf(result);\r\n if (index !== -1) {\r\n results.splice(index, 1);\r\n }\r\n const resultToBeUnshifted = result;\r\n\r\n results.unshift(resultToBeUnshifted);\r\n }\r\n });\r\n\r\n return results;\r\n }\r\n\r\n getFullAddress(location) {\r\n let result = '';\r\n\r\n if (location.civicNumber) {\r\n result += location.civicNumber;\r\n }\r\n\r\n if (location.streetName) {\r\n result += ' ' + location.streetName;\r\n }\r\n\r\n if (location.streetQualifier) {\r\n result += ' ' + location.streetQualifier;\r\n }\r\n\r\n if (location.streetType) {\r\n result += ' ' + location.streetType;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n isIPhone(): boolean {\r\n const userAgent = window.navigator.userAgent.toLowerCase();\r\n return /iphone/.test(userAgent);\r\n }\r\n\r\n countdown(timeoutDuration) {\r\n const promise = new Promise((resolve) => {\r\n setTimeout(() => resolve(false), timeoutDuration);\r\n });\r\n return promise;\r\n }\r\n\r\n checkLocation() {\r\n const promise = new Promise((resolve) => {\r\n Geolocation.getCurrentPosition().then(\r\n (position) => {\r\n resolve(true)\r\n },\r\n (error) => {\r\n resolve(false)\r\n },\r\n );\r\n })\r\n\r\n return promise;\r\n }\r\n\r\n async checkLocationServiceStatus(): Promise {\r\n const timeoutDuration = 5000; // 5 seconds limit\r\n \r\n const locationPromise = await this.checkLocation()\r\n const timeoutPromise = this.countdown(timeoutDuration)\r\n\r\n return Promise.race([timeoutPromise, locationPromise]);\r\n }\r\n\r\n pingService(): Observable {\r\n const url = this.appConfigService.getConfig().rest['wfnews'];\r\n return this.http.get(url);\r\n }\r\n\r\n calculateBearing(\r\n lat1: number,\r\n lon1: number,\r\n lat2: number,\r\n lon2: number,\r\n ): number {\r\n const dLon = this.deg2rad(lon2 - lon1);\r\n const x = Math.sin(dLon) * Math.cos(this.deg2rad(lat2));\r\n const y =\r\n Math.cos(this.deg2rad(lat1)) * Math.sin(this.deg2rad(lat2)) -\r\n Math.sin(this.deg2rad(lat1)) *\r\n Math.cos(this.deg2rad(lat2)) *\r\n Math.cos(dLon);\r\n const bearing = Math.atan2(x, y);\r\n const bearingDegrees = this.rad2deg(bearing);\r\n return (bearingDegrees + 360) % 360;\r\n }\r\n\r\n formatDDM(decimal: number) {\r\n decimal = Math.abs(decimal);\r\n const d = Math.abs(Math.trunc(decimal));\r\n return d + '° ' + (60 * (decimal - d)).toFixed(3) + '\\'';\r\n }\r\n\r\n async checkOnlineStatus(): Promise {\r\n try {\r\n await this.pingService().toPromise();\r\n return true;\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async removeInvalidOfflineRoF() {\r\n try {\r\n // Fetch locally stored data\r\n const offlineReportSaved = this.storageService.getData('offlineReportData');\r\n if (offlineReportSaved) {\r\n const offlineReport = JSON.parse(offlineReportSaved);\r\n\r\n if (offlineReport.resource) {\r\n const resource = JSON.parse(offlineReport.resource);\r\n // Remove the locally stored data if it was submitted more than 24 hours ago\r\n if (\r\n resource.submittedTimestamp &&\r\n this.invalidTimestamp(resource.submittedTimestamp)\r\n ) {\r\n this.storageService.removeData('offlineReportData');\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Error removing invalid RoF data:', error);\r\n }\r\n }\r\n\r\n invalidTimestamp(timestamp: string): boolean {\r\n // check if submitted timestamp is more than 24 hours ago\r\n const now = new Date().getTime();\r\n const submittedTimestamp = Number(timestamp);\r\n const oneDay = 24 * 60 * 60 * 1000;\r\n return now - submittedTimestamp > oneDay;\r\n }\r\n\r\n private deg2rad(deg: number): number {\r\n return deg * (Math.PI / 180);\r\n }\r\n private rad2deg(rad: number): number {\r\n return rad * (180 / Math.PI);\r\n }\r\n\r\n async checkOnline() {\r\n try {\r\n await this.pingService().toPromise();\r\n return true;\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n isAttributePresent(array, attributeName, attributeValue) {\r\n return array.some(existingItem => existingItem.attributes[attributeName] === attributeValue);\r\n }\r\n\r\n checkIfLandscapeMode() {\r\n // also return true if this is table portrait mode wfnews-2022. \r\n if ((window.innerWidth > window.innerHeight) || (window.innerWidth <= 1024 && window.innerWidth >= 768 && window.innerHeight > window.innerWidth) ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n } \r\n\r\n \r\n hasSQLKeywords(jsonBlob) {\r\n //detect standalone sql words\r\n const sqlKeywords = /\\b(SELECT|INSERT|UPDATE|DELETE|ALTER|DROP|CREATE)\\b(?!\\s*\\*)/i;\r\n const sqlDetected = sqlKeywords.test(jsonBlob);\r\n return sqlDetected;\r\n }\r\n\r\n extractPolygonData(response) {\r\n const polygonData = [];\r\n for (const element of response) {\r\n polygonData.push(...element);\r\n }\r\n return polygonData;\r\n }\r\n\r\n createConvex(polygonData) {\r\n const turfPoints = polygonData.map(coord => window['turf'].point(coord));\r\n const pointsFeatureCollection = window['turf'].featureCollection(turfPoints);\r\n const convexHull = window['turf'].convex(pointsFeatureCollection)?.geometry?.coordinates[0];\r\n return convexHull;\r\n }\r\n\r\n getPolygonBond(polygonData) {\r\n const convex = this.createConvex(polygonData);\r\n const bounds = convex?.reduce((acc, coord) => [\r\n [Math.min(acc[0][0], coord[1]), Math.min(acc[0][1], coord[0])],\r\n [Math.max(acc[1][0], coord[1]), Math.max(acc[1][1], coord[0])]\r\n ], [[Infinity, Infinity], [-Infinity, -Infinity]]);\r\n return bounds;\r\n }\r\n\r\n getMapOptions(bounds: any, location: number[]) {\r\n return bounds\r\n ? { attributionControl: false, zoomControl: false, dragging: false, doubleClickZoom: false, boxZoom: false, trackResize: false, scrollWheelZoom: false }\r\n : { attributionControl: false, zoomControl: false, dragging: false, doubleClickZoom: false, boxZoom: false, trackResize: false, scrollWheelZoom: false, center: location, zoom: 9 };\r\n }\r\n \r\n}",
+ "properties": [
+ {
+ "name": "accuracy",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 15,
+ "modifierKind": [
+ 148
+ ]
+ },
+ {
+ "name": "altitude",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number | null",
+ "optional": false,
+ "description": "",
+ "line": 16,
+ "modifierKind": [
+ 148
+ ]
+ },
+ {
+ "name": "altitudeAccuracy",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number | null",
+ "optional": false,
+ "description": "",
+ "line": 17,
+ "modifierKind": [
+ 148
+ ]
+ },
+ {
+ "name": "heading",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number | null",
+ "optional": false,
+ "description": "",
+ "line": 18,
+ "modifierKind": [
+ 148
+ ]
+ },
+ {
+ "name": "latitude",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 19,
+ "modifierKind": [
+ 148
+ ]
+ },
+ {
+ "name": "longitude",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 20,
+ "modifierKind": [
+ 148
+ ]
+ },
+ {
+ "name": "speed",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number | null",
+ "optional": false,
+ "description": "",
+ "line": 21,
+ "modifierKind": [
+ 148
+ ]
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "DeviceOrientationEventiOS",
+ "id": "interface-DeviceOrientationEventiOS-2a825e4905fbb0a4b261c3807f69129c7f91ff85dc7899b8338d557823c006c5085ec96103be5a994f9d0bc4eea803bd3653fb712541d357de102c9a476a6567",
+ "file": "src/app/components/report-of-fire/compass-page/rof-compass-page.component.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';\r\nimport { RoFPage } from '../rofPage';\r\nimport { ReportOfFire } from '../reportOfFireModel';\r\nimport { CommonUtilityService } from '../../../services/common-utility.service';\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { LocationServicesDialogComponent } from './location-services-dialog/location-services-dialog.component';\r\nimport { equalsIgnoreCase } from '../../../utils';\r\n\r\ninterface DeviceOrientationEventiOS extends DeviceOrientationEvent {\r\n requestPermission?: () => Promise<'granted' | 'denied'>;\r\n}\r\n\r\n@Component({\r\n selector: 'rof-compass-page',\r\n templateUrl: './rof-compass-page.component.html',\r\n styleUrls: ['./rof-compass-page.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.Default,\r\n})\r\nexport class RoFCompassPage extends RoFPage implements OnInit {\r\n public compassFaceUrl: string;\r\n public compassHandUrl: string;\r\n public compassHeading = 0;\r\n public currentLat: string;\r\n public currentLong: string;\r\n public heading = '0° N';\r\n public locationSupported = false;\r\n equalsIgnoreCase = equalsIgnoreCase;\r\n\r\n constructor(\r\n private commonUtilityService: CommonUtilityService,\r\n protected dialog: MatDialog,\r\n ) {\r\n super();\r\n }\r\n\r\n isLandscapeMode(): boolean {\r\n return this.commonUtilityService.checkIfLandscapeMode();\r\n }\r\n\r\n initialize(data: any, index: number, reportOfFire: ReportOfFire) {\r\n super.initialize(data, index, reportOfFire);\r\n this.compassFaceUrl = data.compassFaceUrl;\r\n this.compassHandUrl = data.compassHandUrl;\r\n }\r\n\r\n ngOnInit(): void {\r\n this.getOrientation();\r\n this.useMyCurrentLocation();\r\n }\r\n\r\n async getOrientation() {\r\n try {\r\n const self = this;\r\n const requestPermission = (\r\n DeviceOrientationEvent as unknown as DeviceOrientationEventiOS\r\n ).requestPermission;\r\n const iOS = typeof requestPermission === 'function';\r\n if (iOS) {\r\n const response = await requestPermission();\r\n if (equalsIgnoreCase(response, 'granted')) {\r\n window.addEventListener(\r\n 'deviceorientation',\r\n (function(compass) {\r\n return function(e) {\r\n self.handler(e, compass);\r\n };\r\n })(self),\r\n true,\r\n );\r\n } else {\r\n this.dialog.open(LocationServicesDialogComponent, {\r\n width: '350px',\r\n data: {\r\n message: 'Location services are required',\r\n },\r\n });\r\n }\r\n } else {\r\n window.addEventListener(\r\n 'deviceorientationabsolute',\r\n (function(compass) {\r\n return function(e) {\r\n self.handler(e, compass);\r\n };\r\n })(self),\r\n true,\r\n );\r\n }\r\n } catch (err) {\r\n this.dialog.open(LocationServicesDialogComponent, {\r\n width: '350px',\r\n data: {\r\n message: 'Location services are not supported',\r\n },\r\n });\r\n }\r\n }\r\n\r\n handler(e, self) {\r\n if (this.commonUtilityService.checkIfLandscapeMode()) {\r\n this.skip();\r\n }\r\n if (self.reportOfFire?.headingDetectionActive) {\r\n if (!e.alpha && !e.webkitCompassHeading) {\r\n this.reportOfFire.motionSensor = 'no';\r\n this.skip();\r\n } else {\r\n this.reportOfFire.motionSensor = 'yes';\r\n }\r\n\r\n try {\r\n let compassHeading = e.webkitCompassHeading || Math.abs(e.alpha - 360);\r\n compassHeading = Math.trunc(compassHeading);\r\n let cardinalDirection = '';\r\n\r\n if (\r\n (compassHeading >= 0 && compassHeading <= 22) ||\r\n (compassHeading >= 337 && compassHeading <= 360)\r\n ) {\r\n cardinalDirection = 'N';\r\n } else if (compassHeading >= 23 && compassHeading <= 66) {\r\n cardinalDirection = 'NE';\r\n } else if (compassHeading >= 67 && compassHeading <= 112) {\r\n cardinalDirection = 'E';\r\n } else if (compassHeading >= 113 && compassHeading <= 157) {\r\n cardinalDirection = 'SE';\r\n } else if (compassHeading >= 158 && compassHeading <= 202) {\r\n cardinalDirection = 'S';\r\n } else if (compassHeading >= 203 && compassHeading <= 246) {\r\n cardinalDirection = 'SW';\r\n } else if (compassHeading >= 247 && compassHeading <= 292) {\r\n cardinalDirection = 'W';\r\n } else if (compassHeading >= 293 && compassHeading <= 336) {\r\n cardinalDirection = 'NW';\r\n }\r\n\r\n if (document.getElementById('compass-face-image')) {\r\ndocument.getElementById('compass-face-image').style.transform =\r\n `rotate(${-compassHeading}deg)`;\r\n}\r\n if (document.getElementById('compass-heading')) {\r\ndocument.getElementById('compass-heading').innerText =\r\n compassHeading.toString() + '° ' + cardinalDirection;\r\n}\r\n\r\n self.reportOfFire.compassHeading = compassHeading;\r\n\r\n this.useMyCurrentLocation();\r\n\r\n this.reportOfFire = self.reportOfFire;\r\n } catch (err) {\r\n console.error('Could not set compass heading', err);\r\n }\r\n }\r\n }\r\n\r\n async useMyCurrentLocation() {\r\n try {\r\n const location =\r\n await this.commonUtilityService.getCurrentLocationPromise();\r\n if (location) {\r\n this.currentLat = this.commonUtilityService.formatDDM(\r\n Number(location.coords.latitude),\r\n );\r\n this.currentLong = this.commonUtilityService.formatDDM(\r\n Number(location.coords.longitude),\r\n );\r\n }\r\n\r\n if (document.getElementById('location')) {\r\ndocument.getElementById('location').innerText =\r\n this.currentLat + ',' + this.currentLong;\r\n}\r\n } catch (err) {\r\n console.error('Could not find current location', err);\r\n }\r\n }\r\n\r\n confirmHeading() {\r\n try {\r\n this.reportOfFire.headingDetectionActive = false;\r\n this.next();\r\n } catch (err) {\r\n console.error('Could not confirm heading', err);\r\n }\r\n }\r\n\r\n checkIfLandscapeMode() {\r\n if (window.innerWidth > window.innerHeight) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n}\r\n",
+ "properties": [
+ {
+ "name": "requestPermission",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "function",
+ "optional": true,
+ "description": "",
+ "line": 10
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "DeviceOrientationEvent"
+ ]
+ },
+ {
+ "name": "DeviceProperties",
+ "id": "interface-DeviceProperties-8535ce51ccdad526d840669937c2863b8c4704ebacf2e5a788764298904f6dbe7761d1eb638a976f40486932cb843e69f3a4250037faa79d75e0a3680ed65ea9",
+ "file": "src/app/services/capacitor-service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { EventEmitter, Injectable, NgZone } from '@angular/core';\r\nimport { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';\r\nimport { Router } from '@angular/router';\r\nimport { FCM } from '@capacitor-community/fcm';\r\nimport { App, AppState } from '@capacitor/app';\r\nimport { AppLauncher } from '@capacitor/app-launcher';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Device } from '@capacitor/device';\r\nimport { Geolocation, Position } from '@capacitor/geolocation';\r\nimport {\r\n PushNotificationSchema,\r\n PushNotifications,\r\n} from '@capacitor/push-notifications';\r\nimport { Store } from '@ngrx/store';\r\nimport { BehaviorSubject, fromEvent } from 'rxjs';\r\nimport { environment } from '../../environments/environment';\r\nimport { RootState } from '../store';\r\nimport { ApplicationStateService } from './application-state.service';\r\nimport { EventEmitterService } from './event-emitter.service';\r\n\r\nimport { ResourcesRoutes } from '@app/utils';\r\nimport { NotificationSnackbarComponent } from '../components/notification-snackbar/notification-snackbar.component';\r\nimport { Preferences } from '@capacitor/preferences';\r\n\r\nexport interface CompassHeading {\r\n magneticHeading?: number; //The heading in degrees from 0-359.99 at a single moment in time. (Number)\r\n trueHeading?: number; //The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. A negative value indicates that the true heading can't be determined. (Number)\r\n headingAccuracy?: number; //The deviation in degrees between the reported heading and the true heading. (Number)\r\n timestamp?: string; //The time at which this heading was determined. (DOMTimeStamp)\r\n error?: string;\r\n}\r\n\r\nexport interface LocationNotification {\r\n latitude: number;\r\n longitude: number;\r\n radius: number;\r\n featureId: string;\r\n featureType: string;\r\n fireYear?: number;\r\n}\r\n\r\nexport interface ReportOfFireNotification {\r\n title: string;\r\n body: string;\r\n}\r\n\r\nexport interface DeviceProperties {\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n isMobilePlatform: boolean;\r\n deviceId: string;\r\n isTwitterInstalled: boolean;\r\n}\r\n\r\nconst UPDATE_AFTER_INACTIVE_MILLIS = 1000 * 60; // 1 minute\r\nconst REFRESH_INTERVAL_ACTIVE_MILLIS = 5 * 1000 * 60; // 5 minutes\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CapacitorService {\r\n resume: BehaviorSubject;\r\n initialized: Promise;\r\n fbAppInstalled: boolean;\r\n twitterAppInstalled: boolean;\r\n appState: AppState;\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n deviceId: string;\r\n pnNav = null;\r\n notificationToken = null;\r\n updateMainMapLayers = new EventEmitter();\r\n currentHeadingPromise: Promise;\r\n locationNotifications = new EventEmitter();\r\n rofNotifications = new EventEmitter();\r\n inactiveStart: number;\r\n refreshTimer;\r\n locationNotificationsDelay = 5000;\r\n rofNotificationsDelay = 5000;\r\n notificationSnackbarPromise = Promise.resolve();\r\n registeredForNotifications = false;\r\n private devicePropertiesPromise: Promise;\r\n\r\n constructor(\r\n private zone: NgZone,\r\n protected router: Router,\r\n protected store: Store,\r\n protected eventEmitterService: EventEmitterService,\r\n protected stateService: ApplicationStateService,\r\n protected snackbar: MatSnackBar,\r\n ) {\r\n this.resume = new BehaviorSubject(null);\r\n fromEvent(document, 'resume').subscribe((event) => {\r\n this.zone.run(() => {\r\n this.onResume();\r\n });\r\n });\r\n\r\n this.isIOSPlatform = false;\r\n this.isAndroidPlatform = false;\r\n this.isWebPlatform = false;\r\n this.fbAppInstalled = false;\r\n this.twitterAppInstalled = false;\r\n this.deviceId = '';\r\n\r\n this.initialized = this.checkDevice().then(() => {\r\n this.init();\r\n\r\n // use for testing notification at startup\r\n // this.emitLocationNotification( {\r\n // coords: '[48.463259,-123.312635]',\r\n // radius: '20',\r\n // messageID: 'V65055',\r\n // topicKey: 'BCWS_ActiveFires_PublicView',\r\n // } )\r\n });\r\n }\r\n\r\n init() {\r\n const startRefreshTimer = () => {\r\n stopRefreshTimer();\r\n\r\n this.refreshTimer = setTimeout(() => {\r\n this.updateMainMapLayers.emit();\r\n startRefreshTimer();\r\n }, REFRESH_INTERVAL_ACTIVE_MILLIS);\r\n };\r\n\r\n const stopRefreshTimer = () => {\r\n if (!this.refreshTimer) {\r\nreturn;\r\n}\r\n\r\n clearTimeout(this.refreshTimer);\r\n this.refreshTimer = null;\r\n };\r\n\r\n startRefreshTimer();\r\n\r\n App.addListener('appStateChange', (state) => {\r\n if (state.isActive) {\r\n startRefreshTimer();\r\n\r\n if (!this.inactiveStart) {\r\nreturn;\r\n}\r\n\r\n const inactiveDuration = Date.now() - this.inactiveStart;\r\n this.inactiveStart = null;\r\n\r\n if (inactiveDuration > UPDATE_AFTER_INACTIVE_MILLIS) {\r\n this.updateMainMapLayers.emit();\r\n }\r\n } else {\r\n if (!this.inactiveStart) {\r\nthis.inactiveStart = Date.now();\r\n}\r\n\r\n stopRefreshTimer();\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n if (this.isWebPlatform) {\r\n this.notificationToken = 'FakeForWeb';\r\n return;\r\n }\r\n\r\n this.checkInstalledApps();\r\n\r\n if (this.isAndroidPlatform) {\r\n App.addListener('backButton', (state) => {\r\n this.eventEmitterService.androidBackButtonPressed();\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n // Request permission to use push notifications\r\n this.registerForNotifications()\r\n .then((registered) => {\r\n console.log('registeredForNotifications', registered);\r\n this.registeredForNotifications = registered;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // On success, we should be able to receive notifications\r\n PushNotifications.addListener('registration', (token) => {\r\n console.log('PNN REgister success ' + token.value);\r\n if (this.isAndroidPlatform) {\r\n this.notificationToken = token.value;\r\n } else if (this.isIOSPlatform) {\r\n FCM.getToken()\r\n .then((response) => {\r\n this.notificationToken = response.token;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Some issue with our setup and push will not work\r\n PushNotifications.addListener('registrationError', (error) => {\r\n console.log('PNN REgister fail ' + error);\r\n }).catch((err) => {\r\n console.error(err);\r\n });\r\n\r\n // Show us the notification payload if the app is open on our device\r\n PushNotifications.addListener(\r\n 'pushNotificationReceived',\r\n (notification) => {\r\n console.log('pushNotificationReceived', notification);\r\n this.handleRofPushNotification(notification);\r\n },\r\n ).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Method called when tapping on a notification\r\n PushNotifications.addListener('pushNotificationActionPerformed', (ev) => {\r\n const data = ev.notification.data;\r\n console.log('pushNotificationActionPerformed', data);\r\n\r\n this.emitLocationNotification(data);\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n async registerForNotifications(): Promise {\r\n let status = await PushNotifications.checkPermissions();\r\n if (status.receive === 'prompt') {\r\n status = await PushNotifications.requestPermissions();\r\n }\r\n\r\n if (status.receive !== 'granted') {\r\n return false;\r\n }\r\n\r\n await PushNotifications.register();\r\n return true;\r\n }\r\n\r\n handleRofPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n this.emitLocationNotification(notification.body);\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitRofNotification(title, body) {\r\n setTimeout(() => {\r\n try {\r\n this.rofNotifications.emit({ title, body });\r\n\r\n this.rofNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, title + ': ' + body);\r\n }\r\n }, this.rofNotificationsDelay);\r\n }\r\n\r\n handleLocationPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n const c = JSON.parse(notification.data['coords']);\r\n const r = JSON.parse(notification.data['radius']);\r\n this.router.navigate([ResourcesRoutes.ACTIVEWILDFIREMAP], {\r\n queryParams: {\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: notification.data['messageID'],\r\n featureType: notification.data['topicKey'],\r\n identify: true,\r\n notification: true,\r\n time: Date.now(),\r\n },\r\n });\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitLocationNotification(data) {\r\n setTimeout(() => {\r\n try {\r\n const c = JSON.parse(data['coords']);\r\n const r = JSON.parse(data['radius']);\r\n\r\n this.locationNotifications.emit({\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: data['messageID'],\r\n featureType: data['topicKey'],\r\n });\r\n\r\n this.locationNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, data);\r\n }\r\n }, this.locationNotificationsDelay);\r\n }\r\n\r\n showNotificationSnackbar(notification: any) {\r\n const cfg: MatSnackBarConfig = {\r\n data: { notification },\r\n // need to change back to 10 sec. Using 60 sec for testing purpose in case QA missed it.\r\n duration: 60 * 1000,\r\n verticalPosition: 'top',\r\n };\r\n\r\n return this.snackbar.openFromComponent(NotificationSnackbarComponent, cfg);\r\n }\r\n\r\n checkDevice() {\r\n // const deviceInfo = \r\n return Device.getInfo()\r\n .then((devInfo) => {\r\n console.log(devInfo);\r\n if (!devInfo) {\r\nreturn;\r\n}\r\n\r\n this.isIOSPlatform = devInfo.platform === 'ios';\r\n this.isAndroidPlatform = devInfo.platform === 'android';\r\n this.isWebPlatform =\r\n devInfo.platform !== 'ios' && devInfo.platform !== 'android';\r\n\r\n return Device.getId();\r\n })\r\n .then((deviceId) => {\r\n console.log(deviceId);\r\n this.deviceId = deviceId.identifier;\r\n });\r\n }\r\n\r\n async getCurrentPosition(options?: PositionOptions): Promise {\r\n const coordinates = Geolocation.getCurrentPosition(options);\r\n return coordinates;\r\n }\r\n\r\n checkInstalledApps() {\r\n this.checkTwitterAppInstalled().then(\r\n (result) => {\r\n this.twitterAppInstalled = result;\r\n },\r\n (error) => {\r\n this.twitterAppInstalled = false;\r\n },\r\n );\r\n\r\n this.checkFbAppInstalled().then(\r\n (result) => {\r\n this.fbAppInstalled = result;\r\n },\r\n (error) => {\r\n this.fbAppInstalled = false;\r\n },\r\n );\r\n }\r\n\r\n onResume(): void {\r\n this.resume.next(true);\r\n }\r\n\r\n openLinkInAppBrowser(url: string) {\r\n Browser.open({\r\n url,\r\n toolbarColor: '#f7f7f9',\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n private async checkTwitterAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async checkFbAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'fb://' : 'com.facebook.katana';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async appIsInstalled(scheme: string): Promise {\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n\r\n initOfflinePageSettings() {\r\n App.addListener('appStateChange', (state: AppState) => {\r\n this.appState = state;\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n public isMobilePlatform(): boolean {\r\n if (this.isIOSPlatform || this.isAndroidPlatform) {\r\n return true;\r\n }\r\n return !!environment['is_mobile_platform'];\r\n }\r\n\r\n getPnUrl() {\r\n return this.pnNav;\r\n }\r\n\r\n public getNotificationToken() {\r\n return this.notificationToken;\r\n }\r\n\r\n public setNotificationToken(token: string) {\r\n this.notificationToken = token;\r\n }\r\n\r\n openUrlInApp(url: string) {\r\n let scheme;\r\n let schemeUrl;\r\n // twitter\r\n if (url.indexOf('twitter.com/') !== -1) {\r\n scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n schemeUrl = 'twitter://user?screen_name=' + url.split('twitter.com/')[1];\r\n }\r\n\r\n if (scheme && schemeUrl) {\r\n AppLauncher.openUrl({ url: schemeUrl }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }\r\n\r\n isAndroid() {\r\n return this.isAndroidPlatform;\r\n }\r\n\r\n isIOS() {\r\n return this.isIOSPlatform;\r\n }\r\n\r\n getCurrentHeading(): Promise {\r\n const compass = navigator['compass'];\r\n if (!compass) {\r\nreturn Promise.reject(Error('navigator.compass not available'));\r\n} else {\r\n const currentHeading = new Promise((res, rej) => {\r\n compass.getCurrentHeading(\r\n (heading: CompassHeading) => {\r\n res(heading);\r\n this.currentHeadingPromise = null;\r\n },\r\n (error) => {\r\n rej(Error('Failed to get heading: ' + JSON.stringify(error)));\r\n this.currentHeadingPromise = null;\r\n },\r\n );\r\n });\r\n\r\n this.currentHeadingPromise = currentHeading;\r\n\r\n return this.currentHeadingPromise;\r\n }\r\n }\r\n\r\n async checkDeviceSystem() {\r\n // const deviceInfo = \r\n try {\r\n const deviceInfo = await Device.getInfo();\r\n return deviceInfo;\r\n } catch (error) {\r\n console.error('Error getting device info:', error);\r\n }\r\n }\r\n\r\n get deviceProperties(): Promise {\r\n if (!this.devicePropertiesPromise) {\r\nthis.devicePropertiesPromise = Device.getInfo()\r\n .then((devInfo) => Device.getId().then((deviceId) => {\r\n\r\n const p = devInfo && devInfo.platform;\r\n const prop: DeviceProperties = {\r\n isIOSPlatform: p == 'ios',\r\n isAndroidPlatform: p == 'android',\r\n isWebPlatform: p != 'ios' && p != 'android',\r\n isMobilePlatform:\r\n p == 'ios' ||\r\n p == 'android' ||\r\n !!environment['is_mobile_platform'],\r\n deviceId: deviceId.identifier,\r\n isTwitterInstalled: false,\r\n };\r\n const scheme = prop.isIOSPlatform\r\n ? 'twitter://'\r\n : 'com.twitter.android';\r\n return AppLauncher.canOpenUrl({ url: scheme })\r\n .then((canOpen) => {\r\n prop.isTwitterInstalled = canOpen.value;\r\n return prop;\r\n })\r\n .catch((e) => {\r\n console.warn(e);\r\n return prop;\r\n });\r\n }))\r\n .catch((e) => {\r\n console.warn(e);\r\n return {\r\n isIOSPlatform: false,\r\n isAndroidPlatform: false,\r\n isWebPlatform: false,\r\n isMobilePlatform: false,\r\n deviceId: '',\r\n isTwitterInstalled: false,\r\n };\r\n });\r\n}\r\n\r\n return this.devicePropertiesPromise;\r\n }\r\n\r\n get isMobile(): Promise {\r\n return this.deviceProperties.then((p) => p.isMobilePlatform);\r\n }\r\n\r\n async saveData(key: string, value: string) {\r\n await Preferences.set({\r\n key: key,\r\n value: value\r\n });\r\n }\r\n \r\n async getData(key: string) {\r\n const response = await Preferences.get({ key: key });\r\n return response.value;\r\n }\r\n\r\n async removeData(key: string) {\r\n await Preferences.remove({ key: key })\r\n }\r\n}\r\n\r\n\r\n",
+ "properties": [
+ {
+ "name": "deviceId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 52
+ },
+ {
+ "name": "isAndroidPlatform",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 49
+ },
+ {
+ "name": "isIOSPlatform",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 48
+ },
+ {
+ "name": "isMobilePlatform",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 51
+ },
+ {
+ "name": "isTwitterInstalled",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 53
+ },
+ {
+ "name": "isWebPlatform",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 50
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ErrorHandlingInstructions",
+ "id": "interface-ErrorHandlingInstructions-e191d3fc916d48f865f61e0f3c7d85cf9e958e59580bfef03391786d68102b8cf293efd1118b110c207b093672df1bf628d2aa7c5ec095eaabf2f40b6f1a2096",
+ "file": "src/app/utils/user-feedback-utils.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { MatSnackBarConfig } from '@angular/material/snack-bar';\r\nimport { WF_SNACKBAR_TYPES } from '.';\r\n\r\nexport interface ErrorHandlingInstructions {\r\n redirectToRoute?: string;\r\n redirectToRouteData?: any;\r\n snackBarErrorMsg?: string;\r\n}\r\n\r\nexport function getSnackbarConfig(message, type): MatSnackBarConfig {\r\n const config = {\r\n panelClass: 'snackbar-' + type,\r\n data: {\r\n message,\r\n type,\r\n },\r\n };\r\n if (type == WF_SNACKBAR_TYPES.SUCCESS) {\r\n config['duration'] = 5000;\r\n }\r\n return config;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "redirectToRoute",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 5
+ },
+ {
+ "name": "redirectToRouteData",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 6
+ },
+ {
+ "name": "snackBarErrorMsg",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 7
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ErrorState",
+ "id": "interface-ErrorState-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "message",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 20
+ },
+ {
+ "name": "name",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 21
+ },
+ {
+ "name": "responseEtag",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 23
+ },
+ {
+ "name": "status",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 18
+ },
+ {
+ "name": "statusText",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 19
+ },
+ {
+ "name": "type",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "ERROR_TYPE",
+ "optional": false,
+ "description": "",
+ "line": 17
+ },
+ {
+ "name": "uuid",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 16
+ },
+ {
+ "name": "validationErrors",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "ValidationError[]",
+ "optional": true,
+ "description": "",
+ "line": 22
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ErrorStates",
+ "id": "interface-ErrorStates-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "incidents",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "ErrorState[]",
+ "optional": false,
+ "description": "",
+ "line": 53
+ },
+ {
+ "name": "wildfires",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "ErrorState[]",
+ "optional": false,
+ "description": "",
+ "line": 54
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "EvacOrderOption",
+ "id": "interface-EvacOrderOption-578a59039ac4654484d8e4be5fbd449d901a2d6cb9e741f267e162564117f8a272fcd258bbfc777cf74459f717c323464cbe9fd25dca73541ef16adf9822a5a4",
+ "file": "src/app/conversion/models.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface PagedCollection {\r\n pageNumber?: number;\r\n pageRowCount?: number;\r\n totalRowCount?: number;\r\n totalPageCount?: number;\r\n collection?: Array;\r\n}\r\n\r\nexport interface fireCentreOption {\r\n code?: string;\r\n fireCentreName?: string;\r\n}\r\n\r\nexport interface EvacOrderOption {\r\n eventName?: string;\r\n eventType?: string;\r\n orderAlertStatus?: string;\r\n issuingAgency?: string;\r\n preOcCode?: string;\r\n emrgOAAsysID?: number;\r\n centroid?: any;\r\n geometry?: any;\r\n dateModified?: Date;\r\n noticeType?: string;\r\n uri?: string;\r\n issuedOn?: string;\r\n externalUri?: boolean;\r\n eventNumber?: string;\r\n}\r\n\r\nexport interface AreaRestrictionsOption {\r\n protRsSysID?: number;\r\n name?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n noticeType?: string;\r\n}\r\n\r\nexport interface BansAndProhibitionsOption {\r\n protBsSysID?: number;\r\n type?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n accessProhibitionDescription?: string;\r\n noticeType?: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "centroid",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 21
+ },
+ {
+ "name": "dateModified",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Date",
+ "optional": true,
+ "description": "",
+ "line": 23
+ },
+ {
+ "name": "emrgOAAsysID",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 20
+ },
+ {
+ "name": "eventName",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 15
+ },
+ {
+ "name": "eventNumber",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 28
+ },
+ {
+ "name": "eventType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 16
+ },
+ {
+ "name": "externalUri",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": true,
+ "description": "",
+ "line": 27
+ },
+ {
+ "name": "geometry",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 22
+ },
+ {
+ "name": "issuedOn",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 26
+ },
+ {
+ "name": "issuingAgency",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 18
+ },
+ {
+ "name": "noticeType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 24
+ },
+ {
+ "name": "orderAlertStatus",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 17
+ },
+ {
+ "name": "preOcCode",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 19
+ },
+ {
+ "name": "uri",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 25
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "fireCentreOption",
+ "id": "interface-fireCentreOption-578a59039ac4654484d8e4be5fbd449d901a2d6cb9e741f267e162564117f8a272fcd258bbfc777cf74459f717c323464cbe9fd25dca73541ef16adf9822a5a4",
+ "file": "src/app/conversion/models.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface PagedCollection {\r\n pageNumber?: number;\r\n pageRowCount?: number;\r\n totalRowCount?: number;\r\n totalPageCount?: number;\r\n collection?: Array;\r\n}\r\n\r\nexport interface fireCentreOption {\r\n code?: string;\r\n fireCentreName?: string;\r\n}\r\n\r\nexport interface EvacOrderOption {\r\n eventName?: string;\r\n eventType?: string;\r\n orderAlertStatus?: string;\r\n issuingAgency?: string;\r\n preOcCode?: string;\r\n emrgOAAsysID?: number;\r\n centroid?: any;\r\n geometry?: any;\r\n dateModified?: Date;\r\n noticeType?: string;\r\n uri?: string;\r\n issuedOn?: string;\r\n externalUri?: boolean;\r\n eventNumber?: string;\r\n}\r\n\r\nexport interface AreaRestrictionsOption {\r\n protRsSysID?: number;\r\n name?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n noticeType?: string;\r\n}\r\n\r\nexport interface BansAndProhibitionsOption {\r\n protBsSysID?: number;\r\n type?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n accessProhibitionDescription?: string;\r\n noticeType?: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "code",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 10
+ },
+ {
+ "name": "fireCentreName",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 11
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "FormState",
+ "id": "interface-FormState-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "isUnsaved",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 62
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "FormStates",
+ "id": "interface-FormStates-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "incidents",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "FormState",
+ "optional": false,
+ "description": "",
+ "line": 58
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "GetIncidentAction",
+ "id": "interface-GetIncidentAction-d5c19aa81645c659a6a87549599602a3f1ac2b3f4f78989959b6158ee2a27fbbb23f30b33b145b0cc14d9d4cea65fb27cf9446a135d68bfede530ff73b085167",
+ "file": "src/app/store/incident/incident.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport {\r\n IncidentCauseResource,\r\n WildfireIncidentResource,\r\n} from '@wf1/incidents-rest-api';\r\nimport { ErrorState } from '../application/application.state';\r\n\r\nexport const GET_INCIDENT = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_SUCCESS = 'GET_INCIDENT_SUCCESS';\r\nexport const GET_INCIDENT_ERROR = 'GET_INCIDENT_ERROR';\r\n\r\nexport const GET_INCIDENT_CAUSE = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_CAUSE_SUCCESS = 'GET_INCIDENT_CAUSE_SUCCESS';\r\nexport const GET_INCIDENT_CAUSE_ERROR = 'GET_INCIDENT_CAUSE_ERROR';\r\n\r\nexport interface GetIncidentAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentSuccessAction extends Action {\r\n payload: {\r\n incident: WildfireIncidentResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseSuccessAction extends Action {\r\n payload: {\r\n incidentCause: IncidentCauseResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function getIncident(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentAction {\r\n return {\r\n type: GET_INCIDENT,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentSuccess(\r\n incident: WildfireIncidentResource,\r\n): GetIncidentSuccessAction {\r\n return {\r\n type: GET_INCIDENT_SUCCESS,\r\n payload: {\r\n incident,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentError(error: ErrorState): GetIncidentErrorAcion {\r\n return {\r\n type: GET_INCIDENT_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCause(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentCauseAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseSuccess(\r\n incidentCause: IncidentCauseResource,\r\n): GetIncidentCauseSuccessAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE_SUCCESS,\r\n payload: {\r\n incidentCause,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseError(\r\n error: ErrorState,\r\n): GetIncidentCauseErrorAcion {\r\n return {\r\n type: GET_INCIDENT_CAUSE_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 17
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "GetIncidentCauseAction",
+ "id": "interface-GetIncidentCauseAction-d5c19aa81645c659a6a87549599602a3f1ac2b3f4f78989959b6158ee2a27fbbb23f30b33b145b0cc14d9d4cea65fb27cf9446a135d68bfede530ff73b085167",
+ "file": "src/app/store/incident/incident.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport {\r\n IncidentCauseResource,\r\n WildfireIncidentResource,\r\n} from '@wf1/incidents-rest-api';\r\nimport { ErrorState } from '../application/application.state';\r\n\r\nexport const GET_INCIDENT = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_SUCCESS = 'GET_INCIDENT_SUCCESS';\r\nexport const GET_INCIDENT_ERROR = 'GET_INCIDENT_ERROR';\r\n\r\nexport const GET_INCIDENT_CAUSE = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_CAUSE_SUCCESS = 'GET_INCIDENT_CAUSE_SUCCESS';\r\nexport const GET_INCIDENT_CAUSE_ERROR = 'GET_INCIDENT_CAUSE_ERROR';\r\n\r\nexport interface GetIncidentAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentSuccessAction extends Action {\r\n payload: {\r\n incident: WildfireIncidentResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseSuccessAction extends Action {\r\n payload: {\r\n incidentCause: IncidentCauseResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function getIncident(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentAction {\r\n return {\r\n type: GET_INCIDENT,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentSuccess(\r\n incident: WildfireIncidentResource,\r\n): GetIncidentSuccessAction {\r\n return {\r\n type: GET_INCIDENT_SUCCESS,\r\n payload: {\r\n incident,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentError(error: ErrorState): GetIncidentErrorAcion {\r\n return {\r\n type: GET_INCIDENT_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCause(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentCauseAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseSuccess(\r\n incidentCause: IncidentCauseResource,\r\n): GetIncidentCauseSuccessAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE_SUCCESS,\r\n payload: {\r\n incidentCause,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseError(\r\n error: ErrorState,\r\n): GetIncidentCauseErrorAcion {\r\n return {\r\n type: GET_INCIDENT_CAUSE_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 36
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "GetIncidentCauseErrorAcion",
+ "id": "interface-GetIncidentCauseErrorAcion-d5c19aa81645c659a6a87549599602a3f1ac2b3f4f78989959b6158ee2a27fbbb23f30b33b145b0cc14d9d4cea65fb27cf9446a135d68bfede530ff73b085167",
+ "file": "src/app/store/incident/incident.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport {\r\n IncidentCauseResource,\r\n WildfireIncidentResource,\r\n} from '@wf1/incidents-rest-api';\r\nimport { ErrorState } from '../application/application.state';\r\n\r\nexport const GET_INCIDENT = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_SUCCESS = 'GET_INCIDENT_SUCCESS';\r\nexport const GET_INCIDENT_ERROR = 'GET_INCIDENT_ERROR';\r\n\r\nexport const GET_INCIDENT_CAUSE = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_CAUSE_SUCCESS = 'GET_INCIDENT_CAUSE_SUCCESS';\r\nexport const GET_INCIDENT_CAUSE_ERROR = 'GET_INCIDENT_CAUSE_ERROR';\r\n\r\nexport interface GetIncidentAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentSuccessAction extends Action {\r\n payload: {\r\n incident: WildfireIncidentResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseSuccessAction extends Action {\r\n payload: {\r\n incidentCause: IncidentCauseResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function getIncident(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentAction {\r\n return {\r\n type: GET_INCIDENT,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentSuccess(\r\n incident: WildfireIncidentResource,\r\n): GetIncidentSuccessAction {\r\n return {\r\n type: GET_INCIDENT_SUCCESS,\r\n payload: {\r\n incident,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentError(error: ErrorState): GetIncidentErrorAcion {\r\n return {\r\n type: GET_INCIDENT_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCause(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentCauseAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseSuccess(\r\n incidentCause: IncidentCauseResource,\r\n): GetIncidentCauseSuccessAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE_SUCCESS,\r\n payload: {\r\n incidentCause,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseError(\r\n error: ErrorState,\r\n): GetIncidentCauseErrorAcion {\r\n return {\r\n type: GET_INCIDENT_CAUSE_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 49
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "GetIncidentCauseSuccessAction",
+ "id": "interface-GetIncidentCauseSuccessAction-d5c19aa81645c659a6a87549599602a3f1ac2b3f4f78989959b6158ee2a27fbbb23f30b33b145b0cc14d9d4cea65fb27cf9446a135d68bfede530ff73b085167",
+ "file": "src/app/store/incident/incident.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport {\r\n IncidentCauseResource,\r\n WildfireIncidentResource,\r\n} from '@wf1/incidents-rest-api';\r\nimport { ErrorState } from '../application/application.state';\r\n\r\nexport const GET_INCIDENT = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_SUCCESS = 'GET_INCIDENT_SUCCESS';\r\nexport const GET_INCIDENT_ERROR = 'GET_INCIDENT_ERROR';\r\n\r\nexport const GET_INCIDENT_CAUSE = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_CAUSE_SUCCESS = 'GET_INCIDENT_CAUSE_SUCCESS';\r\nexport const GET_INCIDENT_CAUSE_ERROR = 'GET_INCIDENT_CAUSE_ERROR';\r\n\r\nexport interface GetIncidentAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentSuccessAction extends Action {\r\n payload: {\r\n incident: WildfireIncidentResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseSuccessAction extends Action {\r\n payload: {\r\n incidentCause: IncidentCauseResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function getIncident(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentAction {\r\n return {\r\n type: GET_INCIDENT,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentSuccess(\r\n incident: WildfireIncidentResource,\r\n): GetIncidentSuccessAction {\r\n return {\r\n type: GET_INCIDENT_SUCCESS,\r\n payload: {\r\n incident,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentError(error: ErrorState): GetIncidentErrorAcion {\r\n return {\r\n type: GET_INCIDENT_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCause(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentCauseAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseSuccess(\r\n incidentCause: IncidentCauseResource,\r\n): GetIncidentCauseSuccessAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE_SUCCESS,\r\n payload: {\r\n incidentCause,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseError(\r\n error: ErrorState,\r\n): GetIncidentCauseErrorAcion {\r\n return {\r\n type: GET_INCIDENT_CAUSE_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 43
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "GetIncidentErrorAcion",
+ "id": "interface-GetIncidentErrorAcion-d5c19aa81645c659a6a87549599602a3f1ac2b3f4f78989959b6158ee2a27fbbb23f30b33b145b0cc14d9d4cea65fb27cf9446a135d68bfede530ff73b085167",
+ "file": "src/app/store/incident/incident.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport {\r\n IncidentCauseResource,\r\n WildfireIncidentResource,\r\n} from '@wf1/incidents-rest-api';\r\nimport { ErrorState } from '../application/application.state';\r\n\r\nexport const GET_INCIDENT = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_SUCCESS = 'GET_INCIDENT_SUCCESS';\r\nexport const GET_INCIDENT_ERROR = 'GET_INCIDENT_ERROR';\r\n\r\nexport const GET_INCIDENT_CAUSE = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_CAUSE_SUCCESS = 'GET_INCIDENT_CAUSE_SUCCESS';\r\nexport const GET_INCIDENT_CAUSE_ERROR = 'GET_INCIDENT_CAUSE_ERROR';\r\n\r\nexport interface GetIncidentAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentSuccessAction extends Action {\r\n payload: {\r\n incident: WildfireIncidentResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseSuccessAction extends Action {\r\n payload: {\r\n incidentCause: IncidentCauseResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function getIncident(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentAction {\r\n return {\r\n type: GET_INCIDENT,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentSuccess(\r\n incident: WildfireIncidentResource,\r\n): GetIncidentSuccessAction {\r\n return {\r\n type: GET_INCIDENT_SUCCESS,\r\n payload: {\r\n incident,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentError(error: ErrorState): GetIncidentErrorAcion {\r\n return {\r\n type: GET_INCIDENT_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCause(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentCauseAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseSuccess(\r\n incidentCause: IncidentCauseResource,\r\n): GetIncidentCauseSuccessAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE_SUCCESS,\r\n payload: {\r\n incidentCause,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseError(\r\n error: ErrorState,\r\n): GetIncidentCauseErrorAcion {\r\n return {\r\n type: GET_INCIDENT_CAUSE_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 30
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "GetIncidentSuccessAction",
+ "id": "interface-GetIncidentSuccessAction-d5c19aa81645c659a6a87549599602a3f1ac2b3f4f78989959b6158ee2a27fbbb23f30b33b145b0cc14d9d4cea65fb27cf9446a135d68bfede530ff73b085167",
+ "file": "src/app/store/incident/incident.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport {\r\n IncidentCauseResource,\r\n WildfireIncidentResource,\r\n} from '@wf1/incidents-rest-api';\r\nimport { ErrorState } from '../application/application.state';\r\n\r\nexport const GET_INCIDENT = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_SUCCESS = 'GET_INCIDENT_SUCCESS';\r\nexport const GET_INCIDENT_ERROR = 'GET_INCIDENT_ERROR';\r\n\r\nexport const GET_INCIDENT_CAUSE = 'GET_INCIDNT';\r\nexport const GET_INCIDENT_CAUSE_SUCCESS = 'GET_INCIDENT_CAUSE_SUCCESS';\r\nexport const GET_INCIDENT_CAUSE_ERROR = 'GET_INCIDENT_CAUSE_ERROR';\r\n\r\nexport interface GetIncidentAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentSuccessAction extends Action {\r\n payload: {\r\n incident: WildfireIncidentResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseAction extends Action {\r\n payload: {\r\n fireYear: string;\r\n incidentSequenceNumber: string;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseSuccessAction extends Action {\r\n payload: {\r\n incidentCause: IncidentCauseResource;\r\n };\r\n}\r\n\r\nexport interface GetIncidentCauseErrorAcion extends Action {\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function getIncident(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentAction {\r\n return {\r\n type: GET_INCIDENT,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentSuccess(\r\n incident: WildfireIncidentResource,\r\n): GetIncidentSuccessAction {\r\n return {\r\n type: GET_INCIDENT_SUCCESS,\r\n payload: {\r\n incident,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentError(error: ErrorState): GetIncidentErrorAcion {\r\n return {\r\n type: GET_INCIDENT_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCause(\r\n fireYear: string,\r\n incidentSequenceNumber: string,\r\n): GetIncidentCauseAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE,\r\n payload: {\r\n fireYear,\r\n incidentSequenceNumber,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseSuccess(\r\n incidentCause: IncidentCauseResource,\r\n): GetIncidentCauseSuccessAction {\r\n return {\r\n type: GET_INCIDENT_CAUSE_SUCCESS,\r\n payload: {\r\n incidentCause,\r\n },\r\n };\r\n}\r\n\r\nexport function getIncidentCauseError(\r\n error: ErrorState,\r\n): GetIncidentCauseErrorAcion {\r\n return {\r\n type: GET_INCIDENT_CAUSE_ERROR,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 24
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "IncidentsState",
+ "id": "interface-IncidentsState-ce5bfc8beb5c935c7016d5a22a57bbb3c4efed151cc2afba88ef8e694e2661279ee10bfcd157ace76970cde1be7d8fc688716b0f0fd357f678b3beb866c19366",
+ "file": "src/app/store/incidents/incidents.stats.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\nimport { getDefaultPagingInfoRequest } from '../application/application.state';\r\n\r\nexport const SEARCH_INCIDENTS_COMPONENT_ID = 'searchIncidents';\r\nexport const INCIDENTS_COMPONENT_ID = 'Incidents';\r\nexport const LOAD_INCIDENTS_COMPONENT_ID = 'loadIncidents';\r\n\r\nconst EMPTY_INCIDENTS: any = {\r\n pageNumber: null,\r\n pageRowCount: null,\r\n totalPageCount: null,\r\n totalRowCount: null,\r\n collection: [],\r\n};\r\n\r\nexport interface IncidentsState {\r\n // will need to specify the type . use any for now\r\n currentIncidentsSearch?: any;\r\n selectedIncident?: any;\r\n incidents?: any;\r\n}\r\n\r\nexport const initialIncidentsSearchState: SearchState = {\r\n query: null,\r\n sortParam: 'discoveryTimestamp',\r\n sortDirection: 'DESC',\r\n sortModalVisible: false,\r\n filters: {},\r\n hiddenFilters: {},\r\n componentId: SEARCH_INCIDENTS_COMPONENT_ID,\r\n};\r\n\r\nexport const initIncidentsPaging = getDefaultPagingInfoRequest(\r\n 1,\r\n 20,\r\n 'discoveryTimestamp',\r\n 'DESC',\r\n undefined,\r\n);\r\n\r\nexport function getDefaultIncidentsState(): IncidentsState {\r\n return {\r\n currentIncidentsSearch: EMPTY_INCIDENTS,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "currentIncidentsSearch",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 18
+ },
+ {
+ "name": "incidents",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 20
+ },
+ {
+ "name": "selectedIncident",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 19
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "IncidentState",
+ "id": "interface-IncidentState-929c0edefbef9ea45f9062e85f50697a8699d1db0135e3a1c71b3a9f80e05be71a1c6a203ad4745a61125f499b2f282831d7dfcbff46470b61412ecea30828c6",
+ "file": "src/app/store/incident/incident.stats.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export const INCIDENT_COMPONENT_ID = 'Incident';\r\n\r\nexport interface IncidentState {\r\n currentIncident?: any;\r\n currentIncidentCause?: any;\r\n}\r\n\r\nexport function getDefaultIncidentState(): IncidentState {\r\n return {\r\n currentIncident: null,\r\n currentIncidentCause: null,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "currentIncident",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 4
+ },
+ {
+ "name": "currentIncidentCause",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 5
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "InfoPluginSettings",
+ "id": "interface-InfoPluginSettings-d5fb47c34d97b8e41988c062c299c16ed9744e9d33ececc39d4ea788bebd32a02f43d67e37cc5507299b61ce4fe001c8ff138558836da51a627fdfd6cacc78d0",
+ "file": "src/app/components/public-incident-page/incident-gallery-panel/info-plugin/info-plugin-settings.component.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface InfoPluginSettings {\r\n /**\r\n * Enable/Disable info option\r\n */\r\n info: boolean;\r\n infoData: any;\r\n}\r\n\r\nexport const infoSettings: InfoPluginSettings = {\r\n info: true,\r\n infoData: {},\r\n};\r\n",
+ "properties": [
+ {
+ "name": "info",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "Enable/Disable info option
\n",
+ "line": 5,
+ "rawdescription": "\n\nEnable/Disable info option\n"
+ },
+ {
+ "name": "infoData",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": false,
+ "description": "",
+ "line": 6
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "LabeledAction",
+ "id": "interface-LabeledAction-97e807b22dd48389a9e8795594d9abdbaae08bf80a89836e570a2fe1b3a1593a4106dda39fc3562d0e5caeb9a95fb68d68ba0c5ebbd89310aeb2f71c1564f685",
+ "file": "src/app/store/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { routerReducer } from '@ngrx/router-store';\r\nimport { Action, ActionReducer, ActionReducerMap } from '@ngrx/store';\r\nimport { searchReducer, SearchState, SortDirection } from '@wf1/core-ui';\r\nimport { storeLogger } from 'ngrx-store-logger';\r\nimport {\r\n ApplicationState,\r\n PagingSearchState,\r\n} from './application/application.state';\r\nimport { pageSearchReducer } from './common/page-search.reducer';\r\nimport { IncidentEffect } from './incident/incident.effect';\r\nimport { incidentReducer } from './incident/incident.reducer';\r\nimport { IncidentState } from './incident/incident.stats';\r\nimport { IncidentsEffect } from './incidents/incidents.effects';\r\n\r\nimport { incidentsReducer } from './incidents/incidents.reducer';\r\nimport {\r\n initialIncidentsSearchState,\r\n IncidentsState,\r\n} from './incidents/incidents.stats';\r\nimport { WildfiresListEffect } from './wildfiresList/wildfiresList.effects';\r\nimport { wildfiresListReducer } from './wildfiresList/wildfiresList.reducer';\r\nimport {\r\n initialWildfiresSearchState,\r\n WildfiresState,\r\n} from './wildfiresList/wildfiresList.stats';\r\n\r\nexport interface BaseRouterStoreState {\r\n url: string;\r\n}\r\n\r\nexport interface RouterState {\r\n state: BaseRouterStoreState;\r\n}\r\n\r\nexport const rootReducers: ActionReducerMap = {\r\n search: searchReducer,\r\n router: routerReducer,\r\n incidents: incidentsReducer,\r\n searchIncidents: pageSearchReducer,\r\n incident: incidentReducer,\r\n wildfires: wildfiresListReducer,\r\n searchWildfires: pageSearchReducer,\r\n};\r\n\r\nexport interface RootState {\r\n application?: ApplicationState;\r\n incidents?: IncidentsState;\r\n searchIncidents?: PagingSearchState;\r\n incident?: IncidentState;\r\n wildfires?: WildfiresState;\r\n searchWildfires?: PagingSearchState;\r\n}\r\n\r\nexport const initialRootState: RootState = {\r\n searchIncidents: initialIncidentsSearchState,\r\n searchWildfires: initialWildfiresSearchState,\r\n};\r\n\r\nexport const rootEffects: any[] = [\r\n // PlaceNameSearchEffects,\r\n IncidentsEffect,\r\n IncidentEffect,\r\n WildfiresListEffect,\r\n];\r\n\r\nexport function logger(reducer: ActionReducer): any {\r\n // default, no options\r\n return storeLogger({\r\n collapsed: true,\r\n level: 'log',\r\n filter: {\r\n blacklist: [],\r\n },\r\n })(reducer);\r\n}\r\n\r\nexport interface AudibleAlertState {\r\n enableUnacknowledged: boolean;\r\n enableReceivedFromPM: boolean;\r\n selectedZoneIds?: string[];\r\n}\r\n\r\nexport class SearchStateAndConfig implements SearchState {\r\n query: string;\r\n sortParam: string;\r\n sortDirection: SortDirection;\r\n sortModalVisible: boolean;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n hiddenFilters: {\r\n [param: string]: any[];\r\n };\r\n columns?: string[]; //ordered list of columns to display\r\n componentId?: string;\r\n audibleAlert?: AudibleAlertState;\r\n}\r\n\r\nexport function isEmpty(obj) {\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport interface LabeledAction extends Action {\r\n displayLabel: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "displayLabel",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 109
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "layerSettings",
+ "id": "interface-layerSettings-f47d4d45e4fded9a1a422290db7e74e756c01f6518f564f8139b75b27a6c6ef1de1c88d111767424eb261562b2b46c78f60cf8a25bc50c89d0b9397cb992eb63",
+ "file": "src/app/services/map-config.service/layers/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { AppConfigService } from '@wf1/core-ui';\r\nimport { MapServices, MapServiceStatus } from '..';\r\nimport { AbmsMunicipalitiesLayerConfig } from './abms-municipalities.config';\r\nimport { AbmsRegionalDistrictsLayerConfig } from './abms-regional-districts.config';\r\nimport { ActiveWildfiresLayerConfig } from './active-wildfires.config';\r\nimport { ActiveWildfiresHeatmapLayerConfig } from './active-wildfires.heatmap.config';\r\nimport { AreaRestrictionsLayerConfig } from './area-restrictions.config';\r\nimport { BansAndProhibitionsLayerConfig } from './bans-and-prohibitions.config';\r\nimport { BasemapLayerConfig } from './basemap.config';\r\nimport { FireCentresLayerConfig } from './bc-fire-centres.config';\r\nimport { ProtectedLandsAccessRestrictionsLayerConfig } from './bc-parks-closures.config';\r\nimport { WildfiresInactiveLayerConfig } from './bcws-activefires-publicview-inactive.config';\r\nimport { CLABIndianReservesLayerConfig } from './clab-indian-reserves.config';\r\nimport { ClosedRecreationSitesLayerConfig } from './closed-recreation-sites.config';\r\nimport { DangerRatingLayerConfig } from './danger-rating.config';\r\nimport { DriveBCEventsLayerConfig } from './drive-bc-active-events.config';\r\nimport { EvacuationOrdersLayerConfig } from './evacuation-orders-and-alerts-wms.config';\r\nimport { FirePerimetersLayerConfig } from './fire-perimeters.config';\r\nimport { FntTreatyLandLayerConfig } from './fnt-treaty-land.config';\r\nimport { ForestServiceRoadsLayerConfig } from './fsr-safety.config';\r\nimport { SmokeForecastLayerConfig } from './hourly-currentforecast-firesmoke.config';\r\nimport { PrecipitationLayerConfig } from './precipitation.config';\r\nimport { WeatherStationsLayerConfig } from './weather-stations.config';\r\nimport { WeatherLayerConfig } from './weather.config';\r\n//import { FuelTreatmentLayerConfig } from './fuel-treatment';\r\n//import { PrescribedFireLayerConfig } from './prescribed-fire.config';\r\n\r\nexport interface layerSettings {\r\n openmapsBaseUrl: string;\r\n services6BaseUrl: string;\r\n drivebcBaseUrl: string;\r\n wfnewsUrl: string;\r\n evacOrdersURL: string;\r\n}\r\nexport function LayerConfig(\r\n mapServices: MapServices,\r\n serviceStatus: MapServiceStatus,\r\n appConfigService: AppConfigService,\r\n) {\r\n const ls: layerSettings = {\r\n openmapsBaseUrl: mapServices['openmapsBaseUrl'],\r\n drivebcBaseUrl: mapServices['drivebcBaseUrl'],\r\n services6BaseUrl: mapServices['services6BaseUrl'],\r\n wfnewsUrl: mapServices['wfnews'],\r\n evacOrdersURL: appConfigService.getConfig().externalAppConfig['AGOLevacOrders'].toString()\r\n };\r\n\r\n return [\r\n ...ActiveWildfiresLayerConfig(\r\n ls,\r\n appConfigService.getConfig().application['wfnewsApiKey'],\r\n ),\r\n ...AreaRestrictionsLayerConfig(ls),\r\n ...BansAndProhibitionsLayerConfig(ls),\r\n ...FireCentresLayerConfig(ls),\r\n ...WildfiresInactiveLayerConfig(ls),\r\n ...ClosedRecreationSitesLayerConfig(ls),\r\n ...DangerRatingLayerConfig(ls),\r\n ...DriveBCEventsLayerConfig(ls),\r\n ...EvacuationOrdersLayerConfig(ls),\r\n ...FirePerimetersLayerConfig(ls),\r\n ...SmokeForecastLayerConfig(ls),\r\n // ...PrescribedFireLayerConfig( ls ),\r\n ...WeatherLayerConfig(ls),\r\n ...WeatherStationsLayerConfig(ls),\r\n ...PrecipitationLayerConfig(ls),\r\n ...ForestServiceRoadsLayerConfig(ls),\r\n ...ActiveWildfiresHeatmapLayerConfig(ls),\r\n ...CLABIndianReservesLayerConfig(ls),\r\n ...FntTreatyLandLayerConfig(ls),\r\n ...AbmsMunicipalitiesLayerConfig(ls),\r\n ...AbmsRegionalDistrictsLayerConfig(ls),\r\n ...ProtectedLandsAccessRestrictionsLayerConfig(ls),\r\n ...BasemapLayerConfig(ls),\r\n // ...FuelTreatmentLayerConfig(ls),\r\n ];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "drivebcBaseUrl",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 31
+ },
+ {
+ "name": "evacOrdersURL",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 33
+ },
+ {
+ "name": "openmapsBaseUrl",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 29
+ },
+ {
+ "name": "services6BaseUrl",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 30
+ },
+ {
+ "name": "wfnewsUrl",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 32
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "LoadState",
+ "id": "interface-LoadState-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "isLoading",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 66
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "LoadStates",
+ "id": "interface-LoadStates-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "incidents",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "LoadState",
+ "optional": false,
+ "description": "",
+ "line": 48
+ },
+ {
+ "name": "wildfires",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "LoadState",
+ "optional": false,
+ "description": "",
+ "line": 49
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "Location",
+ "id": "interface-Location-ec29c8bce202b551c0e60bf02acd4ca5ae1ed88456d44170c482070d224e87ff191c4bf696bcc8ac5b7e1dd7037aef057c3f21454e4a8a7e9ef1be622aab16e6",
+ "file": "src/app/services/wfnews-map.service/place-data.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { direction, distance, fetchJsonP, LonLat } from './util';\r\n\r\nconst EPSILON = 0.01;\r\n\r\nexport interface Location {\r\n name: string;\r\n type: string;\r\n dist: number;\r\n loc: LonLat;\r\n direction?: string;\r\n isAnchor?: boolean;\r\n}\r\n\r\nexport class PlaceData {\r\n private anchorPoint?: LonLat;\r\n private maxDistance?: number;\r\n private callback?: any;\r\n private searchState: {\r\n placeText?: string;\r\n places?: Location[];\r\n roadText?: string;\r\n roads?: Location[];\r\n intersectionsText?: [string, string];\r\n intersections?: Location[];\r\n } = {};\r\n\r\n init() {\r\n return this.updateResults();\r\n }\r\n\r\n setResultHandler(callback) {\r\n if (callback != null && typeof callback != 'function') {\r\n return;\r\n }\r\n\r\n this.callback = callback;\r\n }\r\n\r\n setMaximumDistance(distance: number) {\r\n this.maxDistance = distance;\r\n return this.updateResults();\r\n }\r\n getMaximumDistance(): number {\r\n return this.maxDistance;\r\n }\r\n\r\n setAnchor(point: LonLat) {\r\n this.anchorPoint = point;\r\n return this.updateResults();\r\n }\r\n getAnchor(): LonLat {\r\n return this.anchorPoint;\r\n }\r\n\r\n getSearchState() {\r\n return this.searchState;\r\n }\r\n\r\n findPlace(text: string) {\r\n this.searchState.places = [];\r\n this.searchState.placeText = text;\r\n\r\n return this.updateResults();\r\n }\r\n\r\n findRoad(text: string) {\r\n this.searchState.roads = [];\r\n this.searchState.roadText = text;\r\n // don't search for intersections\r\n this.searchState.intersections = [];\r\n this.searchState.intersectionsText = null;\r\n\r\n return this.updateResults();\r\n }\r\n\r\n findIntersection(text1, text2) {\r\n this.searchState.intersections = [];\r\n this.searchState.intersectionsText = [text1, text2];\r\n // don't search for roads\r\n this.searchState.roads = [];\r\n this.searchState.roadText = null;\r\n\r\n return this.updateResults();\r\n }\r\n\r\n searchAddresses(txt: string) {\r\n const query = {\r\n ver: 1.2,\r\n maxResults: 10,\r\n outputSRS: 4326,\r\n addressString: txt,\r\n autoComplete: true,\r\n };\r\n\r\n return fetchJsonP(\r\n 'https://geocoder.api.gov.bc.ca/addresses.geojsonp',\r\n query,\r\n )\r\n .response.then(function(result) {\r\n const resultLoc = result.features\r\n .map(function(feature) {\r\n if (!feature.geometry.coordinates) {\r\n return;\r\n }\r\n\r\n // exclude whole province match\r\n if (feature.properties.fullAddress == 'BC') {\r\n return;\r\n }\r\n\r\n const loc = {\r\n streetName: feature.properties.streetName,\r\n streetQualifier: feature.properties.streetQualifier,\r\n streetType: feature.properties.streetType,\r\n localityName: feature.properties.localityName,\r\n localityType: feature.properties.localityType,\r\n civicNumber: feature.properties.civicNumber,\r\n dist: null,\r\n dir: null,\r\n loc: feature.geometry.coordinates,\r\n };\r\n\r\n return loc;\r\n })\r\n .filter(function(item) {\r\n return item;\r\n });\r\n return resultLoc;\r\n })\r\n .catch(function(e) {\r\n console.warn('address match:', e);\r\n });\r\n }\r\n\r\n updateResults(): Promise {\r\n const self = this;\r\n\r\n if (!this.callback) {\r\n return Promise.resolve();\r\n }\r\n\r\n return Promise.resolve()\r\n .then(function() {\r\n return searchPlaces(self);\r\n })\r\n .then(function() {\r\n return searchRoads(self);\r\n })\r\n .then(function() {\r\n return searchOccupants(self);\r\n })\r\n .then(function() {\r\n return searchAddresses(self);\r\n })\r\n .then(function() {\r\n return searchIntersections(self);\r\n })\r\n .then(\r\n function() {\r\n if (!self.callback) {\r\n return;\r\n }\r\n\r\n self.callback.call(\r\n null,\r\n Object.assign(\r\n {\r\n anchorPt: self.anchorPoint,\r\n maxDistance: self.maxDistance,\r\n },\r\n self.searchState,\r\n ),\r\n );\r\n },\r\n function(e) {\r\n if (!self.callback) {\r\n return;\r\n }\r\n self.callback.call(\r\n null,\r\n Object.assign(\r\n {\r\n error: e,\r\n anchorPt: self.anchorPoint,\r\n maxDistance: self.maxDistance,\r\n },\r\n self.searchState,\r\n ),\r\n );\r\n },\r\n );\r\n }\r\n}\r\n\r\n//---------------------------------------------------------------\r\n\r\nconst fetchCache: { [url: string]: Promise } = {};\r\n\r\nfunction fetchData(url: string): Promise {\r\n if (fetchCache[url]) {\r\n return fetchCache[url];\r\n }\r\n\r\n return (fetchCache[url] = fetch(url, { credentials: 'same-origin' }).then(\r\n function(res) {\r\n if (res.ok) {\r\n return res.json();\r\n }\r\n\r\n throw new Error(`fetching ${url}: ${res.statusText}`);\r\n },\r\n ));\r\n}\r\n\r\nfunction searchPlaces(data: PlaceData) {\r\n if (data.getSearchState().placeText) {\r\n return fetchData('assets/place-data/wf-search-places.json')\r\n .then(function(\r\n places: { n: string; t: string; x: number; y: number }[],\r\n ) {\r\n data.getSearchState().places = sortData(\r\n searchData(places, data.getSearchState().placeText, data.getAnchor()),\r\n );\r\n })\r\n .catch(function(e) {\r\n console.warn('place match:', e);\r\n });\r\n } else {\r\n data.getSearchState().places = [];\r\n }\r\n}\r\n\r\nfunction searchRoads(data: PlaceData) {\r\n if (data.getSearchState().roadText) {\r\n return fetchData('assets/place-data/wf-search-roads.json')\r\n .then(function(roads: { n: string; x: number; y: number }[]) {\r\n data.getSearchState().roads = sortData(\r\n searchData(\r\n roads,\r\n data.getSearchState().roadText,\r\n data.getAnchor(),\r\n data.getMaximumDistance(),\r\n ),\r\n );\r\n })\r\n .catch(function(e) {\r\n console.warn('road match:', e);\r\n });\r\n } else {\r\n data.getSearchState().roads = [];\r\n }\r\n}\r\n\r\nfunction searchData(\r\n source: { n: string; t?: string; x: number; y: number }[],\r\n text: string,\r\n anchorPt: LonLat,\r\n maxDist?: number,\r\n): Location[] {\r\n const locs = [];\r\n if (!text || !text.trim()) {\r\n return locs;\r\n }\r\n\r\n const t = text.toLowerCase();\r\n // var strIn = ' ' + strLow;\r\n\r\n for (let i = 0; i < source.length; i++) {\r\n const place = source[i];\r\n if (place.n.toLowerCase().startsWith(t)) {\r\n const location = {\r\n name: place.n,\r\n type: place.t,\r\n dist: null,\r\n loc: [place.x, place.y] as LonLat,\r\n };\r\n\r\n setAnchorData(anchorPt, location);\r\n\r\n if (maxDist && location.dist > maxDist) {\r\n continue;\r\n }\r\n\r\n locs.push(location);\r\n }\r\n }\r\n\r\n return locs;\r\n}\r\n\r\nfunction sortData(locations) {\r\n const sorted = locations.sort(function(a, b) {\r\n if (a.dist == null || b.dist == null) {\r\n return a.name > b.name ? 1 : -1;\r\n }\r\n\r\n return a.dist - b.dist;\r\n });\r\n return sorted;\r\n}\r\n\r\nfunction removeDuplicateIntersections(locations) {\r\n // remove contiguous entries with duplicate names (which will be close to one another)\r\n const uniq = [];\r\n for (let i = 0; i < locations.length; i++) {\r\n const candidate = locations[i];\r\n if (i > 0) {\r\n const current = uniq[uniq.length - 1];\r\n // skip if duplicate\r\n if (isDuplicateIntersection(current, candidate)) {\r\n continue;\r\n }\r\n }\r\n // keep this one\r\n uniq.push(candidate);\r\n }\r\n return uniq;\r\n}\r\n\r\nfunction isDuplicateIntersection(intLoc1, intLoc2) {\r\n if (intLoc1.name !== intLoc2.name) {\r\n return false;\r\n }\r\n if (intLoc1.dist && intLoc2.dist) {\r\n const distanceBetween = intLoc1.dist - intLoc2.dist;\r\n if (distanceBetween > 1) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nfunction setAnchorData(anchorPt: LonLat, location: Location) {\r\n if (!anchorPt) {\r\n return;\r\n }\r\n location.dist = distance(anchorPt, location.loc); // / 1000.0;\r\n location.direction = direction(anchorPt, location.loc);\r\n // MD not sure about this logic, since there can be more than one result with same coordinate\r\n if (location.dist < EPSILON) {\r\n location.isAnchor = true;\r\n }\r\n}\r\n\r\nfunction searchIntersections(data: PlaceData) {\r\n if (!data.getSearchState().intersectionsText) {\r\n data.getSearchState().intersections = [];\r\n return;\r\n }\r\n\r\n const query = {\r\n ver: 1.2,\r\n maxResults: 1000,\r\n outputSRS: 4326,\r\n addressString: data.getSearchState().intersectionsText.join(' and '),\r\n matchPrecision: 'INTERSECTION',\r\n autoComplete: true,\r\n };\r\n\r\n return fetchJsonP('https://geocoder.api.gov.bc.ca/addresses.geojsonp', query)\r\n .response.then(function(result) {\r\n const resultLoc = result.features\r\n .map(function(feature) {\r\n if (!feature.geometry.coordinates) {\r\n return;\r\n }\r\n\r\n // exclude whole province match\r\n if (feature.properties.fullAddress == 'BC') {\r\n return;\r\n }\r\n // only return intersections\r\n if (!feature.properties.intersectionName) {\r\n return;\r\n }\r\n\r\n const loc = {\r\n name: feature.properties.fullAddress,\r\n type: 'intersection',\r\n dist: null,\r\n dir: null,\r\n loc: feature.geometry.coordinates,\r\n };\r\n setAnchorData(data.getAnchor(), loc);\r\n return loc;\r\n })\r\n .filter(function(item) {\r\n return item;\r\n });\r\n data.getSearchState().intersections = removeDuplicateIntersections(\r\n sortData(resultLoc),\r\n );\r\n })\r\n .catch(function(e) {\r\n console.warn('intersection match:', e);\r\n });\r\n}\r\n\r\nfunction searchAddresses(data: PlaceData) {\r\n if (\r\n data.getSearchState().roads.length > 0 ||\r\n !data.getSearchState().roadText ||\r\n !data.getSearchState().roadText.trim()\r\n ) {\r\n return;\r\n }\r\n\r\n const query = {\r\n ver: 1.2,\r\n maxResults: 10,\r\n outputSRS: 4326,\r\n addressString: data.getSearchState().roadText,\r\n autoComplete: true,\r\n };\r\n\r\n return fetchJsonP('https://geocoder.api.gov.bc.ca/addresses.geojsonp', query)\r\n .response.then(function(result) {\r\n const resultLoc = result.features\r\n .map(function(feature) {\r\n if (!feature.geometry.coordinates) {\r\n return;\r\n }\r\n\r\n // exclude whole province match\r\n if (feature.properties.fullAddress == 'BC') {\r\n return;\r\n }\r\n\r\n const loc = {\r\n name: feature.properties.fullAddress,\r\n type: null,\r\n dist: null,\r\n dir: null,\r\n loc: feature.geometry.coordinates,\r\n };\r\n setAnchorData(data.getAnchor(), loc);\r\n return loc;\r\n })\r\n .filter(function(item) {\r\n return item;\r\n });\r\n data.getSearchState().roads = removeDuplicateIntersections(\r\n sortData(resultLoc),\r\n );\r\n })\r\n .catch(function(e) {\r\n console.warn('address match:', e);\r\n });\r\n}\r\n\r\nfunction searchOccupants(data: PlaceData) {\r\n if (\r\n data.getSearchState().places.length > 0 ||\r\n !data.getSearchState().placeText ||\r\n !data.getSearchState().placeText.trim()\r\n ) {\r\n return;\r\n }\r\n\r\n const query = {\r\n ver: 1.2,\r\n maxResults: 100,\r\n outputSRS: 4326,\r\n addressString: data.getSearchState().placeText,\r\n autoComplete: true,\r\n };\r\n\r\n return fetchJsonP(\r\n 'https://geocoder.api.gov.bc.ca/occupants/addresses.geojsonp',\r\n query,\r\n )\r\n .response.then(function(result) {\r\n const resultLoc = result.features\r\n .map(function(feature) {\r\n if (!feature.geometry.coordinates) {\r\n return;\r\n }\r\n\r\n // exclude whole province match\r\n if (feature.properties.fullAddress == 'BC') {\r\n return;\r\n }\r\n\r\n const loc = {\r\n name: feature.properties.fullAddress,\r\n type: null,\r\n dist: null,\r\n dir: null,\r\n loc: feature.geometry.coordinates,\r\n };\r\n setAnchorData(data.getAnchor(), loc);\r\n return loc;\r\n })\r\n .filter(function(item) {\r\n return item;\r\n });\r\n data.getSearchState().places = removeDuplicateIntersections(\r\n sortData(resultLoc),\r\n );\r\n })\r\n .catch(function(e) {\r\n console.warn('occupant match:', e);\r\n });\r\n}\r\n",
+ "properties": [
+ {
+ "name": "direction",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 10
+ },
+ {
+ "name": "dist",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 8
+ },
+ {
+ "name": "isAnchor",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": true,
+ "description": "",
+ "line": 11
+ },
+ {
+ "name": "loc",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "LonLat",
+ "optional": false,
+ "description": "",
+ "line": 9
+ },
+ {
+ "name": "name",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 6
+ },
+ {
+ "name": "type",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 7
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "LocationNotification",
+ "id": "interface-LocationNotification-8535ce51ccdad526d840669937c2863b8c4704ebacf2e5a788764298904f6dbe7761d1eb638a976f40486932cb843e69f3a4250037faa79d75e0a3680ed65ea9",
+ "file": "src/app/services/capacitor-service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { EventEmitter, Injectable, NgZone } from '@angular/core';\r\nimport { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';\r\nimport { Router } from '@angular/router';\r\nimport { FCM } from '@capacitor-community/fcm';\r\nimport { App, AppState } from '@capacitor/app';\r\nimport { AppLauncher } from '@capacitor/app-launcher';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Device } from '@capacitor/device';\r\nimport { Geolocation, Position } from '@capacitor/geolocation';\r\nimport {\r\n PushNotificationSchema,\r\n PushNotifications,\r\n} from '@capacitor/push-notifications';\r\nimport { Store } from '@ngrx/store';\r\nimport { BehaviorSubject, fromEvent } from 'rxjs';\r\nimport { environment } from '../../environments/environment';\r\nimport { RootState } from '../store';\r\nimport { ApplicationStateService } from './application-state.service';\r\nimport { EventEmitterService } from './event-emitter.service';\r\n\r\nimport { ResourcesRoutes } from '@app/utils';\r\nimport { NotificationSnackbarComponent } from '../components/notification-snackbar/notification-snackbar.component';\r\nimport { Preferences } from '@capacitor/preferences';\r\n\r\nexport interface CompassHeading {\r\n magneticHeading?: number; //The heading in degrees from 0-359.99 at a single moment in time. (Number)\r\n trueHeading?: number; //The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. A negative value indicates that the true heading can't be determined. (Number)\r\n headingAccuracy?: number; //The deviation in degrees between the reported heading and the true heading. (Number)\r\n timestamp?: string; //The time at which this heading was determined. (DOMTimeStamp)\r\n error?: string;\r\n}\r\n\r\nexport interface LocationNotification {\r\n latitude: number;\r\n longitude: number;\r\n radius: number;\r\n featureId: string;\r\n featureType: string;\r\n fireYear?: number;\r\n}\r\n\r\nexport interface ReportOfFireNotification {\r\n title: string;\r\n body: string;\r\n}\r\n\r\nexport interface DeviceProperties {\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n isMobilePlatform: boolean;\r\n deviceId: string;\r\n isTwitterInstalled: boolean;\r\n}\r\n\r\nconst UPDATE_AFTER_INACTIVE_MILLIS = 1000 * 60; // 1 minute\r\nconst REFRESH_INTERVAL_ACTIVE_MILLIS = 5 * 1000 * 60; // 5 minutes\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CapacitorService {\r\n resume: BehaviorSubject;\r\n initialized: Promise;\r\n fbAppInstalled: boolean;\r\n twitterAppInstalled: boolean;\r\n appState: AppState;\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n deviceId: string;\r\n pnNav = null;\r\n notificationToken = null;\r\n updateMainMapLayers = new EventEmitter();\r\n currentHeadingPromise: Promise;\r\n locationNotifications = new EventEmitter();\r\n rofNotifications = new EventEmitter();\r\n inactiveStart: number;\r\n refreshTimer;\r\n locationNotificationsDelay = 5000;\r\n rofNotificationsDelay = 5000;\r\n notificationSnackbarPromise = Promise.resolve();\r\n registeredForNotifications = false;\r\n private devicePropertiesPromise: Promise;\r\n\r\n constructor(\r\n private zone: NgZone,\r\n protected router: Router,\r\n protected store: Store,\r\n protected eventEmitterService: EventEmitterService,\r\n protected stateService: ApplicationStateService,\r\n protected snackbar: MatSnackBar,\r\n ) {\r\n this.resume = new BehaviorSubject(null);\r\n fromEvent(document, 'resume').subscribe((event) => {\r\n this.zone.run(() => {\r\n this.onResume();\r\n });\r\n });\r\n\r\n this.isIOSPlatform = false;\r\n this.isAndroidPlatform = false;\r\n this.isWebPlatform = false;\r\n this.fbAppInstalled = false;\r\n this.twitterAppInstalled = false;\r\n this.deviceId = '';\r\n\r\n this.initialized = this.checkDevice().then(() => {\r\n this.init();\r\n\r\n // use for testing notification at startup\r\n // this.emitLocationNotification( {\r\n // coords: '[48.463259,-123.312635]',\r\n // radius: '20',\r\n // messageID: 'V65055',\r\n // topicKey: 'BCWS_ActiveFires_PublicView',\r\n // } )\r\n });\r\n }\r\n\r\n init() {\r\n const startRefreshTimer = () => {\r\n stopRefreshTimer();\r\n\r\n this.refreshTimer = setTimeout(() => {\r\n this.updateMainMapLayers.emit();\r\n startRefreshTimer();\r\n }, REFRESH_INTERVAL_ACTIVE_MILLIS);\r\n };\r\n\r\n const stopRefreshTimer = () => {\r\n if (!this.refreshTimer) {\r\nreturn;\r\n}\r\n\r\n clearTimeout(this.refreshTimer);\r\n this.refreshTimer = null;\r\n };\r\n\r\n startRefreshTimer();\r\n\r\n App.addListener('appStateChange', (state) => {\r\n if (state.isActive) {\r\n startRefreshTimer();\r\n\r\n if (!this.inactiveStart) {\r\nreturn;\r\n}\r\n\r\n const inactiveDuration = Date.now() - this.inactiveStart;\r\n this.inactiveStart = null;\r\n\r\n if (inactiveDuration > UPDATE_AFTER_INACTIVE_MILLIS) {\r\n this.updateMainMapLayers.emit();\r\n }\r\n } else {\r\n if (!this.inactiveStart) {\r\nthis.inactiveStart = Date.now();\r\n}\r\n\r\n stopRefreshTimer();\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n if (this.isWebPlatform) {\r\n this.notificationToken = 'FakeForWeb';\r\n return;\r\n }\r\n\r\n this.checkInstalledApps();\r\n\r\n if (this.isAndroidPlatform) {\r\n App.addListener('backButton', (state) => {\r\n this.eventEmitterService.androidBackButtonPressed();\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n // Request permission to use push notifications\r\n this.registerForNotifications()\r\n .then((registered) => {\r\n console.log('registeredForNotifications', registered);\r\n this.registeredForNotifications = registered;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // On success, we should be able to receive notifications\r\n PushNotifications.addListener('registration', (token) => {\r\n console.log('PNN REgister success ' + token.value);\r\n if (this.isAndroidPlatform) {\r\n this.notificationToken = token.value;\r\n } else if (this.isIOSPlatform) {\r\n FCM.getToken()\r\n .then((response) => {\r\n this.notificationToken = response.token;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Some issue with our setup and push will not work\r\n PushNotifications.addListener('registrationError', (error) => {\r\n console.log('PNN REgister fail ' + error);\r\n }).catch((err) => {\r\n console.error(err);\r\n });\r\n\r\n // Show us the notification payload if the app is open on our device\r\n PushNotifications.addListener(\r\n 'pushNotificationReceived',\r\n (notification) => {\r\n console.log('pushNotificationReceived', notification);\r\n this.handleRofPushNotification(notification);\r\n },\r\n ).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Method called when tapping on a notification\r\n PushNotifications.addListener('pushNotificationActionPerformed', (ev) => {\r\n const data = ev.notification.data;\r\n console.log('pushNotificationActionPerformed', data);\r\n\r\n this.emitLocationNotification(data);\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n async registerForNotifications(): Promise {\r\n let status = await PushNotifications.checkPermissions();\r\n if (status.receive === 'prompt') {\r\n status = await PushNotifications.requestPermissions();\r\n }\r\n\r\n if (status.receive !== 'granted') {\r\n return false;\r\n }\r\n\r\n await PushNotifications.register();\r\n return true;\r\n }\r\n\r\n handleRofPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n this.emitLocationNotification(notification.body);\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitRofNotification(title, body) {\r\n setTimeout(() => {\r\n try {\r\n this.rofNotifications.emit({ title, body });\r\n\r\n this.rofNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, title + ': ' + body);\r\n }\r\n }, this.rofNotificationsDelay);\r\n }\r\n\r\n handleLocationPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n const c = JSON.parse(notification.data['coords']);\r\n const r = JSON.parse(notification.data['radius']);\r\n this.router.navigate([ResourcesRoutes.ACTIVEWILDFIREMAP], {\r\n queryParams: {\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: notification.data['messageID'],\r\n featureType: notification.data['topicKey'],\r\n identify: true,\r\n notification: true,\r\n time: Date.now(),\r\n },\r\n });\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitLocationNotification(data) {\r\n setTimeout(() => {\r\n try {\r\n const c = JSON.parse(data['coords']);\r\n const r = JSON.parse(data['radius']);\r\n\r\n this.locationNotifications.emit({\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: data['messageID'],\r\n featureType: data['topicKey'],\r\n });\r\n\r\n this.locationNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, data);\r\n }\r\n }, this.locationNotificationsDelay);\r\n }\r\n\r\n showNotificationSnackbar(notification: any) {\r\n const cfg: MatSnackBarConfig = {\r\n data: { notification },\r\n // need to change back to 10 sec. Using 60 sec for testing purpose in case QA missed it.\r\n duration: 60 * 1000,\r\n verticalPosition: 'top',\r\n };\r\n\r\n return this.snackbar.openFromComponent(NotificationSnackbarComponent, cfg);\r\n }\r\n\r\n checkDevice() {\r\n // const deviceInfo = \r\n return Device.getInfo()\r\n .then((devInfo) => {\r\n console.log(devInfo);\r\n if (!devInfo) {\r\nreturn;\r\n}\r\n\r\n this.isIOSPlatform = devInfo.platform === 'ios';\r\n this.isAndroidPlatform = devInfo.platform === 'android';\r\n this.isWebPlatform =\r\n devInfo.platform !== 'ios' && devInfo.platform !== 'android';\r\n\r\n return Device.getId();\r\n })\r\n .then((deviceId) => {\r\n console.log(deviceId);\r\n this.deviceId = deviceId.identifier;\r\n });\r\n }\r\n\r\n async getCurrentPosition(options?: PositionOptions): Promise {\r\n const coordinates = Geolocation.getCurrentPosition(options);\r\n return coordinates;\r\n }\r\n\r\n checkInstalledApps() {\r\n this.checkTwitterAppInstalled().then(\r\n (result) => {\r\n this.twitterAppInstalled = result;\r\n },\r\n (error) => {\r\n this.twitterAppInstalled = false;\r\n },\r\n );\r\n\r\n this.checkFbAppInstalled().then(\r\n (result) => {\r\n this.fbAppInstalled = result;\r\n },\r\n (error) => {\r\n this.fbAppInstalled = false;\r\n },\r\n );\r\n }\r\n\r\n onResume(): void {\r\n this.resume.next(true);\r\n }\r\n\r\n openLinkInAppBrowser(url: string) {\r\n Browser.open({\r\n url,\r\n toolbarColor: '#f7f7f9',\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n private async checkTwitterAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async checkFbAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'fb://' : 'com.facebook.katana';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async appIsInstalled(scheme: string): Promise {\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n\r\n initOfflinePageSettings() {\r\n App.addListener('appStateChange', (state: AppState) => {\r\n this.appState = state;\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n public isMobilePlatform(): boolean {\r\n if (this.isIOSPlatform || this.isAndroidPlatform) {\r\n return true;\r\n }\r\n return !!environment['is_mobile_platform'];\r\n }\r\n\r\n getPnUrl() {\r\n return this.pnNav;\r\n }\r\n\r\n public getNotificationToken() {\r\n return this.notificationToken;\r\n }\r\n\r\n public setNotificationToken(token: string) {\r\n this.notificationToken = token;\r\n }\r\n\r\n openUrlInApp(url: string) {\r\n let scheme;\r\n let schemeUrl;\r\n // twitter\r\n if (url.indexOf('twitter.com/') !== -1) {\r\n scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n schemeUrl = 'twitter://user?screen_name=' + url.split('twitter.com/')[1];\r\n }\r\n\r\n if (scheme && schemeUrl) {\r\n AppLauncher.openUrl({ url: schemeUrl }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }\r\n\r\n isAndroid() {\r\n return this.isAndroidPlatform;\r\n }\r\n\r\n isIOS() {\r\n return this.isIOSPlatform;\r\n }\r\n\r\n getCurrentHeading(): Promise {\r\n const compass = navigator['compass'];\r\n if (!compass) {\r\nreturn Promise.reject(Error('navigator.compass not available'));\r\n} else {\r\n const currentHeading = new Promise((res, rej) => {\r\n compass.getCurrentHeading(\r\n (heading: CompassHeading) => {\r\n res(heading);\r\n this.currentHeadingPromise = null;\r\n },\r\n (error) => {\r\n rej(Error('Failed to get heading: ' + JSON.stringify(error)));\r\n this.currentHeadingPromise = null;\r\n },\r\n );\r\n });\r\n\r\n this.currentHeadingPromise = currentHeading;\r\n\r\n return this.currentHeadingPromise;\r\n }\r\n }\r\n\r\n async checkDeviceSystem() {\r\n // const deviceInfo = \r\n try {\r\n const deviceInfo = await Device.getInfo();\r\n return deviceInfo;\r\n } catch (error) {\r\n console.error('Error getting device info:', error);\r\n }\r\n }\r\n\r\n get deviceProperties(): Promise {\r\n if (!this.devicePropertiesPromise) {\r\nthis.devicePropertiesPromise = Device.getInfo()\r\n .then((devInfo) => Device.getId().then((deviceId) => {\r\n\r\n const p = devInfo && devInfo.platform;\r\n const prop: DeviceProperties = {\r\n isIOSPlatform: p == 'ios',\r\n isAndroidPlatform: p == 'android',\r\n isWebPlatform: p != 'ios' && p != 'android',\r\n isMobilePlatform:\r\n p == 'ios' ||\r\n p == 'android' ||\r\n !!environment['is_mobile_platform'],\r\n deviceId: deviceId.identifier,\r\n isTwitterInstalled: false,\r\n };\r\n const scheme = prop.isIOSPlatform\r\n ? 'twitter://'\r\n : 'com.twitter.android';\r\n return AppLauncher.canOpenUrl({ url: scheme })\r\n .then((canOpen) => {\r\n prop.isTwitterInstalled = canOpen.value;\r\n return prop;\r\n })\r\n .catch((e) => {\r\n console.warn(e);\r\n return prop;\r\n });\r\n }))\r\n .catch((e) => {\r\n console.warn(e);\r\n return {\r\n isIOSPlatform: false,\r\n isAndroidPlatform: false,\r\n isWebPlatform: false,\r\n isMobilePlatform: false,\r\n deviceId: '',\r\n isTwitterInstalled: false,\r\n };\r\n });\r\n}\r\n\r\n return this.devicePropertiesPromise;\r\n }\r\n\r\n get isMobile(): Promise {\r\n return this.deviceProperties.then((p) => p.isMobilePlatform);\r\n }\r\n\r\n async saveData(key: string, value: string) {\r\n await Preferences.set({\r\n key: key,\r\n value: value\r\n });\r\n }\r\n \r\n async getData(key: string) {\r\n const response = await Preferences.get({ key: key });\r\n return response.value;\r\n }\r\n\r\n async removeData(key: string) {\r\n await Preferences.remove({ key: key })\r\n }\r\n}\r\n\r\n\r\n",
+ "properties": [
+ {
+ "name": "featureId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 37
+ },
+ {
+ "name": "featureType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 38
+ },
+ {
+ "name": "fireYear",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 39
+ },
+ {
+ "name": "latitude",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 34
+ },
+ {
+ "name": "longitude",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 35
+ },
+ {
+ "name": "radius",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 36
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "MapServices",
+ "id": "interface-MapServices-ac73f8fe0e3b61200cd42b1380ae113b8b2d820d62f03ef31dc45c4268e424916b19124c4e89200c5cdb3fbcac7ec3d41d56684f6dc80656d7b12474eb7d30fc",
+ "file": "src/app/services/map-config.service/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Injectable } from '@angular/core';\r\nimport {\r\n mapConfig,\r\n reportOfFireMapConfig,\r\n reportOfFireOfflineMapConfig,\r\n} from './map.config';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface MapServiceStatus {\r\n useSecure: boolean;\r\n token?: string;\r\n}\r\n\r\nexport interface MapServices {\r\n [service: string]: string;\r\n}\r\n\r\n@Injectable()\r\nexport class MapConfigService {\r\n constructor(private appConfig: AppConfigService) {}\r\n\r\n getMapConfig(): Promise {\r\n const status: MapServiceStatus = {\r\n useSecure: true,\r\n token: null,\r\n };\r\n\r\n return this.appConfig\r\n .loadAppConfig()\r\n .then((config) =>\r\n mapConfig(\r\n this.appConfig.getConfig()['mapServices'],\r\n status,\r\n 'desktop',\r\n this.appConfig,\r\n ),\r\n );\r\n }\r\n\r\n getReportOfFireMapConfig(): Promise {\r\n const status: MapServiceStatus = {\r\n useSecure: true,\r\n token: null,\r\n };\r\n\r\n return this.appConfig\r\n .loadAppConfig()\r\n .then((config) =>\r\n reportOfFireMapConfig(\r\n this.appConfig.getConfig()['mapServices'],\r\n status,\r\n 'desktop',\r\n this.appConfig,\r\n ),\r\n );\r\n }\r\n\r\n getReportOfFireOfflineMapConfig(): Promise {\r\n const status: MapServiceStatus = {\r\n useSecure: true,\r\n token: null,\r\n };\r\n\r\n return this.appConfig\r\n .loadAppConfig()\r\n .then((config) =>\r\n reportOfFireOfflineMapConfig(\r\n this.appConfig.getConfig()['mapServices'],\r\n status,\r\n 'desktop',\r\n this.appConfig,\r\n ),\r\n );\r\n }\r\n}\r\n",
+ "properties": [],
+ "indexSignatures": [
+ {
+ "id": "index-declaration-ac73f8fe0e3b61200cd42b1380ae113b8b2d820d62f03ef31dc45c4268e424916b19124c4e89200c5cdb3fbcac7ec3d41d56684f6dc80656d7b12474eb7d30fc",
+ "args": [
+ {
+ "name": "service",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "returnType": "string",
+ "line": 14,
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "kind": 181,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "MapServiceStatus",
+ "id": "interface-MapServiceStatus-ac73f8fe0e3b61200cd42b1380ae113b8b2d820d62f03ef31dc45c4268e424916b19124c4e89200c5cdb3fbcac7ec3d41d56684f6dc80656d7b12474eb7d30fc",
+ "file": "src/app/services/map-config.service/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Injectable } from '@angular/core';\r\nimport {\r\n mapConfig,\r\n reportOfFireMapConfig,\r\n reportOfFireOfflineMapConfig,\r\n} from './map.config';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface MapServiceStatus {\r\n useSecure: boolean;\r\n token?: string;\r\n}\r\n\r\nexport interface MapServices {\r\n [service: string]: string;\r\n}\r\n\r\n@Injectable()\r\nexport class MapConfigService {\r\n constructor(private appConfig: AppConfigService) {}\r\n\r\n getMapConfig(): Promise {\r\n const status: MapServiceStatus = {\r\n useSecure: true,\r\n token: null,\r\n };\r\n\r\n return this.appConfig\r\n .loadAppConfig()\r\n .then((config) =>\r\n mapConfig(\r\n this.appConfig.getConfig()['mapServices'],\r\n status,\r\n 'desktop',\r\n this.appConfig,\r\n ),\r\n );\r\n }\r\n\r\n getReportOfFireMapConfig(): Promise {\r\n const status: MapServiceStatus = {\r\n useSecure: true,\r\n token: null,\r\n };\r\n\r\n return this.appConfig\r\n .loadAppConfig()\r\n .then((config) =>\r\n reportOfFireMapConfig(\r\n this.appConfig.getConfig()['mapServices'],\r\n status,\r\n 'desktop',\r\n this.appConfig,\r\n ),\r\n );\r\n }\r\n\r\n getReportOfFireOfflineMapConfig(): Promise {\r\n const status: MapServiceStatus = {\r\n useSecure: true,\r\n token: null,\r\n };\r\n\r\n return this.appConfig\r\n .loadAppConfig()\r\n .then((config) =>\r\n reportOfFireOfflineMapConfig(\r\n this.appConfig.getConfig()['mapServices'],\r\n status,\r\n 'desktop',\r\n this.appConfig,\r\n ),\r\n );\r\n }\r\n}\r\n",
+ "properties": [
+ {
+ "name": "token",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 11
+ },
+ {
+ "name": "useSecure",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 10
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "NotificationConfig",
+ "id": "interface-NotificationConfig-f95ae75db62a56ef19436b58b526e5a316872be003dd50eeaaac16bcb14080d8e24a639f9fc61b806805eb47d9742d7fede0bad99c685347fede3e4ddb92d6c8",
+ "file": "src/app/components/notification-snackbar/notification-snackbar.component.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Component, Inject } from '@angular/core';\r\nimport {\r\n MatSnackBarRef,\r\n MAT_SNACK_BAR_DATA,\r\n} from '@angular/material/snack-bar';\r\nimport { Router } from '@angular/router';\r\nimport { ResourcesRoutes } from '@app/utils';\r\n\r\nexport interface NotificationConfig {\r\n title: string;\r\n body: string;\r\n}\r\n\r\n@Component({\r\n selector: 'wfone-notification-snackbar',\r\n template: `\r\n \r\n
\r\n \r\n \r\n {{ title }}
\r\n {{ body }}
\r\n \r\n \r\n \r\n \r\n
\r\n `,\r\n styleUrls: ['./notification-snackbar.component.scss'],\r\n})\r\nexport class NotificationSnackbarComponent {\r\n constructor(\r\n public snackBarRef: MatSnackBarRef,\r\n protected router: Router,\r\n @Inject(MAT_SNACK_BAR_DATA) public data: any,\r\n ) {}\r\n\r\n get title() {\r\n return this.data.notification.title;\r\n }\r\n\r\n get body() {\r\n return this.data.notification.body;\r\n }\r\n\r\n selectNotification() {\r\n const notification = this.data.notification;\r\n const c = JSON.parse(notification.data['coords']);\r\n const r = JSON.parse(notification.data['radius']);\r\n this.router.navigate([ResourcesRoutes.ACTIVEWILDFIREMAP], {\r\n queryParams: {\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: notification.data['messageID'],\r\n featureType: notification.data['topicKey'],\r\n identify: true,\r\n notification: true,\r\n time: Date.now(),\r\n },\r\n });\r\n this.snackBarRef.dismiss();\r\n }\r\n}\r\n",
+ "properties": [
+ {
+ "name": "body",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 11
+ },
+ {
+ "name": "title",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 10
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "NotificationRsrc",
+ "id": "interface-NotificationRsrc-202e8b4af361065a5c9ff67e569650ac69ed946c07e7a48a5068feaedf798ecfd0374c037fcab52c70869343bbe242a22ac75f2d29027ce50db28f62b14d5fa9",
+ "file": "src/app/services/notification.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { CapacitorService } from '@app/services/capacitor-service';\r\nimport { CommonUtilityService } from '@app/services/common-utility.service';\r\nimport { CapacitorHttp } from '@capacitor/core';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface NotificationSettingRsrc {\r\n deviceType: string;\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n notifications: NotificationRsrc[];\r\n}\r\n\r\nexport interface NotificationRsrc {\r\n notificationName: string;\r\n notificationType: string;\r\n radius: number;\r\n point: VmGeometry;\r\n topics: string[];\r\n activeIndicator: boolean;\r\n}\r\n\r\nexport interface VmGeometry {\r\n type: string;\r\n coordinates: number[];\r\n crs: string;\r\n}\r\n\r\nexport interface VmNotificationPreferences {\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n deviceType: string;\r\n notificationDetails: VmNotificationDetail[];\r\n}\r\n\r\nexport interface VmNotificationDetail {\r\n name: string;\r\n type: string;\r\n radius: number;\r\n preferences: string[];\r\n locationCoords: VmCoordinates;\r\n active: boolean;\r\n mapConfig?: Promise;\r\n}\r\n\r\nexport interface VmCoordinates {\r\n long: number;\r\n lat: number;\r\n}\r\n\r\nexport interface BoundingBox {\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class NotificationService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private httpClient: HttpClient,\r\n private capacitorService: CapacitorService,\r\n private commonUtilityService: CommonUtilityService,\r\n ) {}\r\n\r\n public updateUserNotificationPreferences(\r\n notificationSettings,\r\n savedNotification,\r\n ): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n console.log('device properties:\\'', p);\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n const token = this.capacitorService.getNotificationToken();\r\n const notificationSettingRsrc =\r\n convertToNotificationSettingRsrc(notificationSettings);\r\n notificationSettingRsrc.subscriberGuid = p.deviceId;\r\n notificationSettingRsrc.notificationToken = token;\r\n notificationSettingRsrc.deviceType = p.isAndroidPlatform\r\n ? 'android'\r\n : 'ios';\r\n if (savedNotification.length) {\r\n savedNotification.forEach((notification) => {\r\n notificationSettingRsrc.notifications.push(notification);\r\n });\r\n }\r\n const notificationSettingsJSON: string = JSON.stringify(notificationSettingRsrc);\r\n if (this.commonUtilityService.hasSQLKeywords(notificationSettingsJSON)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n\r\n return this.httpClient\r\n .put(url, notificationSettingRsrc, { headers })\r\n .toPromise();\r\n });\r\n }\r\n\r\n public getUserNotificationPreferences(): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p?.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n return this.httpClient.get(url, { headers }).toPromise();\r\n });\r\n }\r\n\r\n public getFireCentreByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.DRP_MOF_FIRE_CENTRES_SP&outputformat=application/json&cql_filter=INTERSECTS(GEOMETRY,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n\r\n public getDangerRatingByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LAND_AND_NATURAL_RESOURCE.PROT_DANGER_RATING_SP&outputformat=application/json&cql_filter=INTERSECTS(SHAPE,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport function convertToNotificationSettingRsrc(\r\n np: any,\r\n): NotificationSettingRsrc {\r\n const notificationTopics = [];\r\n if (np?.pushNotificationsFireBans) {\r\n notificationTopics.push('British_Columbia_Bans_and_Prohibition_Areas');\r\n notificationTopics.push('British_Columbia_Area_Restrictions');\r\n }\r\n if (np?.pushNotificationsWildfires) {\r\n notificationTopics.push('BCWS_ActiveFires_PublicView');\r\n notificationTopics.push('Evacuation_Orders_and_Alerts');\r\n }\r\n return {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notificationSettings',\r\n notifications: np\r\n ? [\r\n {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notification',\r\n notificationName: np.notificationName,\r\n notificationType: 'nearme',\r\n radius: np.radius,\r\n point: {\r\n type: 'Point',\r\n coordinates: [np.longitude, np.latitude],\r\n crs: null,\r\n },\r\n activeIndicator: true,\r\n topics: notificationTopics,\r\n },\r\n ]\r\n : [],\r\n notificationToken: null,\r\n subscriberToken: 'subscriberTpken',\r\n subscriberGuid: null,\r\n deviceType: null,\r\n } as unknown as NotificationSettingRsrc;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "activeIndicator",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 22
+ },
+ {
+ "name": "notificationName",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 17
+ },
+ {
+ "name": "notificationType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 18
+ },
+ {
+ "name": "point",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "VmGeometry",
+ "optional": false,
+ "description": "",
+ "line": 20
+ },
+ {
+ "name": "radius",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 19
+ },
+ {
+ "name": "topics",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": false,
+ "description": "",
+ "line": 21
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "NotificationSettingRsrc",
+ "id": "interface-NotificationSettingRsrc-202e8b4af361065a5c9ff67e569650ac69ed946c07e7a48a5068feaedf798ecfd0374c037fcab52c70869343bbe242a22ac75f2d29027ce50db28f62b14d5fa9",
+ "file": "src/app/services/notification.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { CapacitorService } from '@app/services/capacitor-service';\r\nimport { CommonUtilityService } from '@app/services/common-utility.service';\r\nimport { CapacitorHttp } from '@capacitor/core';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface NotificationSettingRsrc {\r\n deviceType: string;\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n notifications: NotificationRsrc[];\r\n}\r\n\r\nexport interface NotificationRsrc {\r\n notificationName: string;\r\n notificationType: string;\r\n radius: number;\r\n point: VmGeometry;\r\n topics: string[];\r\n activeIndicator: boolean;\r\n}\r\n\r\nexport interface VmGeometry {\r\n type: string;\r\n coordinates: number[];\r\n crs: string;\r\n}\r\n\r\nexport interface VmNotificationPreferences {\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n deviceType: string;\r\n notificationDetails: VmNotificationDetail[];\r\n}\r\n\r\nexport interface VmNotificationDetail {\r\n name: string;\r\n type: string;\r\n radius: number;\r\n preferences: string[];\r\n locationCoords: VmCoordinates;\r\n active: boolean;\r\n mapConfig?: Promise;\r\n}\r\n\r\nexport interface VmCoordinates {\r\n long: number;\r\n lat: number;\r\n}\r\n\r\nexport interface BoundingBox {\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class NotificationService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private httpClient: HttpClient,\r\n private capacitorService: CapacitorService,\r\n private commonUtilityService: CommonUtilityService,\r\n ) {}\r\n\r\n public updateUserNotificationPreferences(\r\n notificationSettings,\r\n savedNotification,\r\n ): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n console.log('device properties:\\'', p);\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n const token = this.capacitorService.getNotificationToken();\r\n const notificationSettingRsrc =\r\n convertToNotificationSettingRsrc(notificationSettings);\r\n notificationSettingRsrc.subscriberGuid = p.deviceId;\r\n notificationSettingRsrc.notificationToken = token;\r\n notificationSettingRsrc.deviceType = p.isAndroidPlatform\r\n ? 'android'\r\n : 'ios';\r\n if (savedNotification.length) {\r\n savedNotification.forEach((notification) => {\r\n notificationSettingRsrc.notifications.push(notification);\r\n });\r\n }\r\n const notificationSettingsJSON: string = JSON.stringify(notificationSettingRsrc);\r\n if (this.commonUtilityService.hasSQLKeywords(notificationSettingsJSON)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n\r\n return this.httpClient\r\n .put(url, notificationSettingRsrc, { headers })\r\n .toPromise();\r\n });\r\n }\r\n\r\n public getUserNotificationPreferences(): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p?.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n return this.httpClient.get(url, { headers }).toPromise();\r\n });\r\n }\r\n\r\n public getFireCentreByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.DRP_MOF_FIRE_CENTRES_SP&outputformat=application/json&cql_filter=INTERSECTS(GEOMETRY,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n\r\n public getDangerRatingByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LAND_AND_NATURAL_RESOURCE.PROT_DANGER_RATING_SP&outputformat=application/json&cql_filter=INTERSECTS(SHAPE,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport function convertToNotificationSettingRsrc(\r\n np: any,\r\n): NotificationSettingRsrc {\r\n const notificationTopics = [];\r\n if (np?.pushNotificationsFireBans) {\r\n notificationTopics.push('British_Columbia_Bans_and_Prohibition_Areas');\r\n notificationTopics.push('British_Columbia_Area_Restrictions');\r\n }\r\n if (np?.pushNotificationsWildfires) {\r\n notificationTopics.push('BCWS_ActiveFires_PublicView');\r\n notificationTopics.push('Evacuation_Orders_and_Alerts');\r\n }\r\n return {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notificationSettings',\r\n notifications: np\r\n ? [\r\n {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notification',\r\n notificationName: np.notificationName,\r\n notificationType: 'nearme',\r\n radius: np.radius,\r\n point: {\r\n type: 'Point',\r\n coordinates: [np.longitude, np.latitude],\r\n crs: null,\r\n },\r\n activeIndicator: true,\r\n topics: notificationTopics,\r\n },\r\n ]\r\n : [],\r\n notificationToken: null,\r\n subscriberToken: 'subscriberTpken',\r\n subscriberGuid: null,\r\n deviceType: null,\r\n } as unknown as NotificationSettingRsrc;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "deviceType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 9
+ },
+ {
+ "name": "notifications",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "NotificationRsrc[]",
+ "optional": false,
+ "description": "",
+ "line": 13
+ },
+ {
+ "name": "notificationToken",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 12
+ },
+ {
+ "name": "subscriberGuid",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 10
+ },
+ {
+ "name": "subscriberToken",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 11
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "NumberFormat",
+ "id": "interface-NumberFormat-bfb9da0dead5a03632178390d94ad64ce30286befe5cec4e76d7b543b0d407a9105863899da783db54814fcab23c79acb2bcbbec360f6dc1bdf73fba58b2a40c",
+ "file": "src/app/services/wfnews-map.service/util.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SpatialUtilsService } from '@wf1/core-ui';\r\n\r\nexport type LonLat = [number, number];\r\nexport type LatLon = [number, number];\r\n\r\nexport const toPoint = (lonLat: LonLat): any => window['turf'].point(lonLat);\r\n\r\nexport const toLatLon = (lonLat: LonLat): LatLon => [lonLat[1], lonLat[0]];\r\n\r\nexport const encodeUrl = (\r\n url: string,\r\n data: { [key: string]: string | number | boolean },\r\n): string => {\r\n if (!data) {\r\n return url;\r\n }\r\n\r\n const params = Object.keys(data)\r\n .filter((k) => data[k])\r\n .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(data[k])}`)\r\n .join('&');\r\n\r\n if (/[?]\\S+$/.test(url)) {\r\n return `${url}&${params}`;\r\n }\r\n\r\n if (/[?]$/.test(url)) {\r\n return `${url}${params}`;\r\n }\r\n\r\n return `${url}?${params}`;\r\n};\r\n\r\nexport const fetchJsonP = (\r\n url: string,\r\n data: { [key: string]: string | number | boolean },\r\n opt = { timeout: 10000 },\r\n): { response: Promise; abort: () => void } => {\r\n data['_'] = Math.round(Math.random() * 1e10);\r\n\r\n const cbfn = `callback_${data['_']}`;\r\n data.callback = cbfn;\r\n\r\n let id;\r\n let cancel;\r\n const req = encodeUrl(url, data);\r\n const promise = new Promise((res, rej) => {\r\n const cleanup = () => {\r\n if (id) {\r\n clearTimeout(id);\r\n }\r\n id = null;\r\n\r\n if (script.parentNode) {\r\n script.parentNode.removeChild(script);\r\n }\r\n\r\n window[cbfn] = null;\r\n };\r\n\r\n window[cbfn] = (payload) => {\r\n cleanup();\r\n res(payload);\r\n };\r\n\r\n cancel = () => {\r\n cleanup();\r\n rej(new Error('cancelled'));\r\n };\r\n const script = window['L'].DomUtil.create('script');\r\n script.type = 'text/javascript';\r\n script.async = true;\r\n script.src = req;\r\n\r\n document.getElementsByTagName('head')[0].appendChild(script);\r\n });\r\n\r\n if (opt.timeout) {\r\n id = setTimeout(cancel, opt.timeout);\r\n }\r\n\r\n return {\r\n response: promise,\r\n abort: cancel,\r\n };\r\n};\r\n\r\n// distance in km\r\nexport const distance = (loc1: LonLat, loc2: LonLat): number => window['turf'].distance(toPoint(loc1), toPoint(loc2));\r\n\r\nexport const formatDistance = (dist: number, unit: string): string => {\r\n if (dist == null) {\r\n return 'n/a';\r\n }\r\n if (dist < 10) {\r\n return dist.toFixed(1) + ' ' + unit;\r\n }\r\n return dist.toFixed(0) + ' ' + unit;\r\n};\r\n\r\nconst DIRECTION = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];\r\n\r\nexport const direction = (start: LonLat, end: LonLat): string => {\r\n const bearing = window['turf'].bearing(toPoint(start), toPoint(end));\r\n return DIRECTION[Math.floor((bearing + 382.5) / 45) % 8];\r\n};\r\n\r\nconst TIME_FORMAT = Intl.DateTimeFormat('en-CA', {\r\n timeZone: undefined,\r\n hour12: false,\r\n year: 'numeric',\r\n month: 'numeric',\r\n day: 'numeric',\r\n hour: 'numeric',\r\n minute: 'numeric',\r\n second: 'numeric',\r\n timeZoneName: 'short',\r\n});\r\nconst DATE_FORMAT = Intl.DateTimeFormat('en-CA', {\r\n timeZone: undefined,\r\n hour12: false,\r\n year: 'numeric',\r\n month: 'numeric',\r\n day: 'numeric',\r\n});\r\nconst CAD_FORMAT = Intl.NumberFormat('en-CA', {\r\n style: 'currency',\r\n currency: 'CAD',\r\n});\r\n\r\nexport interface NumberFormat {\r\n precision: number;\r\n fractionPlaces: number;\r\n}\r\nexport interface UnitWithFormat {\r\n unit: string;\r\n format: NumberFormat;\r\n}\r\n\r\nexport class Translate {\r\n constructor(private spatialUtils: SpatialUtilsService) {}\r\n\r\n parseCoordinate(val: string): LonLat {\r\n const c = this.spatialUtils.parseCoordinates(val);\r\n if (!c) {\r\n return;\r\n }\r\n return c as LonLat;\r\n }\r\n\r\n parseSexagesimal(val: string): number {\r\n if (typeof val == 'number') {\r\n return val;\r\n } else if (/^-?\\d*(\\.\\d*)?$/.test(val)) {\r\n return 0.0 + parseFloat(val);\r\n } else {\r\n let result = 0;\r\n let divisor = 1;\r\n let sign = 1;\r\n if (/[NSEWnsew]$/.test(val)) {\r\n sign = /[SWsw]$/.test(val) ? -1 : 1;\r\n val = val.replace(/[NSEWnsew]$/, '');\r\n }\r\n val.split(/[°DMSdms'\"\\s]+/).forEach((part) => {\r\n const partVal = parseFloat(part);\r\n if (!isNaN(partVal)) {\r\n result += partVal / divisor;\r\n }\r\n divisor *= 60;\r\n });\r\n\r\n return result * sign;\r\n }\r\n }\r\n\r\n formatCoordinate(lonLat: LonLat): string {\r\n if (!lonLat[0] || !lonLat[1]) {\r\n return '';\r\n }\r\n return this.spatialUtils.formatCoordinates(lonLat);\r\n }\r\n\r\n formatLatLon(lat, lon): string {\r\n if (!lat || !lon) {\r\n return '';\r\n }\r\n return this.formatCoordinate([lon, lat]);\r\n }\r\n\r\n parseYyyyMmDd(val): Date {\r\n if (!val) {\r\n return;\r\n }\r\n const s = '' + val;\r\n return new Date(\r\n `${s.substring(0, 4)}-${s.substring(4, 6)}-${s.substring(6, 8)}`,\r\n );\r\n }\r\n parseIsoDateTime(val): Date {\r\n if (!val) {\r\n return;\r\n }\r\n return new Date(val);\r\n }\r\n\r\n parseMilliseconds(val): Date {\r\n if (val == null) {\r\n return;\r\n }\r\n return new Date(1 * val);\r\n }\r\n parseEUDate(val?): Date {\r\n // Fix European style dd/mm/yyyy dates.\r\n if (!val) {\r\n return val;\r\n }\r\n const date = new Date(\r\n val.replace(\r\n /(\\d\\d)\\/(\\d\\d)\\/(\\d\\d\\d\\d)/,\r\n (m, day, month, year) => `${year}-${month}-${day}`,\r\n ),\r\n );\r\n if (isNaN(date.getTime())) {\r\n return null;\r\n }\r\n return date;\r\n }\r\n formatLocalDate(val: Date): string {\r\n if (!val) {\r\n return '';\r\n }\r\n return DATE_FORMAT.format(val);\r\n // return val && new Date( val ).toLocaleDateString()\r\n }\r\n\r\n formatLocalTime(val: Date): string {\r\n if (!val) {\r\n return '';\r\n }\r\n return TIME_FORMAT.format(val);\r\n // return val && new Date( val ).toLocaleDateString()\r\n }\r\n\r\n formatNumber(val: number, numberFormat?: NumberFormat): string {\r\n if (val == null) {\r\n return '';\r\n }\r\n\r\n numberFormat = { precision: 3, fractionPlaces: 1, ...numberFormat };\r\n\r\n const rounded = parseFloat(val.toPrecision(numberFormat.precision));\r\n if (!numberFormat.fractionPlaces) {\r\n return rounded.toLocaleString();\r\n }\r\n\r\n const a = Math.abs(rounded);\r\n const s = Math.sign(rounded);\r\n const i = Math.floor(a);\r\n const f = a - i;\r\n return (\r\n (s * i).toLocaleString() +\r\n f.toFixed(numberFormat.fractionPlaces).substr(1)\r\n );\r\n }\r\n\r\n formatUnit(val: number, unit: string, numberFormat?: NumberFormat): string {\r\n if (val == null) {\r\n return '';\r\n }\r\n return `${this.formatNumber(\r\n val,\r\n numberFormat,\r\n )}\\u202F${unit}`;\r\n }\r\n\r\n formatAndConvertUnit(\r\n val: number,\r\n unit: string,\r\n outputUnit: string | UnitWithFormat,\r\n ) {\r\n if (typeof outputUnit === 'object') {\r\n this.formatUnit(\r\n this.convertUnit(val, unit, outputUnit.unit),\r\n outputUnit.unit,\r\n );\r\n } else {\r\n this.formatUnit(this.convertUnit(val, unit, outputUnit), outputUnit);\r\n }\r\n }\r\n\r\n formatCAD(value?: number): string | null | undefined {\r\n if (value === null || value === undefined) {\r\n return value as null | undefined;\r\n } else {\r\n return CAD_FORMAT.format(value);\r\n }\r\n }\r\n\r\n formatAngle(\r\n val?: number,\r\n numberFormat?: NumberFormat,\r\n ): string | undefined | null {\r\n if (val) {\r\n return `${this.formatNumber(\r\n val,\r\n numberFormat,\r\n )}°`;\r\n } else {\r\n return val as undefined | null;\r\n }\r\n }\r\n\r\n /**\r\n * Converts and formats a value as two different units, the second in parentheses.\r\n */\r\n formatMultipleUnits(\r\n val: number,\r\n unit: string,\r\n standardUnit: string | UnitWithFormat,\r\n otherUnit: string | UnitWithFormat,\r\n ): string {\r\n if (val == null) {\r\n return '';\r\n }\r\n return `${this.formatAndConvertUnit(\r\n val,\r\n unit,\r\n standardUnit,\r\n )} (${this.formatAndConvertUnit(\r\n val,\r\n unit,\r\n otherUnit,\r\n )})`;\r\n }\r\n\r\n convertUnit(val: number, unitFrom: string, unitTo: string = 'm'): number {\r\n if (val == null) {\r\n return;\r\n }\r\n if (!(unitFrom in metersPerUnit)) {\r\n throw Error(`unitFrom \"${unitFrom}\" isn't defined`);\r\n }\r\n if (!(unitTo in metersPerUnit)) {\r\n throw Error(`unitTo \"${unitTo}\" isn't defined`);\r\n }\r\n\r\n const valInMeters = val * metersPerUnit[unitFrom];\r\n return valInMeters / metersPerUnit[unitTo];\r\n }\r\n\r\n formatFireZone(zoneName: string): string {\r\n if (!zoneName) {\r\n return;\r\n }\r\n\r\n const result = zoneName.match(\r\n /^(.+?) (?:Fire )?Zone(?: [(](.+?)[)])?(?: - (\\w\\d))?$/,\r\n );\r\n if (!result) {\r\n return zoneName;\r\n }\r\n\r\n if (result[2]) {\r\n return `${result[1]} (${result[2]})`;\r\n }\r\n return result[1];\r\n }\r\n\r\n formatFireCentre(centreName: string): string {\r\n if (!centreName) {\r\n return;\r\n }\r\n\r\n const result = centreName.match(/^(.+?) (?:Fire )?(?:Centre|Center)$/);\r\n if (!result) {\r\n return centreName;\r\n }\r\n\r\n return result[1];\r\n }\r\n\r\n formatIndicator(\r\n value: boolean | null,\r\n tString = '✔️ Yes',\r\n fString = '❌ No',\r\n nString = '❓ Unknown',\r\n ): string {\r\n if (value === undefined || value === null) {\r\n return nString;\r\n } else if (value) {\r\n return tString;\r\n } else {\r\n return fString;\r\n }\r\n }\r\n\r\n parseIndicator(indString: string, flip = false): boolean | null {\r\n if (indString === 'Y') {\r\n return !flip;\r\n } else if (indString === 'N') {\r\n return flip;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n formatPhoneHtml(phoneNumber: string): string {\r\n if (phoneNumber) {\r\n return `${phoneNumber}`;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n formatEmailHtml(emailAddress: string): string {\r\n if (emailAddress) {\r\n return `${emailAddress}`;\r\n } else {\r\n return null;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * This uses the ‘haversine’ formula to calculate the great-circle distance between two points \r\n * – that is, the shortest distance over the earth’s surface – giving an ‘as-the-crow-flies’ distance between the points.\r\n * a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)\r\n * c = 2 ⋅ atan2( √a, √(1−a) )\r\n * d = R ⋅ c\r\n * Where\tφ is latitude, λ is longitude, R is earth’s radius (mean radius = 6,371km). \r\n * note that angles need to be in radians to pass to trig functions\r\n * @param lat1 Latitude of the location\r\n * @param lat2 Latitude of the destination\r\n * @param lon1 Longitude of the location\r\n * @param lon2 Longitude of the destination\r\n * @returns\r\n */\r\nexport const haversineDistance = (lat1, lat2, lon1, lon2) => {\r\n const R = 6371e3; // metres\r\n const φ1 = (lat1 * Math.PI) / 180; // φ, λ in radians\r\n const φ2 = (lat2 * Math.PI) / 180;\r\n const Δφ = ((lat2 - lat1) * Math.PI) / 180;\r\n const Δλ = ((lon2 - lon1) * Math.PI) / 180;\r\n\r\n const a =\r\n Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +\r\n Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);\r\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\r\n\r\n const d = R * c; // in metres\r\n return d;\r\n};\r\n\r\nconst metersPerUnit = {\r\n Mil: 2.5399999999999996e-8,\r\n MicroInch: 0.0000254,\r\n mm: 0.001,\r\n Millimeter: 0.001,\r\n cm: 0.01,\r\n Centimeter: 0.01,\r\n IInch: 0.0254,\r\n 'us-in': 0.0254000508001016,\r\n Inch: 0.0254000508001016,\r\n in: 0.0254000508001016,\r\n inches: 0.0254000508001016,\r\n Decimeter: 0.1,\r\n ClarkeLink: 0.201166194976,\r\n SearsLink: 0.2011676512155,\r\n BenoitLink: 0.20116782494375873,\r\n IntnlLink: 0.201168,\r\n link: 0.201168,\r\n GunterLink: 0.2011684023368047,\r\n CapeFoot: 0.3047972615,\r\n ClarkeFoot: 0.3047972651151,\r\n 'ind-ft': 0.30479841,\r\n IndianFt37: 0.30479841,\r\n SearsFoot: 0.30479947153867626,\r\n IndianFt75: 0.3047995,\r\n IndianFoot: 0.30479951,\r\n IndianFt62: 0.3047996,\r\n GoldCoastFoot: 0.3047997101815088,\r\n IFoot: 0.3048,\r\n Foot: 0.3048006096012192,\r\n ft: 0.3048006096012192,\r\n 'us-ft': 0.3048006096012192,\r\n ModAmFt: 0.304812252984506,\r\n 'ind-yd': 0.9143952300000001,\r\n IndianYd37: 0.9143952300000001,\r\n SearsYard: 0.914398414616029,\r\n IndianYd75: 0.9143985000000001,\r\n IndianYard: 0.9143985307444409,\r\n IndianYd62: 0.9143987999999998,\r\n IYard: 0.9143999999999999,\r\n Yard: 0.9144018288036576,\r\n yd: 0.9144018288036576,\r\n 'us-yd': 0.9144018288036576,\r\n CaGrid: 0.9997380000000001,\r\n m: 1,\r\n Meter: 1,\r\n GermanMeter: 1.0000135965,\r\n fath: 1.8287999999999998,\r\n Fathom: 1.8287999999999998,\r\n Rood: 3.7782668980000005,\r\n Perch: 5.02921005842012,\r\n Rod: 5.02921005842012,\r\n Pole: 5.02921005842012,\r\n Dekameter: 10,\r\n Decameter: 10,\r\n ClarkeChain: 20.1166194976,\r\n 'ind-ch': 20.11669506,\r\n SearsChain: 20.11676512155,\r\n BenoitChain: 20.116782494375872,\r\n IntnlChain: 20.1168,\r\n ch: 20.1168,\r\n 'us-ch': 20.11684023368047,\r\n GunterChain: 20.11684023368047,\r\n dm: 100,\r\n Hectometer: 100,\r\n Furlong: 201.1684023368046,\r\n Brealey: 375,\r\n km: 1000,\r\n Kilometer: 1000,\r\n IMile: 1609.344,\r\n Mile: 1609.3472186944373,\r\n mi: 1609.3472186944373,\r\n 'us-mi': 1609.3472186944373,\r\n kmi: 1851.9999999999998,\r\n nmi: 1851.9999999999998,\r\n NautM: 1852.0000000000002,\r\n 'NautM-UK': 1853.1840000000002,\r\n '50kilometers': 50000,\r\n 'Lat-66': 110943.31648893275,\r\n 'Lat-83': 110946.25736872235,\r\n dd: 111118.97383794768,\r\n degrees: 111118.97383794768,\r\n '150kilometers': 150000,\r\n};\r\n",
+ "properties": [
+ {
+ "name": "fractionPlaces",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 134
+ },
+ {
+ "name": "precision",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 133
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "PagedCollection",
+ "id": "interface-PagedCollection-578a59039ac4654484d8e4be5fbd449d901a2d6cb9e741f267e162564117f8a272fcd258bbfc777cf74459f717c323464cbe9fd25dca73541ef16adf9822a5a4",
+ "file": "src/app/conversion/models.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface PagedCollection {\r\n pageNumber?: number;\r\n pageRowCount?: number;\r\n totalRowCount?: number;\r\n totalPageCount?: number;\r\n collection?: Array;\r\n}\r\n\r\nexport interface fireCentreOption {\r\n code?: string;\r\n fireCentreName?: string;\r\n}\r\n\r\nexport interface EvacOrderOption {\r\n eventName?: string;\r\n eventType?: string;\r\n orderAlertStatus?: string;\r\n issuingAgency?: string;\r\n preOcCode?: string;\r\n emrgOAAsysID?: number;\r\n centroid?: any;\r\n geometry?: any;\r\n dateModified?: Date;\r\n noticeType?: string;\r\n uri?: string;\r\n issuedOn?: string;\r\n externalUri?: boolean;\r\n eventNumber?: string;\r\n}\r\n\r\nexport interface AreaRestrictionsOption {\r\n protRsSysID?: number;\r\n name?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n noticeType?: string;\r\n}\r\n\r\nexport interface BansAndProhibitionsOption {\r\n protBsSysID?: number;\r\n type?: string;\r\n accessStatusEffectiveDate?: Date;\r\n fireCentre?: string;\r\n fireZone?: string;\r\n bulletinUrl?: string;\r\n centroid?: any;\r\n geometry?: any;\r\n accessProhibitionDescription?: string;\r\n noticeType?: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "collection",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Array",
+ "optional": true,
+ "description": "",
+ "line": 6
+ },
+ {
+ "name": "pageNumber",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 2
+ },
+ {
+ "name": "pageRowCount",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 3
+ },
+ {
+ "name": "totalPageCount",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 5
+ },
+ {
+ "name": "totalRowCount",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 4
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "PagingInfoRequest",
+ "id": "interface-PagingInfoRequest-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "pageNumber",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 9
+ },
+ {
+ "name": "pageRowCount",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 10
+ },
+ {
+ "name": "query",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 8
+ },
+ {
+ "name": "sortColumn",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 11
+ },
+ {
+ "name": "sortDirection",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 12
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "PagingSearchState",
+ "id": "interface-PagingSearchState-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "pageIndex",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 4
+ },
+ {
+ "name": "pageSize",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 5
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "SearchState"
+ ]
+ },
+ {
+ "name": "Position",
+ "id": "interface-Position-d8cb1d18422d250f08384df5fb2272408deadabdf142b0e8e533061fc252ade67243883d97c3593a89d8e2fe8e06ccc7606abc0ddfc637f2b10a34c331048a03",
+ "file": "src/app/services/common-utility.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { NumberFormatStyle } from '@angular/common';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Injectable, Injector } from '@angular/core';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\nimport { App } from '@capacitor/app';\r\nimport { Geolocation } from '@capacitor/geolocation';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\nimport { Observable } from 'rxjs';\r\nimport { ReportOfFireService } from './report-of-fire-service';\r\nimport { LocalStorageService } from './local-storage-service';\r\n\r\nconst MAX_CACHE_AGE = 30 * 1000;\r\n\r\nexport interface Coordinates {\r\n readonly accuracy: number;\r\n readonly altitude: number | null;\r\n readonly altitudeAccuracy: number | null;\r\n readonly heading: number | null;\r\n readonly latitude: number;\r\n readonly longitude: number;\r\n readonly speed: number | null;\r\n}\r\n\r\nexport interface Position {\r\n readonly coords: Coordinates;\r\n readonly timestamp: NumberFormatStyle;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CommonUtilityService {\r\n private myLocation;\r\n private locationTime;\r\n private location;\r\n private rofService;\r\n\r\n constructor(\r\n protected snackbarService: MatSnackBar,\r\n private http: HttpClient,\r\n private appConfigService: AppConfigService,\r\n private injector: Injector,\r\n private storageService: LocalStorageService\r\n ) {\r\n setTimeout(() => (this.rofService = injector.get(ReportOfFireService)));\r\n }\r\n\r\n getCurrentLocationPromise(): Promise {\r\n const self = this;\r\n const now = Date.now();\r\n if (this.locationTime && now - this.locationTime < MAX_CACHE_AGE) {\r\n return this.location;\r\n }\r\n\r\n this.locationTime = now;\r\n this.location = Geolocation.getCurrentPosition();\r\n return this.location;\r\n }\r\n\r\n getCurrentLocation(callback?: (p: Position) => void) {\r\n if (navigator && navigator.geolocation) {\r\n return Geolocation.getCurrentPosition().then(\r\n (position) => {\r\n this.myLocation = position ? position.coords : undefined;\r\n if (callback) {\r\n callback(position);\r\n }\r\n return position ? position.coords : undefined;\r\n },\r\n (error) => {\r\n this.snackbarService.open(\r\n 'Unable to retrieve the current location.',\r\n '',\r\n {\r\n duration: 5,\r\n },\r\n );\r\n },\r\n );\r\n } else {\r\n console.warn('Unable to access geolocation');\r\n this.snackbarService.open('Unable to access location services.', '', {\r\n duration: 5,\r\n });\r\n }\r\n }\r\n\r\n preloadGeolocation() {\r\n Geolocation.getCurrentPosition().then(\r\n (position) => {\r\n this.myLocation = position.coords;\r\n },\r\n (error) => {\r\n this.snackbarService.open(\r\n 'Unable to retrieve the current location',\r\n 'Cancel',\r\n {\r\n duration: 5000,\r\n },\r\n );\r\n },\r\n );\r\n }\r\n\r\n sortAddressList(results: any, value: string) {\r\n let address = null;\r\n let trimmedAddress = null;\r\n let valueLength = null;\r\n let valueMatch = null;\r\n results.forEach((result) => {\r\n address = this.getFullAddress(result);\r\n result.address = address.trim();\r\n trimmedAddress = result.address;\r\n valueLength = value.length;\r\n if (trimmedAddress != null) {\r\nvalueMatch = trimmedAddress.substring(0, valueLength);\r\n}\r\n\r\n if (\r\n address != null &&\r\n valueLength != null &&\r\n valueMatch != null &&\r\n (value.toUpperCase() === address.toUpperCase() ||\r\n value.toUpperCase() === valueMatch.toUpperCase())\r\n ) {\r\n const index = results.indexOf(result);\r\n if (index !== -1) {\r\n results.splice(index, 1);\r\n }\r\n const resultToBeUnshifted = result;\r\n\r\n results.unshift(resultToBeUnshifted);\r\n }\r\n });\r\n\r\n return results;\r\n }\r\n\r\n getFullAddress(location) {\r\n let result = '';\r\n\r\n if (location.civicNumber) {\r\n result += location.civicNumber;\r\n }\r\n\r\n if (location.streetName) {\r\n result += ' ' + location.streetName;\r\n }\r\n\r\n if (location.streetQualifier) {\r\n result += ' ' + location.streetQualifier;\r\n }\r\n\r\n if (location.streetType) {\r\n result += ' ' + location.streetType;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n isIPhone(): boolean {\r\n const userAgent = window.navigator.userAgent.toLowerCase();\r\n return /iphone/.test(userAgent);\r\n }\r\n\r\n countdown(timeoutDuration) {\r\n const promise = new Promise((resolve) => {\r\n setTimeout(() => resolve(false), timeoutDuration);\r\n });\r\n return promise;\r\n }\r\n\r\n checkLocation() {\r\n const promise = new Promise((resolve) => {\r\n Geolocation.getCurrentPosition().then(\r\n (position) => {\r\n resolve(true)\r\n },\r\n (error) => {\r\n resolve(false)\r\n },\r\n );\r\n })\r\n\r\n return promise;\r\n }\r\n\r\n async checkLocationServiceStatus(): Promise {\r\n const timeoutDuration = 5000; // 5 seconds limit\r\n \r\n const locationPromise = await this.checkLocation()\r\n const timeoutPromise = this.countdown(timeoutDuration)\r\n\r\n return Promise.race([timeoutPromise, locationPromise]);\r\n }\r\n\r\n pingService(): Observable {\r\n const url = this.appConfigService.getConfig().rest['wfnews'];\r\n return this.http.get(url);\r\n }\r\n\r\n calculateBearing(\r\n lat1: number,\r\n lon1: number,\r\n lat2: number,\r\n lon2: number,\r\n ): number {\r\n const dLon = this.deg2rad(lon2 - lon1);\r\n const x = Math.sin(dLon) * Math.cos(this.deg2rad(lat2));\r\n const y =\r\n Math.cos(this.deg2rad(lat1)) * Math.sin(this.deg2rad(lat2)) -\r\n Math.sin(this.deg2rad(lat1)) *\r\n Math.cos(this.deg2rad(lat2)) *\r\n Math.cos(dLon);\r\n const bearing = Math.atan2(x, y);\r\n const bearingDegrees = this.rad2deg(bearing);\r\n return (bearingDegrees + 360) % 360;\r\n }\r\n\r\n formatDDM(decimal: number) {\r\n decimal = Math.abs(decimal);\r\n const d = Math.abs(Math.trunc(decimal));\r\n return d + '° ' + (60 * (decimal - d)).toFixed(3) + '\\'';\r\n }\r\n\r\n async checkOnlineStatus(): Promise {\r\n try {\r\n await this.pingService().toPromise();\r\n return true;\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async removeInvalidOfflineRoF() {\r\n try {\r\n // Fetch locally stored data\r\n const offlineReportSaved = this.storageService.getData('offlineReportData');\r\n if (offlineReportSaved) {\r\n const offlineReport = JSON.parse(offlineReportSaved);\r\n\r\n if (offlineReport.resource) {\r\n const resource = JSON.parse(offlineReport.resource);\r\n // Remove the locally stored data if it was submitted more than 24 hours ago\r\n if (\r\n resource.submittedTimestamp &&\r\n this.invalidTimestamp(resource.submittedTimestamp)\r\n ) {\r\n this.storageService.removeData('offlineReportData');\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Error removing invalid RoF data:', error);\r\n }\r\n }\r\n\r\n invalidTimestamp(timestamp: string): boolean {\r\n // check if submitted timestamp is more than 24 hours ago\r\n const now = new Date().getTime();\r\n const submittedTimestamp = Number(timestamp);\r\n const oneDay = 24 * 60 * 60 * 1000;\r\n return now - submittedTimestamp > oneDay;\r\n }\r\n\r\n private deg2rad(deg: number): number {\r\n return deg * (Math.PI / 180);\r\n }\r\n private rad2deg(rad: number): number {\r\n return rad * (180 / Math.PI);\r\n }\r\n\r\n async checkOnline() {\r\n try {\r\n await this.pingService().toPromise();\r\n return true;\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n isAttributePresent(array, attributeName, attributeValue) {\r\n return array.some(existingItem => existingItem.attributes[attributeName] === attributeValue);\r\n }\r\n\r\n checkIfLandscapeMode() {\r\n // also return true if this is table portrait mode wfnews-2022. \r\n if ((window.innerWidth > window.innerHeight) || (window.innerWidth <= 1024 && window.innerWidth >= 768 && window.innerHeight > window.innerWidth) ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n } \r\n\r\n \r\n hasSQLKeywords(jsonBlob) {\r\n //detect standalone sql words\r\n const sqlKeywords = /\\b(SELECT|INSERT|UPDATE|DELETE|ALTER|DROP|CREATE)\\b(?!\\s*\\*)/i;\r\n const sqlDetected = sqlKeywords.test(jsonBlob);\r\n return sqlDetected;\r\n }\r\n\r\n extractPolygonData(response) {\r\n const polygonData = [];\r\n for (const element of response) {\r\n polygonData.push(...element);\r\n }\r\n return polygonData;\r\n }\r\n\r\n createConvex(polygonData) {\r\n const turfPoints = polygonData.map(coord => window['turf'].point(coord));\r\n const pointsFeatureCollection = window['turf'].featureCollection(turfPoints);\r\n const convexHull = window['turf'].convex(pointsFeatureCollection)?.geometry?.coordinates[0];\r\n return convexHull;\r\n }\r\n\r\n getPolygonBond(polygonData) {\r\n const convex = this.createConvex(polygonData);\r\n const bounds = convex?.reduce((acc, coord) => [\r\n [Math.min(acc[0][0], coord[1]), Math.min(acc[0][1], coord[0])],\r\n [Math.max(acc[1][0], coord[1]), Math.max(acc[1][1], coord[0])]\r\n ], [[Infinity, Infinity], [-Infinity, -Infinity]]);\r\n return bounds;\r\n }\r\n\r\n getMapOptions(bounds: any, location: number[]) {\r\n return bounds\r\n ? { attributionControl: false, zoomControl: false, dragging: false, doubleClickZoom: false, boxZoom: false, trackResize: false, scrollWheelZoom: false }\r\n : { attributionControl: false, zoomControl: false, dragging: false, doubleClickZoom: false, boxZoom: false, trackResize: false, scrollWheelZoom: false, center: location, zoom: 9 };\r\n }\r\n \r\n}",
+ "properties": [
+ {
+ "name": "coords",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Coordinates",
+ "optional": false,
+ "description": "",
+ "line": 25,
+ "modifierKind": [
+ 148
+ ]
+ },
+ {
+ "name": "timestamp",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "NumberFormatStyle",
+ "optional": false,
+ "description": "",
+ "line": 26,
+ "modifierKind": [
+ 148
+ ]
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ReportOfFireNotification",
+ "id": "interface-ReportOfFireNotification-8535ce51ccdad526d840669937c2863b8c4704ebacf2e5a788764298904f6dbe7761d1eb638a976f40486932cb843e69f3a4250037faa79d75e0a3680ed65ea9",
+ "file": "src/app/services/capacitor-service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { EventEmitter, Injectable, NgZone } from '@angular/core';\r\nimport { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';\r\nimport { Router } from '@angular/router';\r\nimport { FCM } from '@capacitor-community/fcm';\r\nimport { App, AppState } from '@capacitor/app';\r\nimport { AppLauncher } from '@capacitor/app-launcher';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Device } from '@capacitor/device';\r\nimport { Geolocation, Position } from '@capacitor/geolocation';\r\nimport {\r\n PushNotificationSchema,\r\n PushNotifications,\r\n} from '@capacitor/push-notifications';\r\nimport { Store } from '@ngrx/store';\r\nimport { BehaviorSubject, fromEvent } from 'rxjs';\r\nimport { environment } from '../../environments/environment';\r\nimport { RootState } from '../store';\r\nimport { ApplicationStateService } from './application-state.service';\r\nimport { EventEmitterService } from './event-emitter.service';\r\n\r\nimport { ResourcesRoutes } from '@app/utils';\r\nimport { NotificationSnackbarComponent } from '../components/notification-snackbar/notification-snackbar.component';\r\nimport { Preferences } from '@capacitor/preferences';\r\n\r\nexport interface CompassHeading {\r\n magneticHeading?: number; //The heading in degrees from 0-359.99 at a single moment in time. (Number)\r\n trueHeading?: number; //The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. A negative value indicates that the true heading can't be determined. (Number)\r\n headingAccuracy?: number; //The deviation in degrees between the reported heading and the true heading. (Number)\r\n timestamp?: string; //The time at which this heading was determined. (DOMTimeStamp)\r\n error?: string;\r\n}\r\n\r\nexport interface LocationNotification {\r\n latitude: number;\r\n longitude: number;\r\n radius: number;\r\n featureId: string;\r\n featureType: string;\r\n fireYear?: number;\r\n}\r\n\r\nexport interface ReportOfFireNotification {\r\n title: string;\r\n body: string;\r\n}\r\n\r\nexport interface DeviceProperties {\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n isMobilePlatform: boolean;\r\n deviceId: string;\r\n isTwitterInstalled: boolean;\r\n}\r\n\r\nconst UPDATE_AFTER_INACTIVE_MILLIS = 1000 * 60; // 1 minute\r\nconst REFRESH_INTERVAL_ACTIVE_MILLIS = 5 * 1000 * 60; // 5 minutes\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CapacitorService {\r\n resume: BehaviorSubject;\r\n initialized: Promise;\r\n fbAppInstalled: boolean;\r\n twitterAppInstalled: boolean;\r\n appState: AppState;\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n deviceId: string;\r\n pnNav = null;\r\n notificationToken = null;\r\n updateMainMapLayers = new EventEmitter();\r\n currentHeadingPromise: Promise;\r\n locationNotifications = new EventEmitter();\r\n rofNotifications = new EventEmitter();\r\n inactiveStart: number;\r\n refreshTimer;\r\n locationNotificationsDelay = 5000;\r\n rofNotificationsDelay = 5000;\r\n notificationSnackbarPromise = Promise.resolve();\r\n registeredForNotifications = false;\r\n private devicePropertiesPromise: Promise;\r\n\r\n constructor(\r\n private zone: NgZone,\r\n protected router: Router,\r\n protected store: Store,\r\n protected eventEmitterService: EventEmitterService,\r\n protected stateService: ApplicationStateService,\r\n protected snackbar: MatSnackBar,\r\n ) {\r\n this.resume = new BehaviorSubject(null);\r\n fromEvent(document, 'resume').subscribe((event) => {\r\n this.zone.run(() => {\r\n this.onResume();\r\n });\r\n });\r\n\r\n this.isIOSPlatform = false;\r\n this.isAndroidPlatform = false;\r\n this.isWebPlatform = false;\r\n this.fbAppInstalled = false;\r\n this.twitterAppInstalled = false;\r\n this.deviceId = '';\r\n\r\n this.initialized = this.checkDevice().then(() => {\r\n this.init();\r\n\r\n // use for testing notification at startup\r\n // this.emitLocationNotification( {\r\n // coords: '[48.463259,-123.312635]',\r\n // radius: '20',\r\n // messageID: 'V65055',\r\n // topicKey: 'BCWS_ActiveFires_PublicView',\r\n // } )\r\n });\r\n }\r\n\r\n init() {\r\n const startRefreshTimer = () => {\r\n stopRefreshTimer();\r\n\r\n this.refreshTimer = setTimeout(() => {\r\n this.updateMainMapLayers.emit();\r\n startRefreshTimer();\r\n }, REFRESH_INTERVAL_ACTIVE_MILLIS);\r\n };\r\n\r\n const stopRefreshTimer = () => {\r\n if (!this.refreshTimer) {\r\nreturn;\r\n}\r\n\r\n clearTimeout(this.refreshTimer);\r\n this.refreshTimer = null;\r\n };\r\n\r\n startRefreshTimer();\r\n\r\n App.addListener('appStateChange', (state) => {\r\n if (state.isActive) {\r\n startRefreshTimer();\r\n\r\n if (!this.inactiveStart) {\r\nreturn;\r\n}\r\n\r\n const inactiveDuration = Date.now() - this.inactiveStart;\r\n this.inactiveStart = null;\r\n\r\n if (inactiveDuration > UPDATE_AFTER_INACTIVE_MILLIS) {\r\n this.updateMainMapLayers.emit();\r\n }\r\n } else {\r\n if (!this.inactiveStart) {\r\nthis.inactiveStart = Date.now();\r\n}\r\n\r\n stopRefreshTimer();\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n if (this.isWebPlatform) {\r\n this.notificationToken = 'FakeForWeb';\r\n return;\r\n }\r\n\r\n this.checkInstalledApps();\r\n\r\n if (this.isAndroidPlatform) {\r\n App.addListener('backButton', (state) => {\r\n this.eventEmitterService.androidBackButtonPressed();\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n // Request permission to use push notifications\r\n this.registerForNotifications()\r\n .then((registered) => {\r\n console.log('registeredForNotifications', registered);\r\n this.registeredForNotifications = registered;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // On success, we should be able to receive notifications\r\n PushNotifications.addListener('registration', (token) => {\r\n console.log('PNN REgister success ' + token.value);\r\n if (this.isAndroidPlatform) {\r\n this.notificationToken = token.value;\r\n } else if (this.isIOSPlatform) {\r\n FCM.getToken()\r\n .then((response) => {\r\n this.notificationToken = response.token;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Some issue with our setup and push will not work\r\n PushNotifications.addListener('registrationError', (error) => {\r\n console.log('PNN REgister fail ' + error);\r\n }).catch((err) => {\r\n console.error(err);\r\n });\r\n\r\n // Show us the notification payload if the app is open on our device\r\n PushNotifications.addListener(\r\n 'pushNotificationReceived',\r\n (notification) => {\r\n console.log('pushNotificationReceived', notification);\r\n this.handleRofPushNotification(notification);\r\n },\r\n ).catch((error) => {\r\n console.error(error);\r\n });\r\n\r\n // Method called when tapping on a notification\r\n PushNotifications.addListener('pushNotificationActionPerformed', (ev) => {\r\n const data = ev.notification.data;\r\n console.log('pushNotificationActionPerformed', data);\r\n\r\n this.emitLocationNotification(data);\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n async registerForNotifications(): Promise {\r\n let status = await PushNotifications.checkPermissions();\r\n if (status.receive === 'prompt') {\r\n status = await PushNotifications.requestPermissions();\r\n }\r\n\r\n if (status.receive !== 'granted') {\r\n return false;\r\n }\r\n\r\n await PushNotifications.register();\r\n return true;\r\n }\r\n\r\n handleRofPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n this.emitLocationNotification(notification.body);\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitRofNotification(title, body) {\r\n setTimeout(() => {\r\n try {\r\n this.rofNotifications.emit({ title, body });\r\n\r\n this.rofNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, title + ': ' + body);\r\n }\r\n }, this.rofNotificationsDelay);\r\n }\r\n\r\n handleLocationPushNotification(notification: PushNotificationSchema) {\r\n this.notificationSnackbarPromise = this.notificationSnackbarPromise.then(\r\n () => new Promise((res, rej) => {\r\n const sb = this.showNotificationSnackbar(notification);\r\n\r\n sb.onAction().subscribe(() => {\r\n const c = JSON.parse(notification.data['coords']);\r\n const r = JSON.parse(notification.data['radius']);\r\n this.router.navigate([ResourcesRoutes.ACTIVEWILDFIREMAP], {\r\n queryParams: {\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: notification.data['messageID'],\r\n featureType: notification.data['topicKey'],\r\n identify: true,\r\n notification: true,\r\n time: Date.now(),\r\n },\r\n });\r\n });\r\n\r\n sb.afterDismissed().subscribe(() => {\r\n res();\r\n });\r\n }),\r\n );\r\n\r\n return true;\r\n }\r\n\r\n emitLocationNotification(data) {\r\n setTimeout(() => {\r\n try {\r\n const c = JSON.parse(data['coords']);\r\n const r = JSON.parse(data['radius']);\r\n\r\n this.locationNotifications.emit({\r\n latitude: c[0],\r\n longitude: c[1],\r\n radius: r,\r\n featureId: data['messageID'],\r\n featureType: data['topicKey'],\r\n });\r\n\r\n this.locationNotificationsDelay = 0;\r\n } catch (e) {\r\n console.warn('push notification not handled:', e, data);\r\n }\r\n }, this.locationNotificationsDelay);\r\n }\r\n\r\n showNotificationSnackbar(notification: any) {\r\n const cfg: MatSnackBarConfig = {\r\n data: { notification },\r\n // need to change back to 10 sec. Using 60 sec for testing purpose in case QA missed it.\r\n duration: 60 * 1000,\r\n verticalPosition: 'top',\r\n };\r\n\r\n return this.snackbar.openFromComponent(NotificationSnackbarComponent, cfg);\r\n }\r\n\r\n checkDevice() {\r\n // const deviceInfo = \r\n return Device.getInfo()\r\n .then((devInfo) => {\r\n console.log(devInfo);\r\n if (!devInfo) {\r\nreturn;\r\n}\r\n\r\n this.isIOSPlatform = devInfo.platform === 'ios';\r\n this.isAndroidPlatform = devInfo.platform === 'android';\r\n this.isWebPlatform =\r\n devInfo.platform !== 'ios' && devInfo.platform !== 'android';\r\n\r\n return Device.getId();\r\n })\r\n .then((deviceId) => {\r\n console.log(deviceId);\r\n this.deviceId = deviceId.identifier;\r\n });\r\n }\r\n\r\n async getCurrentPosition(options?: PositionOptions): Promise {\r\n const coordinates = Geolocation.getCurrentPosition(options);\r\n return coordinates;\r\n }\r\n\r\n checkInstalledApps() {\r\n this.checkTwitterAppInstalled().then(\r\n (result) => {\r\n this.twitterAppInstalled = result;\r\n },\r\n (error) => {\r\n this.twitterAppInstalled = false;\r\n },\r\n );\r\n\r\n this.checkFbAppInstalled().then(\r\n (result) => {\r\n this.fbAppInstalled = result;\r\n },\r\n (error) => {\r\n this.fbAppInstalled = false;\r\n },\r\n );\r\n }\r\n\r\n onResume(): void {\r\n this.resume.next(true);\r\n }\r\n\r\n openLinkInAppBrowser(url: string) {\r\n Browser.open({\r\n url,\r\n toolbarColor: '#f7f7f9',\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n private async checkTwitterAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async checkFbAppInstalled(): Promise {\r\n if (this.isMobilePlatform()) {\r\n const scheme = this.isIOSPlatform ? 'fb://' : 'com.facebook.katana';\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n return false;\r\n }\r\n\r\n private async appIsInstalled(scheme: string): Promise {\r\n const ret = await AppLauncher.canOpenUrl({ url: scheme });\r\n return ret.value;\r\n }\r\n\r\n initOfflinePageSettings() {\r\n App.addListener('appStateChange', (state: AppState) => {\r\n this.appState = state;\r\n }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n\r\n public isMobilePlatform(): boolean {\r\n if (this.isIOSPlatform || this.isAndroidPlatform) {\r\n return true;\r\n }\r\n return !!environment['is_mobile_platform'];\r\n }\r\n\r\n getPnUrl() {\r\n return this.pnNav;\r\n }\r\n\r\n public getNotificationToken() {\r\n return this.notificationToken;\r\n }\r\n\r\n public setNotificationToken(token: string) {\r\n this.notificationToken = token;\r\n }\r\n\r\n openUrlInApp(url: string) {\r\n let scheme;\r\n let schemeUrl;\r\n // twitter\r\n if (url.indexOf('twitter.com/') !== -1) {\r\n scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android';\r\n schemeUrl = 'twitter://user?screen_name=' + url.split('twitter.com/')[1];\r\n }\r\n\r\n if (scheme && schemeUrl) {\r\n AppLauncher.openUrl({ url: schemeUrl }).catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n }\r\n\r\n isAndroid() {\r\n return this.isAndroidPlatform;\r\n }\r\n\r\n isIOS() {\r\n return this.isIOSPlatform;\r\n }\r\n\r\n getCurrentHeading(): Promise {\r\n const compass = navigator['compass'];\r\n if (!compass) {\r\nreturn Promise.reject(Error('navigator.compass not available'));\r\n} else {\r\n const currentHeading = new Promise((res, rej) => {\r\n compass.getCurrentHeading(\r\n (heading: CompassHeading) => {\r\n res(heading);\r\n this.currentHeadingPromise = null;\r\n },\r\n (error) => {\r\n rej(Error('Failed to get heading: ' + JSON.stringify(error)));\r\n this.currentHeadingPromise = null;\r\n },\r\n );\r\n });\r\n\r\n this.currentHeadingPromise = currentHeading;\r\n\r\n return this.currentHeadingPromise;\r\n }\r\n }\r\n\r\n async checkDeviceSystem() {\r\n // const deviceInfo = \r\n try {\r\n const deviceInfo = await Device.getInfo();\r\n return deviceInfo;\r\n } catch (error) {\r\n console.error('Error getting device info:', error);\r\n }\r\n }\r\n\r\n get deviceProperties(): Promise {\r\n if (!this.devicePropertiesPromise) {\r\nthis.devicePropertiesPromise = Device.getInfo()\r\n .then((devInfo) => Device.getId().then((deviceId) => {\r\n\r\n const p = devInfo && devInfo.platform;\r\n const prop: DeviceProperties = {\r\n isIOSPlatform: p == 'ios',\r\n isAndroidPlatform: p == 'android',\r\n isWebPlatform: p != 'ios' && p != 'android',\r\n isMobilePlatform:\r\n p == 'ios' ||\r\n p == 'android' ||\r\n !!environment['is_mobile_platform'],\r\n deviceId: deviceId.identifier,\r\n isTwitterInstalled: false,\r\n };\r\n const scheme = prop.isIOSPlatform\r\n ? 'twitter://'\r\n : 'com.twitter.android';\r\n return AppLauncher.canOpenUrl({ url: scheme })\r\n .then((canOpen) => {\r\n prop.isTwitterInstalled = canOpen.value;\r\n return prop;\r\n })\r\n .catch((e) => {\r\n console.warn(e);\r\n return prop;\r\n });\r\n }))\r\n .catch((e) => {\r\n console.warn(e);\r\n return {\r\n isIOSPlatform: false,\r\n isAndroidPlatform: false,\r\n isWebPlatform: false,\r\n isMobilePlatform: false,\r\n deviceId: '',\r\n isTwitterInstalled: false,\r\n };\r\n });\r\n}\r\n\r\n return this.devicePropertiesPromise;\r\n }\r\n\r\n get isMobile(): Promise {\r\n return this.deviceProperties.then((p) => p.isMobilePlatform);\r\n }\r\n\r\n async saveData(key: string, value: string) {\r\n await Preferences.set({\r\n key: key,\r\n value: value\r\n });\r\n }\r\n \r\n async getData(key: string) {\r\n const response = await Preferences.get({ key: key });\r\n return response.value;\r\n }\r\n\r\n async removeData(key: string) {\r\n await Preferences.remove({ key: key })\r\n }\r\n}\r\n\r\n\r\n",
+ "properties": [
+ {
+ "name": "body",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 44
+ },
+ {
+ "name": "title",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 43
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ReportOfFireType",
+ "id": "interface-ReportOfFireType-2bea6fa0d7561a07da0418a9db608fc6f133db9866b8d5c45dd96ff7edb29f0ad0440ef0a67b49e8c02c588724e203975d9abfdcaaae74077166f75a63a4a2fb",
+ "file": "src/app/services/report-of-fire-service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Injectable } from '@angular/core';\r\nimport { GalleryPhoto, Photo } from '@capacitor/camera';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\nimport { CommonUtilityService } from './common-utility.service';\r\nimport { App } from '@capacitor/app';\r\nimport ExifReader from 'exifreader';\r\nimport * as P from 'piexifjs';\r\nimport { Filesystem } from '@capacitor/filesystem';\r\nimport { LocalStorageService } from './local-storage-service';\r\nimport { Subscription } from 'rxjs';\r\n\r\nexport interface ReportOfFireType {\r\n fullName?: string;\r\n phoneNumber?: string;\r\n consentToCall?: boolean;\r\n estimatedDistance?: number;\r\n fireLocation?: number[];\r\n deviceLocation?: number[];\r\n fireSize?: string;\r\n rateOfSpread?: string;\r\n burning?: string[];\r\n smokeColor?: string[];\r\n weather?: string[];\r\n assetsAtRisk?: string[];\r\n signsOfResponse?: string[];\r\n otherInfo?: string;\r\n submittedTimestamp?: string;\r\n visibleFlame?: string[];\r\n submissionID?: string;\r\n image1?: Photo | GalleryPhoto;\r\n image2?: Photo | GalleryPhoto;\r\n image3?: Photo | GalleryPhoto;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ReportOfFireService {\r\n submittedOffline: boolean;\r\n longitude: number;\r\n latitude: number;\r\n formData: FormData\r\n\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private commonUtilityService: CommonUtilityService,\r\n private storageService: LocalStorageService\r\n ) { }\r\n\r\n async saveReportOfFire(\r\n reportOfFire: ReportOfFireType,\r\n image1: Photo | GalleryPhoto,\r\n image2: Photo | GalleryPhoto,\r\n image3: Photo | GalleryPhoto,\r\n ): Promise {\r\n const rofUrl = this.appConfigService.getConfig().rest['fire-report-api'];\r\n const resource = JSON.stringify(reportOfFire);\r\n if (this.commonUtilityService.hasSQLKeywords(resource)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n // if the device's location is not populated use the fire location to set image GPS coordinates\r\n if (reportOfFire?.deviceLocation) {\r\n this.latitude = reportOfFire.deviceLocation[0];\r\n this.longitude = reportOfFire.deviceLocation[1];\r\n } else if (reportOfFire?.fireLocation) {\r\n this.latitude = reportOfFire.fireLocation[0];\r\n this.longitude = reportOfFire.fireLocation[1];\r\n }\r\n\r\n try {\r\n const formData = new FormData();\r\n formData.append('resource', resource);\r\n\r\n if (image1) {\r\n formData.append('image1', await this.convertToBase64(image1));\r\n }\r\n if (image2) {\r\n formData.append('image2', await this.convertToBase64(image2));\r\n }\r\n if (image3) {\r\n formData.append('image3', await this.convertToBase64(image3));\r\n }\r\n this.formData = formData\r\n // if the device is offline save RoF in storage\r\n try {\r\n await this.commonUtilityService.checkOnlineStatus().then(async (result) => {\r\n const self = this;\r\n if (!result) {\r\n await this.submitToStorage(formData);\r\n self.submittedOffline = true;\r\n }\r\n });\r\n } catch (error) {\r\n console.error('Error checking online status for ROF submission', error);\r\n }\r\n\r\n if (this.submittedOffline) {\r\n return;\r\n }\r\n\r\n let storedOfflineReportData;\r\n try {\r\n storedOfflineReportData = this.storageService.removeData('offlineReportData');\r\n } catch (error) {\r\n console.error('An error occurred while retrieving offlineReportData:', error);\r\n }\r\n if (storedOfflineReportData) {\r\n // in case the device back online right after user store the report into ionic, \r\n // should always check to avoid submit the duplicate one\r\n const offlineReport = JSON.parse(storedOfflineReportData);\r\n if (offlineReport.resource) {\r\n const offlineResource = JSON.parse(offlineReport.resource);\r\n if (offlineResource === resource) {\r\n try {\r\n this.storageService.removeData('offlineReportData');\r\n } catch (error) {\r\n console.error('An error occurred while removing offlineReportData:', error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n const response = await fetch(rofUrl, {\r\n method: 'POST',\r\n body: formData,\r\n });\r\n if (response.ok || response.status == 200) {\r\n // The server successfully processed the report\r\n return { success: true, message: 'Report submitted successfully' };\r\n } else {\r\n // submit to storage if there is an issue\r\n if (this.formData) await this.submitToStorage(this.formData)\r\n // The server encountered an error\r\n return { success: false, message: JSON.stringify(response) };\r\n }\r\n } catch (error) {\r\n // submit to storage if there is an error\r\n if (this.formData) await this.submitToStorage(this.formData)\r\n // An error occurred during the HTTP request\r\n return {\r\n success: false,\r\n message: 'An error occurred while submitting the report',\r\n };\r\n }\r\n }\r\n\r\n async blobToBase64(url): Promise {\r\n return new Promise(async (resolve, _) => {\r\n // do a request to the blob uri\r\n const response = await fetch(url);\r\n\r\n // response has a method called .blob() to get the blob file\r\n const blob = await response.blob();\r\n\r\n // instantiate a file reader\r\n const fileReader = new FileReader();\r\n\r\n // read the file\r\n fileReader.readAsDataURL(blob);\r\n\r\n fileReader.onloadend = () => {\r\n resolve(fileReader.result as string); // Here is the base64 string\r\n };\r\n });\r\n }\r\n\r\n async convertToBase64(image: Photo | GalleryPhoto) {\r\n let base64;\r\n let content;\r\n let mimeType;\r\n try {\r\n if (image.path) {\r\n // read binary data (base64 encoded) from plugins that return File URIs, such as\r\n // the Camera.\r\n const contents = await Filesystem.readFile({\r\n path: image.path,\r\n }).then(result => {\r\n content = result.data;\r\n })\r\n\r\n // Filesystem.readFile returns just the content of the base64 string. Detect mimeType from content\r\n const identifier = content.charAt(0)\r\n switch (identifier) {\r\n case '/':\r\n mimeType = 'jpg';\r\n break;\r\n case 'i':\r\n mimeType = 'png';\r\n break;\r\n case 'R':\r\n mimeType = 'gif';\r\n break;\r\n case 'U':\r\n mimeType = 'webp';\r\n break;\r\n default:\r\n mimeType = 'jpg';\r\n break;\r\n }\r\n\r\n base64 = 'data:image/' + mimeType + ';base64,' + content;\r\n }\r\n\r\n // if the webPath is already a base64 string, return it\r\n else if (image?.webPath?.startsWith('data:image')) {\r\n base64 = image.webPath;\r\n }\r\n // if it does not have base64 string convert it to one\r\n else if (image.webPath) {\r\n await this.blobToBase64(image.webPath).then((result) => {\r\n base64 = result;\r\n });\r\n }\r\n // if it does not have a webPath return the dataUrl which should be a base64 string\r\n else {\r\n image = image as Photo;\r\n if (image.dataUrl) {\r\n base64 = image.dataUrl;\r\n }\r\n }\r\n\r\n // if not a JPG, metadata will be checked in notifications api and lat/long will be added if not present.\r\n if (base64?.startsWith('data:image/jpeg')) {\r\n await this.checkExifGPS(base64).then((response) => {\r\n base64 = response;\r\n });\r\n }\r\n } catch (error) {\r\n console.error('Error converting image to base64 string', error);\r\n }\r\n\r\n return base64;\r\n }\r\n\r\n async submitOfflineReportToServer(offlineReport?): Promise {\r\n // retrieve the offline RoF from the device's storage and convert to FormData for submission\r\n // images will already to converted to base64 string from initial submission\r\n const rofUrl = this.appConfigService.getConfig().rest['fire-report-api'];\r\n const rofJson = JSON.parse(offlineReport);\r\n const resource = rofJson.resource;\r\n const image1 = rofJson.image1;\r\n const image2 = rofJson.image2;\r\n const image3 = rofJson.image3;\r\n\r\n const formData = new FormData();\r\n if (resource) {\r\n formData.append('resource', resource);\r\n }\r\n\r\n if (image1) {\r\n formData.append('image1', image1);\r\n }\r\n if (image2) {\r\n formData.append('image2', image2);\r\n }\r\n if (image3) {\r\n formData.append('image3', image3);\r\n }\r\n\r\n try {\r\n // Make an HTTP POST request to your server's API endpoint\r\n const response = await fetch(rofUrl, {\r\n method: 'POST',\r\n body: formData,\r\n });\r\n\r\n if (response.ok || response.status == 200) {\r\n // Remove the locally stored data if sync is successful\r\n this.storageService.removeData('offlineReportData');\r\n App.removeAllListeners();\r\n // The server successfully processed the report\r\n return { success: true, message: 'Report submitted successfully' };\r\n } else {\r\n // The server encountered an error\r\n return { success: false, message: JSON.stringify(response) };\r\n }\r\n } catch (error) {\r\n // An error occurred during the HTTP request\r\n return {\r\n success: false,\r\n message: 'An error occurred while submitting the report',\r\n };\r\n }\r\n }\r\n\r\n async submitToStorage(formData: FormData) {\r\n const object = {};\r\n formData.forEach((value, key) => (object[key] = value));\r\n const json = JSON.stringify(object);\r\n const data = this.storageService.getData('offlineReportData')\r\n if (data == json) {\r\n return;\r\n } else this.storageService.saveData('offlineReportData', json);\r\n }\r\n\r\n // could not seem to get this to work for non-JPEG, those will be handled in notifications api.\r\n async checkExifGPS(base64: string) {\r\n try {\r\n const tags = await ExifReader.load(base64);\r\n // if the base64 string already has GPS metadata return it\r\n if (tags && tags.GPSLongitude && tags.GPSLatitude) {\r\n return base64;\r\n } else {\r\n // add GPS metadata if not present\r\n const gps = {};\r\n gps[P.GPSIFD.GPSLatitudeRef] = this.latitude < 0 ? 'S' : 'N';\r\n gps[P.GPSIFD.GPSLatitude] = P.GPSHelper.degToDmsRational(this.latitude);\r\n gps[P.GPSIFD.GPSLongitudeRef] = this.longitude < 0 ? 'W' : 'E';\r\n gps[P.GPSIFD.GPSLongitude] = P.GPSHelper.degToDmsRational(\r\n this.longitude,\r\n );\r\n const exifObj = { GPS: gps };\r\n const exifbytes = P.dump(exifObj);\r\n const exifModified = P.insert(exifbytes, base64);\r\n return exifModified;\r\n }\r\n } catch (err) {\r\n console.error('Error checking exif: ' + err);\r\n }\r\n }\r\n\r\n async syncDataWithServer(intervalRef: Subscription) {\r\n let dataSynced = false;\r\n let submissionID = null;\r\n let duplicateStored = false;\r\n let submissionIdList = null;\r\n let offlineReport = null;\r\n\r\n try {\r\n // Fetch and submit locally stored data\r\n offlineReport = this.storageService.getData('offlineReportData')\r\n submissionIdList = this.storageService.getData('submissionIDList')\r\n\r\n if (offlineReport) {\r\n // Check for duplicate, reject if submissionID has already been stored\r\n const offlineJson = JSON.parse(offlineReport)\r\n if (offlineJson?.resource) {\r\n const resourceJson = JSON.parse(offlineJson.resource)\r\n submissionID = resourceJson?.submissionID\r\n if (submissionID && submissionIdList?.includes(submissionID)) {\r\n duplicateStored = true;\r\n }\r\n }\r\n\r\n // Reject duplicate if submissionID has already been stored\r\n if (duplicateStored) return true;\r\n\r\n // Send the report to the server\r\n const response =\r\n await this.submitOfflineReportToServer(offlineReport).then(async response => {\r\n if (response.success) {\r\n dataSynced = true;\r\n // Remove the locally stored data if sync is successful\r\n this.storageService.removeData('offlineReportData');\r\n // store submissionID for duplicate check \r\n if (submissionID) {\r\n submissionIdList = submissionIdList ? submissionIdList + \", \" + submissionID : submissionID;\r\n this.storageService.saveData('submissionIDList', submissionIdList)\r\n }\r\n\r\n intervalRef.unsubscribe()\r\n App.removeAllListeners();\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n console.error('Sync failed:', error);\r\n }\r\n return dataSynced;\r\n }\r\n\r\n}",
+ "properties": [
+ {
+ "name": "assetsAtRisk",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": true,
+ "description": "",
+ "line": 24
+ },
+ {
+ "name": "burning",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": true,
+ "description": "",
+ "line": 21
+ },
+ {
+ "name": "consentToCall",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": true,
+ "description": "",
+ "line": 15
+ },
+ {
+ "name": "deviceLocation",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number[]",
+ "optional": true,
+ "description": "",
+ "line": 18
+ },
+ {
+ "name": "estimatedDistance",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": true,
+ "description": "",
+ "line": 16
+ },
+ {
+ "name": "fireLocation",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number[]",
+ "optional": true,
+ "description": "",
+ "line": 17
+ },
+ {
+ "name": "fireSize",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 19
+ },
+ {
+ "name": "fullName",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 13
+ },
+ {
+ "name": "image1",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Photo | GalleryPhoto",
+ "optional": true,
+ "description": "",
+ "line": 30
+ },
+ {
+ "name": "image2",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Photo | GalleryPhoto",
+ "optional": true,
+ "description": "",
+ "line": 31
+ },
+ {
+ "name": "image3",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Photo | GalleryPhoto",
+ "optional": true,
+ "description": "",
+ "line": 32
+ },
+ {
+ "name": "otherInfo",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 26
+ },
+ {
+ "name": "phoneNumber",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 14
+ },
+ {
+ "name": "rateOfSpread",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 20
+ },
+ {
+ "name": "signsOfResponse",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": true,
+ "description": "",
+ "line": 25
+ },
+ {
+ "name": "smokeColor",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": true,
+ "description": "",
+ "line": 22
+ },
+ {
+ "name": "submissionID",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 29
+ },
+ {
+ "name": "submittedTimestamp",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 27
+ },
+ {
+ "name": "visibleFlame",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": true,
+ "description": "",
+ "line": 28
+ },
+ {
+ "name": "weather",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": true,
+ "description": "",
+ "line": 23
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ResourcePanel",
+ "id": "interface-ResourcePanel-68b813bb4d799395e3a1511712c26b77fd09ac3d0814c0d716bcfbe05743db233f95d22b297120786c5ac193aa9f10409780bb69cc4837b3d24a94b77d94d7ed",
+ "file": "src/app/models/ResourcePanel.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface WildfireResource {\r\n title: string;\r\n subtitle: string;\r\n url: string;\r\n description: string;\r\n}\r\n\r\nexport interface ResourcePanel {\r\n title: string;\r\n resources: WildfireResource[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "resources",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "WildfireResource[]",
+ "optional": false,
+ "description": "",
+ "line": 10
+ },
+ {
+ "name": "title",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 9
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "RootState",
+ "id": "interface-RootState-97e807b22dd48389a9e8795594d9abdbaae08bf80a89836e570a2fe1b3a1593a4106dda39fc3562d0e5caeb9a95fb68d68ba0c5ebbd89310aeb2f71c1564f685",
+ "file": "src/app/store/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { routerReducer } from '@ngrx/router-store';\r\nimport { Action, ActionReducer, ActionReducerMap } from '@ngrx/store';\r\nimport { searchReducer, SearchState, SortDirection } from '@wf1/core-ui';\r\nimport { storeLogger } from 'ngrx-store-logger';\r\nimport {\r\n ApplicationState,\r\n PagingSearchState,\r\n} from './application/application.state';\r\nimport { pageSearchReducer } from './common/page-search.reducer';\r\nimport { IncidentEffect } from './incident/incident.effect';\r\nimport { incidentReducer } from './incident/incident.reducer';\r\nimport { IncidentState } from './incident/incident.stats';\r\nimport { IncidentsEffect } from './incidents/incidents.effects';\r\n\r\nimport { incidentsReducer } from './incidents/incidents.reducer';\r\nimport {\r\n initialIncidentsSearchState,\r\n IncidentsState,\r\n} from './incidents/incidents.stats';\r\nimport { WildfiresListEffect } from './wildfiresList/wildfiresList.effects';\r\nimport { wildfiresListReducer } from './wildfiresList/wildfiresList.reducer';\r\nimport {\r\n initialWildfiresSearchState,\r\n WildfiresState,\r\n} from './wildfiresList/wildfiresList.stats';\r\n\r\nexport interface BaseRouterStoreState {\r\n url: string;\r\n}\r\n\r\nexport interface RouterState {\r\n state: BaseRouterStoreState;\r\n}\r\n\r\nexport const rootReducers: ActionReducerMap = {\r\n search: searchReducer,\r\n router: routerReducer,\r\n incidents: incidentsReducer,\r\n searchIncidents: pageSearchReducer,\r\n incident: incidentReducer,\r\n wildfires: wildfiresListReducer,\r\n searchWildfires: pageSearchReducer,\r\n};\r\n\r\nexport interface RootState {\r\n application?: ApplicationState;\r\n incidents?: IncidentsState;\r\n searchIncidents?: PagingSearchState;\r\n incident?: IncidentState;\r\n wildfires?: WildfiresState;\r\n searchWildfires?: PagingSearchState;\r\n}\r\n\r\nexport const initialRootState: RootState = {\r\n searchIncidents: initialIncidentsSearchState,\r\n searchWildfires: initialWildfiresSearchState,\r\n};\r\n\r\nexport const rootEffects: any[] = [\r\n // PlaceNameSearchEffects,\r\n IncidentsEffect,\r\n IncidentEffect,\r\n WildfiresListEffect,\r\n];\r\n\r\nexport function logger(reducer: ActionReducer): any {\r\n // default, no options\r\n return storeLogger({\r\n collapsed: true,\r\n level: 'log',\r\n filter: {\r\n blacklist: [],\r\n },\r\n })(reducer);\r\n}\r\n\r\nexport interface AudibleAlertState {\r\n enableUnacknowledged: boolean;\r\n enableReceivedFromPM: boolean;\r\n selectedZoneIds?: string[];\r\n}\r\n\r\nexport class SearchStateAndConfig implements SearchState {\r\n query: string;\r\n sortParam: string;\r\n sortDirection: SortDirection;\r\n sortModalVisible: boolean;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n hiddenFilters: {\r\n [param: string]: any[];\r\n };\r\n columns?: string[]; //ordered list of columns to display\r\n componentId?: string;\r\n audibleAlert?: AudibleAlertState;\r\n}\r\n\r\nexport function isEmpty(obj) {\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport interface LabeledAction extends Action {\r\n displayLabel: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "application",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "ApplicationState",
+ "optional": true,
+ "description": "",
+ "line": 46
+ },
+ {
+ "name": "incident",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "IncidentState",
+ "optional": true,
+ "description": "",
+ "line": 49
+ },
+ {
+ "name": "incidents",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "IncidentsState",
+ "optional": true,
+ "description": "",
+ "line": 47
+ },
+ {
+ "name": "searchIncidents",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "PagingSearchState",
+ "optional": true,
+ "description": "",
+ "line": 48
+ },
+ {
+ "name": "searchWildfires",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "PagingSearchState",
+ "optional": true,
+ "description": "",
+ "line": 51
+ },
+ {
+ "name": "wildfires",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "WildfiresState",
+ "optional": true,
+ "description": "",
+ "line": 50
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "RouterState",
+ "id": "interface-RouterState-97e807b22dd48389a9e8795594d9abdbaae08bf80a89836e570a2fe1b3a1593a4106dda39fc3562d0e5caeb9a95fb68d68ba0c5ebbd89310aeb2f71c1564f685",
+ "file": "src/app/store/index.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { routerReducer } from '@ngrx/router-store';\r\nimport { Action, ActionReducer, ActionReducerMap } from '@ngrx/store';\r\nimport { searchReducer, SearchState, SortDirection } from '@wf1/core-ui';\r\nimport { storeLogger } from 'ngrx-store-logger';\r\nimport {\r\n ApplicationState,\r\n PagingSearchState,\r\n} from './application/application.state';\r\nimport { pageSearchReducer } from './common/page-search.reducer';\r\nimport { IncidentEffect } from './incident/incident.effect';\r\nimport { incidentReducer } from './incident/incident.reducer';\r\nimport { IncidentState } from './incident/incident.stats';\r\nimport { IncidentsEffect } from './incidents/incidents.effects';\r\n\r\nimport { incidentsReducer } from './incidents/incidents.reducer';\r\nimport {\r\n initialIncidentsSearchState,\r\n IncidentsState,\r\n} from './incidents/incidents.stats';\r\nimport { WildfiresListEffect } from './wildfiresList/wildfiresList.effects';\r\nimport { wildfiresListReducer } from './wildfiresList/wildfiresList.reducer';\r\nimport {\r\n initialWildfiresSearchState,\r\n WildfiresState,\r\n} from './wildfiresList/wildfiresList.stats';\r\n\r\nexport interface BaseRouterStoreState {\r\n url: string;\r\n}\r\n\r\nexport interface RouterState {\r\n state: BaseRouterStoreState;\r\n}\r\n\r\nexport const rootReducers: ActionReducerMap = {\r\n search: searchReducer,\r\n router: routerReducer,\r\n incidents: incidentsReducer,\r\n searchIncidents: pageSearchReducer,\r\n incident: incidentReducer,\r\n wildfires: wildfiresListReducer,\r\n searchWildfires: pageSearchReducer,\r\n};\r\n\r\nexport interface RootState {\r\n application?: ApplicationState;\r\n incidents?: IncidentsState;\r\n searchIncidents?: PagingSearchState;\r\n incident?: IncidentState;\r\n wildfires?: WildfiresState;\r\n searchWildfires?: PagingSearchState;\r\n}\r\n\r\nexport const initialRootState: RootState = {\r\n searchIncidents: initialIncidentsSearchState,\r\n searchWildfires: initialWildfiresSearchState,\r\n};\r\n\r\nexport const rootEffects: any[] = [\r\n // PlaceNameSearchEffects,\r\n IncidentsEffect,\r\n IncidentEffect,\r\n WildfiresListEffect,\r\n];\r\n\r\nexport function logger(reducer: ActionReducer): any {\r\n // default, no options\r\n return storeLogger({\r\n collapsed: true,\r\n level: 'log',\r\n filter: {\r\n blacklist: [],\r\n },\r\n })(reducer);\r\n}\r\n\r\nexport interface AudibleAlertState {\r\n enableUnacknowledged: boolean;\r\n enableReceivedFromPM: boolean;\r\n selectedZoneIds?: string[];\r\n}\r\n\r\nexport class SearchStateAndConfig implements SearchState {\r\n query: string;\r\n sortParam: string;\r\n sortDirection: SortDirection;\r\n sortModalVisible: boolean;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n hiddenFilters: {\r\n [param: string]: any[];\r\n };\r\n columns?: string[]; //ordered list of columns to display\r\n componentId?: string;\r\n audibleAlert?: AudibleAlertState;\r\n}\r\n\r\nexport function isEmpty(obj) {\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport interface LabeledAction extends Action {\r\n displayLabel: string;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "state",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "BaseRouterStoreState",
+ "optional": false,
+ "description": "",
+ "line": 32
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "SearchIncidentsAction",
+ "id": "interface-SearchIncidentsAction-944dcca8398a15c323f67c67b30a29b8d64c0c76571ae200a4d68d77abfbbf212c0eaf1a8445c57773713d0daf451306627cdb8a10d09d67f0ddfba9b53f090a",
+ "file": "src/app/store/incidents/incidents.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport { LabeledAction } from '..';\r\nimport {\r\n ErrorState,\r\n PagingInfoRequest,\r\n} from '../application/application.state';\r\n\r\nexport const SEARCH_INCIDENTS = 'SEARCH_INCIDENTS';\r\nexport const SEARCH_INCIDENTS_SUCCESS = 'SEARCH_INCIDENTS_SUCCESS';\r\nexport const SEARCH_INCIDENTS_ERROR = 'SEARCH_INCIDENTS_ERROR';\r\nexport interface SearchIncidentsAction extends LabeledAction {\r\n componentId: string;\r\n payload: {\r\n pageInfoRequest: PagingInfoRequest;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n };\r\n}\r\n\r\nexport interface SearchIncidentsSuccessAction extends Action {\r\n componentId: string;\r\n payload: {\r\n value: any;\r\n };\r\n}\r\n\r\nexport interface SearchIncidentsErrorAction extends Action {\r\n componentId: string;\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function searchIncidents(\r\n componentId: string,\r\n pageInfoRequest: PagingInfoRequest,\r\n selectedFireCentre: string,\r\n fireOfNotePublishedInd: boolean,\r\n displayLabel: string,\r\n): SearchIncidentsAction {\r\n const filters = {};\r\n filters['selectedFireCentreCode'] = selectedFireCentre\r\n ? [selectedFireCentre]\r\n : [];\r\n filters['selectedFireOfNotePublishedInd'] = fireOfNotePublishedInd\r\n ? [fireOfNotePublishedInd]\r\n : [];\r\n\r\n return {\r\n type: SEARCH_INCIDENTS,\r\n componentId,\r\n displayLabel,\r\n payload: {\r\n pageInfoRequest,\r\n filters,\r\n },\r\n };\r\n}\r\n\r\nexport function searchIncidentsSuccess(\r\n componentId: string,\r\n value: any,\r\n): SearchIncidentsSuccessAction {\r\n return {\r\n type: SEARCH_INCIDENTS_SUCCESS,\r\n componentId,\r\n payload: {\r\n value,\r\n },\r\n };\r\n}\r\n\r\nexport function SearchIncidentsError(\r\n componentId: string,\r\n error: ErrorState,\r\n): SearchIncidentsErrorAction {\r\n return {\r\n type: SEARCH_INCIDENTS_ERROR,\r\n componentId,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "componentId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 12
+ },
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 13
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "LabeledAction"
+ ]
+ },
+ {
+ "name": "SearchIncidentsErrorAction",
+ "id": "interface-SearchIncidentsErrorAction-944dcca8398a15c323f67c67b30a29b8d64c0c76571ae200a4d68d77abfbbf212c0eaf1a8445c57773713d0daf451306627cdb8a10d09d67f0ddfba9b53f090a",
+ "file": "src/app/store/incidents/incidents.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport { LabeledAction } from '..';\r\nimport {\r\n ErrorState,\r\n PagingInfoRequest,\r\n} from '../application/application.state';\r\n\r\nexport const SEARCH_INCIDENTS = 'SEARCH_INCIDENTS';\r\nexport const SEARCH_INCIDENTS_SUCCESS = 'SEARCH_INCIDENTS_SUCCESS';\r\nexport const SEARCH_INCIDENTS_ERROR = 'SEARCH_INCIDENTS_ERROR';\r\nexport interface SearchIncidentsAction extends LabeledAction {\r\n componentId: string;\r\n payload: {\r\n pageInfoRequest: PagingInfoRequest;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n };\r\n}\r\n\r\nexport interface SearchIncidentsSuccessAction extends Action {\r\n componentId: string;\r\n payload: {\r\n value: any;\r\n };\r\n}\r\n\r\nexport interface SearchIncidentsErrorAction extends Action {\r\n componentId: string;\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function searchIncidents(\r\n componentId: string,\r\n pageInfoRequest: PagingInfoRequest,\r\n selectedFireCentre: string,\r\n fireOfNotePublishedInd: boolean,\r\n displayLabel: string,\r\n): SearchIncidentsAction {\r\n const filters = {};\r\n filters['selectedFireCentreCode'] = selectedFireCentre\r\n ? [selectedFireCentre]\r\n : [];\r\n filters['selectedFireOfNotePublishedInd'] = fireOfNotePublishedInd\r\n ? [fireOfNotePublishedInd]\r\n : [];\r\n\r\n return {\r\n type: SEARCH_INCIDENTS,\r\n componentId,\r\n displayLabel,\r\n payload: {\r\n pageInfoRequest,\r\n filters,\r\n },\r\n };\r\n}\r\n\r\nexport function searchIncidentsSuccess(\r\n componentId: string,\r\n value: any,\r\n): SearchIncidentsSuccessAction {\r\n return {\r\n type: SEARCH_INCIDENTS_SUCCESS,\r\n componentId,\r\n payload: {\r\n value,\r\n },\r\n };\r\n}\r\n\r\nexport function SearchIncidentsError(\r\n componentId: string,\r\n error: ErrorState,\r\n): SearchIncidentsErrorAction {\r\n return {\r\n type: SEARCH_INCIDENTS_ERROR,\r\n componentId,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "componentId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 29
+ },
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 30
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "SearchIncidentsSuccessAction",
+ "id": "interface-SearchIncidentsSuccessAction-944dcca8398a15c323f67c67b30a29b8d64c0c76571ae200a4d68d77abfbbf212c0eaf1a8445c57773713d0daf451306627cdb8a10d09d67f0ddfba9b53f090a",
+ "file": "src/app/store/incidents/incidents.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport { LabeledAction } from '..';\r\nimport {\r\n ErrorState,\r\n PagingInfoRequest,\r\n} from '../application/application.state';\r\n\r\nexport const SEARCH_INCIDENTS = 'SEARCH_INCIDENTS';\r\nexport const SEARCH_INCIDENTS_SUCCESS = 'SEARCH_INCIDENTS_SUCCESS';\r\nexport const SEARCH_INCIDENTS_ERROR = 'SEARCH_INCIDENTS_ERROR';\r\nexport interface SearchIncidentsAction extends LabeledAction {\r\n componentId: string;\r\n payload: {\r\n pageInfoRequest: PagingInfoRequest;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n };\r\n}\r\n\r\nexport interface SearchIncidentsSuccessAction extends Action {\r\n componentId: string;\r\n payload: {\r\n value: any;\r\n };\r\n}\r\n\r\nexport interface SearchIncidentsErrorAction extends Action {\r\n componentId: string;\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function searchIncidents(\r\n componentId: string,\r\n pageInfoRequest: PagingInfoRequest,\r\n selectedFireCentre: string,\r\n fireOfNotePublishedInd: boolean,\r\n displayLabel: string,\r\n): SearchIncidentsAction {\r\n const filters = {};\r\n filters['selectedFireCentreCode'] = selectedFireCentre\r\n ? [selectedFireCentre]\r\n : [];\r\n filters['selectedFireOfNotePublishedInd'] = fireOfNotePublishedInd\r\n ? [fireOfNotePublishedInd]\r\n : [];\r\n\r\n return {\r\n type: SEARCH_INCIDENTS,\r\n componentId,\r\n displayLabel,\r\n payload: {\r\n pageInfoRequest,\r\n filters,\r\n },\r\n };\r\n}\r\n\r\nexport function searchIncidentsSuccess(\r\n componentId: string,\r\n value: any,\r\n): SearchIncidentsSuccessAction {\r\n return {\r\n type: SEARCH_INCIDENTS_SUCCESS,\r\n componentId,\r\n payload: {\r\n value,\r\n },\r\n };\r\n}\r\n\r\nexport function SearchIncidentsError(\r\n componentId: string,\r\n error: ErrorState,\r\n): SearchIncidentsErrorAction {\r\n return {\r\n type: SEARCH_INCIDENTS_ERROR,\r\n componentId,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "componentId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 22
+ },
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 23
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "SearchWildfiresAction",
+ "id": "interface-SearchWildfiresAction-7e4da0920409f68d99e788821c5c6c4abbb367237b8e5aeaac8ffc9cbf072d0ec8bc72e09037daf85d4d75eeeab0ad0afc8042e0d7735f6030c01f39f95fc350",
+ "file": "src/app/store/wildfiresList/wildfiresList.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport { LabeledAction } from '..';\r\nimport {\r\n ErrorState,\r\n PagingInfoRequest,\r\n} from '../application/application.state';\r\n\r\nexport const SEARCH_WILDFIRES = 'SEARCH_WILDFIRES';\r\nexport const SEARCH_WILDFIRES_SUCCESS = 'SEARCH_WILDFIRES_SUCCESS';\r\nexport const SEARCH_WILDFIRES_ERROR = 'SEARCH_WILDFIRES_ERROR';\r\nexport interface SearchWildfiresAction extends LabeledAction {\r\n componentId: string;\r\n callback: Function;\r\n payload: {\r\n pageInfoRequest: PagingInfoRequest;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n lat: number;\r\n long: number;\r\n radius: number;\r\n };\r\n}\r\n\r\nexport interface SearchWildfiresSuccessAction extends Action {\r\n componentId: string;\r\n payload: {\r\n value: any;\r\n };\r\n}\r\n\r\nexport interface SearchWildfiresErrorAction extends Action {\r\n componentId: string;\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function searchWildfires(\r\n componentId: string,\r\n pageInfoRequest: PagingInfoRequest,\r\n selectedFireCentre: string,\r\n fireOfNoteInd: boolean,\r\n stageOfControlList: string[],\r\n newFires: boolean,\r\n bbox: string,\r\n displayLabel: string,\r\n lat: number,\r\n long: number,\r\n radius: number,\r\n callback: Function | null = null,\r\n): SearchWildfiresAction {\r\n const filters = {};\r\n filters['fireCentreCode'] = selectedFireCentre\r\n ? selectedFireCentre\r\n : undefined;\r\n filters['fireOfNote'] = fireOfNoteInd ? fireOfNoteInd : undefined;\r\n filters['stageOfControlList'] = stageOfControlList ? stageOfControlList : [];\r\n filters['newFires'] = newFires ? newFires : false;\r\n filters['bbox'] = bbox ? bbox : undefined;\r\n\r\n return {\r\n type: SEARCH_WILDFIRES,\r\n componentId,\r\n displayLabel,\r\n callback: callback ? callback : () => {},\r\n payload: {\r\n pageInfoRequest,\r\n filters,\r\n lat,\r\n long,\r\n radius,\r\n },\r\n };\r\n}\r\n\r\nexport function searchWildfiresSuccess(\r\n componentId: string,\r\n value: any,\r\n): SearchWildfiresSuccessAction {\r\n return {\r\n type: SEARCH_WILDFIRES_SUCCESS,\r\n componentId,\r\n payload: {\r\n value,\r\n },\r\n };\r\n}\r\n\r\nexport function searchWildfiresError(\r\n componentId: string,\r\n error: ErrorState,\r\n): SearchWildfiresErrorAction {\r\n return {\r\n type: SEARCH_WILDFIRES_ERROR,\r\n componentId,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "callback",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Function",
+ "optional": false,
+ "description": "",
+ "line": 13
+ },
+ {
+ "name": "componentId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 12
+ },
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 14
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "LabeledAction"
+ ]
+ },
+ {
+ "name": "SearchWildfiresErrorAction",
+ "id": "interface-SearchWildfiresErrorAction-7e4da0920409f68d99e788821c5c6c4abbb367237b8e5aeaac8ffc9cbf072d0ec8bc72e09037daf85d4d75eeeab0ad0afc8042e0d7735f6030c01f39f95fc350",
+ "file": "src/app/store/wildfiresList/wildfiresList.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport { LabeledAction } from '..';\r\nimport {\r\n ErrorState,\r\n PagingInfoRequest,\r\n} from '../application/application.state';\r\n\r\nexport const SEARCH_WILDFIRES = 'SEARCH_WILDFIRES';\r\nexport const SEARCH_WILDFIRES_SUCCESS = 'SEARCH_WILDFIRES_SUCCESS';\r\nexport const SEARCH_WILDFIRES_ERROR = 'SEARCH_WILDFIRES_ERROR';\r\nexport interface SearchWildfiresAction extends LabeledAction {\r\n componentId: string;\r\n callback: Function;\r\n payload: {\r\n pageInfoRequest: PagingInfoRequest;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n lat: number;\r\n long: number;\r\n radius: number;\r\n };\r\n}\r\n\r\nexport interface SearchWildfiresSuccessAction extends Action {\r\n componentId: string;\r\n payload: {\r\n value: any;\r\n };\r\n}\r\n\r\nexport interface SearchWildfiresErrorAction extends Action {\r\n componentId: string;\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function searchWildfires(\r\n componentId: string,\r\n pageInfoRequest: PagingInfoRequest,\r\n selectedFireCentre: string,\r\n fireOfNoteInd: boolean,\r\n stageOfControlList: string[],\r\n newFires: boolean,\r\n bbox: string,\r\n displayLabel: string,\r\n lat: number,\r\n long: number,\r\n radius: number,\r\n callback: Function | null = null,\r\n): SearchWildfiresAction {\r\n const filters = {};\r\n filters['fireCentreCode'] = selectedFireCentre\r\n ? selectedFireCentre\r\n : undefined;\r\n filters['fireOfNote'] = fireOfNoteInd ? fireOfNoteInd : undefined;\r\n filters['stageOfControlList'] = stageOfControlList ? stageOfControlList : [];\r\n filters['newFires'] = newFires ? newFires : false;\r\n filters['bbox'] = bbox ? bbox : undefined;\r\n\r\n return {\r\n type: SEARCH_WILDFIRES,\r\n componentId,\r\n displayLabel,\r\n callback: callback ? callback : () => {},\r\n payload: {\r\n pageInfoRequest,\r\n filters,\r\n lat,\r\n long,\r\n radius,\r\n },\r\n };\r\n}\r\n\r\nexport function searchWildfiresSuccess(\r\n componentId: string,\r\n value: any,\r\n): SearchWildfiresSuccessAction {\r\n return {\r\n type: SEARCH_WILDFIRES_SUCCESS,\r\n componentId,\r\n payload: {\r\n value,\r\n },\r\n };\r\n}\r\n\r\nexport function searchWildfiresError(\r\n componentId: string,\r\n error: ErrorState,\r\n): SearchWildfiresErrorAction {\r\n return {\r\n type: SEARCH_WILDFIRES_ERROR,\r\n componentId,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "componentId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 33
+ },
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 34
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "SearchWildfiresSuccessAction",
+ "id": "interface-SearchWildfiresSuccessAction-7e4da0920409f68d99e788821c5c6c4abbb367237b8e5aeaac8ffc9cbf072d0ec8bc72e09037daf85d4d75eeeab0ad0afc8042e0d7735f6030c01f39f95fc350",
+ "file": "src/app/store/wildfiresList/wildfiresList.action.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Action } from '@ngrx/store';\r\nimport { LabeledAction } from '..';\r\nimport {\r\n ErrorState,\r\n PagingInfoRequest,\r\n} from '../application/application.state';\r\n\r\nexport const SEARCH_WILDFIRES = 'SEARCH_WILDFIRES';\r\nexport const SEARCH_WILDFIRES_SUCCESS = 'SEARCH_WILDFIRES_SUCCESS';\r\nexport const SEARCH_WILDFIRES_ERROR = 'SEARCH_WILDFIRES_ERROR';\r\nexport interface SearchWildfiresAction extends LabeledAction {\r\n componentId: string;\r\n callback: Function;\r\n payload: {\r\n pageInfoRequest: PagingInfoRequest;\r\n filters: {\r\n [param: string]: any[];\r\n };\r\n lat: number;\r\n long: number;\r\n radius: number;\r\n };\r\n}\r\n\r\nexport interface SearchWildfiresSuccessAction extends Action {\r\n componentId: string;\r\n payload: {\r\n value: any;\r\n };\r\n}\r\n\r\nexport interface SearchWildfiresErrorAction extends Action {\r\n componentId: string;\r\n payload: {\r\n error: ErrorState;\r\n };\r\n}\r\n\r\nexport function searchWildfires(\r\n componentId: string,\r\n pageInfoRequest: PagingInfoRequest,\r\n selectedFireCentre: string,\r\n fireOfNoteInd: boolean,\r\n stageOfControlList: string[],\r\n newFires: boolean,\r\n bbox: string,\r\n displayLabel: string,\r\n lat: number,\r\n long: number,\r\n radius: number,\r\n callback: Function | null = null,\r\n): SearchWildfiresAction {\r\n const filters = {};\r\n filters['fireCentreCode'] = selectedFireCentre\r\n ? selectedFireCentre\r\n : undefined;\r\n filters['fireOfNote'] = fireOfNoteInd ? fireOfNoteInd : undefined;\r\n filters['stageOfControlList'] = stageOfControlList ? stageOfControlList : [];\r\n filters['newFires'] = newFires ? newFires : false;\r\n filters['bbox'] = bbox ? bbox : undefined;\r\n\r\n return {\r\n type: SEARCH_WILDFIRES,\r\n componentId,\r\n displayLabel,\r\n callback: callback ? callback : () => {},\r\n payload: {\r\n pageInfoRequest,\r\n filters,\r\n lat,\r\n long,\r\n radius,\r\n },\r\n };\r\n}\r\n\r\nexport function searchWildfiresSuccess(\r\n componentId: string,\r\n value: any,\r\n): SearchWildfiresSuccessAction {\r\n return {\r\n type: SEARCH_WILDFIRES_SUCCESS,\r\n componentId,\r\n payload: {\r\n value,\r\n },\r\n };\r\n}\r\n\r\nexport function searchWildfiresError(\r\n componentId: string,\r\n error: ErrorState,\r\n): SearchWildfiresErrorAction {\r\n return {\r\n type: SEARCH_WILDFIRES_ERROR,\r\n componentId,\r\n payload: {\r\n error,\r\n },\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "componentId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 26
+ },
+ {
+ "name": "payload",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type",
+ "optional": false,
+ "description": "",
+ "line": 27
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "Action"
+ ]
+ },
+ {
+ "name": "UnitWithFormat",
+ "id": "interface-UnitWithFormat-bfb9da0dead5a03632178390d94ad64ce30286befe5cec4e76d7b543b0d407a9105863899da783db54814fcab23c79acb2bcbbec360f6dc1bdf73fba58b2a40c",
+ "file": "src/app/services/wfnews-map.service/util.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SpatialUtilsService } from '@wf1/core-ui';\r\n\r\nexport type LonLat = [number, number];\r\nexport type LatLon = [number, number];\r\n\r\nexport const toPoint = (lonLat: LonLat): any => window['turf'].point(lonLat);\r\n\r\nexport const toLatLon = (lonLat: LonLat): LatLon => [lonLat[1], lonLat[0]];\r\n\r\nexport const encodeUrl = (\r\n url: string,\r\n data: { [key: string]: string | number | boolean },\r\n): string => {\r\n if (!data) {\r\n return url;\r\n }\r\n\r\n const params = Object.keys(data)\r\n .filter((k) => data[k])\r\n .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(data[k])}`)\r\n .join('&');\r\n\r\n if (/[?]\\S+$/.test(url)) {\r\n return `${url}&${params}`;\r\n }\r\n\r\n if (/[?]$/.test(url)) {\r\n return `${url}${params}`;\r\n }\r\n\r\n return `${url}?${params}`;\r\n};\r\n\r\nexport const fetchJsonP = (\r\n url: string,\r\n data: { [key: string]: string | number | boolean },\r\n opt = { timeout: 10000 },\r\n): { response: Promise; abort: () => void } => {\r\n data['_'] = Math.round(Math.random() * 1e10);\r\n\r\n const cbfn = `callback_${data['_']}`;\r\n data.callback = cbfn;\r\n\r\n let id;\r\n let cancel;\r\n const req = encodeUrl(url, data);\r\n const promise = new Promise((res, rej) => {\r\n const cleanup = () => {\r\n if (id) {\r\n clearTimeout(id);\r\n }\r\n id = null;\r\n\r\n if (script.parentNode) {\r\n script.parentNode.removeChild(script);\r\n }\r\n\r\n window[cbfn] = null;\r\n };\r\n\r\n window[cbfn] = (payload) => {\r\n cleanup();\r\n res(payload);\r\n };\r\n\r\n cancel = () => {\r\n cleanup();\r\n rej(new Error('cancelled'));\r\n };\r\n const script = window['L'].DomUtil.create('script');\r\n script.type = 'text/javascript';\r\n script.async = true;\r\n script.src = req;\r\n\r\n document.getElementsByTagName('head')[0].appendChild(script);\r\n });\r\n\r\n if (opt.timeout) {\r\n id = setTimeout(cancel, opt.timeout);\r\n }\r\n\r\n return {\r\n response: promise,\r\n abort: cancel,\r\n };\r\n};\r\n\r\n// distance in km\r\nexport const distance = (loc1: LonLat, loc2: LonLat): number => window['turf'].distance(toPoint(loc1), toPoint(loc2));\r\n\r\nexport const formatDistance = (dist: number, unit: string): string => {\r\n if (dist == null) {\r\n return 'n/a';\r\n }\r\n if (dist < 10) {\r\n return dist.toFixed(1) + ' ' + unit;\r\n }\r\n return dist.toFixed(0) + ' ' + unit;\r\n};\r\n\r\nconst DIRECTION = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];\r\n\r\nexport const direction = (start: LonLat, end: LonLat): string => {\r\n const bearing = window['turf'].bearing(toPoint(start), toPoint(end));\r\n return DIRECTION[Math.floor((bearing + 382.5) / 45) % 8];\r\n};\r\n\r\nconst TIME_FORMAT = Intl.DateTimeFormat('en-CA', {\r\n timeZone: undefined,\r\n hour12: false,\r\n year: 'numeric',\r\n month: 'numeric',\r\n day: 'numeric',\r\n hour: 'numeric',\r\n minute: 'numeric',\r\n second: 'numeric',\r\n timeZoneName: 'short',\r\n});\r\nconst DATE_FORMAT = Intl.DateTimeFormat('en-CA', {\r\n timeZone: undefined,\r\n hour12: false,\r\n year: 'numeric',\r\n month: 'numeric',\r\n day: 'numeric',\r\n});\r\nconst CAD_FORMAT = Intl.NumberFormat('en-CA', {\r\n style: 'currency',\r\n currency: 'CAD',\r\n});\r\n\r\nexport interface NumberFormat {\r\n precision: number;\r\n fractionPlaces: number;\r\n}\r\nexport interface UnitWithFormat {\r\n unit: string;\r\n format: NumberFormat;\r\n}\r\n\r\nexport class Translate {\r\n constructor(private spatialUtils: SpatialUtilsService) {}\r\n\r\n parseCoordinate(val: string): LonLat {\r\n const c = this.spatialUtils.parseCoordinates(val);\r\n if (!c) {\r\n return;\r\n }\r\n return c as LonLat;\r\n }\r\n\r\n parseSexagesimal(val: string): number {\r\n if (typeof val == 'number') {\r\n return val;\r\n } else if (/^-?\\d*(\\.\\d*)?$/.test(val)) {\r\n return 0.0 + parseFloat(val);\r\n } else {\r\n let result = 0;\r\n let divisor = 1;\r\n let sign = 1;\r\n if (/[NSEWnsew]$/.test(val)) {\r\n sign = /[SWsw]$/.test(val) ? -1 : 1;\r\n val = val.replace(/[NSEWnsew]$/, '');\r\n }\r\n val.split(/[°DMSdms'\"\\s]+/).forEach((part) => {\r\n const partVal = parseFloat(part);\r\n if (!isNaN(partVal)) {\r\n result += partVal / divisor;\r\n }\r\n divisor *= 60;\r\n });\r\n\r\n return result * sign;\r\n }\r\n }\r\n\r\n formatCoordinate(lonLat: LonLat): string {\r\n if (!lonLat[0] || !lonLat[1]) {\r\n return '';\r\n }\r\n return this.spatialUtils.formatCoordinates(lonLat);\r\n }\r\n\r\n formatLatLon(lat, lon): string {\r\n if (!lat || !lon) {\r\n return '';\r\n }\r\n return this.formatCoordinate([lon, lat]);\r\n }\r\n\r\n parseYyyyMmDd(val): Date {\r\n if (!val) {\r\n return;\r\n }\r\n const s = '' + val;\r\n return new Date(\r\n `${s.substring(0, 4)}-${s.substring(4, 6)}-${s.substring(6, 8)}`,\r\n );\r\n }\r\n parseIsoDateTime(val): Date {\r\n if (!val) {\r\n return;\r\n }\r\n return new Date(val);\r\n }\r\n\r\n parseMilliseconds(val): Date {\r\n if (val == null) {\r\n return;\r\n }\r\n return new Date(1 * val);\r\n }\r\n parseEUDate(val?): Date {\r\n // Fix European style dd/mm/yyyy dates.\r\n if (!val) {\r\n return val;\r\n }\r\n const date = new Date(\r\n val.replace(\r\n /(\\d\\d)\\/(\\d\\d)\\/(\\d\\d\\d\\d)/,\r\n (m, day, month, year) => `${year}-${month}-${day}`,\r\n ),\r\n );\r\n if (isNaN(date.getTime())) {\r\n return null;\r\n }\r\n return date;\r\n }\r\n formatLocalDate(val: Date): string {\r\n if (!val) {\r\n return '';\r\n }\r\n return DATE_FORMAT.format(val);\r\n // return val && new Date( val ).toLocaleDateString()\r\n }\r\n\r\n formatLocalTime(val: Date): string {\r\n if (!val) {\r\n return '';\r\n }\r\n return TIME_FORMAT.format(val);\r\n // return val && new Date( val ).toLocaleDateString()\r\n }\r\n\r\n formatNumber(val: number, numberFormat?: NumberFormat): string {\r\n if (val == null) {\r\n return '';\r\n }\r\n\r\n numberFormat = { precision: 3, fractionPlaces: 1, ...numberFormat };\r\n\r\n const rounded = parseFloat(val.toPrecision(numberFormat.precision));\r\n if (!numberFormat.fractionPlaces) {\r\n return rounded.toLocaleString();\r\n }\r\n\r\n const a = Math.abs(rounded);\r\n const s = Math.sign(rounded);\r\n const i = Math.floor(a);\r\n const f = a - i;\r\n return (\r\n (s * i).toLocaleString() +\r\n f.toFixed(numberFormat.fractionPlaces).substr(1)\r\n );\r\n }\r\n\r\n formatUnit(val: number, unit: string, numberFormat?: NumberFormat): string {\r\n if (val == null) {\r\n return '';\r\n }\r\n return `${this.formatNumber(\r\n val,\r\n numberFormat,\r\n )}\\u202F${unit}`;\r\n }\r\n\r\n formatAndConvertUnit(\r\n val: number,\r\n unit: string,\r\n outputUnit: string | UnitWithFormat,\r\n ) {\r\n if (typeof outputUnit === 'object') {\r\n this.formatUnit(\r\n this.convertUnit(val, unit, outputUnit.unit),\r\n outputUnit.unit,\r\n );\r\n } else {\r\n this.formatUnit(this.convertUnit(val, unit, outputUnit), outputUnit);\r\n }\r\n }\r\n\r\n formatCAD(value?: number): string | null | undefined {\r\n if (value === null || value === undefined) {\r\n return value as null | undefined;\r\n } else {\r\n return CAD_FORMAT.format(value);\r\n }\r\n }\r\n\r\n formatAngle(\r\n val?: number,\r\n numberFormat?: NumberFormat,\r\n ): string | undefined | null {\r\n if (val) {\r\n return `${this.formatNumber(\r\n val,\r\n numberFormat,\r\n )}°`;\r\n } else {\r\n return val as undefined | null;\r\n }\r\n }\r\n\r\n /**\r\n * Converts and formats a value as two different units, the second in parentheses.\r\n */\r\n formatMultipleUnits(\r\n val: number,\r\n unit: string,\r\n standardUnit: string | UnitWithFormat,\r\n otherUnit: string | UnitWithFormat,\r\n ): string {\r\n if (val == null) {\r\n return '';\r\n }\r\n return `${this.formatAndConvertUnit(\r\n val,\r\n unit,\r\n standardUnit,\r\n )} (${this.formatAndConvertUnit(\r\n val,\r\n unit,\r\n otherUnit,\r\n )})`;\r\n }\r\n\r\n convertUnit(val: number, unitFrom: string, unitTo: string = 'm'): number {\r\n if (val == null) {\r\n return;\r\n }\r\n if (!(unitFrom in metersPerUnit)) {\r\n throw Error(`unitFrom \"${unitFrom}\" isn't defined`);\r\n }\r\n if (!(unitTo in metersPerUnit)) {\r\n throw Error(`unitTo \"${unitTo}\" isn't defined`);\r\n }\r\n\r\n const valInMeters = val * metersPerUnit[unitFrom];\r\n return valInMeters / metersPerUnit[unitTo];\r\n }\r\n\r\n formatFireZone(zoneName: string): string {\r\n if (!zoneName) {\r\n return;\r\n }\r\n\r\n const result = zoneName.match(\r\n /^(.+?) (?:Fire )?Zone(?: [(](.+?)[)])?(?: - (\\w\\d))?$/,\r\n );\r\n if (!result) {\r\n return zoneName;\r\n }\r\n\r\n if (result[2]) {\r\n return `${result[1]} (${result[2]})`;\r\n }\r\n return result[1];\r\n }\r\n\r\n formatFireCentre(centreName: string): string {\r\n if (!centreName) {\r\n return;\r\n }\r\n\r\n const result = centreName.match(/^(.+?) (?:Fire )?(?:Centre|Center)$/);\r\n if (!result) {\r\n return centreName;\r\n }\r\n\r\n return result[1];\r\n }\r\n\r\n formatIndicator(\r\n value: boolean | null,\r\n tString = '✔️ Yes',\r\n fString = '❌ No',\r\n nString = '❓ Unknown',\r\n ): string {\r\n if (value === undefined || value === null) {\r\n return nString;\r\n } else if (value) {\r\n return tString;\r\n } else {\r\n return fString;\r\n }\r\n }\r\n\r\n parseIndicator(indString: string, flip = false): boolean | null {\r\n if (indString === 'Y') {\r\n return !flip;\r\n } else if (indString === 'N') {\r\n return flip;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n formatPhoneHtml(phoneNumber: string): string {\r\n if (phoneNumber) {\r\n return `${phoneNumber}`;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n formatEmailHtml(emailAddress: string): string {\r\n if (emailAddress) {\r\n return `${emailAddress}`;\r\n } else {\r\n return null;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * This uses the ‘haversine’ formula to calculate the great-circle distance between two points \r\n * – that is, the shortest distance over the earth’s surface – giving an ‘as-the-crow-flies’ distance between the points.\r\n * a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)\r\n * c = 2 ⋅ atan2( √a, √(1−a) )\r\n * d = R ⋅ c\r\n * Where\tφ is latitude, λ is longitude, R is earth’s radius (mean radius = 6,371km). \r\n * note that angles need to be in radians to pass to trig functions\r\n * @param lat1 Latitude of the location\r\n * @param lat2 Latitude of the destination\r\n * @param lon1 Longitude of the location\r\n * @param lon2 Longitude of the destination\r\n * @returns\r\n */\r\nexport const haversineDistance = (lat1, lat2, lon1, lon2) => {\r\n const R = 6371e3; // metres\r\n const φ1 = (lat1 * Math.PI) / 180; // φ, λ in radians\r\n const φ2 = (lat2 * Math.PI) / 180;\r\n const Δφ = ((lat2 - lat1) * Math.PI) / 180;\r\n const Δλ = ((lon2 - lon1) * Math.PI) / 180;\r\n\r\n const a =\r\n Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +\r\n Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);\r\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\r\n\r\n const d = R * c; // in metres\r\n return d;\r\n};\r\n\r\nconst metersPerUnit = {\r\n Mil: 2.5399999999999996e-8,\r\n MicroInch: 0.0000254,\r\n mm: 0.001,\r\n Millimeter: 0.001,\r\n cm: 0.01,\r\n Centimeter: 0.01,\r\n IInch: 0.0254,\r\n 'us-in': 0.0254000508001016,\r\n Inch: 0.0254000508001016,\r\n in: 0.0254000508001016,\r\n inches: 0.0254000508001016,\r\n Decimeter: 0.1,\r\n ClarkeLink: 0.201166194976,\r\n SearsLink: 0.2011676512155,\r\n BenoitLink: 0.20116782494375873,\r\n IntnlLink: 0.201168,\r\n link: 0.201168,\r\n GunterLink: 0.2011684023368047,\r\n CapeFoot: 0.3047972615,\r\n ClarkeFoot: 0.3047972651151,\r\n 'ind-ft': 0.30479841,\r\n IndianFt37: 0.30479841,\r\n SearsFoot: 0.30479947153867626,\r\n IndianFt75: 0.3047995,\r\n IndianFoot: 0.30479951,\r\n IndianFt62: 0.3047996,\r\n GoldCoastFoot: 0.3047997101815088,\r\n IFoot: 0.3048,\r\n Foot: 0.3048006096012192,\r\n ft: 0.3048006096012192,\r\n 'us-ft': 0.3048006096012192,\r\n ModAmFt: 0.304812252984506,\r\n 'ind-yd': 0.9143952300000001,\r\n IndianYd37: 0.9143952300000001,\r\n SearsYard: 0.914398414616029,\r\n IndianYd75: 0.9143985000000001,\r\n IndianYard: 0.9143985307444409,\r\n IndianYd62: 0.9143987999999998,\r\n IYard: 0.9143999999999999,\r\n Yard: 0.9144018288036576,\r\n yd: 0.9144018288036576,\r\n 'us-yd': 0.9144018288036576,\r\n CaGrid: 0.9997380000000001,\r\n m: 1,\r\n Meter: 1,\r\n GermanMeter: 1.0000135965,\r\n fath: 1.8287999999999998,\r\n Fathom: 1.8287999999999998,\r\n Rood: 3.7782668980000005,\r\n Perch: 5.02921005842012,\r\n Rod: 5.02921005842012,\r\n Pole: 5.02921005842012,\r\n Dekameter: 10,\r\n Decameter: 10,\r\n ClarkeChain: 20.1166194976,\r\n 'ind-ch': 20.11669506,\r\n SearsChain: 20.11676512155,\r\n BenoitChain: 20.116782494375872,\r\n IntnlChain: 20.1168,\r\n ch: 20.1168,\r\n 'us-ch': 20.11684023368047,\r\n GunterChain: 20.11684023368047,\r\n dm: 100,\r\n Hectometer: 100,\r\n Furlong: 201.1684023368046,\r\n Brealey: 375,\r\n km: 1000,\r\n Kilometer: 1000,\r\n IMile: 1609.344,\r\n Mile: 1609.3472186944373,\r\n mi: 1609.3472186944373,\r\n 'us-mi': 1609.3472186944373,\r\n kmi: 1851.9999999999998,\r\n nmi: 1851.9999999999998,\r\n NautM: 1852.0000000000002,\r\n 'NautM-UK': 1853.1840000000002,\r\n '50kilometers': 50000,\r\n 'Lat-66': 110943.31648893275,\r\n 'Lat-83': 110946.25736872235,\r\n dd: 111118.97383794768,\r\n degrees: 111118.97383794768,\r\n '150kilometers': 150000,\r\n};\r\n",
+ "properties": [
+ {
+ "name": "format",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "NumberFormat",
+ "optional": false,
+ "description": "",
+ "line": 138
+ },
+ {
+ "name": "unit",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 137
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "ValidationError",
+ "id": "interface-ValidationError-de17b171a62a29758a8c7f641d8e13a2f3b00c00d66e412124df429ec963aecb62249b6cfb7f82b00212bad1a193119d16afc74721ea14d78baea1a1e848be1a",
+ "file": "src/app/store/application/application.state.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\n\r\nexport interface PagingSearchState extends SearchState {\r\n pageIndex?: number;\r\n pageSize?: number;\r\n}\r\nexport interface PagingInfoRequest {\r\n query?: string;\r\n pageNumber: number;\r\n pageRowCount: number;\r\n sortColumn?: string;\r\n sortDirection?: string;\r\n}\r\n\r\nexport interface ErrorState {\r\n uuid: string;\r\n type: ERROR_TYPE;\r\n status: number;\r\n statusText?: string;\r\n message?: string;\r\n name: string;\r\n validationErrors?: ValidationError[];\r\n responseEtag: string;\r\n}\r\n\r\nexport enum ERROR_TYPE {\r\n VALIDATION,\r\n WARNING,\r\n FATAL,\r\n NOT_FOUND,\r\n FAILED_PRECONDITION,\r\n}\r\n\r\nexport interface ValidationError {\r\n path: string;\r\n message: string;\r\n messageTemplate: string;\r\n messageArguments: any[];\r\n}\r\n\r\nexport interface ApplicationState {\r\n loadStates: LoadStates;\r\n errorStates: ErrorStates;\r\n formStates: FormStates;\r\n}\r\n\r\nexport interface LoadStates {\r\n incidents: LoadState;\r\n wildfires: LoadState;\r\n}\r\n\r\nexport interface ErrorStates {\r\n incidents: ErrorState[];\r\n wildfires: ErrorState[];\r\n}\r\n\r\nexport interface FormStates {\r\n incidents: FormState;\r\n}\r\n\r\nexport interface FormState {\r\n isUnsaved: boolean;\r\n}\r\n\r\nexport interface LoadState {\r\n isLoading: boolean;\r\n}\r\n\r\nexport function getDefaultFormState(): FormState {\r\n return {\r\n isUnsaved: false,\r\n };\r\n}\r\n\r\nexport function getDefaultLoadStates(): LoadStates {\r\n return {\r\n incidents: { isLoading: false },\r\n wildfires: { isLoading: false },\r\n };\r\n}\r\n\r\nexport function getDefaultApplicationState(): ApplicationState {\r\n return {\r\n loadStates: getDefaultLoadStates(),\r\n errorStates: getDefaultErrorStates(),\r\n formStates: getDefaultFormStates(),\r\n };\r\n}\r\n\r\nexport function getDefaultErrorStates(): ErrorStates {\r\n return {\r\n incidents: [],\r\n wildfires: [],\r\n };\r\n}\r\n\r\nexport function getDefaultFormStates(): FormStates {\r\n return {\r\n incidents: getDefaultFormState(),\r\n };\r\n}\r\n\r\nexport function getDefaultPagingInfoRequest(\r\n pageNumber = 1,\r\n pageSize = 5,\r\n sortColumn?: string,\r\n sortDirection?: string,\r\n query?: string,\r\n): PagingInfoRequest {\r\n return {\r\n query,\r\n pageNumber,\r\n pageRowCount: pageSize,\r\n sortColumn,\r\n sortDirection,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "message",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 36
+ },
+ {
+ "name": "messageArguments",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any[]",
+ "optional": false,
+ "description": "",
+ "line": 38
+ },
+ {
+ "name": "messageTemplate",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 37
+ },
+ {
+ "name": "path",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 35
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "VmCoordinates",
+ "id": "interface-VmCoordinates-202e8b4af361065a5c9ff67e569650ac69ed946c07e7a48a5068feaedf798ecfd0374c037fcab52c70869343bbe242a22ac75f2d29027ce50db28f62b14d5fa9",
+ "file": "src/app/services/notification.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { CapacitorService } from '@app/services/capacitor-service';\r\nimport { CommonUtilityService } from '@app/services/common-utility.service';\r\nimport { CapacitorHttp } from '@capacitor/core';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface NotificationSettingRsrc {\r\n deviceType: string;\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n notifications: NotificationRsrc[];\r\n}\r\n\r\nexport interface NotificationRsrc {\r\n notificationName: string;\r\n notificationType: string;\r\n radius: number;\r\n point: VmGeometry;\r\n topics: string[];\r\n activeIndicator: boolean;\r\n}\r\n\r\nexport interface VmGeometry {\r\n type: string;\r\n coordinates: number[];\r\n crs: string;\r\n}\r\n\r\nexport interface VmNotificationPreferences {\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n deviceType: string;\r\n notificationDetails: VmNotificationDetail[];\r\n}\r\n\r\nexport interface VmNotificationDetail {\r\n name: string;\r\n type: string;\r\n radius: number;\r\n preferences: string[];\r\n locationCoords: VmCoordinates;\r\n active: boolean;\r\n mapConfig?: Promise;\r\n}\r\n\r\nexport interface VmCoordinates {\r\n long: number;\r\n lat: number;\r\n}\r\n\r\nexport interface BoundingBox {\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class NotificationService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private httpClient: HttpClient,\r\n private capacitorService: CapacitorService,\r\n private commonUtilityService: CommonUtilityService,\r\n ) {}\r\n\r\n public updateUserNotificationPreferences(\r\n notificationSettings,\r\n savedNotification,\r\n ): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n console.log('device properties:\\'', p);\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n const token = this.capacitorService.getNotificationToken();\r\n const notificationSettingRsrc =\r\n convertToNotificationSettingRsrc(notificationSettings);\r\n notificationSettingRsrc.subscriberGuid = p.deviceId;\r\n notificationSettingRsrc.notificationToken = token;\r\n notificationSettingRsrc.deviceType = p.isAndroidPlatform\r\n ? 'android'\r\n : 'ios';\r\n if (savedNotification.length) {\r\n savedNotification.forEach((notification) => {\r\n notificationSettingRsrc.notifications.push(notification);\r\n });\r\n }\r\n const notificationSettingsJSON: string = JSON.stringify(notificationSettingRsrc);\r\n if (this.commonUtilityService.hasSQLKeywords(notificationSettingsJSON)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n\r\n return this.httpClient\r\n .put(url, notificationSettingRsrc, { headers })\r\n .toPromise();\r\n });\r\n }\r\n\r\n public getUserNotificationPreferences(): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p?.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n return this.httpClient.get(url, { headers }).toPromise();\r\n });\r\n }\r\n\r\n public getFireCentreByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.DRP_MOF_FIRE_CENTRES_SP&outputformat=application/json&cql_filter=INTERSECTS(GEOMETRY,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n\r\n public getDangerRatingByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LAND_AND_NATURAL_RESOURCE.PROT_DANGER_RATING_SP&outputformat=application/json&cql_filter=INTERSECTS(SHAPE,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport function convertToNotificationSettingRsrc(\r\n np: any,\r\n): NotificationSettingRsrc {\r\n const notificationTopics = [];\r\n if (np?.pushNotificationsFireBans) {\r\n notificationTopics.push('British_Columbia_Bans_and_Prohibition_Areas');\r\n notificationTopics.push('British_Columbia_Area_Restrictions');\r\n }\r\n if (np?.pushNotificationsWildfires) {\r\n notificationTopics.push('BCWS_ActiveFires_PublicView');\r\n notificationTopics.push('Evacuation_Orders_and_Alerts');\r\n }\r\n return {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notificationSettings',\r\n notifications: np\r\n ? [\r\n {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notification',\r\n notificationName: np.notificationName,\r\n notificationType: 'nearme',\r\n radius: np.radius,\r\n point: {\r\n type: 'Point',\r\n coordinates: [np.longitude, np.latitude],\r\n crs: null,\r\n },\r\n activeIndicator: true,\r\n topics: notificationTopics,\r\n },\r\n ]\r\n : [],\r\n notificationToken: null,\r\n subscriberToken: 'subscriberTpken',\r\n subscriberGuid: null,\r\n deviceType: null,\r\n } as unknown as NotificationSettingRsrc;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "lat",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 51
+ },
+ {
+ "name": "long",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 50
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "VmGeometry",
+ "id": "interface-VmGeometry-202e8b4af361065a5c9ff67e569650ac69ed946c07e7a48a5068feaedf798ecfd0374c037fcab52c70869343bbe242a22ac75f2d29027ce50db28f62b14d5fa9",
+ "file": "src/app/services/notification.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { CapacitorService } from '@app/services/capacitor-service';\r\nimport { CommonUtilityService } from '@app/services/common-utility.service';\r\nimport { CapacitorHttp } from '@capacitor/core';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface NotificationSettingRsrc {\r\n deviceType: string;\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n notifications: NotificationRsrc[];\r\n}\r\n\r\nexport interface NotificationRsrc {\r\n notificationName: string;\r\n notificationType: string;\r\n radius: number;\r\n point: VmGeometry;\r\n topics: string[];\r\n activeIndicator: boolean;\r\n}\r\n\r\nexport interface VmGeometry {\r\n type: string;\r\n coordinates: number[];\r\n crs: string;\r\n}\r\n\r\nexport interface VmNotificationPreferences {\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n deviceType: string;\r\n notificationDetails: VmNotificationDetail[];\r\n}\r\n\r\nexport interface VmNotificationDetail {\r\n name: string;\r\n type: string;\r\n radius: number;\r\n preferences: string[];\r\n locationCoords: VmCoordinates;\r\n active: boolean;\r\n mapConfig?: Promise;\r\n}\r\n\r\nexport interface VmCoordinates {\r\n long: number;\r\n lat: number;\r\n}\r\n\r\nexport interface BoundingBox {\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class NotificationService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private httpClient: HttpClient,\r\n private capacitorService: CapacitorService,\r\n private commonUtilityService: CommonUtilityService,\r\n ) {}\r\n\r\n public updateUserNotificationPreferences(\r\n notificationSettings,\r\n savedNotification,\r\n ): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n console.log('device properties:\\'', p);\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n const token = this.capacitorService.getNotificationToken();\r\n const notificationSettingRsrc =\r\n convertToNotificationSettingRsrc(notificationSettings);\r\n notificationSettingRsrc.subscriberGuid = p.deviceId;\r\n notificationSettingRsrc.notificationToken = token;\r\n notificationSettingRsrc.deviceType = p.isAndroidPlatform\r\n ? 'android'\r\n : 'ios';\r\n if (savedNotification.length) {\r\n savedNotification.forEach((notification) => {\r\n notificationSettingRsrc.notifications.push(notification);\r\n });\r\n }\r\n const notificationSettingsJSON: string = JSON.stringify(notificationSettingRsrc);\r\n if (this.commonUtilityService.hasSQLKeywords(notificationSettingsJSON)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n\r\n return this.httpClient\r\n .put(url, notificationSettingRsrc, { headers })\r\n .toPromise();\r\n });\r\n }\r\n\r\n public getUserNotificationPreferences(): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p?.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n return this.httpClient.get(url, { headers }).toPromise();\r\n });\r\n }\r\n\r\n public getFireCentreByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.DRP_MOF_FIRE_CENTRES_SP&outputformat=application/json&cql_filter=INTERSECTS(GEOMETRY,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n\r\n public getDangerRatingByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LAND_AND_NATURAL_RESOURCE.PROT_DANGER_RATING_SP&outputformat=application/json&cql_filter=INTERSECTS(SHAPE,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport function convertToNotificationSettingRsrc(\r\n np: any,\r\n): NotificationSettingRsrc {\r\n const notificationTopics = [];\r\n if (np?.pushNotificationsFireBans) {\r\n notificationTopics.push('British_Columbia_Bans_and_Prohibition_Areas');\r\n notificationTopics.push('British_Columbia_Area_Restrictions');\r\n }\r\n if (np?.pushNotificationsWildfires) {\r\n notificationTopics.push('BCWS_ActiveFires_PublicView');\r\n notificationTopics.push('Evacuation_Orders_and_Alerts');\r\n }\r\n return {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notificationSettings',\r\n notifications: np\r\n ? [\r\n {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notification',\r\n notificationName: np.notificationName,\r\n notificationType: 'nearme',\r\n radius: np.radius,\r\n point: {\r\n type: 'Point',\r\n coordinates: [np.longitude, np.latitude],\r\n crs: null,\r\n },\r\n activeIndicator: true,\r\n topics: notificationTopics,\r\n },\r\n ]\r\n : [],\r\n notificationToken: null,\r\n subscriberToken: 'subscriberTpken',\r\n subscriberGuid: null,\r\n deviceType: null,\r\n } as unknown as NotificationSettingRsrc;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "coordinates",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number[]",
+ "optional": false,
+ "description": "",
+ "line": 27
+ },
+ {
+ "name": "crs",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 28
+ },
+ {
+ "name": "type",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 26
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "VmNotificationDetail",
+ "id": "interface-VmNotificationDetail-202e8b4af361065a5c9ff67e569650ac69ed946c07e7a48a5068feaedf798ecfd0374c037fcab52c70869343bbe242a22ac75f2d29027ce50db28f62b14d5fa9",
+ "file": "src/app/services/notification.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { CapacitorService } from '@app/services/capacitor-service';\r\nimport { CommonUtilityService } from '@app/services/common-utility.service';\r\nimport { CapacitorHttp } from '@capacitor/core';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface NotificationSettingRsrc {\r\n deviceType: string;\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n notifications: NotificationRsrc[];\r\n}\r\n\r\nexport interface NotificationRsrc {\r\n notificationName: string;\r\n notificationType: string;\r\n radius: number;\r\n point: VmGeometry;\r\n topics: string[];\r\n activeIndicator: boolean;\r\n}\r\n\r\nexport interface VmGeometry {\r\n type: string;\r\n coordinates: number[];\r\n crs: string;\r\n}\r\n\r\nexport interface VmNotificationPreferences {\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n deviceType: string;\r\n notificationDetails: VmNotificationDetail[];\r\n}\r\n\r\nexport interface VmNotificationDetail {\r\n name: string;\r\n type: string;\r\n radius: number;\r\n preferences: string[];\r\n locationCoords: VmCoordinates;\r\n active: boolean;\r\n mapConfig?: Promise;\r\n}\r\n\r\nexport interface VmCoordinates {\r\n long: number;\r\n lat: number;\r\n}\r\n\r\nexport interface BoundingBox {\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class NotificationService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private httpClient: HttpClient,\r\n private capacitorService: CapacitorService,\r\n private commonUtilityService: CommonUtilityService,\r\n ) {}\r\n\r\n public updateUserNotificationPreferences(\r\n notificationSettings,\r\n savedNotification,\r\n ): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n console.log('device properties:\\'', p);\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n const token = this.capacitorService.getNotificationToken();\r\n const notificationSettingRsrc =\r\n convertToNotificationSettingRsrc(notificationSettings);\r\n notificationSettingRsrc.subscriberGuid = p.deviceId;\r\n notificationSettingRsrc.notificationToken = token;\r\n notificationSettingRsrc.deviceType = p.isAndroidPlatform\r\n ? 'android'\r\n : 'ios';\r\n if (savedNotification.length) {\r\n savedNotification.forEach((notification) => {\r\n notificationSettingRsrc.notifications.push(notification);\r\n });\r\n }\r\n const notificationSettingsJSON: string = JSON.stringify(notificationSettingRsrc);\r\n if (this.commonUtilityService.hasSQLKeywords(notificationSettingsJSON)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n\r\n return this.httpClient\r\n .put(url, notificationSettingRsrc, { headers })\r\n .toPromise();\r\n });\r\n }\r\n\r\n public getUserNotificationPreferences(): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p?.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n return this.httpClient.get(url, { headers }).toPromise();\r\n });\r\n }\r\n\r\n public getFireCentreByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.DRP_MOF_FIRE_CENTRES_SP&outputformat=application/json&cql_filter=INTERSECTS(GEOMETRY,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n\r\n public getDangerRatingByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LAND_AND_NATURAL_RESOURCE.PROT_DANGER_RATING_SP&outputformat=application/json&cql_filter=INTERSECTS(SHAPE,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport function convertToNotificationSettingRsrc(\r\n np: any,\r\n): NotificationSettingRsrc {\r\n const notificationTopics = [];\r\n if (np?.pushNotificationsFireBans) {\r\n notificationTopics.push('British_Columbia_Bans_and_Prohibition_Areas');\r\n notificationTopics.push('British_Columbia_Area_Restrictions');\r\n }\r\n if (np?.pushNotificationsWildfires) {\r\n notificationTopics.push('BCWS_ActiveFires_PublicView');\r\n notificationTopics.push('Evacuation_Orders_and_Alerts');\r\n }\r\n return {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notificationSettings',\r\n notifications: np\r\n ? [\r\n {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notification',\r\n notificationName: np.notificationName,\r\n notificationType: 'nearme',\r\n radius: np.radius,\r\n point: {\r\n type: 'Point',\r\n coordinates: [np.longitude, np.latitude],\r\n crs: null,\r\n },\r\n activeIndicator: true,\r\n topics: notificationTopics,\r\n },\r\n ]\r\n : [],\r\n notificationToken: null,\r\n subscriberToken: 'subscriberTpken',\r\n subscriberGuid: null,\r\n deviceType: null,\r\n } as unknown as NotificationSettingRsrc;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "active",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 45
+ },
+ {
+ "name": "locationCoords",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "VmCoordinates",
+ "optional": false,
+ "description": "",
+ "line": 44
+ },
+ {
+ "name": "mapConfig",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Promise",
+ "optional": true,
+ "description": "",
+ "line": 46
+ },
+ {
+ "name": "name",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 40
+ },
+ {
+ "name": "preferences",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string[]",
+ "optional": false,
+ "description": "",
+ "line": 43
+ },
+ {
+ "name": "radius",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 42
+ },
+ {
+ "name": "type",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 41
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "VmNotificationPreferences",
+ "id": "interface-VmNotificationPreferences-202e8b4af361065a5c9ff67e569650ac69ed946c07e7a48a5068feaedf798ecfd0374c037fcab52c70869343bbe242a22ac75f2d29027ce50db28f62b14d5fa9",
+ "file": "src/app/services/notification.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { CapacitorService } from '@app/services/capacitor-service';\r\nimport { CommonUtilityService } from '@app/services/common-utility.service';\r\nimport { CapacitorHttp } from '@capacitor/core';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\n\r\nexport interface NotificationSettingRsrc {\r\n deviceType: string;\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n notifications: NotificationRsrc[];\r\n}\r\n\r\nexport interface NotificationRsrc {\r\n notificationName: string;\r\n notificationType: string;\r\n radius: number;\r\n point: VmGeometry;\r\n topics: string[];\r\n activeIndicator: boolean;\r\n}\r\n\r\nexport interface VmGeometry {\r\n type: string;\r\n coordinates: number[];\r\n crs: string;\r\n}\r\n\r\nexport interface VmNotificationPreferences {\r\n subscriberGuid: string;\r\n subscriberToken: string;\r\n notificationToken: string;\r\n deviceType: string;\r\n notificationDetails: VmNotificationDetail[];\r\n}\r\n\r\nexport interface VmNotificationDetail {\r\n name: string;\r\n type: string;\r\n radius: number;\r\n preferences: string[];\r\n locationCoords: VmCoordinates;\r\n active: boolean;\r\n mapConfig?: Promise;\r\n}\r\n\r\nexport interface VmCoordinates {\r\n long: number;\r\n lat: number;\r\n}\r\n\r\nexport interface BoundingBox {\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class NotificationService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n private httpClient: HttpClient,\r\n private capacitorService: CapacitorService,\r\n private commonUtilityService: CommonUtilityService,\r\n ) {}\r\n\r\n public updateUserNotificationPreferences(\r\n notificationSettings,\r\n savedNotification,\r\n ): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n console.log('device properties:\\'', p);\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n const token = this.capacitorService.getNotificationToken();\r\n const notificationSettingRsrc =\r\n convertToNotificationSettingRsrc(notificationSettings);\r\n notificationSettingRsrc.subscriberGuid = p.deviceId;\r\n notificationSettingRsrc.notificationToken = token;\r\n notificationSettingRsrc.deviceType = p.isAndroidPlatform\r\n ? 'android'\r\n : 'ios';\r\n if (savedNotification.length) {\r\n savedNotification.forEach((notification) => {\r\n notificationSettingRsrc.notifications.push(notification);\r\n });\r\n }\r\n const notificationSettingsJSON: string = JSON.stringify(notificationSettingRsrc);\r\n if (this.commonUtilityService.hasSQLKeywords(notificationSettingsJSON)) {\r\n console.error(\"JSON blob contains SQL keywords. Potential SQL injection attempt.\");\r\n return;\r\n }\r\n\r\n return this.httpClient\r\n .put(url, notificationSettingRsrc, { headers })\r\n .toPromise();\r\n });\r\n }\r\n\r\n public getUserNotificationPreferences(): Promise {\r\n return this.capacitorService.deviceProperties.then((p) => {\r\n const url = `${\r\n this.appConfigService.getConfig().rest['notification-api']\r\n }/notificationSettings/${p?.deviceId}`;\r\n const headers = new HttpHeaders({\r\n apikey: this.appConfigService.getConfig().application['wfnewsApiKey'],\r\n });\r\n return this.httpClient.get(url, { headers }).toPromise();\r\n });\r\n }\r\n\r\n public getFireCentreByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LEGAL_ADMIN_BOUNDARIES.DRP_MOF_FIRE_CENTRES_SP&outputformat=application/json&cql_filter=INTERSECTS(GEOMETRY,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n\r\n public getDangerRatingByLocation(bbox: BoundingBox[]): Promise {\r\n const formattedString = bbox\r\n .map((pair) => `${pair.longitude} ${pair.latitude}`)\r\n .join(',');\r\n let url = (this.appConfigService.getConfig() as any).mapServices[\r\n 'openmapsBaseUrl'\r\n ] as string;\r\n url +=\r\n '?service=WFS&version=1.1.0&request=GetFeature&srsName=EPSG:4326&typename=pub:WHSE_LAND_AND_NATURAL_RESOURCE.PROT_DANGER_RATING_SP&outputformat=application/json&cql_filter=INTERSECTS(SHAPE,SRID=4326;POLYGON((';\r\n url += formattedString + ')))';\r\n return this.capacitorService.isMobile.then((isMobile) => {\r\n if (isMobile) {\r\n const options = {\r\n url,\r\n params: null,\r\n };\r\n const resp = CapacitorHttp.get(options);\r\n return resp;\r\n } else {\r\n const resp = this.httpClient.get(url).toPromise();\r\n return resp;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport function convertToNotificationSettingRsrc(\r\n np: any,\r\n): NotificationSettingRsrc {\r\n const notificationTopics = [];\r\n if (np?.pushNotificationsFireBans) {\r\n notificationTopics.push('British_Columbia_Bans_and_Prohibition_Areas');\r\n notificationTopics.push('British_Columbia_Area_Restrictions');\r\n }\r\n if (np?.pushNotificationsWildfires) {\r\n notificationTopics.push('BCWS_ActiveFires_PublicView');\r\n notificationTopics.push('Evacuation_Orders_and_Alerts');\r\n }\r\n return {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notificationSettings',\r\n notifications: np\r\n ? [\r\n {\r\n '@type': 'http://notifications.wfone.nrs.gov.bc.ca/v1/notification',\r\n notificationName: np.notificationName,\r\n notificationType: 'nearme',\r\n radius: np.radius,\r\n point: {\r\n type: 'Point',\r\n coordinates: [np.longitude, np.latitude],\r\n crs: null,\r\n },\r\n activeIndicator: true,\r\n topics: notificationTopics,\r\n },\r\n ]\r\n : [],\r\n notificationToken: null,\r\n subscriberToken: 'subscriberTpken',\r\n subscriberGuid: null,\r\n deviceType: null,\r\n } as unknown as NotificationSettingRsrc;\r\n}\r\n",
+ "properties": [
+ {
+ "name": "deviceType",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 35
+ },
+ {
+ "name": "notificationDetails",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "VmNotificationDetail[]",
+ "optional": false,
+ "description": "",
+ "line": 36
+ },
+ {
+ "name": "notificationToken",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 34
+ },
+ {
+ "name": "subscriberGuid",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 32
+ },
+ {
+ "name": "subscriberToken",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 33
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "WeatherDailyCondition",
+ "id": "interface-WeatherDailyCondition-fca6a5daf2479caf23ddb96520a7591019088d045327da6306fc3d404062d91427eb31ceb016cfc0e2cad7a57cf0a36e565bb1f02970051b99e7e502ddde6af7",
+ "file": "src/app/services/point-id.service/interfaces.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface WeatherHourlyCondition {\r\n hour: string;\r\n index: number;\r\n // forecastInd: string;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n // buildupIndex: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherDailyCondition {\r\n day: string;\r\n index: number;\r\n forecastInd: boolean;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n buildupIndex: number;\r\n duffMoistureCode: number;\r\n droughtCode: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherStation {\r\n [key: string]: any;\r\n stationCode: string;\r\n stationName: string;\r\n lat?: string;\r\n lon?: string;\r\n elevation: string;\r\n distance: string;\r\n}\r\n\r\nexport interface WeatherStationConditions extends WeatherStation {\r\n hourly: WeatherHourlyCondition[];\r\n daily: WeatherDailyCondition[];\r\n}\r\n\r\nexport interface WeatherStationResult {\r\n [key: string]: any;\r\n stations: WeatherStationConditions[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "buildupIndex",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 27
+ },
+ {
+ "name": "day",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 18
+ },
+ {
+ "name": "droughtCode",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 29
+ },
+ {
+ "name": "duffMoistureCode",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 28
+ },
+ {
+ "name": "fineFuelMoistureCode",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 30
+ },
+ {
+ "name": "fireWeatherIndex",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 32
+ },
+ {
+ "name": "forecastInd",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 20
+ },
+ {
+ "name": "index",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 19
+ },
+ {
+ "name": "initialSpreadIndex",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 31
+ },
+ {
+ "name": "precipitation",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 26
+ },
+ {
+ "name": "relativeHumidity",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 22
+ },
+ {
+ "name": "temp",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 21
+ },
+ {
+ "name": "windCardinalDir",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 25
+ },
+ {
+ "name": "windDirection",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 24
+ },
+ {
+ "name": "windSpeed",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 23
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "WeatherHistoryOptions",
+ "id": "interface-WeatherHistoryOptions-e4484584290ee0426630c116415b3f809a928a5613e3a2d4eeef6d9e5d364798a9a1ba7fece07b0c38cb308ea35ca1163557191d11572d7959bb970e45a4e409",
+ "file": "src/app/services/application-state.service.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { Injectable, Injector } from '@angular/core';\r\nimport { TokenService } from '@wf1/core-ui';\r\nimport { WfDevice } from '@wf1/wfcc-application-ui';\r\nimport { ROLES_UI } from '../shared/scopes/scopes';\r\nimport { Router } from '@angular/router';\r\nimport { MatDialog } from '@angular/material/dialog';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ApplicationStateService {\r\n tokenService: TokenService;\r\n private weatherHistoryOptions: WeatherHistoryOptions = {\r\n historyLength: 72,\r\n chartDataSources: [\r\n {\r\n property: 'temp',\r\n title: 'Temperature',\r\n },\r\n {\r\n property: 'relativeHumidity',\r\n title: 'Relative Humidity',\r\n },\r\n ],\r\n includedSources: [],\r\n };\r\n\r\n constructor(\r\n private injector: Injector,\r\n private router: Router,\r\n private dialog: MatDialog,\r\n ) {}\r\n\r\n getDevice(): WfDevice {\r\n if (\r\n window.innerWidth < 768 ||\r\n (window.innerWidth >= 768 && window.innerHeight < 450)\r\n ) {\r\n return 'mobile';\r\n }\r\n\r\n return 'desktop';\r\n }\r\n\r\n getOrientation(): 'landscape' | 'portrait' {\r\n if (window.innerWidth > window.innerHeight) {\r\n return 'landscape';\r\n }\r\n\r\n return 'portrait';\r\n }\r\n\r\n private checkMobileResolution() {\r\n if (\r\n window.innerWidth < 768 ||\r\n (window.innerWidth < 900 &&\r\n window.innerHeight < 450) /*support for landscape mobile views*/\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n public getIsMobileResolution(): boolean {\r\n return this.checkMobileResolution();\r\n }\r\n\r\n public doesUserHaveScopes(scopes: string[]): boolean {\r\n return this.getTokenService().doesUserHaveApplicationPermissions(scopes);\r\n }\r\n\r\n public getUserCredentialsEmitter() {\r\n return this.getTokenService().credentialsEmitter;\r\n }\r\n\r\n public getUserDetails() {\r\n return this.getTokenService()\r\n ? this.getTokenService().getTokenDetails()\r\n : null;\r\n }\r\n\r\n private getTokenService() {\r\n return this.tokenService\r\n ? this.tokenService\r\n : this.injector.get(TokenService);\r\n }\r\n\r\n public isAdminPageAccessable(): boolean {\r\n return (\r\n this.doesUserHaveScopes([ROLES_UI.ADMIN]) ||\r\n this.doesUserHaveScopes([ROLES_UI.IM_ADMIN])\r\n );\r\n }\r\n\r\n public getWeatherHistoryOptions(): WeatherHistoryOptions {\r\n return this.weatherHistoryOptions;\r\n }\r\n\r\n public setWeatherHistoryOptions(opt: WeatherHistoryOptions) {\r\n return (this.weatherHistoryOptions = opt);\r\n }\r\n}\r\n\r\nexport interface WeatherHistoryOptions {\r\n historyLength: number; // hours\r\n chartDataSources: {\r\n property: string;\r\n title: string;\r\n }[];\r\n includedSources: {\r\n property: string;\r\n }[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "chartDataSources",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type[]",
+ "optional": false,
+ "description": "",
+ "line": 107
+ },
+ {
+ "name": "historyLength",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 106
+ },
+ {
+ "name": "includedSources",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "literal type[]",
+ "optional": false,
+ "description": "",
+ "line": 111
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "WeatherHourlyCondition",
+ "id": "interface-WeatherHourlyCondition-fca6a5daf2479caf23ddb96520a7591019088d045327da6306fc3d404062d91427eb31ceb016cfc0e2cad7a57cf0a36e565bb1f02970051b99e7e502ddde6af7",
+ "file": "src/app/services/point-id.service/interfaces.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface WeatherHourlyCondition {\r\n hour: string;\r\n index: number;\r\n // forecastInd: string;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n // buildupIndex: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherDailyCondition {\r\n day: string;\r\n index: number;\r\n forecastInd: boolean;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n buildupIndex: number;\r\n duffMoistureCode: number;\r\n droughtCode: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherStation {\r\n [key: string]: any;\r\n stationCode: string;\r\n stationName: string;\r\n lat?: string;\r\n lon?: string;\r\n elevation: string;\r\n distance: string;\r\n}\r\n\r\nexport interface WeatherStationConditions extends WeatherStation {\r\n hourly: WeatherHourlyCondition[];\r\n daily: WeatherDailyCondition[];\r\n}\r\n\r\nexport interface WeatherStationResult {\r\n [key: string]: any;\r\n stations: WeatherStationConditions[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "fineFuelMoistureCode",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 12
+ },
+ {
+ "name": "fireWeatherIndex",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 14
+ },
+ {
+ "name": "hour",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 2
+ },
+ {
+ "name": "index",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 3
+ },
+ {
+ "name": "initialSpreadIndex",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 13
+ },
+ {
+ "name": "precipitation",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 10
+ },
+ {
+ "name": "relativeHumidity",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 6
+ },
+ {
+ "name": "temp",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 5
+ },
+ {
+ "name": "windCardinalDir",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 9
+ },
+ {
+ "name": "windDirection",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 8
+ },
+ {
+ "name": "windSpeed",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 7
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "WeatherStation",
+ "id": "interface-WeatherStation-fca6a5daf2479caf23ddb96520a7591019088d045327da6306fc3d404062d91427eb31ceb016cfc0e2cad7a57cf0a36e565bb1f02970051b99e7e502ddde6af7",
+ "file": "src/app/services/point-id.service/interfaces.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface WeatherHourlyCondition {\r\n hour: string;\r\n index: number;\r\n // forecastInd: string;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n // buildupIndex: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherDailyCondition {\r\n day: string;\r\n index: number;\r\n forecastInd: boolean;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n buildupIndex: number;\r\n duffMoistureCode: number;\r\n droughtCode: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherStation {\r\n [key: string]: any;\r\n stationCode: string;\r\n stationName: string;\r\n lat?: string;\r\n lon?: string;\r\n elevation: string;\r\n distance: string;\r\n}\r\n\r\nexport interface WeatherStationConditions extends WeatherStation {\r\n hourly: WeatherHourlyCondition[];\r\n daily: WeatherDailyCondition[];\r\n}\r\n\r\nexport interface WeatherStationResult {\r\n [key: string]: any;\r\n stations: WeatherStationConditions[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "distance",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 42
+ },
+ {
+ "name": "elevation",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 41
+ },
+ {
+ "name": "lat",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 39
+ },
+ {
+ "name": "lon",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": true,
+ "description": "",
+ "line": 40
+ },
+ {
+ "name": "stationCode",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 37
+ },
+ {
+ "name": "stationName",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 38
+ }
+ ],
+ "indexSignatures": [
+ {
+ "id": "index-declaration-fca6a5daf2479caf23ddb96520a7591019088d045327da6306fc3d404062d91427eb31ceb016cfc0e2cad7a57cf0a36e565bb1f02970051b99e7e502ddde6af7",
+ "args": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "returnType": "any",
+ "line": 35,
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "WeatherStationConditions",
+ "id": "interface-WeatherStationConditions-fca6a5daf2479caf23ddb96520a7591019088d045327da6306fc3d404062d91427eb31ceb016cfc0e2cad7a57cf0a36e565bb1f02970051b99e7e502ddde6af7",
+ "file": "src/app/services/point-id.service/interfaces.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface WeatherHourlyCondition {\r\n hour: string;\r\n index: number;\r\n // forecastInd: string;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n // buildupIndex: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherDailyCondition {\r\n day: string;\r\n index: number;\r\n forecastInd: boolean;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n buildupIndex: number;\r\n duffMoistureCode: number;\r\n droughtCode: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherStation {\r\n [key: string]: any;\r\n stationCode: string;\r\n stationName: string;\r\n lat?: string;\r\n lon?: string;\r\n elevation: string;\r\n distance: string;\r\n}\r\n\r\nexport interface WeatherStationConditions extends WeatherStation {\r\n hourly: WeatherHourlyCondition[];\r\n daily: WeatherDailyCondition[];\r\n}\r\n\r\nexport interface WeatherStationResult {\r\n [key: string]: any;\r\n stations: WeatherStationConditions[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "daily",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "WeatherDailyCondition[]",
+ "optional": false,
+ "description": "",
+ "line": 47
+ },
+ {
+ "name": "hourly",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "WeatherHourlyCondition[]",
+ "optional": false,
+ "description": "",
+ "line": 46
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": [
+ "WeatherStation"
+ ]
+ },
+ {
+ "name": "WeatherStationResult",
+ "id": "interface-WeatherStationResult-fca6a5daf2479caf23ddb96520a7591019088d045327da6306fc3d404062d91427eb31ceb016cfc0e2cad7a57cf0a36e565bb1f02970051b99e7e502ddde6af7",
+ "file": "src/app/services/point-id.service/interfaces.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface WeatherHourlyCondition {\r\n hour: string;\r\n index: number;\r\n // forecastInd: string;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n // buildupIndex: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherDailyCondition {\r\n day: string;\r\n index: number;\r\n forecastInd: boolean;\r\n temp: number;\r\n relativeHumidity: number;\r\n windSpeed: number;\r\n windDirection: number;\r\n windCardinalDir: string;\r\n precipitation: number;\r\n buildupIndex: number;\r\n duffMoistureCode: number;\r\n droughtCode: number;\r\n fineFuelMoistureCode: number;\r\n initialSpreadIndex: number;\r\n fireWeatherIndex: number;\r\n}\r\n\r\nexport interface WeatherStation {\r\n [key: string]: any;\r\n stationCode: string;\r\n stationName: string;\r\n lat?: string;\r\n lon?: string;\r\n elevation: string;\r\n distance: string;\r\n}\r\n\r\nexport interface WeatherStationConditions extends WeatherStation {\r\n hourly: WeatherHourlyCondition[];\r\n daily: WeatherDailyCondition[];\r\n}\r\n\r\nexport interface WeatherStationResult {\r\n [key: string]: any;\r\n stations: WeatherStationConditions[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "stations",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "WeatherStationConditions[]",
+ "optional": false,
+ "description": "",
+ "line": 52
+ }
+ ],
+ "indexSignatures": [
+ {
+ "id": "index-declaration-fca6a5daf2479caf23ddb96520a7591019088d045327da6306fc3d404062d91427eb31ceb016cfc0e2cad7a57cf0a36e565bb1f02970051b99e7e502ddde6af7",
+ "args": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "returnType": "any",
+ "line": 50,
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "WildfireResource",
+ "id": "interface-WildfireResource-68b813bb4d799395e3a1511712c26b77fd09ac3d0814c0d716bcfbe05743db233f95d22b297120786c5ac193aa9f10409780bb69cc4837b3d24a94b77d94d7ed",
+ "file": "src/app/models/ResourcePanel.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "export interface WildfireResource {\r\n title: string;\r\n subtitle: string;\r\n url: string;\r\n description: string;\r\n}\r\n\r\nexport interface ResourcePanel {\r\n title: string;\r\n resources: WildfireResource[];\r\n}\r\n",
+ "properties": [
+ {
+ "name": "description",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 5
+ },
+ {
+ "name": "subtitle",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 3
+ },
+ {
+ "name": "title",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 2
+ },
+ {
+ "name": "url",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 4
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ },
+ {
+ "name": "WildfiresState",
+ "id": "interface-WildfiresState-30c6fc20799ac13194e1905bd7cef78d940cb3f78357c086388528be8b323d3dfa2e954bbddf2fdd23719f7b8550b0853e239dd81e4b27514ee725cd14065ff2",
+ "file": "src/app/store/wildfiresList/wildfiresList.stats.ts",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "interface",
+ "sourceCode": "import { SearchState } from '@wf1/core-ui';\r\nimport { getDefaultPagingInfoRequest } from '../application/application.state';\r\n\r\nexport const SEARCH_WILDFIRES_COMPONENT_ID = 'searchWildfires';\r\nexport const WILDFIRESLIST_COMPONENT_ID = 'WildfiresList';\r\nexport const LOAD_WILDFIRES_COMPONENT_ID = 'loadWildfires';\r\n\r\nconst EMPTY_WILDFIRESLIST: any = {\r\n pageNumber: null,\r\n pageRowCount: null,\r\n totalPageCount: null,\r\n totalRowCount: null,\r\n collection: [],\r\n};\r\n\r\nexport interface WildfiresState {\r\n // will need to specify the type . use any for now\r\n currentWildfiresSearch?: any;\r\n selectedWildfire?: any;\r\n wildfires?: any;\r\n}\r\n\r\nexport const initialWildfiresSearchState: SearchState = {\r\n query: null,\r\n sortParam: 'lastUpdatedTimestamp',\r\n sortDirection: 'DESC',\r\n sortModalVisible: false,\r\n filters: {},\r\n hiddenFilters: {},\r\n componentId: SEARCH_WILDFIRES_COMPONENT_ID,\r\n};\r\n\r\nexport const initWildfiresListPaging = getDefaultPagingInfoRequest(\r\n 1,\r\n 20,\r\n 'discoveryTimestamp',\r\n 'DESC',\r\n undefined,\r\n);\r\n\r\nexport function getDefaultWildfiresListState(): WildfiresState {\r\n return {\r\n currentWildfiresSearch: EMPTY_WILDFIRESLIST,\r\n };\r\n}\r\n",
+ "properties": [
+ {
+ "name": "currentWildfiresSearch",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 18
+ },
+ {
+ "name": "selectedWildfire",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 19
+ },
+ {
+ "name": "wildfires",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": true,
+ "description": "",
+ "line": 20
+ }
+ ],
+ "indexSignatures": [],
+ "kind": 171,
+ "methods": [],
+ "extends": []
+ }
+ ],
+ "injectables": [
+ {
+ "name": "AGOLService",
+ "id": "injectable-AGOLService-45e960f81ae10a923d8d2a8ab60d53c41df3ca39dab8c86410faaf0735ceb078ecba84502b8ff2a5160310ee2f3ce5d226e24a009acd193476868f5ae0d11b59",
+ "file": "src/app/services/AGOL-service.ts",
+ "properties": [],
+ "methods": [
+ {
+ "name": "getActiveFireCount",
+ "args": [],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 271,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getActiveFiresNoGeom",
+ "args": [],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 279,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getAreaRestrictions",
+ "args": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 140,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getAreaRestrictionsWfs",
+ "args": [],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 261,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getBansAndProhibitions",
+ "args": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 214,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getBansAndProhibitionsById",
+ "args": [
+ {
+ "name": "sysId",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 187,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "sysId",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getCurrentYearFireLastXDaysStats",
+ "args": [
+ {
+ "name": "lastXDays",
+ "type": "number",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 295,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "lastXDays",
+ "type": "number",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getCurrentYearFireStats",
+ "args": [],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 329,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getDangerRatings",
+ "args": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 338,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getEvacOrders",
+ "args": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 70,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "where",
+ "type": "string | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "location",
+ "type": "literal type | null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getEvacOrdersByEventNumber",
+ "args": [
+ {
+ "name": "eventNumber",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 45,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "eventNumber",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getEvacOrdersByParam",
+ "args": [
+ {
+ "name": "where",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 118,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "where",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getFirePerimetre",
+ "args": [
+ {
+ "name": "fireNumber",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null"
+ }
+ ],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 23,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "fireNumber",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "options",
+ "type": "AgolOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "defaultValue": "null",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getOutFiresNoGeom",
+ "args": [],
+ "optional": false,
+ "returnType": "Observable",
+ "typeParameters": [],
+ "line": 287,
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "deprecated": false,
+ "deprecationMessage": "",
+ "description": "",
+ "rawdescription": "\n",
+ "sourceCode": "import { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { AppConfigService } from '@wf1/core-ui';\r\nimport { Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\n\r\nexport interface AgolOptions {\r\n returnCentroid?: boolean;\r\n returnGeometry?: boolean;\r\n returnExtent?: boolean;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AGOLService {\r\n constructor(\r\n private appConfigService: AppConfigService,\r\n protected http: HttpClient,\r\n ) {\r\n /* empty */\r\n }\r\n\r\n getFirePerimetre(fireNumber: string, options: AgolOptions = null) {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLperimetres'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n // append query. Only search for Fire events\r\n url += `query?where=FIRE_NUMBER='${fireNumber}'&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getEvacOrdersByEventNumber(\r\n eventNumber: string,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLevacOrders'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n // append query. Only search for Fire events\r\n url += `query?where=EVENT_NUMBER='${eventNumber}'&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getEvacOrders(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLevacOrders'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query. Only search for Fire events\r\n url += `query?where=EVENT_TYPE='Wildfire' OR EVENT_TYPE='fire'${\r\n where ? ' AND (' + where + ')' : ''\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n url = encodeURI(url).replaceAll(' ', '%20')\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(url, { headers });\r\n }\r\n\r\n getEvacOrdersByParam(where: string, options: AgolOptions = null): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLevacOrders'].toString();\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n // append query. Only search for Fire events\r\n url += `query?where=${where}&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getAreaRestrictions(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLareaRestrictions'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=${\r\n where ? where : '1=1'\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getBansAndProhibitionsById(\r\n sysId: string,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLBansAndProhibitions'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=PROT_BAP_SYSID=${sysId}&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getBansAndProhibitions(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLBansAndProhibitions'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=${\r\n where ? where : '1=1'\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n getAreaRestrictionsWfs() {\r\n const url =\r\n 'https://openmaps.gov.bc.ca/geo/pub/WHSE_LAND_AND_NATURAL_RESOURCE.PROT_RESTRICTED_AREAS_SP/ows?service=wfs&version=1.1.0&request=GetFeature&typename=WHSE_LAND_AND_NATURAL_RESOURCE.PROT_RESTRICTED_AREAS_SP&outputFormat=application/json&SRSName=urn:x-ogc:def:crs:EPSG:4326';\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n\r\n // Wont be needed when we point to our internal cache\r\n getActiveFireCount(): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLactiveFirest'].toString();\r\n url += `/query?f=json&where=FIRE_STATUS <> 'Out'&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&outStatistics=[{\\\"statisticType\\\":\\\"count\\\",\\\"onStatisticField\\\":\\\"OBJECTID\\\",\\\"outStatisticFieldName\\\":\\\"value\\\"}]`;\r\n return this.http.get(encodeURI(url));\r\n }\r\n\r\n getActiveFiresNoGeom(): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLactiveFirest'].toString();\r\n url += `/query?f=json&where=FIRE_STATUS <> 'Out'&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*`;\r\n return this.http.get(encodeURI(url));\r\n }\r\n\r\n getOutFiresNoGeom(): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLactiveFirest'].toString();\r\n url += `/query?f=json&where=FIRE_STATUS = 'Out'&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*`;\r\n return this.http.get(encodeURI(url));\r\n }\r\n\r\n getCurrentYearFireLastXDaysStats(lastXDays: number): Observable {\r\n const startdate = new Date();\r\n const enddate = new Date();\r\n startdate.setDate(startdate.getDate() - lastXDays);\r\n const sStartdate = `${startdate.getFullYear()}-${\r\n startdate.getMonth() + 1\r\n }-${startdate.getDate()} ${\r\n startdate.getHours() < 10 ? '0' : ''\r\n }${startdate.getHours()}:${\r\n startdate.getMinutes() < 10 ? '0' : ''\r\n }${startdate.getMinutes()}:${\r\n startdate.getSeconds() < 10 ? '0' : ''\r\n }${startdate.getSeconds()}`;\r\n const sEnddate = `${enddate.getFullYear()}-${\r\n enddate.getMonth() + 1\r\n }-${enddate.getDate()} ${\r\n enddate.getHours() < 10 ? '0' : ''\r\n }${enddate.getHours()}:${\r\n enddate.getMinutes() < 10 ? '0' : ''\r\n }${enddate.getMinutes()}:${\r\n enddate.getSeconds() < 10 ? '0' : ''\r\n }${enddate.getSeconds()}`;\r\n\r\n let url =\r\n `${\r\n this.appConfigService.getConfig().externalAppConfig['AGOLactiveFirest']\r\n }/query?f=json&` +\r\n `where=IGNITION_DATE<=timestamp '${sEnddate}' AND IGNITION_DATE>=timestamp '${sStartdate}'` +\r\n `&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*` +\r\n `&outStatistics=[{\\\"statisticType\\\":\\\"count\\\",\\\"onStatisticField\\\":\\\"OBJECTID\\\",\\\"outStatisticFieldName\\\":\\\"value\\\"}]`;\r\n url = encodeURI(url);\r\n return this.http.get(url);\r\n }\r\n\r\n getCurrentYearFireStats(): Observable {\r\n let url = `${\r\n this.appConfigService.getConfig().externalAppConfig['AGOLactiveFirest']\r\n }/query?f=json&where=1=1&returnGeometry=false&spatialRel=esriSpatialRelIntersects&\r\n outFields=*&outStatistics=[{\\\"statisticType\\\":\\\"count\\\",\\\"onStatisticField\\\":\\\"OBJECTID\\\",\\\"outStatisticFieldName\\\":\\\"value\\\"}]`;\r\n url = encodeURI(url);\r\n return this.http.get(url);\r\n }\r\n\r\n getDangerRatings(\r\n where: string | null,\r\n location: { x: number; y: number; radius: number | null } | null = null,\r\n options: AgolOptions = null,\r\n ): Observable {\r\n let url = this.appConfigService\r\n .getConfig()\r\n .externalAppConfig['AGOLDangerRatings'].toString();\r\n\r\n if (!url.endsWith('/')) {\r\n url += '/';\r\n }\r\n\r\n // append query\r\n url += `query?where=${\r\n where ? where : '1=1'\r\n }&geometryType=esriGeometryEnvelope&inSR=4326&spatialRel=esriSpatialRelIntersects&units=esriSRUnit_Meter&outFields=*&returnGeometry=${\r\n options && options.returnGeometry ? true : false\r\n }&returnCentroid=${\r\n options && options.returnCentroid ? true : false\r\n }&returnExtentOnly=${\r\n options && options.returnExtent ? true : false\r\n }&featureEncoding=esriDefault&outSR=4326&defaultSR=4326&returnIdsOnly=false&returnQueryGeometry=false&cacheHint=false&returnExceededLimitFeatures=true&sqlFormat=none&f=pjson&token=`;\r\n if (location) {\r\n if (location.radius) {\r\n const turf = window['turf'];\r\n const point = turf.point([location.x, location.y]);\r\n const buffered = turf.buffer(point, location.radius, {\r\n units: 'kilometers',\r\n });\r\n const bbox = turf.bbox(buffered);\r\n\r\n url += `&geometry=${bbox}`;\r\n } else {\r\n url += `&geometry=${location.x - 1},${location.y - 1},${\r\n location.x + 1\r\n },${location.y + 1}`;\r\n }\r\n }\r\n\r\n const headers = new HttpHeaders();\r\n headers.append('Access-Control-Allow-Origin', '*');\r\n headers.append('Accept', '*/*');\r\n return this.http.get(encodeURI(url), { headers });\r\n }\r\n}\r\n",
+ "constructorObj": {
+ "name": "constructor",
+ "description": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "args": [
+ {
+ "name": "appConfigService",
+ "type": "AppConfigService",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "http",
+ "type": "HttpClient",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "line": 15,
+ "jsdoctags": [
+ {
+ "name": "appConfigService",
+ "type": "AppConfigService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "http",
+ "type": "HttpClient",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ "extends": [],
+ "type": "injectable"
+ },
+ {
+ "name": "ApplicationStateService",
+ "id": "injectable-ApplicationStateService-e4484584290ee0426630c116415b3f809a928a5613e3a2d4eeef6d9e5d364798a9a1ba7fece07b0c38cb308ea35ca1163557191d11572d7959bb970e45a4e409",
+ "file": "src/app/services/application-state.service.ts",
+ "properties": [
+ {
+ "name": "tokenService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "TokenService",
+ "optional": false,
+ "description": "",
+ "line": 12
+ },
+ {
+ "name": "weatherHistoryOptions",
+ "defaultValue": "{\r\n historyLength: 72,\r\n chartDataSources: [\r\n {\r\n property: 'temp',\r\n title: 'Temperature',\r\n },\r\n {\r\n property: 'relativeHumidity',\r\n title: 'Relative Humidity',\r\n },\r\n ],\r\n includedSources: [],\r\n }",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "WeatherHistoryOptions",
+ "optional": false,
+ "description": "",
+ "line": 13,
+ "modifierKind": [
+ 123
+ ]
+ }
+ ],
+ "methods": [
+ {
+ "name": "checkMobileResolution",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 53,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 123
+ ]
+ },
+ {
+ "name": "doesUserHaveScopes",
+ "args": [
+ {
+ "name": "scopes",
+ "type": "string[]",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 69,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ],
+ "jsdoctags": [
+ {
+ "name": "scopes",
+ "type": "string[]",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getDevice",
+ "args": [],
+ "optional": false,
+ "returnType": "WfDevice",
+ "typeParameters": [],
+ "line": 34,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getIsMobileResolution",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 65,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "getOrientation",
+ "args": [],
+ "optional": false,
+ "returnType": "\"landscape\" | \"portrait\"",
+ "typeParameters": [],
+ "line": 45,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getTokenService",
+ "args": [],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 83,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 123
+ ]
+ },
+ {
+ "name": "getUserCredentialsEmitter",
+ "args": [],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 73,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "getUserDetails",
+ "args": [],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 77,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "getWeatherHistoryOptions",
+ "args": [],
+ "optional": false,
+ "returnType": "WeatherHistoryOptions",
+ "typeParameters": [],
+ "line": 96,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "isAdminPageAccessable",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 89,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "setWeatherHistoryOptions",
+ "args": [
+ {
+ "name": "opt",
+ "type": "WeatherHistoryOptions",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "WeatherHistoryOptions",
+ "typeParameters": [],
+ "line": 100,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ],
+ "jsdoctags": [
+ {
+ "name": "opt",
+ "type": "WeatherHistoryOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ }
+ ],
+ "deprecated": false,
+ "deprecationMessage": "",
+ "description": "",
+ "rawdescription": "\n",
+ "sourceCode": "import { Injectable, Injector } from '@angular/core';\r\nimport { TokenService } from '@wf1/core-ui';\r\nimport { WfDevice } from '@wf1/wfcc-application-ui';\r\nimport { ROLES_UI } from '../shared/scopes/scopes';\r\nimport { Router } from '@angular/router';\r\nimport { MatDialog } from '@angular/material/dialog';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ApplicationStateService {\r\n tokenService: TokenService;\r\n private weatherHistoryOptions: WeatherHistoryOptions = {\r\n historyLength: 72,\r\n chartDataSources: [\r\n {\r\n property: 'temp',\r\n title: 'Temperature',\r\n },\r\n {\r\n property: 'relativeHumidity',\r\n title: 'Relative Humidity',\r\n },\r\n ],\r\n includedSources: [],\r\n };\r\n\r\n constructor(\r\n private injector: Injector,\r\n private router: Router,\r\n private dialog: MatDialog,\r\n ) {}\r\n\r\n getDevice(): WfDevice {\r\n if (\r\n window.innerWidth < 768 ||\r\n (window.innerWidth >= 768 && window.innerHeight < 450)\r\n ) {\r\n return 'mobile';\r\n }\r\n\r\n return 'desktop';\r\n }\r\n\r\n getOrientation(): 'landscape' | 'portrait' {\r\n if (window.innerWidth > window.innerHeight) {\r\n return 'landscape';\r\n }\r\n\r\n return 'portrait';\r\n }\r\n\r\n private checkMobileResolution() {\r\n if (\r\n window.innerWidth < 768 ||\r\n (window.innerWidth < 900 &&\r\n window.innerHeight < 450) /*support for landscape mobile views*/\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n public getIsMobileResolution(): boolean {\r\n return this.checkMobileResolution();\r\n }\r\n\r\n public doesUserHaveScopes(scopes: string[]): boolean {\r\n return this.getTokenService().doesUserHaveApplicationPermissions(scopes);\r\n }\r\n\r\n public getUserCredentialsEmitter() {\r\n return this.getTokenService().credentialsEmitter;\r\n }\r\n\r\n public getUserDetails() {\r\n return this.getTokenService()\r\n ? this.getTokenService().getTokenDetails()\r\n : null;\r\n }\r\n\r\n private getTokenService() {\r\n return this.tokenService\r\n ? this.tokenService\r\n : this.injector.get(TokenService);\r\n }\r\n\r\n public isAdminPageAccessable(): boolean {\r\n return (\r\n this.doesUserHaveScopes([ROLES_UI.ADMIN]) ||\r\n this.doesUserHaveScopes([ROLES_UI.IM_ADMIN])\r\n );\r\n }\r\n\r\n public getWeatherHistoryOptions(): WeatherHistoryOptions {\r\n return this.weatherHistoryOptions;\r\n }\r\n\r\n public setWeatherHistoryOptions(opt: WeatherHistoryOptions) {\r\n return (this.weatherHistoryOptions = opt);\r\n }\r\n}\r\n\r\nexport interface WeatherHistoryOptions {\r\n historyLength: number; // hours\r\n chartDataSources: {\r\n property: string;\r\n title: string;\r\n }[];\r\n includedSources: {\r\n property: string;\r\n }[];\r\n}\r\n",
+ "constructorObj": {
+ "name": "constructor",
+ "description": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "args": [
+ {
+ "name": "injector",
+ "type": "Injector",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "router",
+ "type": "Router",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "dialog",
+ "type": "MatDialog",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "line": 26,
+ "jsdoctags": [
+ {
+ "name": "injector",
+ "type": "Injector",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "router",
+ "type": "Router",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "dialog",
+ "type": "MatDialog",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ "extends": [],
+ "type": "injectable"
+ },
+ {
+ "name": "BaseComponent",
+ "id": "injectable-BaseComponent-30aa0f6062dc6fa64c38c925822ada46b663bc38cd24076cb8e1df432f1548d05237b48f6709350aa8c901c4f30d62a0adf16fea2b9636685802dd6f58cce3b1",
+ "file": "src/app/components/base/base.component.ts",
+ "properties": [
+ {
+ "name": "backRoute",
+ "defaultValue": "null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "ResourcesRoutes",
+ "optional": false,
+ "description": "",
+ "line": 52
+ },
+ {
+ "name": "backRouteLabel",
+ "defaultValue": "null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 54
+ },
+ {
+ "name": "backRouteQueryParams",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": false,
+ "description": "",
+ "line": 53
+ },
+ {
+ "name": "componentId",
+ "defaultValue": "''",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 59
+ },
+ {
+ "name": "config",
+ "defaultValue": "{\r\n id: 'Paginator',\r\n itemsPerPage: 5,\r\n currentPage: 1,\r\n totalItems: 0,\r\n }",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "PaginationInstance",
+ "optional": false,
+ "description": "",
+ "line": 76
+ },
+ {
+ "name": "CONSTANTS",
+ "defaultValue": "CONSTANTS",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 62
+ },
+ {
+ "name": "DATE_FORMATS",
+ "defaultValue": "DATE_FORMATS",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 67
+ },
+ {
+ "name": "displayLabel",
+ "defaultValue": "'Data'",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 50
+ },
+ {
+ "name": "getElementInnerText",
+ "defaultValue": "getElementInnerText",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 73
+ },
+ {
+ "name": "isConnected",
+ "defaultValue": "true",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 56
+ },
+ {
+ "name": "isElementTruncated",
+ "defaultValue": "isElementTruncated",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 74
+ },
+ {
+ "name": "isLoading",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 58
+ },
+ {
+ "name": "isUnsaved",
+ "defaultValue": "false",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 71
+ },
+ {
+ "name": "mobile",
+ "defaultValue": "this.getIsMobileResolution()",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 60
+ },
+ {
+ "name": "model",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "BaseComponentModel",
+ "optional": false,
+ "description": "",
+ "line": 93,
+ "modifierKind": [
+ 124
+ ]
+ },
+ {
+ "name": "paginatorLabels",
+ "defaultValue": "{\r\n previousLabel: '',\r\n nextLabel: '',\r\n }",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": false,
+ "description": "",
+ "line": 83,
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "SAVE_FAIL_TEXT",
+ "defaultValue": "'Save failed'",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 64
+ },
+ {
+ "name": "SAVE_SUCCESS_TEXT",
+ "defaultValue": "'Saved Successfully'",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 65
+ },
+ {
+ "name": "showingErrorDialog",
+ "defaultValue": "false",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 51
+ },
+ {
+ "name": "simplePaginatorLabels",
+ "defaultValue": "{\r\n previousLabel: 'Back',\r\n nextLabel: 'Next',\r\n }",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "any",
+ "optional": false,
+ "description": "",
+ "line": 88,
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "summaryString",
+ "defaultValue": "null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 55
+ },
+ {
+ "name": "unsavedChangesMessage",
+ "defaultValue": "'Unsaved Changes'",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 69
+ },
+ {
+ "name": "viewModel",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "BaseComponentModel",
+ "optional": false,
+ "description": "",
+ "line": 57,
+ "modifierKind": [
+ 125
+ ]
+ }
+ ],
+ "methods": [
+ {
+ "name": "disableBatchSaveForm",
+ "args": [
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "form",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true
+ }
+ ],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 182,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "form",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true,
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "disableSaveForm",
+ "args": [
+ {
+ "name": "form",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true
+ }
+ ],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 177,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "form",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true,
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "doUnsavedStateUpdateIfNeeded",
+ "args": [
+ {
+ "name": "componentId",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "newUnsavedState",
+ "type": "boolean",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 234,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "componentId",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "newUnsavedState",
+ "type": "boolean",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getActionRowClass",
+ "args": [],
+ "optional": false,
+ "returnType": "string",
+ "typeParameters": [],
+ "line": 260,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getAsFormGroup",
+ "args": [
+ {
+ "name": "ac",
+ "type": "AbstractControl",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "UntypedFormGroup",
+ "typeParameters": [],
+ "line": 173,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "ac",
+ "type": "AbstractControl",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getIsMobileResolution",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 163,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getPagingConfig",
+ "args": [],
+ "optional": false,
+ "returnType": "PaginationInstance",
+ "typeParameters": [],
+ "line": 115,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "hasAddedUnsavedItemNotBlank",
+ "args": [
+ {
+ "name": "fgMain",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 238,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "fgMain",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "initModels",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 119,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "invokeAfterLoaded",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 155,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "loadPage",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 123,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "ngAfterViewInit",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 135,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "ngOnChanges",
+ "args": [
+ {
+ "name": "changes",
+ "type": "SimpleChanges",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 139,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "changes",
+ "type": "SimpleChanges",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "ngOnInit",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 131,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "redirectWithOAuth",
+ "args": [
+ {
+ "name": "redirectRoutePath",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 167,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "redirectRoutePath",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "reload",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 127,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "unsavedBatchForm",
+ "args": [
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 218,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "unsavedForm",
+ "args": [
+ {
+ "name": "form",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true
+ },
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true
+ }
+ ],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 208,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "form",
+ "type": "UntypedFormGroup",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true,
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "arrayProperty",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true,
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "updateView",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 159,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 124
+ ]
+ }
+ ],
+ "deprecated": false,
+ "deprecationMessage": "",
+ "description": "",
+ "rawdescription": "\n",
+ "sourceCode": "import {\r\n AfterViewInit,\r\n ChangeDetectorRef,\r\n Directive,\r\n Injectable,\r\n Input,\r\n OnChanges,\r\n OnInit,\r\n SimpleChanges,\r\n} from '@angular/core';\r\nimport { ActivatedRoute, Router } from '@angular/router';\r\nimport { DomSanitizer } from '@angular/platform-browser';\r\nimport { Store } from '@ngrx/store';\r\nimport { BaseComponentModel } from './base.component.model';\r\nimport {\r\n DATE_FORMATS,\r\n getElementInnerText,\r\n hasValues,\r\n isElementTruncated,\r\n ResourcesRoutes,\r\n} from '../../../app/utils';\r\nimport {\r\n AbstractControl,\r\n UntypedFormBuilder,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\nimport { Overlay } from '@angular/cdk/overlay';\r\nimport { ApplicationStateService } from '../../services/application-state.service';\r\nimport { AppConfigService, TokenService } from '@wf1/core-ui';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\nimport { PaginationInstance } from 'ngx-pagination';\r\nimport { RootState } from '../../store';\r\nimport {\r\n ErrorState,\r\n LoadState,\r\n} from '../../store/application/application.state';\r\nimport { CONSTANTS } from '../../../app/utils/index';\r\nimport { CommonUtilityService } from '../../services/common-utility.service';\r\nimport { WatchlistService } from '../../services/watchlist-service';\r\n\r\n@Directive()\r\n@Injectable()\r\nexport class BaseComponent implements OnInit, OnChanges, AfterViewInit {\r\n @Input() loadState: LoadState;\r\n @Input() errorState: ErrorState[];\r\n @Input() saveErrorState: ErrorState[];\r\n @Input() severeErrorState?: ErrorState[];\r\n displayLabel = 'Data';\r\n showingErrorDialog = false;\r\n backRoute: ResourcesRoutes = null;\r\n backRouteQueryParams: any;\r\n backRouteLabel: string = null;\r\n summaryString: string = null;\r\n isConnected = true;\r\n public viewModel: BaseComponentModel;\r\n isLoading: boolean;\r\n componentId = '';\r\n mobile = this.getIsMobileResolution();\r\n\r\n CONSTANTS = CONSTANTS;\r\n\r\n SAVE_FAIL_TEXT = 'Save failed';\r\n SAVE_SUCCESS_TEXT = 'Saved Successfully';\r\n\r\n DATE_FORMATS = DATE_FORMATS;\r\n\r\n unsavedChangesMessage = 'Unsaved Changes';\r\n\r\n isUnsaved = false;\r\n\r\n getElementInnerText = getElementInnerText;\r\n isElementTruncated = isElementTruncated;\r\n\r\n config: PaginationInstance = {\r\n id: 'Paginator',\r\n itemsPerPage: 5,\r\n currentPage: 1,\r\n totalItems: 0,\r\n };\r\n\r\n public paginatorLabels: any = {\r\n previousLabel: '',\r\n nextLabel: '',\r\n };\r\n\r\n public simplePaginatorLabels: any = {\r\n previousLabel: 'Back',\r\n nextLabel: 'Next',\r\n };\r\n\r\n protected model: BaseComponentModel;\r\n\r\n constructor(\r\n protected router: Router,\r\n protected route: ActivatedRoute,\r\n protected sanitizer: DomSanitizer,\r\n protected store: Store,\r\n protected fb: UntypedFormBuilder,\r\n protected dialog: MatDialog,\r\n protected applicationStateService: ApplicationStateService,\r\n protected tokenService: TokenService,\r\n protected snackbarService: MatSnackBar,\r\n protected overlay: Overlay,\r\n protected cdr: ChangeDetectorRef,\r\n protected appConfigService: AppConfigService,\r\n protected http: HttpClient,\r\n protected watchlistService: WatchlistService,\r\n protected commonUtilityService?: CommonUtilityService,\r\n ) {\r\n this.initModels();\r\n }\r\n\r\n getPagingConfig(): PaginationInstance {\r\n return this.config;\r\n }\r\n\r\n initModels() {\r\n /* empty, for override purposes only */\r\n }\r\n\r\n loadPage() {\r\n /* empty, for override purposes only */\r\n }\r\n\r\n reload() {\r\n /* empty, for override purposes only */\r\n }\r\n\r\n ngOnInit() {\r\n this.loadPage();\r\n }\r\n\r\n ngAfterViewInit() {\r\n /* empty */\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n if (changes.loadState && changes.loadState.currentValue) {\r\n this.isLoading = changes.loadState.currentValue.isLoading;\r\n const previousValue = changes.loadState.previousValue;\r\n if (!this.isLoading && previousValue && previousValue.isLoading) {\r\n this.invokeAfterLoaded();\r\n }\r\n }\r\n if (changes.errorState) {\r\n this.errorState = changes.errorState.currentValue as ErrorState[];\r\n if (this.viewModel.formGroup) {\r\n this.viewModel.setErrorState(this.errorState);\r\n }\r\n }\r\n }\r\n\r\n invokeAfterLoaded() {\r\n /* empty, for override purposes only */\r\n }\r\n\r\n protected updateView(): void {\r\n this.viewModel = this.model.clone();\r\n }\r\n\r\n getIsMobileResolution(): boolean {\r\n return this.applicationStateService.getIsMobileResolution();\r\n }\r\n\r\n redirectWithOAuth(redirectRoutePath: string) {\r\n const baseUrl = this.appConfigService.getConfig().application.baseUrl;\r\n const url = baseUrl;\r\n window.location.href = url;\r\n }\r\n\r\n getAsFormGroup(ac: AbstractControl): UntypedFormGroup {\r\n return ac as UntypedFormGroup;\r\n }\r\n\r\n disableSaveForm(form?: UntypedFormGroup): boolean {\r\n const fg = form ? form : this.viewModel.formGroup;\r\n return !fg.dirty || !fg.valid;\r\n }\r\n\r\n disableBatchSaveForm(\r\n arrayProperty: string,\r\n form?: UntypedFormGroup,\r\n ): boolean {\r\n const fg = form ? form : this.viewModel.formGroup;\r\n //Check form array for dirty flag\r\n const fgArray: UntypedFormGroup[] = fg?.controls[arrayProperty]['controls'];\r\n\r\n const arrayHasDirtyFlag = fgArray.some((contactFg) => contactFg.dirty);\r\n const arrayHasInvalidFlag = fgArray.some((contactFg) => !contactFg.valid);\r\n\r\n /*\r\n * Disable if\r\n * 1) the form array and main form is not dirty OR\r\n * 2) a form array form group is invalid\r\n */\r\n if (!arrayHasDirtyFlag && !fg.dirty) {\r\n return true;\r\n }\r\n if (arrayHasInvalidFlag) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n unsavedForm(form?: UntypedFormGroup, arrayProperty?: string): boolean {\r\n const fg = form ? form : this.viewModel.formGroup;\r\n if (arrayProperty) {\r\n this.unsavedBatchForm(arrayProperty);\r\n } else {\r\n this.doUnsavedStateUpdateIfNeeded(this.componentId, fg.dirty);\r\n }\r\n return fg.dirty;\r\n }\r\n\r\n unsavedBatchForm(arrayProperty: string): boolean {\r\n const fg = this.viewModel.formGroup;\r\n //Check form array for dirty flag\r\n const fgArray: UntypedFormGroup[] = fg?.controls[arrayProperty]['controls'];\r\n const arrayHasDirtyFlag = fgArray.some((contactFg) => contactFg.dirty);\r\n const hasAddedUnsavedItem = this.hasAddedUnsavedItemNotBlank(\r\n fg,\r\n arrayProperty,\r\n );\r\n this.doUnsavedStateUpdateIfNeeded(\r\n this.componentId,\r\n arrayHasDirtyFlag || fg.dirty || hasAddedUnsavedItem,\r\n );\r\n return this.isUnsaved;\r\n }\r\n\r\n doUnsavedStateUpdateIfNeeded(componentId: string, newUnsavedState: boolean) {\r\n this.isUnsaved = newUnsavedState;\r\n }\r\n\r\n hasAddedUnsavedItemNotBlank(fgMain: UntypedFormGroup, arrayProperty: string) {\r\n const controls = fgMain?.controls[arrayProperty]['controls'];\r\n const ret = controls.some((ac) => {\r\n const fg: UntypedFormGroup = ac as UntypedFormGroup;\r\n if (!fg.get('id').value && controls.length > 1) {\r\n //not a default empty entry\r\n return true;\r\n } else if (!fg.get('id').value && controls.length == 1) {\r\n //check if empty entry\r\n const item = fg.getRawValue();\r\n if (!hasValues(item)) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n } else {\r\n return false;\r\n }\r\n });\r\n return ret;\r\n }\r\n\r\n getActionRowClass() {\r\n return 'space-between';\r\n }\r\n}\r\n",
+ "constructorObj": {
+ "name": "constructor",
+ "description": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "args": [
+ {
+ "name": "router",
+ "type": "Router",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "route",
+ "type": "ActivatedRoute",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "sanitizer",
+ "type": "DomSanitizer",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "store",
+ "type": "Store",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "fb",
+ "type": "UntypedFormBuilder",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "dialog",
+ "type": "MatDialog",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "applicationStateService",
+ "type": "ApplicationStateService",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "tokenService",
+ "type": "TokenService",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "snackbarService",
+ "type": "MatSnackBar",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "overlay",
+ "type": "Overlay",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "cdr",
+ "type": "ChangeDetectorRef",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "appConfigService",
+ "type": "AppConfigService",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "http",
+ "type": "HttpClient",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "watchlistService",
+ "type": "WatchlistService",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "commonUtilityService",
+ "type": "CommonUtilityService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true
+ }
+ ],
+ "line": 93,
+ "jsdoctags": [
+ {
+ "name": "router",
+ "type": "Router",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "route",
+ "type": "ActivatedRoute",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "sanitizer",
+ "type": "DomSanitizer",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "store",
+ "type": "Store",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "fb",
+ "type": "UntypedFormBuilder",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "dialog",
+ "type": "MatDialog",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "applicationStateService",
+ "type": "ApplicationStateService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "tokenService",
+ "type": "TokenService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "snackbarService",
+ "type": "MatSnackBar",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "overlay",
+ "type": "Overlay",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "cdr",
+ "type": "ChangeDetectorRef",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "appConfigService",
+ "type": "AppConfigService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "http",
+ "type": "HttpClient",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "watchlistService",
+ "type": "WatchlistService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "commonUtilityService",
+ "type": "CommonUtilityService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true,
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ "extends": [],
+ "type": "injectable"
+ },
+ {
+ "name": "BaseContainer",
+ "id": "injectable-BaseContainer-dd102ccb78908565418b4af0cc1e79c96d3486a13959717bb1f6f7e2facbd4c65b5a5919ae1119cba9ce98609d973538bf4e1ee270d08c4dc5b906ec1a9c8346",
+ "file": "src/app/containers/base/base-container.component.ts",
+ "properties": [
+ {
+ "name": "displayLabel",
+ "defaultValue": "''",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 16
+ },
+ {
+ "name": "hasUnsavedForms",
+ "defaultValue": "false",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 14
+ },
+ {
+ "name": "snackBar",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "MatSnackBar",
+ "optional": false,
+ "description": "",
+ "line": 21,
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "unsavedForms$",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Observable",
+ "optional": false,
+ "description": "",
+ "line": 13
+ },
+ {
+ "name": "unsavedFormsSub",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Subscription",
+ "optional": false,
+ "description": "",
+ "line": 15
+ }
+ ],
+ "methods": [
+ {
+ "name": "getAssociatedComponentIds",
+ "args": [],
+ "optional": false,
+ "returnType": "string[]",
+ "typeParameters": [],
+ "line": 40,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getDisplayLabel",
+ "args": [],
+ "optional": false,
+ "returnType": "string",
+ "typeParameters": [],
+ "line": 48,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "getHasUnsavedForms",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 44,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "ngOnDestroy",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 34,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "onBeforeUnload",
+ "args": [
+ {
+ "name": "event",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 53,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "decorators": [
+ {
+ "name": "HostListener",
+ "stringifiedArguments": "'window:beforeunload', ['$event']"
+ }
+ ],
+ "modifierKind": [
+ 170
+ ],
+ "jsdoctags": [
+ {
+ "name": "event",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ }
+ ],
+ "deprecated": false,
+ "deprecationMessage": "",
+ "description": "",
+ "rawdescription": "\n",
+ "sourceCode": "import { Directive, HostListener, Injectable, OnDestroy } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { select, Store } from '@ngrx/store';\r\nimport { RootState } from '../../store';\r\nimport { ApplicationStateService } from '../../services/application-state.service';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\nimport { Observable, Subscription } from 'rxjs';\r\nimport { selectFormStatesUnsaved } from '../../store/application/application.selector';\r\n\r\n@Directive()\r\n@Injectable()\r\nexport class BaseContainer implements OnDestroy {\r\n unsavedForms$: Observable;\r\n hasUnsavedForms = false;\r\n unsavedFormsSub: Subscription;\r\n displayLabel = '';\r\n\r\n constructor(\r\n protected store: Store,\r\n protected router: Router,\r\n public snackBar: MatSnackBar,\r\n protected applicationStateService: ApplicationStateService,\r\n ) {\r\n this.unsavedForms$ = this.store.pipe(\r\n select(selectFormStatesUnsaved(this.getAssociatedComponentIds())),\r\n );\r\n if (this.unsavedForms$) {\r\n this.unsavedFormsSub = this.unsavedForms$.subscribe((value) => {\r\n this.hasUnsavedForms = value;\r\n });\r\n }\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.unsavedFormsSub) {\r\n this.unsavedFormsSub.unsubscribe();\r\n }\r\n }\r\n\r\n getAssociatedComponentIds(): string[] {\r\n return [];\r\n }\r\n\r\n public getHasUnsavedForms(): boolean {\r\n return this.hasUnsavedForms;\r\n }\r\n\r\n public getDisplayLabel(): string {\r\n return this.displayLabel;\r\n }\r\n\r\n @HostListener('window:beforeunload', ['$event'])\r\n onBeforeUnload(event) {\r\n if (this.hasUnsavedForms) {\r\n event.preventDefault();\r\n event.returnValue = true; //force a browser confirmation before closing the tab/window\r\n }\r\n }\r\n}\r\n",
+ "constructorObj": {
+ "name": "constructor",
+ "description": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "args": [
+ {
+ "name": "store",
+ "type": "Store",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "router",
+ "type": "Router",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "snackBar",
+ "type": "MatSnackBar",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "applicationStateService",
+ "type": "ApplicationStateService",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "line": 16,
+ "jsdoctags": [
+ {
+ "name": "store",
+ "type": "Store",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "router",
+ "type": "Router",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "snackBar",
+ "type": "MatSnackBar",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "applicationStateService",
+ "type": "ApplicationStateService",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ "extends": [],
+ "type": "injectable"
+ },
+ {
+ "name": "CapacitorService",
+ "id": "injectable-CapacitorService-8535ce51ccdad526d840669937c2863b8c4704ebacf2e5a788764298904f6dbe7761d1eb638a976f40486932cb843e69f3a4250037faa79d75e0a3680ed65ea9",
+ "file": "src/app/services/capacitor-service.ts",
+ "properties": [
+ {
+ "name": "appState",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "AppState",
+ "optional": false,
+ "description": "",
+ "line": 67
+ },
+ {
+ "name": "currentHeadingPromise",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Promise",
+ "optional": false,
+ "description": "",
+ "line": 75
+ },
+ {
+ "name": "deviceId",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "string",
+ "optional": false,
+ "description": "",
+ "line": 71
+ },
+ {
+ "name": "devicePropertiesPromise",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Promise",
+ "optional": false,
+ "description": "",
+ "line": 84,
+ "modifierKind": [
+ 123
+ ]
+ },
+ {
+ "name": "fbAppInstalled",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 65
+ },
+ {
+ "name": "inactiveStart",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 78
+ },
+ {
+ "name": "initialized",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "Promise",
+ "optional": false,
+ "description": "",
+ "line": 64
+ },
+ {
+ "name": "isAndroidPlatform",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 69
+ },
+ {
+ "name": "isIOSPlatform",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 68
+ },
+ {
+ "name": "isWebPlatform",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 70
+ },
+ {
+ "name": "locationNotifications",
+ "defaultValue": "new EventEmitter()",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 76
+ },
+ {
+ "name": "locationNotificationsDelay",
+ "defaultValue": "5000",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 80
+ },
+ {
+ "name": "notificationSnackbarPromise",
+ "defaultValue": "Promise.resolve()",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 82
+ },
+ {
+ "name": "notificationToken",
+ "defaultValue": "null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "null",
+ "optional": false,
+ "description": "",
+ "line": 73
+ },
+ {
+ "name": "pnNav",
+ "defaultValue": "null",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "null",
+ "optional": false,
+ "description": "",
+ "line": 72
+ },
+ {
+ "name": "refreshTimer",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 79
+ },
+ {
+ "name": "registeredForNotifications",
+ "defaultValue": "false",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 83
+ },
+ {
+ "name": "resume",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "BehaviorSubject",
+ "optional": false,
+ "description": "",
+ "line": 63
+ },
+ {
+ "name": "rofNotifications",
+ "defaultValue": "new EventEmitter()",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 77
+ },
+ {
+ "name": "rofNotificationsDelay",
+ "defaultValue": "5000",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "number",
+ "optional": false,
+ "description": "",
+ "line": 81
+ },
+ {
+ "name": "twitterAppInstalled",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "boolean",
+ "optional": false,
+ "description": "",
+ "line": 66
+ },
+ {
+ "name": "updateMainMapLayers",
+ "defaultValue": "new EventEmitter()",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "type": "",
+ "optional": false,
+ "description": "",
+ "line": 74
+ }
+ ],
+ "methods": [
+ {
+ "name": "appIsInstalled",
+ "args": [
+ {
+ "name": "scheme",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "Promise",
+ "typeParameters": [],
+ "line": 424,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 123,
+ 134
+ ],
+ "jsdoctags": [
+ {
+ "name": "scheme",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "checkDevice",
+ "args": [],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 346,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "checkDeviceSystem",
+ "args": [],
+ "optional": false,
+ "returnType": "unknown",
+ "typeParameters": [],
+ "line": 504,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 134
+ ]
+ },
+ {
+ "name": "checkFbAppInstalled",
+ "args": [],
+ "optional": false,
+ "returnType": "Promise",
+ "typeParameters": [],
+ "line": 415,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 123,
+ 134
+ ]
+ },
+ {
+ "name": "checkInstalledApps",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 373,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "checkTwitterAppInstalled",
+ "args": [],
+ "optional": false,
+ "returnType": "Promise",
+ "typeParameters": [],
+ "line": 406,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 123,
+ 134
+ ]
+ },
+ {
+ "name": "emitLocationNotification",
+ "args": [
+ {
+ "name": "data",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 314,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "data",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "emitRofNotification",
+ "args": [
+ {
+ "name": "title",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "body",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 271,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "title",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "body",
+ "type": "",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getCurrentHeading",
+ "args": [],
+ "optional": false,
+ "returnType": "Promise",
+ "typeParameters": [],
+ "line": 480,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "getCurrentPosition",
+ "args": [
+ {
+ "name": "options",
+ "type": "PositionOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true
+ }
+ ],
+ "optional": false,
+ "returnType": "Promise",
+ "typeParameters": [],
+ "line": 368,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 134
+ ],
+ "jsdoctags": [
+ {
+ "name": "options",
+ "type": "PositionOptions",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "optional": true,
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getData",
+ "args": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "unknown",
+ "typeParameters": [],
+ "line": 571,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 134
+ ],
+ "jsdoctags": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "getNotificationToken",
+ "args": [],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 448,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "getPnUrl",
+ "args": [],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 444,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "handleLocationPushNotification",
+ "args": [
+ {
+ "name": "notification",
+ "type": "PushNotificationSchema",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 283,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "notification",
+ "type": "PushNotificationSchema",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "handleRofPushNotification",
+ "args": [
+ {
+ "name": "notification",
+ "type": "PushNotificationSchema",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 253,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "notification",
+ "type": "PushNotificationSchema",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "init",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 121,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "initOfflinePageSettings",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 429,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "isAndroid",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 472,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "isIOS",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 476,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "isMobilePlatform",
+ "args": [],
+ "optional": false,
+ "returnType": "boolean",
+ "typeParameters": [],
+ "line": 437,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ]
+ },
+ {
+ "name": "onResume",
+ "args": [],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 393,
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "openLinkInAppBrowser",
+ "args": [
+ {
+ "name": "url",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 397,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "url",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "openUrlInApp",
+ "args": [
+ {
+ "name": "url",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 456,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "url",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "registerForNotifications",
+ "args": [],
+ "optional": false,
+ "returnType": "Promise",
+ "typeParameters": [],
+ "line": 239,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 134
+ ]
+ },
+ {
+ "name": "removeData",
+ "args": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 576,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 134
+ ],
+ "jsdoctags": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "saveData",
+ "args": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ },
+ {
+ "name": "value",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 564,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 134
+ ],
+ "jsdoctags": [
+ {
+ "name": "key",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ },
+ {
+ "name": "value",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "setNotificationToken",
+ "args": [
+ {
+ "name": "token",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "void",
+ "typeParameters": [],
+ "line": 452,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "modifierKind": [
+ 125
+ ],
+ "jsdoctags": [
+ {
+ "name": "token",
+ "type": "string",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ },
+ {
+ "name": "showNotificationSnackbar",
+ "args": [
+ {
+ "name": "notification",
+ "type": "any",
+ "deprecated": false,
+ "deprecationMessage": ""
+ }
+ ],
+ "optional": false,
+ "returnType": "any",
+ "typeParameters": [],
+ "line": 335,
+ "deprecated": false,
+ "deprecationMessage": "",
+ "jsdoctags": [
+ {
+ "name": "notification",
+ "type": "any",
+ "deprecated": false,
+ "deprecationMessage": "",
+ "tagName": {
+ "text": "param"
+ }
+ }
+ ]
+ }
+ ],
+ "deprecated": false,
+ "deprecationMessage": "",
+ "description": "",
+ "rawdescription": "\n",
+ "sourceCode": "import { EventEmitter, Injectable, NgZone } from '@angular/core';\r\nimport { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';\r\nimport { Router } from '@angular/router';\r\nimport { FCM } from '@capacitor-community/fcm';\r\nimport { App, AppState } from '@capacitor/app';\r\nimport { AppLauncher } from '@capacitor/app-launcher';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Device } from '@capacitor/device';\r\nimport { Geolocation, Position } from '@capacitor/geolocation';\r\nimport {\r\n PushNotificationSchema,\r\n PushNotifications,\r\n} from '@capacitor/push-notifications';\r\nimport { Store } from '@ngrx/store';\r\nimport { BehaviorSubject, fromEvent } from 'rxjs';\r\nimport { environment } from '../../environments/environment';\r\nimport { RootState } from '../store';\r\nimport { ApplicationStateService } from './application-state.service';\r\nimport { EventEmitterService } from './event-emitter.service';\r\n\r\nimport { ResourcesRoutes } from '@app/utils';\r\nimport { NotificationSnackbarComponent } from '../components/notification-snackbar/notification-snackbar.component';\r\nimport { Preferences } from '@capacitor/preferences';\r\n\r\nexport interface CompassHeading {\r\n magneticHeading?: number; //The heading in degrees from 0-359.99 at a single moment in time. (Number)\r\n trueHeading?: number; //The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. A negative value indicates that the true heading can't be determined. (Number)\r\n headingAccuracy?: number; //The deviation in degrees between the reported heading and the true heading. (Number)\r\n timestamp?: string; //The time at which this heading was determined. (DOMTimeStamp)\r\n error?: string;\r\n}\r\n\r\nexport interface LocationNotification {\r\n latitude: number;\r\n longitude: number;\r\n radius: number;\r\n featureId: string;\r\n featureType: string;\r\n fireYear?: number;\r\n}\r\n\r\nexport interface ReportOfFireNotification {\r\n title: string;\r\n body: string;\r\n}\r\n\r\nexport interface DeviceProperties {\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n isMobilePlatform: boolean;\r\n deviceId: string;\r\n isTwitterInstalled: boolean;\r\n}\r\n\r\nconst UPDATE_AFTER_INACTIVE_MILLIS = 1000 * 60; // 1 minute\r\nconst REFRESH_INTERVAL_ACTIVE_MILLIS = 5 * 1000 * 60; // 5 minutes\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CapacitorService {\r\n resume: BehaviorSubject;\r\n initialized: Promise;\r\n fbAppInstalled: boolean;\r\n twitterAppInstalled: boolean;\r\n appState: AppState;\r\n isIOSPlatform: boolean;\r\n isAndroidPlatform: boolean;\r\n isWebPlatform: boolean;\r\n deviceId: string;\r\n pnNav = null;\r\n notificationToken = null;\r\n updateMainMapLayers = new EventEmitter();\r\n currentHeadingPromise: Promise;\r\n locationNotifications = new EventEmitter