diff --git a/.gitignore b/.gitignore
index 937c0b0f..cadc4152 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,5 +13,6 @@ data/config.ts
public/images-custom/*
+temp/wmf/
temp/config.*
-temp/wmf/
\ No newline at end of file
+temp/*.csv
diff --git a/app.js b/app.js
index 399d4769..4f2f932f 100644
--- a/app.js
+++ b/app.js
@@ -57,6 +57,7 @@ app.use(urlPrefix, express.static(path.join("public")));
app.use(urlPrefix + "/lib/fa", express.static(path.join("node_modules", "@fortawesome", "fontawesome-free")));
app.use(urlPrefix + "/lib/cityssm-bulma-webapp-js", express.static(path.join("node_modules", "@cityssm", "bulma-webapp-js")));
app.use(urlPrefix + "/lib/cityssm-bulma-js", express.static(path.join("node_modules", "@cityssm", "bulma-js", "dist")));
+app.use(urlPrefix + "/lib/leaflet", express.static(path.join("node_modules", "leaflet", "dist")));
const sessionCookieName = configFunctions.getProperty("session.cookieName");
const FileStoreSession = FileStore(session);
app.use(session({
diff --git a/app.ts b/app.ts
index 2495dd4a..f69759cc 100644
--- a/app.ts
+++ b/app.ts
@@ -109,6 +109,9 @@ app.use(urlPrefix + "/lib/cityssm-bulma-webapp-js",
app.use(urlPrefix + "/lib/cityssm-bulma-js",
express.static(path.join("node_modules", "@cityssm", "bulma-js", "dist")));
+app.use(urlPrefix + "/lib/leaflet",
+ express.static(path.join("node_modules", "leaflet", "dist")));
+
/*
* SESSION MANAGEMENT
diff --git a/handlers/maps-get/search.d.ts b/handlers/maps-get/search.d.ts
new file mode 100644
index 00000000..9621c611
--- /dev/null
+++ b/handlers/maps-get/search.d.ts
@@ -0,0 +1,3 @@
+import type { RequestHandler } from "express";
+export declare const handler: RequestHandler;
+export default handler;
diff --git a/handlers/maps-get/search.js b/handlers/maps-get/search.js
new file mode 100644
index 00000000..f6495414
--- /dev/null
+++ b/handlers/maps-get/search.js
@@ -0,0 +1,10 @@
+import * as configFunctions from "../../helpers/functions.config.js";
+import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js";
+export const handler = (_request, response) => {
+ const maps = getMaps();
+ response.render("map-search", {
+ headTitle: configFunctions.getProperty("aliases.map") + " Search",
+ maps
+ });
+};
+export default handler;
diff --git a/handlers/maps-get/search.ts b/handlers/maps-get/search.ts
new file mode 100644
index 00000000..d15163f1
--- /dev/null
+++ b/handlers/maps-get/search.ts
@@ -0,0 +1,23 @@
+import type {
+ RequestHandler
+} from "express";
+
+import * as configFunctions from "../../helpers/functions.config.js";
+
+import {
+ getMaps
+} from "../../helpers/lotOccupancyDB/getMaps.js";
+
+
+export const handler: RequestHandler = (_request, response) => {
+
+ const maps = getMaps();
+
+ response.render("map-search", {
+ headTitle: configFunctions.getProperty("aliases.map") + " Search",
+ maps
+ });
+};
+
+
+export default handler;
\ No newline at end of file
diff --git a/handlers/maps-get/view.d.ts b/handlers/maps-get/view.d.ts
new file mode 100644
index 00000000..9621c611
--- /dev/null
+++ b/handlers/maps-get/view.d.ts
@@ -0,0 +1,3 @@
+import type { RequestHandler } from "express";
+export declare const handler: RequestHandler;
+export default handler;
diff --git a/handlers/maps-get/view.js b/handlers/maps-get/view.js
new file mode 100644
index 00000000..931c4d18
--- /dev/null
+++ b/handlers/maps-get/view.js
@@ -0,0 +1,13 @@
+import * as configFunctions from "../../helpers/functions.config.js";
+import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
+export const handler = (request, response) => {
+ const map = getMap(request.params.mapId);
+ if (!map) {
+ return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound");
+ }
+ response.render("map-view", {
+ headTitle: map.mapName,
+ map
+ });
+};
+export default handler;
diff --git a/handlers/maps-get/view.ts b/handlers/maps-get/view.ts
new file mode 100644
index 00000000..5ac8413c
--- /dev/null
+++ b/handlers/maps-get/view.ts
@@ -0,0 +1,23 @@
+import type { RequestHandler } from "express";
+
+import * as configFunctions from "../../helpers/functions.config.js";
+
+import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
+
+
+export const handler: RequestHandler = (request, response) => {
+
+ const map = getMap(request.params.mapId);
+
+ if (!map) {
+ return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound");
+ }
+
+ response.render("map-view", {
+ headTitle: map.mapName,
+ map
+ });
+};
+
+
+export default handler;
\ No newline at end of file
diff --git a/helpers/databaseInitializer.js b/helpers/databaseInitializer.js
index 98ed9faa..b1a4e601 100644
--- a/helpers/databaseInitializer.js
+++ b/helpers/databaseInitializer.js
@@ -68,6 +68,7 @@ export const initLotOccupancyDB = () => {
" lotTypeId integer not null," +
" lotName varchar(100)," +
" mapId integer," +
+ " mapKey varchar(100)," +
" lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90)," +
" lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180)," +
" lotTypeStatusId integer," +
diff --git a/helpers/databaseInitializer.ts b/helpers/databaseInitializer.ts
index 708ee973..daea6860 100644
--- a/helpers/databaseInitializer.ts
+++ b/helpers/databaseInitializer.ts
@@ -93,6 +93,7 @@ export const initLotOccupancyDB = (): boolean => {
" lotTypeId integer not null," +
" lotName varchar(100)," +
" mapId integer," +
+ " mapKey varchar(100)," +
" lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90)," +
" lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180)," +
diff --git a/helpers/lotOccupancyDB/addLot.d.ts b/helpers/lotOccupancyDB/addLot.d.ts
new file mode 100644
index 00000000..ddd1fff1
--- /dev/null
+++ b/helpers/lotOccupancyDB/addLot.d.ts
@@ -0,0 +1,12 @@
+import type * as recordTypes from "../../types/recordTypes";
+interface AddLotForm {
+ lotName: string;
+ lotTypeId: string | number;
+ lotTypeStatusId: string | number;
+ mapId: string | number;
+ mapKey: string;
+ lotLatitude: string;
+ lotLongitude: string;
+}
+export declare const addLot: (lotForm: AddLotForm, requestSession: recordTypes.PartialSession) => number;
+export default addLot;
diff --git a/helpers/lotOccupancyDB/addLot.js b/helpers/lotOccupancyDB/addLot.js
new file mode 100644
index 00000000..a0659e1a
--- /dev/null
+++ b/helpers/lotOccupancyDB/addLot.js
@@ -0,0 +1,18 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+export const addLot = (lotForm, requestSession) => {
+ const database = sqlite(databasePath);
+ const rightNowMillis = Date.now();
+ const result = database
+ .prepare("insert into Lots (" +
+ "lotName, lotTypeId, lotTypeStatusId," +
+ " mapId, mapKey," +
+ " lotLatitude, lotLongitude," +
+ " recordCreate_userName, recordCreate_timeMillis," +
+ " recordUpdate_userName, recordUpdate_timeMillis)" +
+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ .run(lotForm.lotName, lotForm.lotTypeId, (lotForm.lotTypeStatusId === "" ? undefined : lotForm.lotTypeStatusId), (lotForm.mapId === "" ? undefined : lotForm.mapId), lotForm.mapKey, (lotForm.lotLatitude === "" ? undefined : lotForm.lotLatitude), (lotForm.lotLongitude === "" ? undefined : lotForm.lotLongitude), requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
+ database.close();
+ return result.lastInsertRowid;
+};
+export default addLot;
diff --git a/helpers/lotOccupancyDB/addLot.ts b/helpers/lotOccupancyDB/addLot.ts
new file mode 100644
index 00000000..009681a5
--- /dev/null
+++ b/helpers/lotOccupancyDB/addLot.ts
@@ -0,0 +1,53 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+
+import type * as recordTypes from "../../types/recordTypes";
+
+
+interface AddLotForm {
+ lotName: string;
+ lotTypeId: string | number;
+ lotTypeStatusId: string | number;
+
+ mapId: string | number;
+ mapKey: string;
+
+ lotLatitude: string;
+ lotLongitude: string;
+}
+
+
+export const addLot =
+ (lotForm: AddLotForm, requestSession: recordTypes.PartialSession): number => {
+
+ const database = sqlite(databasePath);
+
+ const rightNowMillis = Date.now();
+
+ const result = database
+ .prepare("insert into Lots (" +
+ "lotName, lotTypeId, lotTypeStatusId," +
+ " mapId, mapKey," +
+ " lotLatitude, lotLongitude," +
+ " recordCreate_userName, recordCreate_timeMillis," +
+ " recordUpdate_userName, recordUpdate_timeMillis)" +
+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ .run(lotForm.lotName,
+ lotForm.lotTypeId,
+ (lotForm.lotTypeStatusId === "" ? undefined : lotForm.lotTypeStatusId),
+ (lotForm.mapId === "" ? undefined : lotForm.mapId),
+ lotForm.mapKey,
+ (lotForm.lotLatitude === "" ? undefined : lotForm.lotLatitude),
+ (lotForm.lotLongitude === "" ? undefined : lotForm.lotLongitude),
+ requestSession.user.userName,
+ rightNowMillis,
+ requestSession.user.userName,
+ rightNowMillis);
+
+ database.close();
+
+ return result.lastInsertRowid as number;
+ };
+
+
+export default addLot;
\ No newline at end of file
diff --git a/helpers/lotOccupancyDB/addMap.d.ts b/helpers/lotOccupancyDB/addMap.d.ts
new file mode 100644
index 00000000..77588578
--- /dev/null
+++ b/helpers/lotOccupancyDB/addMap.d.ts
@@ -0,0 +1,16 @@
+import type * as recordTypes from "../../types/recordTypes";
+interface AddMapForm {
+ mapName: string;
+ mapDescription: string;
+ mapSVG: string;
+ mapLatitude: string;
+ mapLongitude: string;
+ mapAddress1: string;
+ mapAddress2: string;
+ mapCity: string;
+ mapProvince: string;
+ mapPostalCode: string;
+ mapPhoneNumber: string;
+}
+export declare const addMap: (mapForm: AddMapForm, requestSession: recordTypes.PartialSession) => number;
+export default addMap;
diff --git a/helpers/lotOccupancyDB/addMap.js b/helpers/lotOccupancyDB/addMap.js
new file mode 100644
index 00000000..bff4bf07
--- /dev/null
+++ b/helpers/lotOccupancyDB/addMap.js
@@ -0,0 +1,18 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+export const addMap = (mapForm, requestSession) => {
+ const database = sqlite(databasePath);
+ const rightNowMillis = Date.now();
+ const result = database
+ .prepare("insert into Maps (" +
+ "mapName, mapDescription," +
+ " mapSVG, mapLatitude, mapLongitude," +
+ " mapAddress1, mapAddress2, mapCity, mapProvince, mapPostalCode, mapPhoneNumber," +
+ " recordCreate_userName, recordCreate_timeMillis," +
+ " recordUpdate_userName, recordUpdate_timeMillis)" +
+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ .run(mapForm.mapName, mapForm.mapDescription, mapForm.mapSVG, (mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude), (mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude), mapForm.mapAddress1, mapForm.mapAddress2, mapForm.mapCity, mapForm.mapProvince, mapForm.mapPostalCode, mapForm.mapPhoneNumber, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
+ database.close();
+ return result.lastInsertRowid;
+};
+export default addMap;
diff --git a/helpers/lotOccupancyDB/addMap.ts b/helpers/lotOccupancyDB/addMap.ts
new file mode 100644
index 00000000..dad05a5a
--- /dev/null
+++ b/helpers/lotOccupancyDB/addMap.ts
@@ -0,0 +1,59 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+
+import type * as recordTypes from "../../types/recordTypes";
+
+
+interface AddMapForm {
+ mapName: string;
+ mapDescription: string;
+ mapSVG: string;
+ mapLatitude: string;
+ mapLongitude: string;
+ mapAddress1: string;
+ mapAddress2: string;
+ mapCity: string;
+ mapProvince: string;
+ mapPostalCode: string;
+ mapPhoneNumber: string;
+}
+
+
+export const addMap =
+ (mapForm: AddMapForm, requestSession: recordTypes.PartialSession): number => {
+
+ const database = sqlite(databasePath);
+
+ const rightNowMillis = Date.now();
+
+ const result = database
+ .prepare("insert into Maps (" +
+ "mapName, mapDescription," +
+ " mapSVG, mapLatitude, mapLongitude," +
+ " mapAddress1, mapAddress2, mapCity, mapProvince, mapPostalCode, mapPhoneNumber," +
+ " recordCreate_userName, recordCreate_timeMillis," +
+ " recordUpdate_userName, recordUpdate_timeMillis)" +
+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ .run(mapForm.mapName,
+ mapForm.mapDescription,
+ mapForm.mapSVG,
+ (mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude),
+ (mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude),
+ mapForm.mapAddress1,
+ mapForm.mapAddress2,
+ mapForm.mapCity,
+ mapForm.mapProvince,
+ mapForm.mapPostalCode,
+ mapForm.mapPhoneNumber,
+ requestSession.user.userName,
+ rightNowMillis,
+ requestSession.user.userName,
+ rightNowMillis);
+
+ database.close();
+
+ return result.lastInsertRowid as number;
+ };
+
+
+export default addMap;
\ No newline at end of file
diff --git a/helpers/lotOccupancyDB/addOccupant.d.ts b/helpers/lotOccupancyDB/addOccupant.d.ts
new file mode 100644
index 00000000..369fc04c
--- /dev/null
+++ b/helpers/lotOccupancyDB/addOccupant.d.ts
@@ -0,0 +1,13 @@
+import sqlite from "better-sqlite3";
+import type * as recordTypes from "../../types/recordTypes";
+interface AddOccupantForm {
+ occupantName: string;
+ occupantAddress1: string;
+ occupantAddress2: string;
+ occupantCity: string;
+ occupantProvince: string;
+ occupantPostalCode: string;
+ occupantPhoneNumber: string;
+}
+export declare const addOccupant: (occupantForm: AddOccupantForm, requestSession: recordTypes.PartialSession, connectedDatabase?: sqlite.Database) => number;
+export default addOccupant;
diff --git a/helpers/lotOccupancyDB/addOccupant.js b/helpers/lotOccupancyDB/addOccupant.js
new file mode 100644
index 00000000..02c3b4d7
--- /dev/null
+++ b/helpers/lotOccupancyDB/addOccupant.js
@@ -0,0 +1,19 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+export const addOccupant = (occupantForm, requestSession, connectedDatabase) => {
+ const database = connectedDatabase || sqlite(databasePath);
+ const rightNowMillis = Date.now();
+ const result = database
+ .prepare("insert into Occupants (" +
+ "occupantName," +
+ " occupantAddress1, occupantAddress2, occupantCity, occupantProvince, occupantPostalCode, occupantPhoneNumber," +
+ " recordCreate_userName, recordCreate_timeMillis," +
+ " recordUpdate_userName, recordUpdate_timeMillis)" +
+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ .run(occupantForm.occupantName, occupantForm.occupantAddress1, occupantForm.occupantAddress2, occupantForm.occupantCity, occupantForm.occupantProvince, occupantForm.occupantPostalCode, occupantForm.occupantPhoneNumber, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
+ if (!connectedDatabase) {
+ database.close();
+ }
+ return result.lastInsertRowid;
+};
+export default addOccupant;
diff --git a/helpers/lotOccupancyDB/addOccupant.ts b/helpers/lotOccupancyDB/addOccupant.ts
new file mode 100644
index 00000000..a442ab9c
--- /dev/null
+++ b/helpers/lotOccupancyDB/addOccupant.ts
@@ -0,0 +1,54 @@
+import sqlite from "better-sqlite3";
+import {
+ lotOccupancyDB as databasePath
+} from "../../data/databasePaths.js";
+
+import type * as recordTypes from "../../types/recordTypes";
+
+
+interface AddOccupantForm {
+ occupantName: string;
+ occupantAddress1: string;
+ occupantAddress2: string;
+ occupantCity: string;
+ occupantProvince: string;
+ occupantPostalCode: string;
+ occupantPhoneNumber: string;
+}
+
+
+export const addOccupant =
+ (occupantForm: AddOccupantForm, requestSession: recordTypes.PartialSession, connectedDatabase ? : sqlite.Database): number => {
+
+ const database = connectedDatabase || sqlite(databasePath);
+
+ const rightNowMillis = Date.now();
+
+ const result = database
+ .prepare("insert into Occupants (" +
+ "occupantName," +
+ " occupantAddress1, occupantAddress2, occupantCity, occupantProvince, occupantPostalCode, occupantPhoneNumber," +
+ " recordCreate_userName, recordCreate_timeMillis," +
+ " recordUpdate_userName, recordUpdate_timeMillis)" +
+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ .run(occupantForm.occupantName,
+ occupantForm.occupantAddress1,
+ occupantForm.occupantAddress2,
+ occupantForm.occupantCity,
+ occupantForm.occupantProvince,
+ occupantForm.occupantPostalCode,
+ occupantForm.occupantPhoneNumber,
+ requestSession.user.userName,
+ rightNowMillis,
+ requestSession.user.userName,
+ rightNowMillis);
+
+ if (!connectedDatabase) {
+ database.close();
+ }
+
+ return result.lastInsertRowid as number;
+ };
+
+
+export default addOccupant;
\ No newline at end of file
diff --git a/helpers/lotOccupancyDB/getLotTypes.d.ts b/helpers/lotOccupancyDB/getLotTypes.d.ts
new file mode 100644
index 00000000..e952d4d2
--- /dev/null
+++ b/helpers/lotOccupancyDB/getLotTypes.d.ts
@@ -0,0 +1,3 @@
+import type * as recordTypes from "../../types/recordTypes";
+export declare const getLotTypes: () => recordTypes.LotType[];
+export default getLotTypes;
diff --git a/helpers/lotOccupancyDB/getLotTypes.js b/helpers/lotOccupancyDB/getLotTypes.js
new file mode 100644
index 00000000..f890d11e
--- /dev/null
+++ b/helpers/lotOccupancyDB/getLotTypes.js
@@ -0,0 +1,15 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+export const getLotTypes = () => {
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+ const lotTypes = database
+ .prepare("select * from LotTypes" +
+ " where recordDelete_timeMillis is null" +
+ " order by orderNumber, lotType")
+ .all();
+ database.close();
+ return lotTypes;
+};
+export default getLotTypes;
diff --git a/helpers/lotOccupancyDB/getLotTypes.ts b/helpers/lotOccupancyDB/getLotTypes.ts
new file mode 100644
index 00000000..a2d02145
--- /dev/null
+++ b/helpers/lotOccupancyDB/getLotTypes.ts
@@ -0,0 +1,25 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+
+import type * as recordTypes from "../../types/recordTypes";
+
+
+export const getLotTypes = (): recordTypes.LotType[] => {
+
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+
+ const lotTypes: recordTypes.LotType[] = database
+ .prepare("select * from LotTypes" +
+ " where recordDelete_timeMillis is null" +
+ " order by orderNumber, lotType")
+ .all();
+
+ database.close();
+
+ return lotTypes;
+ };
+
+
+export default getLotTypes;
\ No newline at end of file
diff --git a/helpers/lotOccupancyDB/getMap.d.ts b/helpers/lotOccupancyDB/getMap.d.ts
new file mode 100644
index 00000000..20e0b8cc
--- /dev/null
+++ b/helpers/lotOccupancyDB/getMap.d.ts
@@ -0,0 +1,3 @@
+import type * as recordTypes from "../../types/recordTypes";
+export declare const getMap: (mapId: number | string) => recordTypes.Map;
+export default getMap;
diff --git a/helpers/lotOccupancyDB/getMap.js b/helpers/lotOccupancyDB/getMap.js
new file mode 100644
index 00000000..af3ddff8
--- /dev/null
+++ b/helpers/lotOccupancyDB/getMap.js
@@ -0,0 +1,28 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+export const getMap = (mapId) => {
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+ const map = database
+ .prepare("select m.mapId, m.mapName, m.mapDescription," +
+ " m.mapLatitude, m.mapLongitude, m.mapSVG," +
+ " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
+ " m.recordCreate_userName, m.recordCreate_timeMillis," +
+ " m.recordUpdate_userName, m.recordUpdate_timeMillis," +
+ " m.recordDelete_userName, m.recordDelete_timeMillis," +
+ " count(l.lotId) as lotCount" +
+ " from Maps m" +
+ " left join Lots l on m.mapId = l.mapId and l.recordDelete_timeMillis is null" +
+ " where m.mapId = ?" +
+ " group by m.mapId, m.mapName, m.mapDescription," +
+ " m.mapLatitude, m.mapLongitude, m.mapSVG," +
+ " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
+ " m.recordCreate_userName, m.recordCreate_timeMillis," +
+ " m.recordUpdate_userName, m.recordUpdate_timeMillis," +
+ " m.recordDelete_userName, m.recordDelete_timeMillis")
+ .get(mapId);
+ database.close();
+ return map;
+};
+export default getMap;
diff --git a/helpers/lotOccupancyDB/getMap.ts b/helpers/lotOccupancyDB/getMap.ts
new file mode 100644
index 00000000..27909324
--- /dev/null
+++ b/helpers/lotOccupancyDB/getMap.ts
@@ -0,0 +1,38 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+
+import type * as recordTypes from "../../types/recordTypes";
+
+
+export const getMap = (mapId: number | string): recordTypes.Map => {
+
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+
+ const map: recordTypes.Map = database
+ .prepare("select m.mapId, m.mapName, m.mapDescription," +
+ " m.mapLatitude, m.mapLongitude, m.mapSVG," +
+ " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
+ " m.recordCreate_userName, m.recordCreate_timeMillis," +
+ " m.recordUpdate_userName, m.recordUpdate_timeMillis," +
+ " m.recordDelete_userName, m.recordDelete_timeMillis," +
+ " count(l.lotId) as lotCount" +
+ " from Maps m" +
+ " left join Lots l on m.mapId = l.mapId and l.recordDelete_timeMillis is null" +
+ " where m.mapId = ?" +
+ " group by m.mapId, m.mapName, m.mapDescription," +
+ " m.mapLatitude, m.mapLongitude, m.mapSVG," +
+ " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
+ " m.recordCreate_userName, m.recordCreate_timeMillis," +
+ " m.recordUpdate_userName, m.recordUpdate_timeMillis," +
+ " m.recordDelete_userName, m.recordDelete_timeMillis")
+ .get(mapId);
+
+ database.close();
+
+ return map;
+ };
+
+
+export default getMap;
\ No newline at end of file
diff --git a/helpers/lotOccupancyDB/getMaps.d.ts b/helpers/lotOccupancyDB/getMaps.d.ts
new file mode 100644
index 00000000..b07dfda9
--- /dev/null
+++ b/helpers/lotOccupancyDB/getMaps.d.ts
@@ -0,0 +1,5 @@
+import type * as recordTypes from "../../types/recordTypes";
+interface GetMapsFilters {
+}
+export declare const getMaps: (filters?: GetMapsFilters) => recordTypes.Map[];
+export default getMaps;
diff --git a/helpers/lotOccupancyDB/getMaps.js b/helpers/lotOccupancyDB/getMaps.js
new file mode 100644
index 00000000..2b04821b
--- /dev/null
+++ b/helpers/lotOccupancyDB/getMaps.js
@@ -0,0 +1,24 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+export const getMaps = (filters) => {
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+ const maps = database
+ .prepare("select m.mapId, m.mapName, m.mapDescription," +
+ " m.mapLatitude, m.mapLongitude, m.mapSVG," +
+ " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
+ " l.lotCount" +
+ " from Maps m" +
+ (" left join (" +
+ "select mapId, count(lotId) as lotCount" +
+ " from Lots" +
+ " where recordDelete_timeMillis is null" +
+ " group by mapId) l on m.mapId = l.mapId") +
+ " where m.recordDelete_timeMillis is null" +
+ " order by m.mapName, m.mapId")
+ .all();
+ database.close();
+ return maps;
+};
+export default getMaps;
diff --git a/helpers/lotOccupancyDB/getMaps.ts b/helpers/lotOccupancyDB/getMaps.ts
new file mode 100644
index 00000000..813669f5
--- /dev/null
+++ b/helpers/lotOccupancyDB/getMaps.ts
@@ -0,0 +1,41 @@
+import sqlite from "better-sqlite3";
+import {
+ lotOccupancyDB as databasePath
+} from "../../data/databasePaths.js";
+
+import type * as recordTypes from "../../types/recordTypes";
+
+
+interface GetMapsFilters {
+
+}
+
+
+export const getMaps = (filters ? : GetMapsFilters): recordTypes.Map[] => {
+
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+
+ const maps: recordTypes.Map[] = database
+ .prepare("select m.mapId, m.mapName, m.mapDescription," +
+ " m.mapLatitude, m.mapLongitude, m.mapSVG," +
+ " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
+ " l.lotCount" +
+ " from Maps m" +
+ (" left join (" +
+ "select mapId, count(lotId) as lotCount" +
+ " from Lots" +
+ " where recordDelete_timeMillis is null" +
+ " group by mapId) l on m.mapId = l.mapId") +
+ " where m.recordDelete_timeMillis is null" +
+ " order by m.mapName, m.mapId")
+ .all();
+
+ database.close();
+
+ return maps;
+};
+
+
+export default getMaps;
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 61e8a9a8..0503e526 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"express-rate-limit": "^6.4.0",
"express-session": "^1.17.3",
"http-errors": "^2.0.0",
+ "leaflet": "^1.8.0",
"session-file-store": "^1.5.0"
},
"devDependencies": {
@@ -46,9 +47,11 @@
"@types/gulp-minify": "^3.1.1",
"@types/gulp-sass": "^5.0.0",
"@types/http-errors": "^1.8.2",
+ "@types/leaflet": "^1.7.11",
"@types/mocha": "^9.1.1",
"@types/mssql": "^8.0.3",
"@types/node-windows": "^0.1.2",
+ "@types/papaparse": "^5.3.2",
"@types/session-file-store": "^1.2.2",
"@typescript-eslint/eslint-plugin": "^5.30.6",
"@typescript-eslint/parser": "^5.30.6",
@@ -62,6 +65,7 @@
"gulp-minify": "^3.1.0",
"gulp-sass": "^5.1.0",
"nodemon": "^2.0.19",
+ "papaparse": "^5.3.2",
"sass": "^1.53.0"
},
"engines": {
@@ -843,6 +847,12 @@
"@types/express": "*"
}
},
+ "node_modules/@types/geojson": {
+ "version": "7946.0.10",
+ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
+ "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
+ "dev": true
+ },
"node_modules/@types/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
@@ -930,6 +940,15 @@
"@types/node": "*"
}
},
+ "node_modules/@types/leaflet": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.11.tgz",
+ "integrity": "sha512-VwAYom2pfIAf/pLj1VR5aLltd4tOtHyvfaJlNYCoejzP2nu52PrMi1ehsLRMUS+bgafmIIKBV1cMfKeS+uJ0Vg==",
+ "dev": true,
+ "dependencies": {
+ "@types/geojson": "*"
+ }
+ },
"node_modules/@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@@ -1019,6 +1038,15 @@
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
"dev": true
},
+ "node_modules/@types/papaparse": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.2.tgz",
+ "integrity": "sha512-BNbCHJkTE4RwmAFkCxEalET4mDvGr/1ld7ZtQ4i/laWI/iiVt+GL07stdvufle4KfywyvloqqpIiJscXNCrKxA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
@@ -6329,6 +6357,11 @@
"node": ">= 0.10"
}
},
+ "node_modules/leaflet": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz",
+ "integrity": "sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA=="
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -7506,6 +7539,12 @@
"node": ">=4"
}
},
+ "node_modules/papaparse": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz",
+ "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==",
+ "dev": true
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -11187,6 +11226,12 @@
"@types/express": "*"
}
},
+ "@types/geojson": {
+ "version": "7946.0.10",
+ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
+ "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
+ "dev": true
+ },
"@types/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
@@ -11274,6 +11319,15 @@
"@types/node": "*"
}
},
+ "@types/leaflet": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.11.tgz",
+ "integrity": "sha512-VwAYom2pfIAf/pLj1VR5aLltd4tOtHyvfaJlNYCoejzP2nu52PrMi1ehsLRMUS+bgafmIIKBV1cMfKeS+uJ0Vg==",
+ "dev": true,
+ "requires": {
+ "@types/geojson": "*"
+ }
+ },
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@@ -11362,6 +11416,15 @@
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
"dev": true
},
+ "@types/papaparse": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.2.tgz",
+ "integrity": "sha512-BNbCHJkTE4RwmAFkCxEalET4mDvGr/1ld7ZtQ4i/laWI/iiVt+GL07stdvufle4KfywyvloqqpIiJscXNCrKxA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
@@ -15459,6 +15522,11 @@
"flush-write-stream": "^1.0.2"
}
},
+ "leaflet": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz",
+ "integrity": "sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA=="
+ },
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -16381,6 +16449,12 @@
"integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
"dev": true
},
+ "papaparse": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz",
+ "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==",
+ "dev": true
+ },
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
diff --git a/package.json b/package.json
index 967709cb..ef631002 100644
--- a/package.json
+++ b/package.json
@@ -9,15 +9,12 @@
},
"scripts": {
"build:version": "npx genversion --es6 --semi version.js",
-
"start": "cross-env NODE_ENV=production node ./bin/www",
-
"dev:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon ./bin/www",
"dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon ./bin/www",
-
"test": "echo \"Error: no test specified\" && exit 1",
-
- "temp:so:importMaps": "node ./temp/so.importMaps.js"
+ "temp:legacy:importFromCSV": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true node ./temp/legacy.importFromCSV.js",
+ "temp:so:exportMaps": "node ./temp/so.exportMaps.js"
},
"repository": {
"type": "git",
@@ -49,6 +46,7 @@
"express-rate-limit": "^6.4.0",
"express-session": "^1.17.3",
"http-errors": "^2.0.0",
+ "leaflet": "^1.8.0",
"session-file-store": "^1.5.0"
},
"devDependencies": {
@@ -68,9 +66,11 @@
"@types/gulp-minify": "^3.1.1",
"@types/gulp-sass": "^5.0.0",
"@types/http-errors": "^1.8.2",
+ "@types/leaflet": "^1.7.11",
"@types/mocha": "^9.1.1",
"@types/mssql": "^8.0.3",
"@types/node-windows": "^0.1.2",
+ "@types/papaparse": "^5.3.2",
"@types/session-file-store": "^1.2.2",
"@typescript-eslint/eslint-plugin": "^5.30.6",
"@typescript-eslint/parser": "^5.30.6",
@@ -84,6 +84,7 @@
"gulp-minify": "^3.1.0",
"gulp-sass": "^5.1.0",
"nodemon": "^2.0.19",
+ "papaparse": "^5.3.2",
"sass": "^1.53.0"
}
}
diff --git a/public-typescript/licence-search.js b/public-typescript/licence-search.js
deleted file mode 100644
index e0703cc2..00000000
--- a/public-typescript/licence-search.js
+++ /dev/null
@@ -1,93 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-(() => {
- const urlPrefix = document.querySelector("main").dataset.urlPrefix;
- const formElement = document.querySelector("#form--filters");
- const limitElement = document.querySelector("#filter--limit");
- const offsetElement = document.querySelector("#filter--offset");
- const searchResultsElement = document.querySelector("#container--searchResults");
- const doLicenceSearchFunction = () => {
- const currentLimit = Number.parseInt(limitElement.value, 10);
- const currentOffset = Number.parseInt(offsetElement.value, 10);
- searchResultsElement.innerHTML = "
" +
- " " +
- "Loading licences... " +
- "
";
- cityssm.postJSON(urlPrefix + "/licences/doSearch", formElement, (licenceResults) => {
- const licenceList = licenceResults.licences;
- if (licenceList.length === 0) {
- searchResultsElement.innerHTML = "" +
- "
" +
- "Your search returned no results. " +
- "Please try expanding your search criteria." +
- "
" +
- "
";
- return;
- }
- searchResultsElement.innerHTML = "" +
- "" +
- " " +
- " " +
- "
";
- const tbodyElement = searchResultsElement.querySelector("tbody");
- for (const licenceObject of licenceList) {
- const trElement = document.createElement("tr");
- trElement.innerHTML = "";
- tbodyElement.append(trElement);
- }
- searchResultsElement.insertAdjacentHTML("beforeend", "" +
- "
" +
- "Displaying licences " +
- (currentOffset + 1).toString() +
- " to " +
- Math.min(currentLimit + currentOffset, licenceResults.count).toString() +
- " of " +
- licenceResults.count.toString() +
- "
" +
- "
");
- if (currentLimit < licenceResults.count) {
- const paginationElement = document.createElement("nav");
- paginationElement.className = "level-right is-hidden-print";
- paginationElement.setAttribute("role", "pagination");
- paginationElement.setAttribute("aria-label", "pagination");
- if (currentOffset > 0) {
- const previousElement = document.createElement("a");
- previousElement.className = "button";
- previousElement.textContent = "Previous";
- previousElement.addEventListener("click", (clickEvent) => {
- clickEvent.preventDefault();
- offsetElement.value = Math.max(0, currentOffset - currentLimit).toString();
- doLicenceSearchFunction();
- });
- paginationElement.append(previousElement);
- }
- if (currentLimit + currentOffset < licenceResults.count) {
- const nextElement = document.createElement("a");
- nextElement.className = "button ml-3";
- nextElement.innerHTML =
- "Next Licences " +
- " ";
- nextElement.addEventListener("click", (clickEvent) => {
- clickEvent.preventDefault();
- offsetElement.value = (currentOffset + currentLimit).toString();
- doLicenceSearchFunction();
- });
- paginationElement.append(nextElement);
- }
- searchResultsElement.querySelector(".level").append(paginationElement);
- }
- });
- };
- const resetOffsetAndDoLicenceSearchFunction = () => {
- offsetElement.value = "0";
- doLicenceSearchFunction();
- };
- formElement.addEventListener("submit", (formEvent) => {
- formEvent.preventDefault();
- });
- const inputElements = formElement.querySelectorAll(".input, .select select");
- for (const inputElement of inputElements) {
- inputElement.addEventListener("change", resetOffsetAndDoLicenceSearchFunction);
- }
- resetOffsetAndDoLicenceSearchFunction();
-})();
diff --git a/public-typescript/licence-search.ts b/public-typescript/licence-search.ts
deleted file mode 100644
index 64b286f7..00000000
--- a/public-typescript/licence-search.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-/* eslint-disable unicorn/filename-case */
-
-import type { cityssmGlobal } from "@cityssm/bulma-webapp-js/src/types";
-import type * as recordTypes from "../types/recordTypes";
-
-declare const cityssm: cityssmGlobal;
-
-
-(() => {
-
- const urlPrefix = document.querySelector("main").dataset.urlPrefix;
-
- const formElement = document.querySelector("#form--filters") as HTMLFormElement;
-
- const limitElement = document.querySelector("#filter--limit") as HTMLInputElement;
- const offsetElement = document.querySelector("#filter--offset") as HTMLInputElement;
-
- const searchResultsElement = document.querySelector("#container--searchResults") as HTMLElement;
-
- const doLicenceSearchFunction = () => {
-
- const currentLimit = Number.parseInt(limitElement.value, 10);
- const currentOffset = Number.parseInt(offsetElement.value, 10);
-
- searchResultsElement.innerHTML = "" +
- " " +
- "Loading licences... " +
- "
";
-
- cityssm.postJSON(urlPrefix + "/licences/doSearch",
- formElement,
- (licenceResults: { count: number; licences: recordTypes.Licence[] }) => {
-
- const licenceList = licenceResults.licences;
-
- if (licenceList.length === 0) {
-
- searchResultsElement.innerHTML = "" +
- "
" +
- "Your search returned no results. " +
- "Please try expanding your search criteria." +
- "
" +
- "
";
-
- return;
- }
-
- searchResultsElement.innerHTML = "" +
- "" +
-
- " " +
- " " +
- "
";
-
- const tbodyElement = searchResultsElement.querySelector("tbody");
-
- for (const licenceObject of licenceList) {
-
- const trElement = document.createElement("tr");
-
- trElement.innerHTML = "";
-
- tbodyElement.append(trElement);
- }
-
- searchResultsElement.insertAdjacentHTML("beforeend", "" +
- "
" +
- "Displaying licences " +
- (currentOffset + 1).toString() +
- " to " +
- Math.min(currentLimit + currentOffset, licenceResults.count).toString() +
- " of " +
- licenceResults.count.toString() +
- "
" +
- "
");
-
- if (currentLimit < licenceResults.count) {
-
- const paginationElement = document.createElement("nav");
- paginationElement.className = "level-right is-hidden-print";
- paginationElement.setAttribute("role", "pagination");
- paginationElement.setAttribute("aria-label", "pagination");
-
- if (currentOffset > 0) {
-
- const previousElement = document.createElement("a");
- previousElement.className = "button";
- previousElement.textContent = "Previous";
- previousElement.addEventListener("click", (clickEvent) => {
-
- clickEvent.preventDefault();
- offsetElement.value = Math.max(0, currentOffset - currentLimit).toString();
- doLicenceSearchFunction();
-
- });
-
- paginationElement.append(previousElement);
- }
-
- if (currentLimit + currentOffset < licenceResults.count) {
-
- const nextElement = document.createElement("a");
- nextElement.className = "button ml-3";
-
- nextElement.innerHTML =
- "Next Licences " +
- " ";
-
- nextElement.addEventListener("click", (clickEvent) => {
-
- clickEvent.preventDefault();
- offsetElement.value = (currentOffset + currentLimit).toString();
- doLicenceSearchFunction();
- });
-
- paginationElement.append(nextElement);
- }
-
- searchResultsElement.querySelector(".level").append(paginationElement);
- }
- }
- );
- };
-
-
- const resetOffsetAndDoLicenceSearchFunction = () => {
- offsetElement.value = "0";
- doLicenceSearchFunction();
- };
-
- formElement.addEventListener("submit", (formEvent) => {
- formEvent.preventDefault();
- });
-
- const inputElements = formElement.querySelectorAll(".input, .select select");
-
- for (const inputElement of inputElements) {
- inputElement.addEventListener("change", resetOffsetAndDoLicenceSearchFunction);
- }
-
- resetOffsetAndDoLicenceSearchFunction();
-})();
diff --git a/public-typescript/licence-search.d.ts b/public-typescript/mapSearch.d.ts
similarity index 100%
rename from public-typescript/licence-search.d.ts
rename to public-typescript/mapSearch.d.ts
diff --git a/public-typescript/mapSearch.js b/public-typescript/mapSearch.js
new file mode 100644
index 00000000..ed18aff9
--- /dev/null
+++ b/public-typescript/mapSearch.js
@@ -0,0 +1,77 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+(() => {
+ const urlPrefix = document.querySelector("main").dataset.urlPrefix;
+ const maps = exports.maps;
+ const searchFilterElement = document.querySelector("#searchFilter--map");
+ const searchResultsContainerElement = document.querySelector("#container--searchResults");
+ const renderResults = () => {
+ searchResultsContainerElement.innerHTML = "" +
+ " " +
+ "Loading " + exports.aliases.maps + "..." +
+ "
";
+ let searchResultCount = 0;
+ const searchResultsTbodyElement = document.createElement("tbody");
+ const filterStringSplit = searchFilterElement.value.trim().toLowerCase().split(" ");
+ for (const map of maps) {
+ const mapSearchString = (map.mapName + " " +
+ map.mapDescription + " " +
+ map.mapAddress1 + " " +
+ map.mapAddress2).toLowerCase();
+ let showMap = true;
+ for (const filterStringPiece of filterStringSplit) {
+ if (!mapSearchString.includes(filterStringPiece)) {
+ showMap = false;
+ break;
+ }
+ }
+ if (!showMap) {
+ continue;
+ }
+ searchResultCount += 1;
+ const mapName = map.mapName === ""
+ ? "(No Name)"
+ : map.mapName;
+ searchResultsTbodyElement.insertAdjacentHTML("beforeend", "" +
+ ("" +
+ "" +
+ cityssm.escapeHTML(mapName) +
+ " " +
+ cityssm.escapeHTML(map.mapAddress1) +
+ " ") +
+ "" +
+ (map.mapLatitude && map.mapLongitude
+ ? " "
+ : "") +
+ " " +
+ "" +
+ (map.mapSVG
+ ? " "
+ : "") +
+ " " +
+ "" + map.lotCount + " " +
+ " ");
+ }
+ searchResultsContainerElement.innerHTML = "";
+ if (searchResultCount === 0) {
+ searchResultsContainerElement.innerHTML = "" +
+ "
There are no " + exports.aliases.maps.toLowerCase() + " that meet the search criteria.
" +
+ "
";
+ }
+ else {
+ const searchResultsTableElement = document.createElement("table");
+ searchResultsTableElement.className = "table is-fullwidth is-striped is-hoverable";
+ searchResultsTableElement.innerHTML = "" +
+ "" + exports.aliases.map + " " +
+ "Coordinates " +
+ "Image " +
+ "" + exports.aliases.lot + " Count " +
+ " ";
+ searchResultsTableElement.append(searchResultsTbodyElement);
+ searchResultsContainerElement.append(searchResultsTableElement);
+ }
+ };
+ searchFilterElement.addEventListener("keyup", renderResults);
+ document.querySelector("#form--searchFilters").addEventListener("submit", renderResults);
+ renderResults();
+})();
diff --git a/public-typescript/mapSearch.ts b/public-typescript/mapSearch.ts
new file mode 100644
index 00000000..ca995a72
--- /dev/null
+++ b/public-typescript/mapSearch.ts
@@ -0,0 +1,107 @@
+/* eslint-disable unicorn/prefer-module */
+
+import type * as recordTypes from "../types/recordTypes";
+
+import type { cityssmGlobal } from "@cityssm/bulma-webapp-js/src/types";
+import type { BulmaJS } from "@cityssm/bulma-js/types";
+
+declare const cityssm: cityssmGlobal;
+declare const bulmaJS: BulmaJS;
+
+(() => {
+ const urlPrefix = document.querySelector("main").dataset.urlPrefix;
+
+ const maps: recordTypes.Map[] = exports.maps;
+
+ const searchFilterElement = document.querySelector("#searchFilter--map") as HTMLInputElement;
+ const searchResultsContainerElement = document.querySelector("#container--searchResults") as HTMLElement;
+
+ const renderResults = () => {
+
+ searchResultsContainerElement.innerHTML = "" +
+ " " +
+ "Loading " + exports.aliases.maps + "..." +
+ "
";
+
+ let searchResultCount = 0;
+ const searchResultsTbodyElement = document.createElement("tbody");
+
+ const filterStringSplit = searchFilterElement.value.trim().toLowerCase().split(" ");
+
+ for (const map of maps) {
+
+ const mapSearchString = (map.mapName + " " +
+ map.mapDescription + " " +
+ map.mapAddress1 + " " +
+ map.mapAddress2).toLowerCase();
+
+ let showMap = true;
+
+ for (const filterStringPiece of filterStringSplit) {
+ if (!mapSearchString.includes(filterStringPiece)) {
+ showMap = false;
+ break;
+ }
+ }
+
+ if (!showMap) {
+ continue;
+ }
+
+ searchResultCount += 1;
+
+ const mapName = map.mapName === ""
+ ? "(No Name)"
+ : map.mapName;
+
+ searchResultsTbodyElement.insertAdjacentHTML("beforeend", "" +
+ ("" +
+ "" +
+ cityssm.escapeHTML(mapName) +
+ " " +
+ cityssm.escapeHTML(map.mapAddress1) +
+ " ") +
+ "" +
+ (map.mapLatitude && map.mapLongitude
+ ? " "
+ : "") +
+ " " +
+ "" +
+ (map.mapSVG
+ ? " "
+ : "") +
+ " " +
+ "" + map.lotCount + " " +
+ " ");
+ }
+
+ searchResultsContainerElement.innerHTML = "";
+
+ if (searchResultCount === 0) {
+
+ searchResultsContainerElement.innerHTML = "" +
+ "
There are no " + exports.aliases.maps.toLowerCase() + " that meet the search criteria.
" +
+ "
";
+
+ } else {
+
+ const searchResultsTableElement = document.createElement("table");
+ searchResultsTableElement.className = "table is-fullwidth is-striped is-hoverable";
+ searchResultsTableElement.innerHTML = "" +
+ "" + exports.aliases.map + " " +
+ "Coordinates " +
+ "Image " +
+ "" + exports.aliases.lot + " Count " +
+ " ";
+
+ searchResultsTableElement.append(searchResultsTbodyElement);
+
+ searchResultsContainerElement.append(searchResultsTableElement);
+ }
+ };
+
+ searchFilterElement.addEventListener("keyup", renderResults);
+ document.querySelector("#form--searchFilters").addEventListener("submit", renderResults);
+
+ renderResults();
+})();
\ No newline at end of file
diff --git a/public-typescript/mapView.d.ts b/public-typescript/mapView.d.ts
new file mode 100644
index 00000000..cb0ff5c3
--- /dev/null
+++ b/public-typescript/mapView.d.ts
@@ -0,0 +1 @@
+export {};
diff --git a/public-typescript/mapView.js b/public-typescript/mapView.js
new file mode 100644
index 00000000..474e52e3
--- /dev/null
+++ b/public-typescript/mapView.js
@@ -0,0 +1,17 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+(() => {
+ const mapContainerElement = document.querySelector("#map--leaflet");
+ if (mapContainerElement) {
+ const mapLatitude = Number.parseFloat(mapContainerElement.dataset.mapLatitude);
+ const mapLongitude = Number.parseFloat(mapContainerElement.dataset.mapLongitude);
+ const mapCoordinates = [mapLatitude, mapLongitude];
+ const map = L.map(mapContainerElement);
+ map.setView(mapCoordinates, 15);
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ maxZoom: 19,
+ attribution: '© OpenStreetMap'
+ }).addTo(map);
+ L.marker(mapCoordinates).addTo(map);
+ }
+})();
diff --git a/public-typescript/mapView.ts b/public-typescript/mapView.ts
new file mode 100644
index 00000000..e5da60ce
--- /dev/null
+++ b/public-typescript/mapView.ts
@@ -0,0 +1,30 @@
+import type { cityssmGlobal } from "@cityssm/bulma-webapp-js/src/types";
+import type { BulmaJS } from "@cityssm/bulma-js/types";
+import type * as Leaflet from "leaflet";
+
+declare const cityssm: cityssmGlobal;
+declare const bulmaJS: BulmaJS;
+declare const L;
+
+(() => {
+
+ const mapContainerElement = document.querySelector("#map--leaflet") as HTMLElement;
+
+ if (mapContainerElement) {
+
+ const mapLatitude = Number.parseFloat(mapContainerElement.dataset.mapLatitude);
+ const mapLongitude = Number.parseFloat(mapContainerElement.dataset.mapLongitude);
+
+ const mapCoordinates: Leaflet.LatLngTuple = [mapLatitude, mapLongitude];
+
+ const map: Leaflet.Map = L.map(mapContainerElement);
+ map.setView(mapCoordinates, 15);
+
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ maxZoom: 19,
+ attribution: '© OpenStreetMap'
+ }).addTo(map);
+
+ L.marker(mapCoordinates).addTo(map);
+ }
+})();
\ No newline at end of file
diff --git a/maps/holySepulchre-block-A-rows-1-52 (79ddc302-6e77-47cd-a108-681a76d91c19, ad84d98e-1a4b-45a0-8abf-7386b16da322).svg b/public/images/maps/holySepulchre-block-A-rows-1-52 (79ddc302-6e77-47cd-a108-681a76d91c19, ad84d98e-1a4b-45a0-8abf-7386b16da322).svg
similarity index 100%
rename from maps/holySepulchre-block-A-rows-1-52 (79ddc302-6e77-47cd-a108-681a76d91c19, ad84d98e-1a4b-45a0-8abf-7386b16da322).svg
rename to public/images/maps/holySepulchre-block-A-rows-1-52 (79ddc302-6e77-47cd-a108-681a76d91c19, ad84d98e-1a4b-45a0-8abf-7386b16da322).svg
diff --git a/maps/holySepulchre-block-A-rows-53-97 (87fa11c9-8f12-4154-88eb-a5992b702ca0, 428b0587-d662-4764-9bfd-92c775f1135f).svg b/public/images/maps/holySepulchre-block-A-rows-53-97 (87fa11c9-8f12-4154-88eb-a5992b702ca0, 428b0587-d662-4764-9bfd-92c775f1135f).svg
similarity index 100%
rename from maps/holySepulchre-block-A-rows-53-97 (87fa11c9-8f12-4154-88eb-a5992b702ca0, 428b0587-d662-4764-9bfd-92c775f1135f).svg
rename to public/images/maps/holySepulchre-block-A-rows-53-97 (87fa11c9-8f12-4154-88eb-a5992b702ca0, 428b0587-d662-4764-9bfd-92c775f1135f).svg
diff --git a/maps/holySepulchre-block-A-rows-B-T (c1602e8b-983f-4d38-9508-cac02a245468, 87f66f73-da7d-4cd5-a126-34a86af80c52).svg b/public/images/maps/holySepulchre-block-A-rows-B-T (c1602e8b-983f-4d38-9508-cac02a245468, 87f66f73-da7d-4cd5-a126-34a86af80c52).svg
similarity index 100%
rename from maps/holySepulchre-block-A-rows-B-T (c1602e8b-983f-4d38-9508-cac02a245468, 87f66f73-da7d-4cd5-a126-34a86af80c52).svg
rename to public/images/maps/holySepulchre-block-A-rows-B-T (c1602e8b-983f-4d38-9508-cac02a245468, 87f66f73-da7d-4cd5-a126-34a86af80c52).svg
diff --git a/maps/holySepulchre-block-A-urnRanges-52A-53A (b7d3ab77-6a63-4aaf-8e86-1056d1aebfc9, bf11a70e-193c-47ca-9bdb-e07a2f1c5bb3).svg b/public/images/maps/holySepulchre-block-A-urnRanges-52A-53A (b7d3ab77-6a63-4aaf-8e86-1056d1aebfc9, bf11a70e-193c-47ca-9bdb-e07a2f1c5bb3).svg
similarity index 100%
rename from maps/holySepulchre-block-A-urnRanges-52A-53A (b7d3ab77-6a63-4aaf-8e86-1056d1aebfc9, bf11a70e-193c-47ca-9bdb-e07a2f1c5bb3).svg
rename to public/images/maps/holySepulchre-block-A-urnRanges-52A-53A (b7d3ab77-6a63-4aaf-8e86-1056d1aebfc9, bf11a70e-193c-47ca-9bdb-e07a2f1c5bb3).svg
diff --git a/maps/holySepulchre-block-A-urnRanges-72A-73A (29590769-cfc5-455e-8893-35d6839b4b7c, 2361fec7-93e6-413b-93ae-4e9ce7474df4).svg b/public/images/maps/holySepulchre-block-A-urnRanges-72A-73A (29590769-cfc5-455e-8893-35d6839b4b7c, 2361fec7-93e6-413b-93ae-4e9ce7474df4).svg
similarity index 100%
rename from maps/holySepulchre-block-A-urnRanges-72A-73A (29590769-cfc5-455e-8893-35d6839b4b7c, 2361fec7-93e6-413b-93ae-4e9ce7474df4).svg
rename to public/images/maps/holySepulchre-block-A-urnRanges-72A-73A (29590769-cfc5-455e-8893-35d6839b4b7c, 2361fec7-93e6-413b-93ae-4e9ce7474df4).svg
diff --git a/maps/holySepulchre-block-A-urnRanges-97A-97B (479eb600-ed96-40d6-a842-26a0b3056c9f, 367f0188-c246-434b-b93a-ce4ffadba5fe).svg b/public/images/maps/holySepulchre-block-A-urnRanges-97A-97B (479eb600-ed96-40d6-a842-26a0b3056c9f, 367f0188-c246-434b-b93a-ce4ffadba5fe).svg
similarity index 100%
rename from maps/holySepulchre-block-A-urnRanges-97A-97B (479eb600-ed96-40d6-a842-26a0b3056c9f, 367f0188-c246-434b-b93a-ce4ffadba5fe).svg
rename to public/images/maps/holySepulchre-block-A-urnRanges-97A-97B (479eb600-ed96-40d6-a842-26a0b3056c9f, 367f0188-c246-434b-b93a-ce4ffadba5fe).svg
diff --git a/maps/holySepulchre-block-B-rows-1-52 (d2e00207-a44a-4be4-b2cd-7a3441f05f66, d4aa206a-8642-477d-b3c8-a451c82e863a).svg b/public/images/maps/holySepulchre-block-B-rows-1-52 (d2e00207-a44a-4be4-b2cd-7a3441f05f66, d4aa206a-8642-477d-b3c8-a451c82e863a).svg
similarity index 100%
rename from maps/holySepulchre-block-B-rows-1-52 (d2e00207-a44a-4be4-b2cd-7a3441f05f66, d4aa206a-8642-477d-b3c8-a451c82e863a).svg
rename to public/images/maps/holySepulchre-block-B-rows-1-52 (d2e00207-a44a-4be4-b2cd-7a3441f05f66, d4aa206a-8642-477d-b3c8-a451c82e863a).svg
diff --git a/maps/holySepulchre-block-B-rows-53-97 (737723fa-a595-44ef-a5c8-648e2984824c, dea8722a-9317-4a9d-b67d-1d404a3af085).svg b/public/images/maps/holySepulchre-block-B-rows-53-97 (737723fa-a595-44ef-a5c8-648e2984824c, dea8722a-9317-4a9d-b67d-1d404a3af085).svg
similarity index 100%
rename from maps/holySepulchre-block-B-rows-53-97 (737723fa-a595-44ef-a5c8-648e2984824c, dea8722a-9317-4a9d-b67d-1d404a3af085).svg
rename to public/images/maps/holySepulchre-block-B-rows-53-97 (737723fa-a595-44ef-a5c8-648e2984824c, dea8722a-9317-4a9d-b67d-1d404a3af085).svg
diff --git a/maps/holySepulchre-block-B-rows-B-T (e8727845-47ea-4e93-8fab-3226f776b35d, b70d6495-1dbc-4d9a-8cfc-69f9b1b15418).svg b/public/images/maps/holySepulchre-block-B-rows-B-T (e8727845-47ea-4e93-8fab-3226f776b35d, b70d6495-1dbc-4d9a-8cfc-69f9b1b15418).svg
similarity index 100%
rename from maps/holySepulchre-block-B-rows-B-T (e8727845-47ea-4e93-8fab-3226f776b35d, b70d6495-1dbc-4d9a-8cfc-69f9b1b15418).svg
rename to public/images/maps/holySepulchre-block-B-rows-B-T (e8727845-47ea-4e93-8fab-3226f776b35d, b70d6495-1dbc-4d9a-8cfc-69f9b1b15418).svg
diff --git a/maps/holySepulchre-block-C-rows-1-36 (de24779a-edc6-4623-bf32-31625e7eeae9, 96e0da65-b04c-41c3-b534-256068440a78).svg b/public/images/maps/holySepulchre-block-C-rows-1-36 (de24779a-edc6-4623-bf32-31625e7eeae9, 96e0da65-b04c-41c3-b534-256068440a78).svg
similarity index 100%
rename from maps/holySepulchre-block-C-rows-1-36 (de24779a-edc6-4623-bf32-31625e7eeae9, 96e0da65-b04c-41c3-b534-256068440a78).svg
rename to public/images/maps/holySepulchre-block-C-rows-1-36 (de24779a-edc6-4623-bf32-31625e7eeae9, 96e0da65-b04c-41c3-b534-256068440a78).svg
diff --git a/maps/holySepulchre-block-C-rows-B-U (f1c463b9-f542-4c94-bb1d-682c93a6bff2, e3007ea8-721c-414c-b1cd-f5f3ad29a5ea).svg b/public/images/maps/holySepulchre-block-C-rows-B-U (f1c463b9-f542-4c94-bb1d-682c93a6bff2, e3007ea8-721c-414c-b1cd-f5f3ad29a5ea).svg
similarity index 100%
rename from maps/holySepulchre-block-C-rows-B-U (f1c463b9-f542-4c94-bb1d-682c93a6bff2, e3007ea8-721c-414c-b1cd-f5f3ad29a5ea).svg
rename to public/images/maps/holySepulchre-block-C-rows-B-U (f1c463b9-f542-4c94-bb1d-682c93a6bff2, e3007ea8-721c-414c-b1cd-f5f3ad29a5ea).svg
diff --git a/maps/holySepulchre-block-D-babyShrine (49be9136-7f17-4c8f-95df-f03446c46a7b, 24128a8b-bf58-4eed-b160-7533f3f2195f).svg b/public/images/maps/holySepulchre-block-D-babyShrine (49be9136-7f17-4c8f-95df-f03446c46a7b, 24128a8b-bf58-4eed-b160-7533f3f2195f).svg
similarity index 100%
rename from maps/holySepulchre-block-D-babyShrine (49be9136-7f17-4c8f-95df-f03446c46a7b, 24128a8b-bf58-4eed-b160-7533f3f2195f).svg
rename to public/images/maps/holySepulchre-block-D-babyShrine (49be9136-7f17-4c8f-95df-f03446c46a7b, 24128a8b-bf58-4eed-b160-7533f3f2195f).svg
diff --git a/maps/holySepulchre-block-D-rows-A-L (be29f5d8-b724-4663-885a-3dd5cfc15928, 26b795dc-c542-4d7b-9d83-7108b01472e4).svg b/public/images/maps/holySepulchre-block-D-rows-A-L (be29f5d8-b724-4663-885a-3dd5cfc15928, 26b795dc-c542-4d7b-9d83-7108b01472e4).svg
similarity index 100%
rename from maps/holySepulchre-block-D-rows-A-L (be29f5d8-b724-4663-885a-3dd5cfc15928, 26b795dc-c542-4d7b-9d83-7108b01472e4).svg
rename to public/images/maps/holySepulchre-block-D-rows-A-L (be29f5d8-b724-4663-885a-3dd5cfc15928, 26b795dc-c542-4d7b-9d83-7108b01472e4).svg
diff --git a/maps/holySepulchre-block-D-rows-M-V (631c9e8f-0aaa-4109-85e5-8207f78600f3, d1390b43-2f7b-48d7-bd6e-a7cb28b2f7e2).svg b/public/images/maps/holySepulchre-block-D-rows-M-V (631c9e8f-0aaa-4109-85e5-8207f78600f3, d1390b43-2f7b-48d7-bd6e-a7cb28b2f7e2).svg
similarity index 100%
rename from maps/holySepulchre-block-D-rows-M-V (631c9e8f-0aaa-4109-85e5-8207f78600f3, d1390b43-2f7b-48d7-bd6e-a7cb28b2f7e2).svg
rename to public/images/maps/holySepulchre-block-D-rows-M-V (631c9e8f-0aaa-4109-85e5-8207f78600f3, d1390b43-2f7b-48d7-bd6e-a7cb28b2f7e2).svg
diff --git a/maps/holySepulchre-block-E-sectionCenter (def8122b-dc2a-4fff-a258-cbd0d31df80f, 13846d63-37f0-47a7-8725-cd3032f8f150).svg b/public/images/maps/holySepulchre-block-E-sectionCenter (def8122b-dc2a-4fff-a258-cbd0d31df80f, 13846d63-37f0-47a7-8725-cd3032f8f150).svg
similarity index 100%
rename from maps/holySepulchre-block-E-sectionCenter (def8122b-dc2a-4fff-a258-cbd0d31df80f, 13846d63-37f0-47a7-8725-cd3032f8f150).svg
rename to public/images/maps/holySepulchre-block-E-sectionCenter (def8122b-dc2a-4fff-a258-cbd0d31df80f, 13846d63-37f0-47a7-8725-cd3032f8f150).svg
diff --git a/maps/holySepulchre-block-E-sectionEast (3f307004-d609-435a-a253-7ee50f3dd544, 270ae920-4fb2-4510-a136-92b7381b78f5).svg b/public/images/maps/holySepulchre-block-E-sectionEast (3f307004-d609-435a-a253-7ee50f3dd544, 270ae920-4fb2-4510-a136-92b7381b78f5).svg
similarity index 100%
rename from maps/holySepulchre-block-E-sectionEast (3f307004-d609-435a-a253-7ee50f3dd544, 270ae920-4fb2-4510-a136-92b7381b78f5).svg
rename to public/images/maps/holySepulchre-block-E-sectionEast (3f307004-d609-435a-a253-7ee50f3dd544, 270ae920-4fb2-4510-a136-92b7381b78f5).svg
diff --git a/maps/holySepulchre-block-E-sectionWest (fbcfd412-992e-440c-97d7-a0bd685a8105, 6388bc74-af34-4cad-90b8-3e1836d5d443).svg b/public/images/maps/holySepulchre-block-E-sectionWest (fbcfd412-992e-440c-97d7-a0bd685a8105, 6388bc74-af34-4cad-90b8-3e1836d5d443).svg
similarity index 100%
rename from maps/holySepulchre-block-E-sectionWest (fbcfd412-992e-440c-97d7-a0bd685a8105, 6388bc74-af34-4cad-90b8-3e1836d5d443).svg
rename to public/images/maps/holySepulchre-block-E-sectionWest (fbcfd412-992e-440c-97d7-a0bd685a8105, 6388bc74-af34-4cad-90b8-3e1836d5d443).svg
diff --git a/maps/holySepulchre-block-F-rows-1-22 (f7b9867e-7800-4f5b-891c-be8769504300, 42fe726e-7ac9-4d77-b088-694b4cd41c43).svg b/public/images/maps/holySepulchre-block-F-rows-1-22 (f7b9867e-7800-4f5b-891c-be8769504300, 42fe726e-7ac9-4d77-b088-694b4cd41c43).svg
similarity index 100%
rename from maps/holySepulchre-block-F-rows-1-22 (f7b9867e-7800-4f5b-891c-be8769504300, 42fe726e-7ac9-4d77-b088-694b4cd41c43).svg
rename to public/images/maps/holySepulchre-block-F-rows-1-22 (f7b9867e-7800-4f5b-891c-be8769504300, 42fe726e-7ac9-4d77-b088-694b4cd41c43).svg
diff --git a/maps/holySepulchre-block-G-rows-1-32 (55916a1b-d520-456c-9d0a-4e29f1bc833e, a100603f-ca65-429b-b96b-9da820b97ca5).svg b/public/images/maps/holySepulchre-block-G-rows-1-32 (55916a1b-d520-456c-9d0a-4e29f1bc833e, a100603f-ca65-429b-b96b-9da820b97ca5).svg
similarity index 100%
rename from maps/holySepulchre-block-G-rows-1-32 (55916a1b-d520-456c-9d0a-4e29f1bc833e, a100603f-ca65-429b-b96b-9da820b97ca5).svg
rename to public/images/maps/holySepulchre-block-G-rows-1-32 (55916a1b-d520-456c-9d0a-4e29f1bc833e, a100603f-ca65-429b-b96b-9da820b97ca5).svg
diff --git a/maps/holySepulchre-block-H-rows-1-16 (6f0741ef-0f33-41eb-a614-243ee496e611, 98fd283b-d429-406c-a474-97af36626a0a).svg b/public/images/maps/holySepulchre-block-H-rows-1-16 (6f0741ef-0f33-41eb-a614-243ee496e611, 98fd283b-d429-406c-a474-97af36626a0a).svg
similarity index 100%
rename from maps/holySepulchre-block-H-rows-1-16 (6f0741ef-0f33-41eb-a614-243ee496e611, 98fd283b-d429-406c-a474-97af36626a0a).svg
rename to public/images/maps/holySepulchre-block-H-rows-1-16 (6f0741ef-0f33-41eb-a614-243ee496e611, 98fd283b-d429-406c-a474-97af36626a0a).svg
diff --git a/maps/holySepulchre-block-J-rows-1-18 (9b77b6fb-097e-4793-9bb0-5f873ff8402c, b5345ea4-f092-4985-8829-b8877f1322bc).svg b/public/images/maps/holySepulchre-block-J-rows-1-18 (9b77b6fb-097e-4793-9bb0-5f873ff8402c, b5345ea4-f092-4985-8829-b8877f1322bc).svg
similarity index 100%
rename from maps/holySepulchre-block-J-rows-1-18 (9b77b6fb-097e-4793-9bb0-5f873ff8402c, b5345ea4-f092-4985-8829-b8877f1322bc).svg
rename to public/images/maps/holySepulchre-block-J-rows-1-18 (9b77b6fb-097e-4793-9bb0-5f873ff8402c, b5345ea4-f092-4985-8829-b8877f1322bc).svg
diff --git a/maps/holySepulchre-block-K-rows-1-19 (17aeb1c1-5da8-4ed1-b079-85578df1f1a5, f75f8788-9409-41d2-beec-4bd6059656f8).svg b/public/images/maps/holySepulchre-block-K-rows-1-19 (17aeb1c1-5da8-4ed1-b079-85578df1f1a5, f75f8788-9409-41d2-beec-4bd6059656f8).svg
similarity index 100%
rename from maps/holySepulchre-block-K-rows-1-19 (17aeb1c1-5da8-4ed1-b079-85578df1f1a5, f75f8788-9409-41d2-beec-4bd6059656f8).svg
rename to public/images/maps/holySepulchre-block-K-rows-1-19 (17aeb1c1-5da8-4ed1-b079-85578df1f1a5, f75f8788-9409-41d2-beec-4bd6059656f8).svg
diff --git a/maps/holySepulchre-columbarium-O-P (ccf0e42c-36e2-4313-a6b2-399c82878dcc, 5c506eff-e84d-4a49-ad5c-b0f7678ba520).svg b/public/images/maps/holySepulchre-columbarium-O-P (ccf0e42c-36e2-4313-a6b2-399c82878dcc, 5c506eff-e84d-4a49-ad5c-b0f7678ba520).svg
similarity index 100%
rename from maps/holySepulchre-columbarium-O-P (ccf0e42c-36e2-4313-a6b2-399c82878dcc, 5c506eff-e84d-4a49-ad5c-b0f7678ba520).svg
rename to public/images/maps/holySepulchre-columbarium-O-P (ccf0e42c-36e2-4313-a6b2-399c82878dcc, 5c506eff-e84d-4a49-ad5c-b0f7678ba520).svg
diff --git a/maps/holySepulchre-columbarium-S (d11ffca7-cdbb-4e0a-beef-fe0fe1dfb409, 893af7dd-8004-481c-b891-886b294425e0).svg b/public/images/maps/holySepulchre-columbarium-S (d11ffca7-cdbb-4e0a-beef-fe0fe1dfb409, 893af7dd-8004-481c-b891-886b294425e0).svg
similarity index 100%
rename from maps/holySepulchre-columbarium-S (d11ffca7-cdbb-4e0a-beef-fe0fe1dfb409, 893af7dd-8004-481c-b891-886b294425e0).svg
rename to public/images/maps/holySepulchre-columbarium-S (d11ffca7-cdbb-4e0a-beef-fe0fe1dfb409, 893af7dd-8004-481c-b891-886b294425e0).svg
diff --git a/maps/holySepulchre-columbarium-T (363ceb66-0273-4e00-9c80-9b7496a269c2, 51c4fd29-dbc2-40e1-b24f-2cef72f8a06f).svg b/public/images/maps/holySepulchre-columbarium-T (363ceb66-0273-4e00-9c80-9b7496a269c2, 51c4fd29-dbc2-40e1-b24f-2cef72f8a06f).svg
similarity index 100%
rename from maps/holySepulchre-columbarium-T (363ceb66-0273-4e00-9c80-9b7496a269c2, 51c4fd29-dbc2-40e1-b24f-2cef72f8a06f).svg
rename to public/images/maps/holySepulchre-columbarium-T (363ceb66-0273-4e00-9c80-9b7496a269c2, 51c4fd29-dbc2-40e1-b24f-2cef72f8a06f).svg
diff --git a/maps/holySepulchre-columbarium-U (7dead22a-40ff-4e49-befc-c0a396250b0e, e6883102-b4fd-4638-bc7a-555d16d663d1).svg b/public/images/maps/holySepulchre-columbarium-U (7dead22a-40ff-4e49-befc-c0a396250b0e, e6883102-b4fd-4638-bc7a-555d16d663d1).svg
similarity index 100%
rename from maps/holySepulchre-columbarium-U (7dead22a-40ff-4e49-befc-c0a396250b0e, e6883102-b4fd-4638-bc7a-555d16d663d1).svg
rename to public/images/maps/holySepulchre-columbarium-U (7dead22a-40ff-4e49-befc-c0a396250b0e, e6883102-b4fd-4638-bc7a-555d16d663d1).svg
diff --git a/maps/holySepulchre-columbarium-V (4adc587d-e480-4332-9db0-7aa77010f802, 478e1bce-1a7a-4ad3-97d8-61daa71609d9).svg b/public/images/maps/holySepulchre-columbarium-V (4adc587d-e480-4332-9db0-7aa77010f802, 478e1bce-1a7a-4ad3-97d8-61daa71609d9).svg
similarity index 100%
rename from maps/holySepulchre-columbarium-V (4adc587d-e480-4332-9db0-7aa77010f802, 478e1bce-1a7a-4ad3-97d8-61daa71609d9).svg
rename to public/images/maps/holySepulchre-columbarium-V (4adc587d-e480-4332-9db0-7aa77010f802, 478e1bce-1a7a-4ad3-97d8-61daa71609d9).svg
diff --git a/maps/holySepulchre-columbarium-W (2b87dd96-dc65-4972-9c47-af3e479507e1, 59d32426-d93a-4201-b976-d523e2d01ce8).svg b/public/images/maps/holySepulchre-columbarium-W (2b87dd96-dc65-4972-9c47-af3e479507e1, 59d32426-d93a-4201-b976-d523e2d01ce8).svg
similarity index 100%
rename from maps/holySepulchre-columbarium-W (2b87dd96-dc65-4972-9c47-af3e479507e1, 59d32426-d93a-4201-b976-d523e2d01ce8).svg
rename to public/images/maps/holySepulchre-columbarium-W (2b87dd96-dc65-4972-9c47-af3e479507e1, 59d32426-d93a-4201-b976-d523e2d01ce8).svg
diff --git a/maps/holySepulchre-mausoleum-east (fc9a4bcc-a762-493f-a78d-d6115f01d236, e70375d9-7314-4dde-ba43-8cd4508fa1b2).svg b/public/images/maps/holySepulchre-mausoleum-east (fc9a4bcc-a762-493f-a78d-d6115f01d236, e70375d9-7314-4dde-ba43-8cd4508fa1b2).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-east (fc9a4bcc-a762-493f-a78d-d6115f01d236, e70375d9-7314-4dde-ba43-8cd4508fa1b2).svg
rename to public/images/maps/holySepulchre-mausoleum-east (fc9a4bcc-a762-493f-a78d-d6115f01d236, e70375d9-7314-4dde-ba43-8cd4508fa1b2).svg
diff --git a/maps/holySepulchre-mausoleum-niche-J-E (2d378027-a930-4285-b8ba-9fa507599a0e, 78751aaf-4592-469d-9a7a-0ae8daacedab).svg b/public/images/maps/holySepulchre-mausoleum-niche-J-E (2d378027-a930-4285-b8ba-9fa507599a0e, 78751aaf-4592-469d-9a7a-0ae8daacedab).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-J-E (2d378027-a930-4285-b8ba-9fa507599a0e, 78751aaf-4592-469d-9a7a-0ae8daacedab).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-J-E (2d378027-a930-4285-b8ba-9fa507599a0e, 78751aaf-4592-469d-9a7a-0ae8daacedab).svg
diff --git a/maps/holySepulchre-mausoleum-niche-J-W (f5afcccf-8328-4031-933e-804023fe9a7f, f14e21fb-dcc6-4fe0-8703-c77f599321f7).svg b/public/images/maps/holySepulchre-mausoleum-niche-J-W (f5afcccf-8328-4031-933e-804023fe9a7f, f14e21fb-dcc6-4fe0-8703-c77f599321f7).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-J-W (f5afcccf-8328-4031-933e-804023fe9a7f, f14e21fb-dcc6-4fe0-8703-c77f599321f7).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-J-W (f5afcccf-8328-4031-933e-804023fe9a7f, f14e21fb-dcc6-4fe0-8703-c77f599321f7).svg
diff --git a/maps/holySepulchre-mausoleum-niche-L (8b60a236-4a19-4a28-874a-6492873236cc, b711cd8b-6adf-4e74-9a93-9c472c806f5a).svg b/public/images/maps/holySepulchre-mausoleum-niche-L (8b60a236-4a19-4a28-874a-6492873236cc, b711cd8b-6adf-4e74-9a93-9c472c806f5a).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-L (8b60a236-4a19-4a28-874a-6492873236cc, b711cd8b-6adf-4e74-9a93-9c472c806f5a).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-L (8b60a236-4a19-4a28-874a-6492873236cc, b711cd8b-6adf-4e74-9a93-9c472c806f5a).svg
diff --git a/maps/holySepulchre-mausoleum-niche-L-E (3f285df1-721a-423f-a2ff-d440c933a6c3, 5dcb31b8-dcf8-4a6f-9b8c-7b0e4bb2b4bf).svg b/public/images/maps/holySepulchre-mausoleum-niche-L-E (3f285df1-721a-423f-a2ff-d440c933a6c3, 5dcb31b8-dcf8-4a6f-9b8c-7b0e4bb2b4bf).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-L-E (3f285df1-721a-423f-a2ff-d440c933a6c3, 5dcb31b8-dcf8-4a6f-9b8c-7b0e4bb2b4bf).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-L-E (3f285df1-721a-423f-a2ff-d440c933a6c3, 5dcb31b8-dcf8-4a6f-9b8c-7b0e4bb2b4bf).svg
diff --git a/maps/holySepulchre-mausoleum-niche-L-W (12d943ad-3e7c-43f4-ac85-0938e6fc919d, 9c4edf97-b139-4dba-80e1-246cf0a5f73a).svg b/public/images/maps/holySepulchre-mausoleum-niche-L-W (12d943ad-3e7c-43f4-ac85-0938e6fc919d, 9c4edf97-b139-4dba-80e1-246cf0a5f73a).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-L-W (12d943ad-3e7c-43f4-ac85-0938e6fc919d, 9c4edf97-b139-4dba-80e1-246cf0a5f73a).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-L-W (12d943ad-3e7c-43f4-ac85-0938e6fc919d, 9c4edf97-b139-4dba-80e1-246cf0a5f73a).svg
diff --git a/maps/holySepulchre-mausoleum-niche-M (6016d5cd-819a-44fc-b1f1-1aefbde6a360, dae1a3fb-d58e-43f2-a8c4-8cafbf412d2c).svg b/public/images/maps/holySepulchre-mausoleum-niche-M (6016d5cd-819a-44fc-b1f1-1aefbde6a360, dae1a3fb-d58e-43f2-a8c4-8cafbf412d2c).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-M (6016d5cd-819a-44fc-b1f1-1aefbde6a360, dae1a3fb-d58e-43f2-a8c4-8cafbf412d2c).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-M (6016d5cd-819a-44fc-b1f1-1aefbde6a360, dae1a3fb-d58e-43f2-a8c4-8cafbf412d2c).svg
diff --git a/maps/holySepulchre-mausoleum-niche-M-E (c3a1dc37-833e-4499-92eb-9585ab30da84, 4551f949-162e-4285-9160-0cca1eeeb9c4).svg b/public/images/maps/holySepulchre-mausoleum-niche-M-E (c3a1dc37-833e-4499-92eb-9585ab30da84, 4551f949-162e-4285-9160-0cca1eeeb9c4).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-M-E (c3a1dc37-833e-4499-92eb-9585ab30da84, 4551f949-162e-4285-9160-0cca1eeeb9c4).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-M-E (c3a1dc37-833e-4499-92eb-9585ab30da84, 4551f949-162e-4285-9160-0cca1eeeb9c4).svg
diff --git a/maps/holySepulchre-mausoleum-niche-M-W (657d144e-4632-418a-b72c-0b6eb517101c, 111ae74e-f104-4778-9347-023d1e7736f4).svg b/public/images/maps/holySepulchre-mausoleum-niche-M-W (657d144e-4632-418a-b72c-0b6eb517101c, 111ae74e-f104-4778-9347-023d1e7736f4).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-niche-M-W (657d144e-4632-418a-b72c-0b6eb517101c, 111ae74e-f104-4778-9347-023d1e7736f4).svg
rename to public/images/maps/holySepulchre-mausoleum-niche-M-W (657d144e-4632-418a-b72c-0b6eb517101c, 111ae74e-f104-4778-9347-023d1e7736f4).svg
diff --git a/maps/holySepulchre-mausoleum-section-T (30692472-f7dd-41cc-bbca-12e94680e83f, 2c15bd67-de67-4474-9106-ad1c67eb8650).svg b/public/images/maps/holySepulchre-mausoleum-section-T (30692472-f7dd-41cc-bbca-12e94680e83f, 2c15bd67-de67-4474-9106-ad1c67eb8650).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-section-T (30692472-f7dd-41cc-bbca-12e94680e83f, 2c15bd67-de67-4474-9106-ad1c67eb8650).svg
rename to public/images/maps/holySepulchre-mausoleum-section-T (30692472-f7dd-41cc-bbca-12e94680e83f, 2c15bd67-de67-4474-9106-ad1c67eb8650).svg
diff --git a/maps/holySepulchre-mausoleum-section-U (8cd267db-1d30-454c-b3a2-7f21f9c0ba18, 094f14cb-7b5f-4488-aa96-7f80bd8aa3fd).svg b/public/images/maps/holySepulchre-mausoleum-section-U (8cd267db-1d30-454c-b3a2-7f21f9c0ba18, 094f14cb-7b5f-4488-aa96-7f80bd8aa3fd).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-section-U (8cd267db-1d30-454c-b3a2-7f21f9c0ba18, 094f14cb-7b5f-4488-aa96-7f80bd8aa3fd).svg
rename to public/images/maps/holySepulchre-mausoleum-section-U (8cd267db-1d30-454c-b3a2-7f21f9c0ba18, 094f14cb-7b5f-4488-aa96-7f80bd8aa3fd).svg
diff --git a/maps/holySepulchre-mausoleum-west (0b7cc779-d151-4732-bd9f-55f27ba13ffb, 9f055a1f-86ae-4fe0-945e-0a9e83fdf263).svg b/public/images/maps/holySepulchre-mausoleum-west (0b7cc779-d151-4732-bd9f-55f27ba13ffb, 9f055a1f-86ae-4fe0-945e-0a9e83fdf263).svg
similarity index 100%
rename from maps/holySepulchre-mausoleum-west (0b7cc779-d151-4732-bd9f-55f27ba13ffb, 9f055a1f-86ae-4fe0-945e-0a9e83fdf263).svg
rename to public/images/maps/holySepulchre-mausoleum-west (0b7cc779-d151-4732-bd9f-55f27ba13ffb, 9f055a1f-86ae-4fe0-945e-0a9e83fdf263).svg
diff --git a/maps/holySepulchre-overview (96ecac1f-21d2-4507-908b-eedafe0702a9, 547d27bb-71b0-4758-8081-163838199e94).svg b/public/images/maps/holySepulchre-overview.svg
similarity index 100%
rename from maps/holySepulchre-overview (96ecac1f-21d2-4507-908b-eedafe0702a9, 547d27bb-71b0-4758-8081-163838199e94).svg
rename to public/images/maps/holySepulchre-overview.svg
diff --git a/maps/newGreenwood-columbarium-A (f73f9667-d215-4a62-bb7c-5ad95e1352db, 67c0ecba-141e-4fb5-9c06-8363904063c0).svg b/public/images/maps/newGreenwood-columbarium-A (f73f9667-d215-4a62-bb7c-5ad95e1352db, 67c0ecba-141e-4fb5-9c06-8363904063c0).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-A (f73f9667-d215-4a62-bb7c-5ad95e1352db, 67c0ecba-141e-4fb5-9c06-8363904063c0).svg
rename to public/images/maps/newGreenwood-columbarium-A (f73f9667-d215-4a62-bb7c-5ad95e1352db, 67c0ecba-141e-4fb5-9c06-8363904063c0).svg
diff --git a/maps/newGreenwood-columbarium-B (16be946c-ae5a-4ee0-90db-c6721f490a2c, 1481cf4b-cd08-4bfc-ad94-806fcf2bef33).svg b/public/images/maps/newGreenwood-columbarium-B (16be946c-ae5a-4ee0-90db-c6721f490a2c, 1481cf4b-cd08-4bfc-ad94-806fcf2bef33).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-B (16be946c-ae5a-4ee0-90db-c6721f490a2c, 1481cf4b-cd08-4bfc-ad94-806fcf2bef33).svg
rename to public/images/maps/newGreenwood-columbarium-B (16be946c-ae5a-4ee0-90db-c6721f490a2c, 1481cf4b-cd08-4bfc-ad94-806fcf2bef33).svg
diff --git a/maps/newGreenwood-columbarium-C (e83f5e2b-4580-40be-9657-ac13a310c77f, 6c713d9d-5493-47a1-a390-8497a35dd5c7).svg b/public/images/maps/newGreenwood-columbarium-C (e83f5e2b-4580-40be-9657-ac13a310c77f, 6c713d9d-5493-47a1-a390-8497a35dd5c7).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-C (e83f5e2b-4580-40be-9657-ac13a310c77f, 6c713d9d-5493-47a1-a390-8497a35dd5c7).svg
rename to public/images/maps/newGreenwood-columbarium-C (e83f5e2b-4580-40be-9657-ac13a310c77f, 6c713d9d-5493-47a1-a390-8497a35dd5c7).svg
diff --git a/maps/newGreenwood-columbarium-D (ad9ebc87-dfe5-417f-8294-54ee73dd47f4, 3194e7fa-7267-459a-b13c-b9a6c14deed1).svg b/public/images/maps/newGreenwood-columbarium-D (ad9ebc87-dfe5-417f-8294-54ee73dd47f4, 3194e7fa-7267-459a-b13c-b9a6c14deed1).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-D (ad9ebc87-dfe5-417f-8294-54ee73dd47f4, 3194e7fa-7267-459a-b13c-b9a6c14deed1).svg
rename to public/images/maps/newGreenwood-columbarium-D (ad9ebc87-dfe5-417f-8294-54ee73dd47f4, 3194e7fa-7267-459a-b13c-b9a6c14deed1).svg
diff --git a/maps/newGreenwood-columbarium-E (57e2fc58-0ae2-45cb-9021-6437bb530202, 4cbd9e7d-8b17-4eba-91d8-7f99976df376).svg b/public/images/maps/newGreenwood-columbarium-E (57e2fc58-0ae2-45cb-9021-6437bb530202, 4cbd9e7d-8b17-4eba-91d8-7f99976df376).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-E (57e2fc58-0ae2-45cb-9021-6437bb530202, 4cbd9e7d-8b17-4eba-91d8-7f99976df376).svg
rename to public/images/maps/newGreenwood-columbarium-E (57e2fc58-0ae2-45cb-9021-6437bb530202, 4cbd9e7d-8b17-4eba-91d8-7f99976df376).svg
diff --git a/maps/newGreenwood-columbarium-F (eacfeb63-7d75-454c-b891-2eaf69a4cf3e, 814234ea-5870-4428-92b9-edf03a89995a).svg b/public/images/maps/newGreenwood-columbarium-F (eacfeb63-7d75-454c-b891-2eaf69a4cf3e, 814234ea-5870-4428-92b9-edf03a89995a).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-F (eacfeb63-7d75-454c-b891-2eaf69a4cf3e, 814234ea-5870-4428-92b9-edf03a89995a).svg
rename to public/images/maps/newGreenwood-columbarium-F (eacfeb63-7d75-454c-b891-2eaf69a4cf3e, 814234ea-5870-4428-92b9-edf03a89995a).svg
diff --git a/maps/newGreenwood-columbarium-G (0c1a6bb9-ae10-4e77-99ef-0de506c0cd42, 564d3437-abfd-410a-94b1-6d4b0bc1275a).svg b/public/images/maps/newGreenwood-columbarium-G (0c1a6bb9-ae10-4e77-99ef-0de506c0cd42, 564d3437-abfd-410a-94b1-6d4b0bc1275a).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-G (0c1a6bb9-ae10-4e77-99ef-0de506c0cd42, 564d3437-abfd-410a-94b1-6d4b0bc1275a).svg
rename to public/images/maps/newGreenwood-columbarium-G (0c1a6bb9-ae10-4e77-99ef-0de506c0cd42, 564d3437-abfd-410a-94b1-6d4b0bc1275a).svg
diff --git a/maps/newGreenwood-columbarium-H (5fec6c60-45fd-46b0-90b3-7cdf88ddb905, 865aae59-2535-4690-a03d-cdd08bcbe12c).svg b/public/images/maps/newGreenwood-columbarium-H (5fec6c60-45fd-46b0-90b3-7cdf88ddb905, 865aae59-2535-4690-a03d-cdd08bcbe12c).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-H (5fec6c60-45fd-46b0-90b3-7cdf88ddb905, 865aae59-2535-4690-a03d-cdd08bcbe12c).svg
rename to public/images/maps/newGreenwood-columbarium-H (5fec6c60-45fd-46b0-90b3-7cdf88ddb905, 865aae59-2535-4690-a03d-cdd08bcbe12c).svg
diff --git a/maps/newGreenwood-columbarium-I (bd647893-d7b0-4017-9c4c-2ca46e5cfd9a, c496a6a6-1f52-4539-9c4a-fcc03e3b573a).svg b/public/images/maps/newGreenwood-columbarium-I (bd647893-d7b0-4017-9c4c-2ca46e5cfd9a, c496a6a6-1f52-4539-9c4a-fcc03e3b573a).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-I (bd647893-d7b0-4017-9c4c-2ca46e5cfd9a, c496a6a6-1f52-4539-9c4a-fcc03e3b573a).svg
rename to public/images/maps/newGreenwood-columbarium-I (bd647893-d7b0-4017-9c4c-2ca46e5cfd9a, c496a6a6-1f52-4539-9c4a-fcc03e3b573a).svg
diff --git a/maps/newGreenwood-columbarium-J (b21345a5-65d5-4a2e-b0ee-b946c9408d8a, 9121ae96-f3d6-4016-b7ff-8423f4d94d76).svg b/public/images/maps/newGreenwood-columbarium-J (b21345a5-65d5-4a2e-b0ee-b946c9408d8a, 9121ae96-f3d6-4016-b7ff-8423f4d94d76).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-J (b21345a5-65d5-4a2e-b0ee-b946c9408d8a, 9121ae96-f3d6-4016-b7ff-8423f4d94d76).svg
rename to public/images/maps/newGreenwood-columbarium-J (b21345a5-65d5-4a2e-b0ee-b946c9408d8a, 9121ae96-f3d6-4016-b7ff-8423f4d94d76).svg
diff --git a/maps/newGreenwood-columbarium-K (de3985aa-51cf-4247-8101-22046117e618, 89b5120d-e644-46a1-bb6c-198de36c5b24).svg b/public/images/maps/newGreenwood-columbarium-K (de3985aa-51cf-4247-8101-22046117e618, 89b5120d-e644-46a1-bb6c-198de36c5b24).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-K (de3985aa-51cf-4247-8101-22046117e618, 89b5120d-e644-46a1-bb6c-198de36c5b24).svg
rename to public/images/maps/newGreenwood-columbarium-K (de3985aa-51cf-4247-8101-22046117e618, 89b5120d-e644-46a1-bb6c-198de36c5b24).svg
diff --git a/maps/newGreenwood-columbarium-L (14cfb32d-4eb0-4c74-a788-2a6454ccaf4a, 4a122656-89eb-43eb-ada0-ceb2b9342c81).svg b/public/images/maps/newGreenwood-columbarium-L (14cfb32d-4eb0-4c74-a788-2a6454ccaf4a, 4a122656-89eb-43eb-ada0-ceb2b9342c81).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-L (14cfb32d-4eb0-4c74-a788-2a6454ccaf4a, 4a122656-89eb-43eb-ada0-ceb2b9342c81).svg
rename to public/images/maps/newGreenwood-columbarium-L (14cfb32d-4eb0-4c74-a788-2a6454ccaf4a, 4a122656-89eb-43eb-ada0-ceb2b9342c81).svg
diff --git a/maps/newGreenwood-columbarium-M (b7c858a3-0326-4ee6-83e7-9b0cf8a3fb53, 315c09b4-e465-418f-82d0-c3580b83913d).svg b/public/images/maps/newGreenwood-columbarium-M (b7c858a3-0326-4ee6-83e7-9b0cf8a3fb53, 315c09b4-e465-418f-82d0-c3580b83913d).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-M (b7c858a3-0326-4ee6-83e7-9b0cf8a3fb53, 315c09b4-e465-418f-82d0-c3580b83913d).svg
rename to public/images/maps/newGreenwood-columbarium-M (b7c858a3-0326-4ee6-83e7-9b0cf8a3fb53, 315c09b4-e465-418f-82d0-c3580b83913d).svg
diff --git a/maps/newGreenwood-columbarium-N (5b265feb-9a0f-4ee1-af11-930feb6583b1, 0839376b-0e3f-4e90-b78c-8740ba44e14c).svg b/public/images/maps/newGreenwood-columbarium-N (5b265feb-9a0f-4ee1-af11-930feb6583b1, 0839376b-0e3f-4e90-b78c-8740ba44e14c).svg
similarity index 100%
rename from maps/newGreenwood-columbarium-N (5b265feb-9a0f-4ee1-af11-930feb6583b1, 0839376b-0e3f-4e90-b78c-8740ba44e14c).svg
rename to public/images/maps/newGreenwood-columbarium-N (5b265feb-9a0f-4ee1-af11-930feb6583b1, 0839376b-0e3f-4e90-b78c-8740ba44e14c).svg
diff --git a/maps/newGreenwood-infantsSection (e9e319bd-2c5b-415f-a013-d3ba86c15083, ba4aa864-ab4a-4bf8-8b51-a47dddcafe59).svg b/public/images/maps/newGreenwood-infantsSection (e9e319bd-2c5b-415f-a013-d3ba86c15083, ba4aa864-ab4a-4bf8-8b51-a47dddcafe59).svg
similarity index 100%
rename from maps/newGreenwood-infantsSection (e9e319bd-2c5b-415f-a013-d3ba86c15083, ba4aa864-ab4a-4bf8-8b51-a47dddcafe59).svg
rename to public/images/maps/newGreenwood-infantsSection (e9e319bd-2c5b-415f-a013-d3ba86c15083, ba4aa864-ab4a-4bf8-8b51-a47dddcafe59).svg
diff --git a/maps/newGreenwood-nicheWall-1-40 (5b70b2b7-0db7-4035-9954-bf96f608c902, 947b8dd6-5daa-46ad-9f96-90f270d8ab3d).svg b/public/images/maps/newGreenwood-nicheWall-1-40 (5b70b2b7-0db7-4035-9954-bf96f608c902, 947b8dd6-5daa-46ad-9f96-90f270d8ab3d).svg
similarity index 100%
rename from maps/newGreenwood-nicheWall-1-40 (5b70b2b7-0db7-4035-9954-bf96f608c902, 947b8dd6-5daa-46ad-9f96-90f270d8ab3d).svg
rename to public/images/maps/newGreenwood-nicheWall-1-40 (5b70b2b7-0db7-4035-9954-bf96f608c902, 947b8dd6-5daa-46ad-9f96-90f270d8ab3d).svg
diff --git a/maps/newGreenwood-nicheWall-41-80 (5739ffcc-9618-4170-b004-7459a948a008, 5fd580c8-0831-4a5d-8a61-609d5b4b1269).svg b/public/images/maps/newGreenwood-nicheWall-41-80 (5739ffcc-9618-4170-b004-7459a948a008, 5fd580c8-0831-4a5d-8a61-609d5b4b1269).svg
similarity index 100%
rename from maps/newGreenwood-nicheWall-41-80 (5739ffcc-9618-4170-b004-7459a948a008, 5fd580c8-0831-4a5d-8a61-609d5b4b1269).svg
rename to public/images/maps/newGreenwood-nicheWall-41-80 (5739ffcc-9618-4170-b004-7459a948a008, 5fd580c8-0831-4a5d-8a61-609d5b4b1269).svg
diff --git a/maps/newGreenwood-nicheWall-81-106 (5f565cde-1049-4b8c-8119-7e1002ecab9d, 718faff5-191d-4cb0-a6c4-fc100dcb8d12).svg b/public/images/maps/newGreenwood-nicheWall-81-106 (5f565cde-1049-4b8c-8119-7e1002ecab9d, 718faff5-191d-4cb0-a6c4-fc100dcb8d12).svg
similarity index 100%
rename from maps/newGreenwood-nicheWall-81-106 (5f565cde-1049-4b8c-8119-7e1002ecab9d, 718faff5-191d-4cb0-a6c4-fc100dcb8d12).svg
rename to public/images/maps/newGreenwood-nicheWall-81-106 (5f565cde-1049-4b8c-8119-7e1002ecab9d, 718faff5-191d-4cb0-a6c4-fc100dcb8d12).svg
diff --git a/maps/newGreenwood-overview (a509dd33-816e-4ff5-9ba6-30c0763b4333, 0a3188ee-4841-478a-b737-c8918a82145e).svg b/public/images/maps/newGreenwood-overview.svg
similarity index 100%
rename from maps/newGreenwood-overview (a509dd33-816e-4ff5-9ba6-30c0763b4333, 0a3188ee-4841-478a-b737-c8918a82145e).svg
rename to public/images/maps/newGreenwood-overview.svg
diff --git a/maps/newGreenwood-rows-1-31-lots 3-21 (88754d9d-9895-4de4-a977-b9a2e8069c88, ad19b731-c37d-43b7-a89e-5caaf1daff59).svg b/public/images/maps/newGreenwood-rows-1-31-lots 3-21 (88754d9d-9895-4de4-a977-b9a2e8069c88, ad19b731-c37d-43b7-a89e-5caaf1daff59).svg
similarity index 100%
rename from maps/newGreenwood-rows-1-31-lots 3-21 (88754d9d-9895-4de4-a977-b9a2e8069c88, ad19b731-c37d-43b7-a89e-5caaf1daff59).svg
rename to public/images/maps/newGreenwood-rows-1-31-lots 3-21 (88754d9d-9895-4de4-a977-b9a2e8069c88, ad19b731-c37d-43b7-a89e-5caaf1daff59).svg
diff --git a/maps/newGreenwood-rows-1-31-lots-22-46 (d8c5f1ee-0bbc-4796-99fb-7886c2f24a37, 57cbdb69-24d9-4fa4-ac1b-27d73a7cbdb3).svg b/public/images/maps/newGreenwood-rows-1-31-lots-22-46 (d8c5f1ee-0bbc-4796-99fb-7886c2f24a37, 57cbdb69-24d9-4fa4-ac1b-27d73a7cbdb3).svg
similarity index 100%
rename from maps/newGreenwood-rows-1-31-lots-22-46 (d8c5f1ee-0bbc-4796-99fb-7886c2f24a37, 57cbdb69-24d9-4fa4-ac1b-27d73a7cbdb3).svg
rename to public/images/maps/newGreenwood-rows-1-31-lots-22-46 (d8c5f1ee-0bbc-4796-99fb-7886c2f24a37, 57cbdb69-24d9-4fa4-ac1b-27d73a7cbdb3).svg
diff --git a/maps/newGreenwood-rows-25-61-lots-47-59 (17cde84a-d718-4f8c-b390-a5b1be7790f9, cbde6623-43ae-4e85-a519-a0b12cd82569).svg b/public/images/maps/newGreenwood-rows-25-61-lots-47-59 (17cde84a-d718-4f8c-b390-a5b1be7790f9, cbde6623-43ae-4e85-a519-a0b12cd82569).svg
similarity index 100%
rename from maps/newGreenwood-rows-25-61-lots-47-59 (17cde84a-d718-4f8c-b390-a5b1be7790f9, cbde6623-43ae-4e85-a519-a0b12cd82569).svg
rename to public/images/maps/newGreenwood-rows-25-61-lots-47-59 (17cde84a-d718-4f8c-b390-a5b1be7790f9, cbde6623-43ae-4e85-a519-a0b12cd82569).svg
diff --git a/maps/newGreenwood-rows-33-60-lots-4-21A (2d82ebf0-ca52-44cb-adbe-7ac9805261ed, 17d566ca-1689-49cd-9295-d6e6e9ad4e10).svg b/public/images/maps/newGreenwood-rows-33-60-lots-4-21A (2d82ebf0-ca52-44cb-adbe-7ac9805261ed, 17d566ca-1689-49cd-9295-d6e6e9ad4e10).svg
similarity index 100%
rename from maps/newGreenwood-rows-33-60-lots-4-21A (2d82ebf0-ca52-44cb-adbe-7ac9805261ed, 17d566ca-1689-49cd-9295-d6e6e9ad4e10).svg
rename to public/images/maps/newGreenwood-rows-33-60-lots-4-21A (2d82ebf0-ca52-44cb-adbe-7ac9805261ed, 17d566ca-1689-49cd-9295-d6e6e9ad4e10).svg
diff --git a/maps/newGreenwood-rows-33-61-lots-22-46 (f13bf83f-1d75-43e1-a20c-0baf439e645e, 9cd6fd8c-63e4-47ce-964b-83a959ba8a6e).svg b/public/images/maps/newGreenwood-rows-33-61-lots-22-46 (f13bf83f-1d75-43e1-a20c-0baf439e645e, 9cd6fd8c-63e4-47ce-964b-83a959ba8a6e).svg
similarity index 100%
rename from maps/newGreenwood-rows-33-61-lots-22-46 (f13bf83f-1d75-43e1-a20c-0baf439e645e, 9cd6fd8c-63e4-47ce-964b-83a959ba8a6e).svg
rename to public/images/maps/newGreenwood-rows-33-61-lots-22-46 (f13bf83f-1d75-43e1-a20c-0baf439e645e, 9cd6fd8c-63e4-47ce-964b-83a959ba8a6e).svg
diff --git a/maps/newGreenwood-rows-63-94-lots-24-40 (09dfd9ab-3470-495c-8fc2-bf79aa2149e8, 71ab5496-f1bf-4152-8c40-16e5dad875c9).svg b/public/images/maps/newGreenwood-rows-63-94-lots-24-40 (09dfd9ab-3470-495c-8fc2-bf79aa2149e8, 71ab5496-f1bf-4152-8c40-16e5dad875c9).svg
similarity index 100%
rename from maps/newGreenwood-rows-63-94-lots-24-40 (09dfd9ab-3470-495c-8fc2-bf79aa2149e8, 71ab5496-f1bf-4152-8c40-16e5dad875c9).svg
rename to public/images/maps/newGreenwood-rows-63-94-lots-24-40 (09dfd9ab-3470-495c-8fc2-bf79aa2149e8, 71ab5496-f1bf-4152-8c40-16e5dad875c9).svg
diff --git a/maps/newGreenwood-rows-63-94-lots-47-59 (03a3a261-6bb9-402f-b884-095e74162e2b, 14738395-5610-4e97-855b-43c66ff6eb03).svg b/public/images/maps/newGreenwood-rows-63-94-lots-47-59 (03a3a261-6bb9-402f-b884-095e74162e2b, 14738395-5610-4e97-855b-43c66ff6eb03).svg
similarity index 100%
rename from maps/newGreenwood-rows-63-94-lots-47-59 (03a3a261-6bb9-402f-b884-095e74162e2b, 14738395-5610-4e97-855b-43c66ff6eb03).svg
rename to public/images/maps/newGreenwood-rows-63-94-lots-47-59 (03a3a261-6bb9-402f-b884-095e74162e2b, 14738395-5610-4e97-855b-43c66ff6eb03).svg
diff --git a/maps/newGreenwood-rows-66-95-lots-12-24 (67484236-41db-4cc4-a9f7-4539c472bce7, ebd4968b-04ec-4288-9810-10e2ed43ed0b).svg b/public/images/maps/newGreenwood-rows-66-95-lots-12-24 (67484236-41db-4cc4-a9f7-4539c472bce7, ebd4968b-04ec-4288-9810-10e2ed43ed0b).svg
similarity index 100%
rename from maps/newGreenwood-rows-66-95-lots-12-24 (67484236-41db-4cc4-a9f7-4539c472bce7, ebd4968b-04ec-4288-9810-10e2ed43ed0b).svg
rename to public/images/maps/newGreenwood-rows-66-95-lots-12-24 (67484236-41db-4cc4-a9f7-4539c472bce7, ebd4968b-04ec-4288-9810-10e2ed43ed0b).svg
diff --git a/maps/newGreenwood-urnGarden (0e8bc6f3-3354-425a-a43b-9121894a4749, 9ce753aa-e0f2-440c-a7a2-83826a97ee79).svg b/public/images/maps/newGreenwood-urnGarden.svg
similarity index 100%
rename from maps/newGreenwood-urnGarden (0e8bc6f3-3354-425a-a43b-9121894a4749, 9ce753aa-e0f2-440c-a7a2-83826a97ee79).svg
rename to public/images/maps/newGreenwood-urnGarden.svg
diff --git a/maps/newGreenwood-veteransSection (dfa8960b-47fb-4ba0-b48a-00d2c268fefb, cafbec22-337d-4ac8-9b57-e0f48803943a).svg b/public/images/maps/newGreenwood-veteransSection (dfa8960b-47fb-4ba0-b48a-00d2c268fefb, cafbec22-337d-4ac8-9b57-e0f48803943a).svg
similarity index 100%
rename from maps/newGreenwood-veteransSection (dfa8960b-47fb-4ba0-b48a-00d2c268fefb, cafbec22-337d-4ac8-9b57-e0f48803943a).svg
rename to public/images/maps/newGreenwood-veteransSection (dfa8960b-47fb-4ba0-b48a-00d2c268fefb, cafbec22-337d-4ac8-9b57-e0f48803943a).svg
diff --git a/maps/oldGreenwood-babySection (badc8b5a-d687-48b0-ac11-6290e977b3ca, 09730968-79ec-45f7-aca7-c3790beca297).svg b/public/images/maps/oldGreenwood-babySection (badc8b5a-d687-48b0-ac11-6290e977b3ca, 09730968-79ec-45f7-aca7-c3790beca297).svg
similarity index 100%
rename from maps/oldGreenwood-babySection (badc8b5a-d687-48b0-ac11-6290e977b3ca, 09730968-79ec-45f7-aca7-c3790beca297).svg
rename to public/images/maps/oldGreenwood-babySection (badc8b5a-d687-48b0-ac11-6290e977b3ca, 09730968-79ec-45f7-aca7-c3790beca297).svg
diff --git a/maps/oldGreenwood-eastNorth-rows-1-18-lots-1-11 (76619606-411d-4387-a78f-66e47f9ba7be, 2bc05828-d127-4f53-8a10-43464bf56601).svg b/public/images/maps/oldGreenwood-eastNorth-rows-1-18-lots-1-11 (76619606-411d-4387-a78f-66e47f9ba7be, 2bc05828-d127-4f53-8a10-43464bf56601).svg
similarity index 100%
rename from maps/oldGreenwood-eastNorth-rows-1-18-lots-1-11 (76619606-411d-4387-a78f-66e47f9ba7be, 2bc05828-d127-4f53-8a10-43464bf56601).svg
rename to public/images/maps/oldGreenwood-eastNorth-rows-1-18-lots-1-11 (76619606-411d-4387-a78f-66e47f9ba7be, 2bc05828-d127-4f53-8a10-43464bf56601).svg
diff --git a/maps/oldGreenwood-eastNorth-rows-1-18-lots-12-17 (be441559-acdd-4364-b086-2fd9094ae669, eddfaa59-e592-4f2b-84af-4ab078c29f1c).svg b/public/images/maps/oldGreenwood-eastNorth-rows-1-18-lots-12-17 (be441559-acdd-4364-b086-2fd9094ae669, eddfaa59-e592-4f2b-84af-4ab078c29f1c).svg
similarity index 100%
rename from maps/oldGreenwood-eastNorth-rows-1-18-lots-12-17 (be441559-acdd-4364-b086-2fd9094ae669, eddfaa59-e592-4f2b-84af-4ab078c29f1c).svg
rename to public/images/maps/oldGreenwood-eastNorth-rows-1-18-lots-12-17 (be441559-acdd-4364-b086-2fd9094ae669, eddfaa59-e592-4f2b-84af-4ab078c29f1c).svg
diff --git a/maps/oldGreenwood-eastNorth-rows-19-38-lots-1-11 (39a0037c-0145-4d99-b1f4-a51d89802da0, 12836593-877e-4953-b638-71b894084e46).svg b/public/images/maps/oldGreenwood-eastNorth-rows-19-38-lots-1-11 (39a0037c-0145-4d99-b1f4-a51d89802da0, 12836593-877e-4953-b638-71b894084e46).svg
similarity index 100%
rename from maps/oldGreenwood-eastNorth-rows-19-38-lots-1-11 (39a0037c-0145-4d99-b1f4-a51d89802da0, 12836593-877e-4953-b638-71b894084e46).svg
rename to public/images/maps/oldGreenwood-eastNorth-rows-19-38-lots-1-11 (39a0037c-0145-4d99-b1f4-a51d89802da0, 12836593-877e-4953-b638-71b894084e46).svg
diff --git a/maps/oldGreenwood-eastNorth-rows-19-38-lots-12-17 (1b6d21ab-66c6-4264-9a75-4d6d93c0cbc3, 3c3441be-3c04-458f-9da5-59bb27b9fb5c).svg b/public/images/maps/oldGreenwood-eastNorth-rows-19-38-lots-12-17 (1b6d21ab-66c6-4264-9a75-4d6d93c0cbc3, 3c3441be-3c04-458f-9da5-59bb27b9fb5c).svg
similarity index 100%
rename from maps/oldGreenwood-eastNorth-rows-19-38-lots-12-17 (1b6d21ab-66c6-4264-9a75-4d6d93c0cbc3, 3c3441be-3c04-458f-9da5-59bb27b9fb5c).svg
rename to public/images/maps/oldGreenwood-eastNorth-rows-19-38-lots-12-17 (1b6d21ab-66c6-4264-9a75-4d6d93c0cbc3, 3c3441be-3c04-458f-9da5-59bb27b9fb5c).svg
diff --git a/maps/oldGreenwood-eastSouthA-rows-1-18-lots 23-31 (c7184cfa-31b3-445c-84f7-560465e58031, 8b103b97-c945-4b92-961d-3359dddbe2db).svg b/public/images/maps/oldGreenwood-eastSouthA-rows-1-18-lots 23-31 (c7184cfa-31b3-445c-84f7-560465e58031, 8b103b97-c945-4b92-961d-3359dddbe2db).svg
similarity index 100%
rename from maps/oldGreenwood-eastSouthA-rows-1-18-lots 23-31 (c7184cfa-31b3-445c-84f7-560465e58031, 8b103b97-c945-4b92-961d-3359dddbe2db).svg
rename to public/images/maps/oldGreenwood-eastSouthA-rows-1-18-lots 23-31 (c7184cfa-31b3-445c-84f7-560465e58031, 8b103b97-c945-4b92-961d-3359dddbe2db).svg
diff --git a/maps/oldGreenwood-eastSouthA-rows-1-18-lots-1-22 (874dc9bd-92af-4657-9f88-b659ab8fbb3c, aa68c1e1-dc27-47f5-afd2-3632d58c8811).svg b/public/images/maps/oldGreenwood-eastSouthA-rows-1-18-lots-1-22 (874dc9bd-92af-4657-9f88-b659ab8fbb3c, aa68c1e1-dc27-47f5-afd2-3632d58c8811).svg
similarity index 100%
rename from maps/oldGreenwood-eastSouthA-rows-1-18-lots-1-22 (874dc9bd-92af-4657-9f88-b659ab8fbb3c, aa68c1e1-dc27-47f5-afd2-3632d58c8811).svg
rename to public/images/maps/oldGreenwood-eastSouthA-rows-1-18-lots-1-22 (874dc9bd-92af-4657-9f88-b659ab8fbb3c, aa68c1e1-dc27-47f5-afd2-3632d58c8811).svg
diff --git a/maps/oldGreenwood-eastSouthA-rows-19-32-lots-1-22 (2fee7675-e377-483e-993a-1bb4d3b8b04b, 0cdca656-adc8-4927-ac09-414bac7d7f11).svg b/public/images/maps/oldGreenwood-eastSouthA-rows-19-32-lots-1-22 (2fee7675-e377-483e-993a-1bb4d3b8b04b, 0cdca656-adc8-4927-ac09-414bac7d7f11).svg
similarity index 100%
rename from maps/oldGreenwood-eastSouthA-rows-19-32-lots-1-22 (2fee7675-e377-483e-993a-1bb4d3b8b04b, 0cdca656-adc8-4927-ac09-414bac7d7f11).svg
rename to public/images/maps/oldGreenwood-eastSouthA-rows-19-32-lots-1-22 (2fee7675-e377-483e-993a-1bb4d3b8b04b, 0cdca656-adc8-4927-ac09-414bac7d7f11).svg
diff --git a/maps/oldGreenwood-eastSouthA-rows-19-32-lots-23-31 (453fd8e1-d5b8-42b5-bb3b-a89b96ca0d06, 4b20396b-9827-4639-80c2-94466ebca164).svg b/public/images/maps/oldGreenwood-eastSouthA-rows-19-32-lots-23-31 (453fd8e1-d5b8-42b5-bb3b-a89b96ca0d06, 4b20396b-9827-4639-80c2-94466ebca164).svg
similarity index 100%
rename from maps/oldGreenwood-eastSouthA-rows-19-32-lots-23-31 (453fd8e1-d5b8-42b5-bb3b-a89b96ca0d06, 4b20396b-9827-4639-80c2-94466ebca164).svg
rename to public/images/maps/oldGreenwood-eastSouthA-rows-19-32-lots-23-31 (453fd8e1-d5b8-42b5-bb3b-a89b96ca0d06, 4b20396b-9827-4639-80c2-94466ebca164).svg
diff --git a/maps/oldGreenwood-eastSouthB-lots-33-45-rows-1-22 (f5eadd1c-9d23-4f43-9b9b-c33eea9fb51b, db49f720-2b27-4faa-9000-d57c23d857a0).svg b/public/images/maps/oldGreenwood-eastSouthB-lots-33-45-rows-1-22 (f5eadd1c-9d23-4f43-9b9b-c33eea9fb51b, db49f720-2b27-4faa-9000-d57c23d857a0).svg
similarity index 100%
rename from maps/oldGreenwood-eastSouthB-lots-33-45-rows-1-22 (f5eadd1c-9d23-4f43-9b9b-c33eea9fb51b, db49f720-2b27-4faa-9000-d57c23d857a0).svg
rename to public/images/maps/oldGreenwood-eastSouthB-lots-33-45-rows-1-22 (f5eadd1c-9d23-4f43-9b9b-c33eea9fb51b, db49f720-2b27-4faa-9000-d57c23d857a0).svg
diff --git a/maps/oldGreenwood-eastSouthB-rows-33-57-lots 23-31 (3a833486-a869-490b-8e47-bcf07b0045a0, 8e2b9dd7-5364-44ff-9103-4e476ded3104).svg b/public/images/maps/oldGreenwood-eastSouthB-rows-33-57-lots 23-31 (3a833486-a869-490b-8e47-bcf07b0045a0, 8e2b9dd7-5364-44ff-9103-4e476ded3104).svg
similarity index 100%
rename from maps/oldGreenwood-eastSouthB-rows-33-57-lots 23-31 (3a833486-a869-490b-8e47-bcf07b0045a0, 8e2b9dd7-5364-44ff-9103-4e476ded3104).svg
rename to public/images/maps/oldGreenwood-eastSouthB-rows-33-57-lots 23-31 (3a833486-a869-490b-8e47-bcf07b0045a0, 8e2b9dd7-5364-44ff-9103-4e476ded3104).svg
diff --git a/maps/oldGreenwood-eastSouthB-rows-46-57-lots-11-24 (28daa4e5-edb8-495d-92dd-5c773663fed2, 24d47e75-9b02-4b61-8545-9d694d81b060).svg b/public/images/maps/oldGreenwood-eastSouthB-rows-46-57-lots-11-24 (28daa4e5-edb8-495d-92dd-5c773663fed2, 24d47e75-9b02-4b61-8545-9d694d81b060).svg
similarity index 100%
rename from maps/oldGreenwood-eastSouthB-rows-46-57-lots-11-24 (28daa4e5-edb8-495d-92dd-5c773663fed2, 24d47e75-9b02-4b61-8545-9d694d81b060).svg
rename to public/images/maps/oldGreenwood-eastSouthB-rows-46-57-lots-11-24 (28daa4e5-edb8-495d-92dd-5c773663fed2, 24d47e75-9b02-4b61-8545-9d694d81b060).svg
diff --git a/maps/oldGreenwood-overview (94cce7b1-4f54-421e-905c-e953d6bd155d, ef21451a-803f-48dd-8cfe-594b9642df10).svg b/public/images/maps/oldGreenwood-overview.svg
similarity index 100%
rename from maps/oldGreenwood-overview (94cce7b1-4f54-421e-905c-e953d6bd155d, ef21451a-803f-48dd-8cfe-594b9642df10).svg
rename to public/images/maps/oldGreenwood-overview.svg
diff --git a/maps/oldGreenwood-westSection (ebd63d44-f2e9-4f0f-bd4c-3eaf5ecfe4ee, 297879ac-3833-4466-addf-8a9e0a08f190).svg b/public/images/maps/oldGreenwood-westSection.svg
similarity index 100%
rename from maps/oldGreenwood-westSection (ebd63d44-f2e9-4f0f-bd4c-3eaf5ecfe4ee, 297879ac-3833-4466-addf-8a9e0a08f190).svg
rename to public/images/maps/oldGreenwood-westSection.svg
diff --git a/maps/pineGrove-overview (cd4cefe3-bc61-4e00-a1ca-8e317e126ae3, 06899e91-7606-40c5-9877-68964c6e36b2).svg b/public/images/maps/pineGrove-overview.svg
similarity index 100%
rename from maps/pineGrove-overview (cd4cefe3-bc61-4e00-a1ca-8e317e126ae3, 06899e91-7606-40c5-9877-68964c6e36b2).svg
rename to public/images/maps/pineGrove-overview.svg
diff --git a/maps/westKorah-eastSection (4eb1d691-e170-44fe-9c16-d0b07bfc2cef, b2bbfb9e-020e-4c9d-b8a1-e9505432d225).svg b/public/images/maps/westKorah-eastSection (4eb1d691-e170-44fe-9c16-d0b07bfc2cef, b2bbfb9e-020e-4c9d-b8a1-e9505432d225).svg
similarity index 100%
rename from maps/westKorah-eastSection (4eb1d691-e170-44fe-9c16-d0b07bfc2cef, b2bbfb9e-020e-4c9d-b8a1-e9505432d225).svg
rename to public/images/maps/westKorah-eastSection (4eb1d691-e170-44fe-9c16-d0b07bfc2cef, b2bbfb9e-020e-4c9d-b8a1-e9505432d225).svg
diff --git a/maps/westKorah-northSection (eb81c28a-3683-467a-aed9-293b451b1dc1, c0135b86-8f79-48b4-9e1c-155a5bda24a0).svg b/public/images/maps/westKorah-northSection (eb81c28a-3683-467a-aed9-293b451b1dc1, c0135b86-8f79-48b4-9e1c-155a5bda24a0).svg
similarity index 100%
rename from maps/westKorah-northSection (eb81c28a-3683-467a-aed9-293b451b1dc1, c0135b86-8f79-48b4-9e1c-155a5bda24a0).svg
rename to public/images/maps/westKorah-northSection (eb81c28a-3683-467a-aed9-293b451b1dc1, c0135b86-8f79-48b4-9e1c-155a5bda24a0).svg
diff --git a/maps/westKorah-overview (af4837ba-e5a6-4573-aa78-3f770a19451e, dc1fbc3f-d188-4f28-b3d0-2bfc118bd8bc).svg b/public/images/maps/westKorah-overview.svg
similarity index 100%
rename from maps/westKorah-overview (af4837ba-e5a6-4573-aa78-3f770a19451e, dc1fbc3f-d188-4f28-b3d0-2bfc118bd8bc).svg
rename to public/images/maps/westKorah-overview.svg
diff --git a/maps/westKorah-westSection (53f302a5-e46c-4a1c-863c-dd40b8f18144, 2c5e13e5-4ec0-4b9a-b472-1237b5d9f4e9).svg b/public/images/maps/westKorah-westSection (53f302a5-e46c-4a1c-863c-dd40b8f18144, 2c5e13e5-4ec0-4b9a-b472-1237b5d9f4e9).svg
similarity index 100%
rename from maps/westKorah-westSection (53f302a5-e46c-4a1c-863c-dd40b8f18144, 2c5e13e5-4ec0-4b9a-b472-1237b5d9f4e9).svg
rename to public/images/maps/westKorah-westSection (53f302a5-e46c-4a1c-863c-dd40b8f18144, 2c5e13e5-4ec0-4b9a-b472-1237b5d9f4e9).svg
diff --git a/public/javascripts/licence-search.min.js b/public/javascripts/licence-search.min.js
deleted file mode 100644
index 14423fd7..00000000
--- a/public/javascripts/licence-search.min.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=document.querySelector("#form--filters"),n=document.querySelector("#filter--limit"),r=document.querySelector("#filter--offset"),s=document.querySelector("#container--searchResults"),a=()=>{const i=Number.parseInt(n.value,10),c=Number.parseInt(r.value,10);s.innerHTML='Loading licences...
',cityssm.postJSON(e+"/licences/doSearch",t,e=>{const t=e.licences;if(0===t.length)return void(s.innerHTML='Your search returned no results. Please try expanding your search criteria.
');s.innerHTML='';const n=s.querySelector("tbody");for(const e of t){const e=document.createElement("tr");e.innerHTML="",n.append(e)}if(s.insertAdjacentHTML("beforeend",'Displaying licences '+(c+1).toString()+" to "+Math.min(i+c,e.count).toString()+" of "+e.count.toString()+"
"),i0){const e=document.createElement("a");e.className="button",e.textContent="Previous",e.addEventListener("click",e=>{e.preventDefault(),r.value=Math.max(0,c-i).toString(),a()}),t.append(e)}if(i+cNext Licences ',e.addEventListener("click",e=>{e.preventDefault(),r.value=(c+i).toString(),a()}),t.append(e)}s.querySelector(".level").append(t)}})},i=()=>{r.value="0",a()};t.addEventListener("submit",e=>{e.preventDefault()});const c=t.querySelectorAll(".input, .select select");for(const e of c)e.addEventListener("change",i);i()})();
\ No newline at end of file
diff --git a/public/javascripts/mapSearch.min.js b/public/javascripts/mapSearch.min.js
new file mode 100644
index 00000000..f3b44881
--- /dev/null
+++ b/public/javascripts/mapSearch.min.js
@@ -0,0 +1 @@
+"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=exports.maps,s=document.querySelector("#searchFilter--map"),a=document.querySelector("#container--searchResults"),r=()=>{a.innerHTML=' Loading '+exports.aliases.maps+"...
";let r=0;const i=document.createElement("tbody"),o=s.value.trim().toLowerCase().split(" ");for(const s of t){const t=(s.mapName+" "+s.mapDescription+" "+s.mapAddress1+" "+s.mapAddress2).toLowerCase();let a=!0;for(const e of o)if(!t.includes(e)){a=!1;break}if(!a)continue;r+=1;const c=""===s.mapName?"(No Name)":s.mapName;i.insertAdjacentHTML("beforeend",''+cityssm.escapeHTML(c)+" "+cityssm.escapeHTML(s.mapAddress1)+''+(s.mapLatitude&&s.mapLongitude?' ':"")+' '+(s.mapSVG?' ':"")+' '+s.lotCount+" ")}if(a.innerHTML="",0===r)a.innerHTML='There are no '+exports.aliases.maps.toLowerCase()+" that meet the search criteria.
";else{const e=document.createElement("table");e.className="table is-fullwidth is-striped is-hoverable",e.innerHTML=""+exports.aliases.map+' Coordinates Image '+exports.aliases.lot+" Count ",e.append(i),a.append(e)}};s.addEventListener("keyup",r),document.querySelector("#form--searchFilters").addEventListener("submit",r),r()})();
\ No newline at end of file
diff --git a/public/javascripts/mapView.min.js b/public/javascripts/mapView.min.js
new file mode 100644
index 00000000..97f43ab7
--- /dev/null
+++ b/public/javascripts/mapView.min.js
@@ -0,0 +1 @@
+"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("#map--leaflet");if(e){const t=[Number.parseFloat(e.dataset.mapLatitude),Number.parseFloat(e.dataset.mapLongitude)],a=L.map(e);a.setView(t,15),L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{maxZoom:19,attribution:"© OpenStreetMap"}).addTo(a),L.marker(t).addTo(a)}})();
\ No newline at end of file
diff --git a/routes/maps.js b/routes/maps.js
index 67c5d9fc..568472d7 100644
--- a/routes/maps.js
+++ b/routes/maps.js
@@ -1,12 +1,10 @@
import { Router } from "express";
import * as permissionHandlers from "../handlers/permissions.js";
-import * as configFunctions from "../helpers/functions.config.js";
+import handler_search from "../handlers/maps-get/search.js";
+import handler_view from "../handlers/maps-get/view.js";
import handler_new from "../handlers/maps-get/new.js";
export const router = Router();
-router.get("/", (_request, response) => {
- response.render("map-search", {
- headTitle: configFunctions.getProperty("aliases.maps")
- });
-});
+router.get("/", handler_search);
router.get("/new", permissionHandlers.updateGetHandler, handler_new);
+router.get("/:mapId", handler_view);
export default router;
diff --git a/routes/maps.ts b/routes/maps.ts
index 6efda7db..91c61a16 100644
--- a/routes/maps.ts
+++ b/routes/maps.ts
@@ -1,26 +1,28 @@
import { Router } from "express";
import * as permissionHandlers from "../handlers/permissions.js";
-import * as configFunctions from "../helpers/functions.config.js";
+import handler_search from "../handlers/maps-get/search.js";
+
+import handler_view from "../handlers/maps-get/view.js";
import handler_new from "../handlers/maps-get/new.js";
export const router = Router();
-router.get("/", (_request, response) => {
+router.get("/",
+ handler_search);
- response.render("map-search", {
- headTitle: configFunctions.getProperty("aliases.maps")
- });
-
-});
router.get("/new",
permissionHandlers.updateGetHandler,
handler_new);
+router.get("/:mapId",
+ handler_view);
+
+
export default router;
\ No newline at end of file
diff --git a/temp/legacy.importFromCSV.d.ts b/temp/legacy.importFromCSV.d.ts
new file mode 100644
index 00000000..cb0ff5c3
--- /dev/null
+++ b/temp/legacy.importFromCSV.d.ts
@@ -0,0 +1 @@
+export {};
diff --git a/temp/legacy.importFromCSV.js b/temp/legacy.importFromCSV.js
new file mode 100644
index 00000000..d49e4fb5
--- /dev/null
+++ b/temp/legacy.importFromCSV.js
@@ -0,0 +1,99 @@
+import fs from "node:fs";
+import papa from "papaparse";
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../data/databasePaths.js";
+import { addMap } from "../helpers/lotOccupancyDB/addMap.js";
+import { getMap as getMapFromDatabase } from "../helpers/lotOccupancyDB/getMap.js";
+import { getLotTypes } from "../helpers/lotOccupancyDB/getLotTypes.js";
+import { addLot } from "../helpers/lotOccupancyDB/addLot.js";
+const user = {
+ user: {
+ userName: "import.unix",
+ userProperties: {
+ canUpdate: true,
+ isAdmin: false
+ }
+ }
+};
+const configTablesInString = "'Maps', 'LotTypes'";
+function purgeTables() {
+ const database = sqlite(databasePath);
+ database.prepare("delete from Lots").run();
+ database.prepare("delete from sqlite_sequence where name not in (" + configTablesInString + ")").run();
+ database.close();
+}
+function purgeConfigTables() {
+ const database = sqlite(databasePath);
+ database.prepare("delete from Maps").run();
+ database.prepare("delete from sqlite_sequence where name in ('Maps')").run();
+ database.close();
+}
+function getMapByMapDescription(mapDescription) {
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+ const map = database
+ .prepare("select * from Maps" +
+ " where mapDescription = ?")
+ .get(mapDescription);
+ database.close();
+ return map;
+}
+const mapCache = new Map();
+function getMap(masterRow) {
+ if (mapCache.has(masterRow.CM_CEMETERY)) {
+ return mapCache.get(masterRow.CM_CEMETERY);
+ }
+ let map = getMapByMapDescription(masterRow.CM_CEMETERY);
+ if (!map) {
+ console.log("Creating map: " + masterRow.CM_CEMETERY);
+ const mapId = addMap({
+ mapName: masterRow.CM_CEMETERY,
+ mapDescription: masterRow.CM_CEMETERY,
+ mapSVG: "",
+ mapLatitude: "",
+ mapLongitude: "",
+ mapAddress1: "",
+ mapAddress2: "",
+ mapCity: "Sault Ste. Marie",
+ mapProvince: "ON",
+ mapPostalCode: "",
+ mapPhoneNumber: ""
+ }, user);
+ map = getMapFromDatabase(mapId);
+ }
+ mapCache.set(masterRow.CM_CEMETERY, map);
+ return map;
+}
+function importFromCSV() {
+ const lotTypes = getLotTypes();
+ const rawData = fs.readFileSync("./temp/CMMASTER.csv").toString();
+ const cmmaster = papa.parse(rawData, {
+ delimiter: ",",
+ header: true,
+ skipEmptyLines: true
+ });
+ for (const parseError of cmmaster.errors) {
+ console.log(parseError);
+ }
+ for (const masterRow of cmmaster.data) {
+ const map = getMap(masterRow);
+ const lotName = masterRow.CM_CEMETERY + "-" +
+ (masterRow.CM_BLOCK === "" ? "" : masterRow.CM_BLOCK + "-") +
+ (masterRow.CM_RANGE2 === "" ? masterRow.CM_RANGE1.toString() : masterRow.CM_RANGE2) + "-" +
+ (masterRow.CM_LOT2 === "" ? masterRow.CM_LOT1.toString() : masterRow.CM_LOT2) + "-" +
+ (masterRow.CM_GRAVE2 === "" ? masterRow.CM_GRAVE1.toString() : masterRow.CM_GRAVE2) + "-" +
+ masterRow.CM_INTERMENT;
+ const lotId = addLot({
+ lotName: lotName,
+ lotTypeId: lotTypes[0].lotTypeId,
+ lotTypeStatusId: "",
+ mapId: map.mapId,
+ mapKey: lotName,
+ lotLatitude: "",
+ lotLongitude: ""
+ }, user);
+ }
+}
+purgeTables();
+importFromCSV();
diff --git a/temp/legacy.importFromCSV.ts b/temp/legacy.importFromCSV.ts
new file mode 100644
index 00000000..6e38d185
--- /dev/null
+++ b/temp/legacy.importFromCSV.ts
@@ -0,0 +1,192 @@
+/* eslint-disable node/no-extraneous-import, node/no-unpublished-import */
+
+import fs from "node:fs";
+import papa from "papaparse";
+
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../data/databasePaths.js";
+
+import { addMap } from "../helpers/lotOccupancyDB/addMap.js";
+import { getMap as getMapFromDatabase } from "../helpers/lotOccupancyDB/getMap.js";
+
+import { getLotTypes } from "../helpers/lotOccupancyDB/getLotTypes.js";
+import { addLot } from "../helpers/lotOccupancyDB/addLot.js";
+
+import type * as recordTypes from "../types/recordTypes";
+
+
+interface MasterRecord {
+ CM_SYSREC: string;
+ CM_CEMETERY: string;
+ CM_BLOCK: string;
+ CM_RANGE1: number;
+ CM_RANGE2: string;
+ CM_LOT1: number;
+ CM_LOT2: string;
+ CM_GRAVE1: number;
+ CM_GRAVE2: string;
+ CM_INTERMENT: number;
+ CM_PRENEED_OWNER: string;
+ CM_PRENEED_OWNER_SEQ: number;
+ CM_DECEASED_NAME: string;
+ CM_DECEASED_NAME_SEQ: number;
+ CM_ADDRESS: string;
+ CM_CITY: string;
+ CM_PROV: string;
+ CM_POST1: string;
+ CM_POST2: string;
+ CM_PRENEED_ORDER: string;
+ CM_PURCHASE_YR: number;
+ CM_PURCHASE_MON: number;
+ CM_PURCHASE_DAY: number;
+ CM_NO_GRAVES: number;
+ CM_DEATH_YR: number;
+ CM_DEATH_MON: number;
+ CM_DEATH_DAY: number;
+ CM_WORK_ORDER: string;
+ CM_INTERMENT_YR: number;
+ CM_INTERMENT_MON: number;
+ CM_INTERMENT_DAY: number;
+ CM_AGE: number;
+ CM_CONTAINER_TYPE: string;
+ CM_COMMITTAL_TYPE: string;
+ CM_CREMATION: string;
+ CM_FUNERAL_HOME: string;
+ CM_FUNERAL_YR: number;
+ CM_FUNERAL_MON: number;
+ CM_FUNERAL_DAY: number;
+ CM_RESIDENT_TYPE: string;
+ CM_REMARK1: string;
+ CM_REMARK2: string;
+ CM_STATUS: string;
+ CM_PERIOD: string;
+ CM_LAST_CHG_DATE: string;
+ CM_DEPTH: string;
+}
+
+
+const user: recordTypes.PartialSession = {
+ user: {
+ userName: "import.unix",
+ userProperties: {
+ canUpdate: true,
+ isAdmin: false
+ }
+ }
+};
+
+const configTablesInString = "'Maps', 'LotTypes'";
+
+
+function purgeTables () {
+ const database = sqlite(databasePath);
+ database.prepare("delete from Lots").run();
+ database.prepare("delete from sqlite_sequence where name not in (" + configTablesInString + ")").run();
+ database.close();
+}
+
+
+function purgeConfigTables () {
+ const database = sqlite(databasePath);
+ database.prepare("delete from Maps").run();
+ database.prepare("delete from sqlite_sequence where name in ('Maps')").run();
+ database.close();
+}
+
+
+function getMapByMapDescription (mapDescription: string) {
+
+ const database = sqlite(databasePath, {
+ readonly: true
+ });
+
+ const map: recordTypes.Map = database
+ .prepare("select * from Maps" +
+ " where mapDescription = ?")
+ .get(mapDescription);
+
+ database.close();
+
+ return map;
+}
+
+
+const mapCache: Map = new Map();
+
+
+function getMap(masterRow: MasterRecord): recordTypes.Map {
+
+ if (mapCache.has(masterRow.CM_CEMETERY)) {
+ return mapCache.get(masterRow.CM_CEMETERY);
+ }
+
+ let map = getMapByMapDescription(masterRow.CM_CEMETERY);
+
+ if (!map) {
+
+ console.log("Creating map: " + masterRow.CM_CEMETERY);
+
+ const mapId = addMap({
+ mapName: masterRow.CM_CEMETERY,
+ mapDescription: masterRow.CM_CEMETERY,
+ mapSVG: "",
+ mapLatitude: "",
+ mapLongitude: "",
+ mapAddress1: "",
+ mapAddress2: "",
+ mapCity: "Sault Ste. Marie",
+ mapProvince: "ON",
+ mapPostalCode: "",
+ mapPhoneNumber: ""
+ }, user);
+
+ map = getMapFromDatabase(mapId);
+ }
+
+ mapCache.set(masterRow.CM_CEMETERY, map);
+
+ return map;
+}
+
+
+function importFromCSV () {
+
+ const lotTypes = getLotTypes();
+
+ const rawData = fs.readFileSync("./temp/CMMASTER.csv").toString();
+
+ const cmmaster: papa.ParseResult = papa.parse(rawData, {
+ delimiter: ",",
+ header: true,
+ skipEmptyLines: true
+ });
+
+ for (const parseError of cmmaster.errors) {
+ console.log(parseError);
+ }
+
+ for (const masterRow of cmmaster.data) {
+ const map = getMap(masterRow);
+
+ const lotName = masterRow.CM_CEMETERY + "-" +
+ (masterRow.CM_BLOCK === "" ? "" : masterRow.CM_BLOCK + "-") +
+ (masterRow.CM_RANGE2 === "" ? masterRow.CM_RANGE1.toString() : masterRow.CM_RANGE2) + "-" +
+ (masterRow.CM_LOT2 === "" ? masterRow.CM_LOT1.toString() : masterRow.CM_LOT2) + "-" +
+ (masterRow.CM_GRAVE2 === "" ? masterRow.CM_GRAVE1.toString() : masterRow.CM_GRAVE2) + "-" +
+ masterRow.CM_INTERMENT;
+
+ const lotId = addLot({
+ lotName: lotName,
+ lotTypeId: lotTypes[0].lotTypeId,
+ lotTypeStatusId: "",
+ mapId: map.mapId,
+ mapKey: lotName,
+ lotLatitude: "",
+ lotLongitude: ""
+ }, user);
+ }
+}
+
+purgeTables();
+// purgeMaps();
+importFromCSV();
\ No newline at end of file
diff --git a/temp/so.exportMaps.d.ts b/temp/so.exportMaps.d.ts
new file mode 100644
index 00000000..cb0ff5c3
--- /dev/null
+++ b/temp/so.exportMaps.d.ts
@@ -0,0 +1 @@
+export {};
diff --git a/temp/so.exportMaps.js b/temp/so.exportMaps.js
new file mode 100644
index 00000000..6367a925
--- /dev/null
+++ b/temp/so.exportMaps.js
@@ -0,0 +1,32 @@
+import fs from "node:fs";
+import * as sql from "@cityssm/mssql-multi-pool";
+import { soMSSQL } from "./config.js";
+async function importMaps() {
+ let pool;
+ try {
+ pool = await sql.connect(soMSSQL);
+ const result = await pool.query("select m.ID as mapId, m.Name as mapName," +
+ " l.ID as layerId, l.Name as layerName, l.Image as layerImage" +
+ " from Legacy_Maps m" +
+ " left join Legacy_Layers l on m.ID = l.Map_ID");
+ for (const layer of result.recordset) {
+ const imageBuffer = layer.layerImage;
+ const fileName = layer.mapName + " - " + layer.layerName + " (" + layer.mapId + ", " + layer.layerId + ").wmf";
+ fs.writeFile("./temp/wmf/" + fileName, imageBuffer, (error) => {
+ if (error) {
+ console.log(error);
+ }
+ });
+ }
+ }
+ catch (_a) {
+ }
+ finally {
+ try {
+ pool.close();
+ }
+ catch (_b) {
+ }
+ }
+}
+await importMaps();
diff --git a/temp/so.exportMaps.ts b/temp/so.exportMaps.ts
new file mode 100644
index 00000000..140f4648
--- /dev/null
+++ b/temp/so.exportMaps.ts
@@ -0,0 +1,45 @@
+/* eslint-disable node/no-extraneous-import, node/no-unpublished-import */
+
+import fs from "node:fs";
+import * as sql from "@cityssm/mssql-multi-pool";
+import { soMSSQL } from "./config.js";
+import type * as sqlTypes from "mssql";
+
+async function importMaps() {
+
+ let pool: sqlTypes.ConnectionPool;
+
+ try {
+ pool = await sql.connect(soMSSQL);
+
+ const result = await pool.query("select m.ID as mapId, m.Name as mapName," +
+ " l.ID as layerId, l.Name as layerName, l.Image as layerImage" +
+ " from Legacy_Maps m" +
+ " left join Legacy_Layers l on m.ID = l.Map_ID");
+
+ for (const layer of result.recordset) {
+
+ const imageBuffer: Buffer = layer.layerImage;
+
+ const fileName = layer.mapName + " - " + layer.layerName + " (" + layer.mapId + ", " + layer.layerId + ").wmf";
+
+ fs.writeFile("./temp/wmf/" + fileName, imageBuffer, (error) => {
+ if (error) {
+ console.log(error);
+ }
+ });
+ }
+
+ } catch {
+ // ignore
+ } finally {
+ try {
+ pool.close();
+ } catch {
+ // ignore
+ }
+ }
+}
+
+
+await importMaps();
\ No newline at end of file
diff --git a/types/recordTypes.d.ts b/types/recordTypes.d.ts
index 8ce8c639..68e4cf3f 100644
--- a/types/recordTypes.d.ts
+++ b/types/recordTypes.d.ts
@@ -23,6 +23,55 @@ export interface Map extends Record {
mapProvince?: string;
mapPostalCode?: string;
mapPhoneNumber?: string;
+ lotCount?: number;
+}
+export interface LotType extends Record {
+ lotTypeId?: number;
+ lotType?: string;
+ orderNumber?: number;
+ lotTypeStatuses?: LotTypeStatus[];
+ lotTypeFields?: LotTypeField[];
+}
+export interface LotTypeField extends Record {
+ lotTypeFieldId?: number;
+ lotTypeField?: string;
+ lotTypeId?: number;
+ lotType: LotType;
+ lotTypeFieldValues?: string;
+ isRequired?: boolean;
+ pattern?: string;
+ minimumLength?: number;
+ maximumLength?: number;
+ orderNumber?: number;
+}
+export interface LotTypeStatus extends Record {
+ lotTypeStatusId?: number;
+ lotTypeId?: number;
+ lotTypeStatus?: string;
+ orderNumber?: number;
+}
+export interface Lot extends Record {
+ lotId?: number;
+ lotName?: string;
+ lotTypeId?: number;
+ lotType?: LotType;
+ mapId?: number;
+ map?: Map;
+ mapKey?: string;
+ lotLatitude?: number;
+ lotLongitude?: number;
+ lotTypeStatusId?: number;
+ lotTypeStatus?: LotTypeStatus;
+}
+export interface Occupant extends Record {
+ occupantId?: number;
+ occupantName?: string;
+ occupantAddress1?: string;
+ occupantAddress2?: string;
+ occupantCity?: string;
+ occupantProvince?: string;
+ occupantPostalCode?: string;
+ occupantPhoneNumber?: string;
}
export interface User {
userName: string;
@@ -37,3 +86,6 @@ declare module "express-session" {
user: User;
}
}
+export interface PartialSession {
+ user: User;
+}
diff --git a/types/recordTypes.ts b/types/recordTypes.ts
index 850dcea9..95edbc7a 100644
--- a/types/recordTypes.ts
+++ b/types/recordTypes.ts
@@ -1,8 +1,3 @@
-/*
- * LOT OCCUPANCY DB TYPES
- */
-
-
export interface Record {
recordCreate_userName?: string;
recordCreate_timeMillis?: number;
@@ -18,8 +13,13 @@ export interface Record {
recordDelete_dateString?: string;
}
-export interface Map extends Record {
+/*
+ * LOT OCCUPANCY DB TYPES
+ */
+
+
+export interface Map extends Record {
mapId?: number;
mapName?: string;
mapDescription?: string;
@@ -34,9 +34,81 @@ export interface Map extends Record {
mapProvince?: string;
mapPostalCode?: string;
mapPhoneNumber?: string;
+
+ lotCount?: number;
}
+export interface LotType extends Record {
+ lotTypeId?: number;
+ lotType?: string;
+ orderNumber?: number;
+ lotTypeStatuses?: LotTypeStatus[];
+ lotTypeFields?: LotTypeField[];
+}
+
+
+export interface LotTypeField extends Record {
+ lotTypeFieldId?: number;
+ lotTypeField?: string;
+
+ lotTypeId?: number;
+ lotType: LotType;
+
+ lotTypeFieldValues?: string;
+ isRequired?: boolean;
+ pattern?: string;
+ minimumLength?: number;
+ maximumLength?: number;
+
+ orderNumber?: number;
+}
+
+
+export interface LotTypeStatus extends Record {
+ lotTypeStatusId?: number;
+ lotTypeId?: number;
+ lotTypeStatus?: string;
+ orderNumber?: number;
+}
+
+
+export interface Lot extends Record {
+ lotId?: number;
+ lotName?: string;
+
+ lotTypeId?: number;
+ lotType?: LotType;
+
+ mapId?: number;
+ map?: Map;
+ mapKey?: string;
+
+ lotLatitude?: number;
+ lotLongitude?: number;
+
+ lotTypeStatusId?: number;
+ lotTypeStatus?: LotTypeStatus;
+}
+
+
+export interface Occupant extends Record {
+ occupantId?: number;
+ occupantName?: string;
+ occupantAddress1?: string;
+ occupantAddress2?: string;
+ occupantCity?: string;
+ occupantProvince?: string;
+ occupantPostalCode?: string;
+ occupantPhoneNumber?: string;
+}
+
+
+/*
+ * USER TYPES
+ */
+
+
export interface User {
userName: string;
userProperties?: UserProperties;
@@ -53,3 +125,7 @@ declare module "express-session" {
user: User;
}
}
+
+export interface PartialSession {
+ user: User;
+}
\ No newline at end of file
diff --git a/views/_footerA.ejs b/views/_footerA.ejs
index a39c36d6..492f0f66 100644
--- a/views/_footerA.ejs
+++ b/views/_footerA.ejs
@@ -13,9 +13,16 @@
+
+
<%- include('_footerB'); -%>
diff --git a/views/map-view.ejs b/views/map-view.ejs
index e69de29b..c58f97a4 100644
--- a/views/map-view.ejs
+++ b/views/map-view.ejs
@@ -0,0 +1,81 @@
+<%- include('_header'); -%>
+
+
+
+
+
+
+
+
+
+ <%= map.mapName %>
+
+
+ <% if (user.userProperties.canUpdate) { %>
+
+ <% } %>
+
+
+ <%= map.mapDescription %>
+
+
+
+
+
Geographic Location
+
+ <% if (map.mapLatitude && map.mapLongitude) { %>
+
+ <% } else { %>
+
+
There are no geographic coordinates associated with this <%= configFunctions.getProperty("aliases.map").toLowerCase() %>.
+
+ <% } %>
+
+
+
Image
+
+ <% if (map.mapSVG) { %>
+
+ <% const imageURL = urlPrefix + "/images/maps/" + map.mapSVG %>
+
+ Image" />
+
+
+ <% } else { %>
+
+
There are no image associated with this <%= configFunctions.getProperty("aliases.map").toLowerCase() %>.
+
+ <% } %>
+
+
+
+
+ <%= configFunctions.getProperty("aliases.lots") %>
+ <%= map.lotCount %>
+
+
+
+
+<%- include('_footerA'); -%>
+
+
+
+<%- include('_footerB'); -%>
\ No newline at end of file