Compare commits
2 Commits
59d94a0281
...
fa3267b30c
Author | SHA1 | Date | |
---|---|---|---|
|
fa3267b30c | ||
|
90f6ae7695
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -2,4 +2,8 @@ package-lock.json
|
|||||||
yarn-error.log
|
yarn-error.log
|
||||||
node_modules/
|
node_modules/
|
||||||
auth/
|
auth/
|
||||||
db/
|
db/
|
||||||
|
.yarn/
|
||||||
|
public/*.js
|
||||||
|
public/*.map
|
||||||
|
.yarnrc.yml
|
||||||
|
56
package.json
56
package.json
@@ -1,28 +1,32 @@
|
|||||||
{
|
{
|
||||||
"name": "volp",
|
"name": "volp",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Open Travel Mapper",
|
"description": "Open Travel Mapper",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"start": "node server.js",
|
"build": "esbuild src/app.ts --bundle --outfile=public/main.js --bundle --minify --sourcemap --tsconfig=tsconfig.json",
|
||||||
"demon": "nodemon server.js"
|
"start": "node server.js",
|
||||||
},
|
"demon": "nodemon -e ts,pug --watch src --exec \"yarn build && yarn start\""
|
||||||
"repository": {
|
},
|
||||||
"type": "git",
|
"repository": {
|
||||||
"url": "git@git.helcel.net:sora/otm.git"
|
"type": "git",
|
||||||
},
|
"url": "git@git.helcel.net:sora/otm.git"
|
||||||
"author": "",
|
},
|
||||||
"license": "ISC",
|
"author": "",
|
||||||
"dependencies": {
|
"license": "ISC",
|
||||||
"@fastify/leveldb": "^6.0.0",
|
"dependencies": {
|
||||||
"@fastify/static": "^8.0.0",
|
"@fastify/leveldb": "^6.0.0",
|
||||||
"@fastify/view": "^10.0.0",
|
"@fastify/static": "^8.0.0",
|
||||||
"@prettier/plugin-pug": "^3.0.0",
|
"@fastify/view": "^10.0.0",
|
||||||
"axios": "^1.4.0",
|
"@prettier/plugin-pug": "^3.0.0",
|
||||||
"fastify": "^5.0.0",
|
"@types/node": "^22.13.5",
|
||||||
"nodemon": "^3.0.1",
|
"axios": "^1.7.9",
|
||||||
"prettier": "^3.0.0",
|
"esbuild": "^0.25.0",
|
||||||
"pug": "^3.0.2"
|
"fastify": "^5.0.0",
|
||||||
}
|
"nodemon": "^3.0.1",
|
||||||
|
"pretier": "^0.0.1",
|
||||||
|
"prettier": "^3.5.2",
|
||||||
|
"pug": "^3.0.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
BIN
public/js/.DS_Store
vendored
BIN
public/js/.DS_Store
vendored
Binary file not shown.
122
src/api.ts
Normal file
122
src/api.ts
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export const load = (id: string) =>
|
||||||
|
axios.get("/api/" + id).then((response) => {
|
||||||
|
if (response.data == "") throw "Invalid Journey Data Received";
|
||||||
|
let res = response.data;
|
||||||
|
|
||||||
|
for (let e of res.main) {
|
||||||
|
if (e.dateRange) {
|
||||||
|
e.dateRange[0] = new Date(e.dateRange[0]);
|
||||||
|
e.dateRange[1] = new Date(e.dateRange[1]);
|
||||||
|
}
|
||||||
|
e.step_title = e.step_title || [];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
|
||||||
|
export const save = (id: string, v: string) =>
|
||||||
|
axios
|
||||||
|
.post("/api/" + id, v)
|
||||||
|
.then((response) => {
|
||||||
|
console.log("Saved...");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn("Error! Could not reach the API.");
|
||||||
|
});
|
||||||
|
|
||||||
|
export const query_nominatim = (
|
||||||
|
q: string,
|
||||||
|
f: (v: string) => Boolean = () => true,
|
||||||
|
) =>
|
||||||
|
axios
|
||||||
|
.get("/api/place/" + q)
|
||||||
|
.then((res) => res.data)
|
||||||
|
.then((res) => res.filter(f));
|
||||||
|
|
||||||
|
export const query_flight = (q: string) =>
|
||||||
|
axios.get("/api/flight/" + q).then((res) => res.data);
|
||||||
|
|
||||||
|
type NominatimResult = {
|
||||||
|
type: string;
|
||||||
|
category: string;
|
||||||
|
display_name: string; // DEBUG ONLY
|
||||||
|
};
|
||||||
|
|
||||||
|
export const is_restauration_type = (e: NominatimResult) =>
|
||||||
|
["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"].indexOf(
|
||||||
|
e.type,
|
||||||
|
) != -1;
|
||||||
|
|
||||||
|
export const is_attraction_type = (e: NominatimResult): boolean =>
|
||||||
|
[
|
||||||
|
"tourism",
|
||||||
|
"leisure",
|
||||||
|
"place",
|
||||||
|
"amenity",
|
||||||
|
"highway",
|
||||||
|
"historic",
|
||||||
|
"natural",
|
||||||
|
"waterway",
|
||||||
|
].indexOf(e.category) != -1 ||
|
||||||
|
[
|
||||||
|
"place_of_worship",
|
||||||
|
"national_park",
|
||||||
|
"nature_reserve",
|
||||||
|
"protected_area",
|
||||||
|
].indexOf(e.type) != -1;
|
||||||
|
|
||||||
|
export const icon_type = (item: NominatimResult): string => {
|
||||||
|
let t = item.type;
|
||||||
|
let c = item.category;
|
||||||
|
const arr = ["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"];
|
||||||
|
if (arr.indexOf(t) != -1) {
|
||||||
|
return "utensils";
|
||||||
|
} else if (t == "hotel" || t == "hostel" || t == "guest_house") {
|
||||||
|
return "bed";
|
||||||
|
} else if (t == "museum" || c == "historic" || t == "place_of_worship") {
|
||||||
|
return "landmark";
|
||||||
|
} else if (t == "peak" || t == "viewpoint") {
|
||||||
|
return "mountain";
|
||||||
|
} else if (t == "parking") {
|
||||||
|
return "parking";
|
||||||
|
} else if (
|
||||||
|
t == "water" ||
|
||||||
|
t == "river" ||
|
||||||
|
t == "lake" ||
|
||||||
|
t == "torrent" ||
|
||||||
|
t == "aquarium"
|
||||||
|
) {
|
||||||
|
return "water";
|
||||||
|
} else if (t == "community_centre" || t == "locality") {
|
||||||
|
return "building";
|
||||||
|
} else if (t == "attraction") {
|
||||||
|
return "landmark";
|
||||||
|
} else if (t == "information" || t == "university") {
|
||||||
|
return "landmark";
|
||||||
|
} else if (t == "bridge") {
|
||||||
|
return "archway";
|
||||||
|
} else if (
|
||||||
|
t == "woodland" ||
|
||||||
|
t == "shieling" ||
|
||||||
|
t == "national_park" ||
|
||||||
|
t == "zoo" ||
|
||||||
|
t == "park" ||
|
||||||
|
t == "garden" ||
|
||||||
|
0
|
||||||
|
) {
|
||||||
|
return "tree";
|
||||||
|
} else if (t == "water_park" || t == "theme_park") {
|
||||||
|
return "dice-five";
|
||||||
|
} else if (
|
||||||
|
t == "?" ||
|
||||||
|
t == "neighbourhood" ||
|
||||||
|
t == "quarter" ||
|
||||||
|
c == "highway"
|
||||||
|
) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
console.log(item.display_name, item.category, item.type);
|
||||||
|
return "question";
|
||||||
|
}
|
||||||
|
};
|
13
src/app.ts
Normal file
13
src/app.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import "./types/ext";
|
||||||
|
import "./api";
|
||||||
|
import "./old.js";
|
||||||
|
|
||||||
|
console.log("TEST");
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
console.log("B");
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
console.log("CC");
|
||||||
|
}
|
@@ -1,142 +1,4 @@
|
|||||||
const gen_id = (length) => {
|
import * as api from "./api";
|
||||||
var result = "";
|
|
||||||
const characters =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
const len = characters.length;
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
result += characters.charAt(Math.floor(Math.random() * len));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.toJSONLocal = (function () {
|
|
||||||
function addZ(n) {
|
|
||||||
return (n < 10 ? "0" : "") + n;
|
|
||||||
}
|
|
||||||
return function () {
|
|
||||||
return (
|
|
||||||
this.getFullYear() +
|
|
||||||
"-" +
|
|
||||||
addZ(this.getMonth() + 1) +
|
|
||||||
"-" +
|
|
||||||
addZ(this.getDate())
|
|
||||||
);
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
function toEncoded(string) {
|
|
||||||
const codeUnits = Uint16Array.from(
|
|
||||||
{ length: string.length },
|
|
||||||
(element, index) => string.charCodeAt(index),
|
|
||||||
);
|
|
||||||
const charCodes = new Uint8Array(codeUnits.buffer);
|
|
||||||
|
|
||||||
let result = "";
|
|
||||||
charCodes.forEach((char) => {
|
|
||||||
result += String.fromCharCode(char);
|
|
||||||
});
|
|
||||||
return window.btoa(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toDecoded(string) {
|
|
||||||
let binary = window.atob(string);
|
|
||||||
const bytes = Uint8Array.from({ length: binary.length }, (element, index) =>
|
|
||||||
binary.charCodeAt(index),
|
|
||||||
);
|
|
||||||
const charCodes = new Uint16Array(bytes.buffer);
|
|
||||||
|
|
||||||
let result = "";
|
|
||||||
charCodes.forEach((char) => {
|
|
||||||
result += String.fromCharCode(char);
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const query_nominatim = (q, f) =>
|
|
||||||
axios
|
|
||||||
.get("/api/place/" + q)
|
|
||||||
.then((res) => res.data)
|
|
||||||
.then((res) => res.filter(f));
|
|
||||||
const query_flight = (q) =>
|
|
||||||
axios.get("/api/flight/" + q).then((res) => res.data);
|
|
||||||
|
|
||||||
const is_restauration_type = (e) =>
|
|
||||||
["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"].indexOf(
|
|
||||||
e.type,
|
|
||||||
) != -1;
|
|
||||||
|
|
||||||
const is_attraction_type = (e) =>
|
|
||||||
[
|
|
||||||
"tourism",
|
|
||||||
"leisure",
|
|
||||||
"place",
|
|
||||||
"amenity",
|
|
||||||
"highway",
|
|
||||||
"historic",
|
|
||||||
"natural",
|
|
||||||
"waterway",
|
|
||||||
].indexOf(e.category) != -1 ||
|
|
||||||
[
|
|
||||||
"place_of_worship",
|
|
||||||
"national_park",
|
|
||||||
"nature_reserve",
|
|
||||||
"protected_area",
|
|
||||||
].indexOf(e.type != -1);
|
|
||||||
|
|
||||||
const icon_type = (item) => {
|
|
||||||
let t = item.type;
|
|
||||||
let c = item.category;
|
|
||||||
const arr = ["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"];
|
|
||||||
if (arr.indexOf(t) != -1) {
|
|
||||||
return "utensils";
|
|
||||||
} else if (t == "hotel" || t == "hostel" || t == "guest_house") {
|
|
||||||
return "bed";
|
|
||||||
} else if (t == "museum" || c == "historic" || t == "place_of_worship") {
|
|
||||||
return "landmark";
|
|
||||||
} else if (t == "peak" || t == "viewpoint") {
|
|
||||||
return "mountain";
|
|
||||||
} else if (t == "parking") {
|
|
||||||
return "parking";
|
|
||||||
} else if (
|
|
||||||
t == "water" ||
|
|
||||||
t == "river" ||
|
|
||||||
t == "lake" ||
|
|
||||||
t == "torrent" ||
|
|
||||||
t == "aquarium"
|
|
||||||
) {
|
|
||||||
return "water";
|
|
||||||
} else if (t == "community_centre" || t == "locality") {
|
|
||||||
return "building";
|
|
||||||
} else if (t == "attraction") {
|
|
||||||
return "landmark";
|
|
||||||
} else if (t == "information" || t == "university") {
|
|
||||||
return "landmark";
|
|
||||||
} else if (t == "bridge") {
|
|
||||||
return "archway";
|
|
||||||
} else if (
|
|
||||||
t == "woodland" ||
|
|
||||||
t == "shieling" ||
|
|
||||||
t == "national_park" ||
|
|
||||||
t == "zoo" ||
|
|
||||||
t == "park" ||
|
|
||||||
t == "garden" ||
|
|
||||||
0
|
|
||||||
) {
|
|
||||||
return "tree";
|
|
||||||
} else if ((t == "water_park", t == "theme_park")) {
|
|
||||||
return "dice-five";
|
|
||||||
} else if (
|
|
||||||
t == "?" ||
|
|
||||||
t == "neighbourhood" ||
|
|
||||||
t == "quarter" ||
|
|
||||||
c == "highway"
|
|
||||||
) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
console.log(item.display_name, item.category, item.type);
|
|
||||||
return "question";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Vue.component("l-map", window.Vue2Leaflet.LMap);
|
Vue.component("l-map", window.Vue2Leaflet.LMap);
|
||||||
Vue.component("l-tile-layer", window.Vue2Leaflet.LTileLayer);
|
Vue.component("l-tile-layer", window.Vue2Leaflet.LTileLayer);
|
||||||
@@ -153,7 +15,7 @@ const app = new Vue({
|
|||||||
data: {
|
data: {
|
||||||
journey_edit:
|
journey_edit:
|
||||||
["view", "short"].indexOf(window.location.pathname.split("/")[1]) == -1,
|
["view", "short"].indexOf(window.location.pathname.split("/")[1]) == -1,
|
||||||
journey_id: window.location.pathname.split("/").pop() || gen_id(16),
|
journey_id: window.location.pathname.split("/").pop() || String.gen_id(16),
|
||||||
|
|
||||||
journey_step_data: { day: 1, section: 0 },
|
journey_step_data: { day: 1, section: 0 },
|
||||||
journey_data: {
|
journey_data: {
|
||||||
@@ -374,25 +236,21 @@ const app = new Vue({
|
|||||||
},
|
},
|
||||||
generate_icon: function (item, fcolor) {
|
generate_icon: function (item, fcolor) {
|
||||||
return L.AwesomeMarkers.icon({
|
return L.AwesomeMarkers.icon({
|
||||||
icon: icon_type(item) || "star",
|
icon: api.icon_type(item) || "star",
|
||||||
prefix: "fa",
|
prefix: "fa",
|
||||||
markerColor: fcolor || item.color || "blue",
|
markerColor: fcolor || item.color || "blue",
|
||||||
}).createIcon().outerHTML;
|
}).createIcon().outerHTML;
|
||||||
},
|
},
|
||||||
|
|
||||||
save_data: function () {
|
save_data: function () {
|
||||||
this.impexp = toEncoded(JSON.stringify(this.journey_data));
|
this.impexp = JSON.stringify(this.journey_data).toEncoded();
|
||||||
axios
|
api.save(this.journey_id, this.journey_data);
|
||||||
.post("/api/" + this.journey_id, this.journey_data)
|
|
||||||
.then((response) => {
|
|
||||||
console.log("Saved...");
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.warn("Error! Could not reach the API.");
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
import_data: function () {
|
import_data: function () {
|
||||||
this.journey_data = Object.assign({}, JSON.parse(toDecoded(this.impexp)));
|
this.journey_data = Object.assign(
|
||||||
|
{},
|
||||||
|
JSON.parse(this.impexp.toDecoded()),
|
||||||
|
);
|
||||||
this.journey_data.main.forEach((e) => {
|
this.journey_data.main.forEach((e) => {
|
||||||
if (e.dateRange) {
|
if (e.dateRange) {
|
||||||
e.dateRange[0] = new Date(e.dateRange[0]);
|
e.dateRange[0] = new Date(e.dateRange[0]);
|
||||||
@@ -401,7 +259,7 @@ const app = new Vue({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
export_data: function () {
|
export_data: function () {
|
||||||
this.impexp = toEncoded(JSON.stringify(this.journey_data));
|
this.impexp = JSON.stringify(this.journey_data).toEncoded();
|
||||||
},
|
},
|
||||||
filter_selected: function (list, step) {
|
filter_selected: function (list, step) {
|
||||||
return list.filter((e) =>
|
return list.filter((e) =>
|
||||||
@@ -438,18 +296,7 @@ const app = new Vue({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
axios.get("/api/" + this.journey_id).then((response) => {
|
api.load(this.journey_id).then((r) => (app.journey_data = r));
|
||||||
if (response.data == "") throw "Invalid Journey Data Received";
|
|
||||||
app.journey_data = response.data;
|
|
||||||
|
|
||||||
for (let e of app.journey_data.main) {
|
|
||||||
if (e.dateRange) {
|
|
||||||
e.dateRange[0] = new Date(e.dateRange[0]);
|
|
||||||
e.dateRange[1] = new Date(e.dateRange[1]);
|
|
||||||
}
|
|
||||||
e.step_title = e.step_title || [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.debounceSave = _.debounce(this.save_data, 500);
|
this.debounceSave = _.debounce(this.save_data, 500);
|
||||||
this.debounceSearch = {
|
this.debounceSearch = {
|
||||||
@@ -465,13 +312,15 @@ const app = new Vue({
|
|||||||
}, 500),
|
}, 500),
|
||||||
restaurants: _.debounce((q) => {
|
restaurants: _.debounce((q) => {
|
||||||
this.querying.food = true;
|
this.querying.food = true;
|
||||||
this.search_nominatim(q, (r) => is_restauration_type(r)).then((r) => {
|
this.search_nominatim(q, (r) => api.is_restauration_type(r)).then(
|
||||||
this.querying.food = false;
|
(r) => {
|
||||||
});
|
this.querying.food = false;
|
||||||
|
},
|
||||||
|
);
|
||||||
}, 500),
|
}, 500),
|
||||||
places: _.debounce((q) => {
|
places: _.debounce((q) => {
|
||||||
this.querying.place = true;
|
this.querying.place = true;
|
||||||
this.search_nominatim(q, (r) => is_attraction_type(r)).then((r) => {
|
this.search_nominatim(q, (r) => api.is_attraction_type(r)).then((r) => {
|
||||||
this.querying.place = false;
|
this.querying.place = false;
|
||||||
});
|
});
|
||||||
}, 500),
|
}, 500),
|
79
src/types/ext.ts
Normal file
79
src/types/ext.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// DATE EXTENTION
|
||||||
|
declare global {
|
||||||
|
interface Date {
|
||||||
|
toJSONLocal: () => string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Date.prototype.toJSONLocal = function () {
|
||||||
|
function addZ(n: number): string {
|
||||||
|
return n <= 9 ? `0${n}` : `${n}`;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
this.getFullYear(),
|
||||||
|
addZ(this.getMonth() + 1),
|
||||||
|
addZ(this.getDate()),
|
||||||
|
].join("-");
|
||||||
|
};
|
||||||
|
|
||||||
|
// ARRAY EXTENTION
|
||||||
|
declare global {
|
||||||
|
interface Array<T> {
|
||||||
|
foldl<B>(f: (x: T, acc: B) => B, acc: B): B;
|
||||||
|
foldr<B>(f: (x: T, acc: B) => B, acc: B): B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Array.prototype.foldr = function <T, B>(f: (x: T, acc: B) => B, acc: B): B {
|
||||||
|
return this.reverse().foldl(f, acc);
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.foldl = function <T, B>(f: (x: T, acc: B) => B, acc: B): B {
|
||||||
|
for (let i = 0; i < this.length; i++) acc = f(this[i], acc);
|
||||||
|
return acc;
|
||||||
|
};
|
||||||
|
|
||||||
|
// STRING EXTENTION
|
||||||
|
declare global {
|
||||||
|
interface String {
|
||||||
|
btoa: () => String;
|
||||||
|
toEncoded: () => String;
|
||||||
|
toDecoded: () => String;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.btoa = function () {
|
||||||
|
return window.btoa(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.toEncoded = function () {
|
||||||
|
return window.btoa(
|
||||||
|
Array.from(this as string, (c) => c.charCodeAt(0)).foldl(
|
||||||
|
(e, v) => v + String.fromCharCode(e),
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.toDecoded = function () {
|
||||||
|
return Array.from(window.atob(this), (c) => c.charCodeAt(0)).foldl(
|
||||||
|
(e, v) => v + String.fromCharCode(e),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface StringConstructor {
|
||||||
|
gen_id: (l: Number) => String;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String.gen_id = function (length) {
|
||||||
|
const characters =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
return Array.from(Array(length))
|
||||||
|
.map((_v) =>
|
||||||
|
characters.charAt(Math.floor(Math.random() * characters.length)),
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
|
};
|
||||||
|
|
||||||
|
export {};
|
@@ -1,16 +1,16 @@
|
|||||||
|
script(src="https://unpkg.com/leaflet")
|
||||||
|
script(src="https://unpkg.com/leaflet.awesome-markers")
|
||||||
|
//- script(src="https://unpkg.com/axios")
|
||||||
|
script(src="https://unpkg.com/lodash")
|
||||||
|
script(src="https://unpkg.com/sortablejs")
|
||||||
|
|
||||||
script(src="https://unpkg.com/vue@2")
|
script(src="https://unpkg.com/vue@2")
|
||||||
script(src="https://unpkg.com/vue2-datepicker")
|
script(src="https://unpkg.com/vue2-datepicker")
|
||||||
script(src="https://unpkg.com/leaflet")
|
|
||||||
script(src="https://unpkg.com/vue2-leaflet")
|
|
||||||
script(src="https://unpkg.com/leaflet.awesome-markers")
|
|
||||||
script(src="https://unpkg.com/axios")
|
|
||||||
script(src="https://unpkg.com/lodash")
|
|
||||||
script(src="https://unpkg.com/vue-multiselect@2")
|
|
||||||
script(src="https://unpkg.com/vue-textarea-autosize")
|
script(src="https://unpkg.com/vue-textarea-autosize")
|
||||||
script(src="https://unpkg.com/sortablejs")
|
script(src="https://unpkg.com/vue-multiselect@2")
|
||||||
|
script(src="https://unpkg.com/vue2-leaflet")
|
||||||
script(src="https://unpkg.com/vuedraggable")
|
script(src="https://unpkg.com/vuedraggable")
|
||||||
|
script(src="/public/main.js", type="text/javascript", charset="utf-8")
|
||||||
script(src="/public/js/main.js", type="text/javascript", charset="utf-8")
|
|
||||||
footer.bg-dark
|
footer.bg-dark
|
||||||
.container
|
.container
|
||||||
.section.text-center.text-small
|
.section.text-center.text-small
|
||||||
|
12
tsconfig.json
Normal file
12
tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"typeRoots": ["./node_modules/@types", "./types/ext"],
|
||||||
|
"lib": ["esnext", "DOM"],
|
||||||
|
"noEmit": true, // Disable emitting output (use esbuild to handle this)
|
||||||
|
"skipLibCheck": true, // Skip type checking of all declaration files (*.d.ts)
|
||||||
|
"strict": false, // Disable strict type checks if needed
|
||||||
|
"moduleResolution": "node",
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user