Add tool for scanning items delivered (close #14)

master
Skylar Ittner 5 years ago
parent 70fa409015
commit d0c3988566

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
class="svg-inline--fa fa-history fa-w-16"
aria-hidden="true"
data-icon="history"
data-prefix="far"
focusable="false"
role="img"
version="1.1"
viewBox="0 0 512 512"
id="svg877"
sodipodi:docname="barcode-dashed.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata883">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs881" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1015"
id="namedview879"
showgrid="false"
inkscape:zoom="1.4980469"
inkscape:cx="256"
inkscape:cy="256"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg877" />
<path
id="path952"
d="M 25.36636,428.97523 V 83.02477 h 16.216428 v 345.95046 z m 24.195811,-0.24595 V 83.02477 h 8.237044 v 345.70451 z m 24.453472,0 V 83.02477 h 7.979383 v 345.70451 z m 40.412237,0 V 83.02477 h 7.97938 v 345.70451 z m 32.43286,0 V 83.02477 h 15.95876 v 345.70451 z m 40.41224,0 V 83.02477 h 7.97938 v 345.70451 z m 16.21642,0 V 83.02477 h 7.97939 v 345.70451 z m 16.21643,0 V 83.02477 h 7.97938 v 345.70451 z m 32.1761,0 V 83.02477 h 16.21642 v 345.70451 z m 40.41224,0 V 83.02477 h 16.21642 v 345.70451 z m 32.43195,0 V 83.02477 h 16.21733 v 345.70451 z m 32.43376,0 V 83.02477 h 16.21732 v 345.70451 z m 24.19581,0 V 83.02477 h 16.21642 v 345.70451 z m 40.6699,0 V 83.02477 h 24.19581 v 345.70451 z m 32.17519,0 V 83.02477 h 8.23705 v 345.70451 z m 16.21643,0.24595 V 83.02477 h 16.21643 v 345.95046 z"
inkscape:connector-curvature="0"
style="fill:#9e9e9e;fill-opacity:1;stroke:none;stroke-width:10.00063038;stroke-miterlimit:4;stroke-dasharray:5.00031521, 5.00031521;stroke-dashoffset:0;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,209 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
var scannerCodes = [];
function resetScanner() {
scannerCodes = [];
app.popup.close("#scanEventTypePopup");
app.popup.close("#scanEventPopup");
router.refreshPage();
}
function brokenScannerEsc() {
app.dialog.confirm(
"Clear list?",
"Confirm",
function () {
resetScanner();
},
function () {
// cancel
}
);
}
function brokenScannerScan() {
scanBarcode(function (code) {
playSound("scan");
if (code != "" && code.length > 5 && code.match(/^[0-9A-Z]+$/i)) {
addCodeToScannerList(code);
} else {
app.dialog.alert("That's not a valid tracking code.", "Error");
}
}, function (error) {
app.dialog.alert(error, "Error");
});
}
function brokenScannerAddTextEntry() {
var code = $("#brokenscannerinput").val();
if (code != "" && code.length > 5 && code.match(/^[0-9A-Z]+$/i)) {
addCodeToScannerList(code);
$("#brokenscannerinput").val("");
} else {
app.dialog.alert("That's not a valid tracking code.", "Error");
}
}
function addCodeToScannerList(code) {
code = code.toUpperCase();
var codeEntryTemplate = Template7.compile('<li class="codelist-entry" data-code="{{code}}">'
+ ' <div class="item-content">'
+ ' <div class="item-inner">'
+ ' <div class="item-title">{{code}}</div>'
+ ' </div>'
+ ' </div>'
+ '</li>');
$("#codelist").append(codeEntryTemplate({
code: code
}));
}
function chooseScanEvent() {
if ($("#codelist li.codelist-entry").length <= 0) {
app.dialog.alert("Nothing was entered!");
return;
}
$("#codelist li.codelist-entry").each(function () {
scannerCodes.push($(this).data("code"));
});
openEventPopup();
}
function openEventPopup() {
var eventItemTemplate = Template7.compile('<li data-button="{{button}}" data-title="{{title}}" class="eventbutton" onclick=\'openEventTypePopup("{{title}}");\'>'
+ ' <div class="item-link item-content">'
+ ' <div class="item-media">{{button}}</div>'
+ ' <div class="item-inner">'
+ ' <div class="item-title">{{title}}</div>'
+ ' </div>'
+ ' </div>'
+ '</li>');
$("#scanEventPopup ul.eventlist").html("");
for (i in SETTINGS.scannerevents) {
var event = SETTINGS.scannerevents[i];
$("#scanEventPopup ul.eventlist").append(eventItemTemplate({
button: event.button,
title: event.title
}));
}
app.popup.open("#scanEventPopup");
}
function openEventTypePopup(eventname) {
var eventItemTemplate = Template7.compile('<li data-button="{{button}}" data-title="{{title}}" data-parenttitle="{{parenttitle}}" data-form3849="{{form3849}}" class="eventbutton eventtypebutton">'
+ ' <div class="item-link item-content">'
+ ' <div class="item-media">{{button}}</div>'
+ ' <div class="item-inner">'
+ ' <div class="item-title">{{title}}</div>'
+ ' </div>'
+ ' </div>'
+ '</li>');
var eventafter = false;
for (i in SETTINGS.scannerevents) {
var event = SETTINGS.scannerevents[i];
if (event.title == eventname) {
eventafter = event.after;
break;
}
}
$("#scanEventTypePopup ul.eventlist").html("");
for (i in eventafter) {
var event = eventafter[i];
$("#scanEventTypePopup ul.eventlist").append(eventItemTemplate({
button: event.button,
title: event.title,
parenttitle: eventname,
form3849: event.after == "3849" ? "1" : "0"
}));
}
app.popup.open("#scanEventTypePopup");
}
function saveScanCode(code) {
if (localStorage.getItem("scanevents") == null) {
localStorage.setItem("scanevents", "[]");
}
var events = JSON.parse(localStorage.getItem("scanevents"));
events.push(code);
localStorage.setItem("scanevents", JSON.stringify(events));
}
$(".view-main").off("click", "#codelist li.codelist-entry");
$(".view-main").on("click", "#codelist li.codelist-entry", function () {
var entry = $(this);
var code = entry.data("code");
app.dialog.confirm(
"Remove " + code + " from list?",
"Confirm",
function () {
// delete
entry.remove();
},
function () {
// cancel
}
);
});
$("#app").off("click", "ul li.eventtypebutton");
$("#app").on("click", "ul li.eventtypebutton", function () {
var eventname = $(this).data("parenttitle");
var eventtypename = $(this).data("title");
var scanEvent = [];
scanEvent.push(eventname);
scanEvent.push(eventtypename);
if ($(this).data("form3849") == "1") {
// TODO: make this not a hack
app.dialog.prompt("Type in 3849 form", "3849 Form", function (formcode) {
for (i in scannerCodes) {
saveScanCode({
code: scannerCodes[i],
event: scanEvent,
form3849: formcode,
date: timestampToDateTimeString((new Date).getTime() / 1000)
});
}
app.toast.show({
text: 'Information recorded successfully!',
position: "bottom",
destroyOnClose: true,
closeTimeout: 1000 * 3
});
resetScanner();
}, function () {
}, "");
} else {
for (i in scannerCodes) {
saveScanCode({
code: scannerCodes[i],
event: scanEvent,
form3849: "",
date: timestampToDateTimeString((new Date).getTime() / 1000)
});
}
app.toast.show({
text: 'Information recorded successfully!',
position: "bottom",
destroyOnClose: true,
closeTimeout: 1000 * 3
});
resetScanner();
}
});

@ -0,0 +1,23 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function confirmDeleteScanEntries() {
app.dialog.confirm(
"Really delete all entries from scan list?",
"Clear Entries",
function () {
// clear
localStorage.setItem("scanevents", "[]");
router.navigate("/toolbox/scanner/entries", {
reloadCurrent: true
});
},
function () {
// cancel
}
);
}

@ -136,7 +136,7 @@ function scanTrackingBarcode() {
}
}, function (error) {
app.dialog.alert(error, "Error");
})
});
}
$("#trackbtn").click(function () {

@ -19,6 +19,14 @@
<div class="page-content">
<div class="list no-hairlines tablet-inset" style="margin-top: 0;">
<ul>
<li>
<a href="/toolbox/scanner" class="item-link item-content">
<div class="item-media"><i class="icon fas fa-barcode"></i></div>
<div class="item-inner">
<div class="item-title">Broken Scanner</div>
</div>
</a>
</li>
<li>
<a href="/toolbox/track" class="item-link item-content">
<div class="item-media"><i class="icon fas fa-search-location"></i></div>
@ -35,14 +43,6 @@
</div>
</a>
</li>
<!--<li>
<a href="/toolbox/scanner" class="item-link item-content">
<div class="item-media"><i class="icon fas fa-barcode"></i></div>
<div class="item-inner">
<div class="item-title">Scan for Delivery</div>
</div>
</a>
</li>-->
</ul>
</div>
</div>

@ -0,0 +1,50 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only back">
<i class="icon icon-back"></i>
</a>
</div>
<div class="title">Broken Scanner</div>
</div>
</div>
<div class="page-content">
<div class="list no-hairlines tablet-inset" style="margin-top: 0;">
<ul>
<li>
<a href="/toolbox/scanner/scanner" class="item-link item-content">
<div class="item-media">1</div>
<div class="item-inner">
<div class="item-title">Scan Barcode</div>
</div>
</a>
</li>
<li>
<a href="/toolbox/scanner/entries" class="item-link item-content">
<div class="item-media">2</div>
<div class="item-inner">
<div class="item-title">Review Entries</div>
</div>
</a>
</li>
</ul>
</div>
<div class="block text-align-center">
<i class="material-icons">info</i>
<br />
Scan barcodes while your postal scanner is crashed or restarting.
When the scanner is working again, you can scan all the saved
barcodes from your phone screen using the scanner's Manual Input or
Scan Barcode feature.
</div>
</div>
</div>

@ -0,0 +1,60 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="scanner">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only back">
<i class="icon icon-back"></i>
</a>
</div>
<div class="title">Review Entries</div>
<div class="right">
<a class="link text-color-red" onclick="confirmDeleteScanEntries()">
<i class="icon material-icons">delete</i>
</a>
</div>
</div>
</div>
<div class="page-content">
{{#if entries}}
<div class="list media-list">
<ul>
{{#each entries}}
<li style="padding-top: 2rem; padding-bottom: 2rem;">
<div class="item-content">
<div class="item-inner">
<div style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
<svg class="barcode_entry" id="barcode_{{code}}" data-barcode="{{code}}"></svg>
</div>
<div class="item-text text-align-center">{{event}}</div>
<div class="item-text text-align-center">{{date}}</div>
{{#if form3849}}
<h2 class="item-text text-align-center">Form 3849:</h2>
<div style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
<svg class="barcode_entry" id="barcode_{{form3849}}" data-barcode="{{form3849}}"></svg>
</div>
{{/if}}
</div>
</div>
</li>
{{/each}}
</ul>
</div>
{{else}}
<div class="block text-align-center">
<img style="width: 60%; max-width: 300px; max-height: 40vh;" src="assets/images/barcode-dashed.svg" class="margin-vertical" />
<h2 class="margin-top">
No scan entries.
</h2>
</div>
{{/if}}
</div>
<script src="assets/js/toolbox_scannerentries.js"></script>
</div>

@ -0,0 +1,94 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="scanner">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only back">
<i class="icon icon-back"></i>
</a>
</div>
<div class="title">Scan Barcode</div>
<div class="subnavbar" style="background-color: var(--f7-page-bg-color);">
<div class="subnavbar-inner">
<div class="searchbar">
<div class="searchbar-inner">
<div class="searchbar-input-wrap">
<input type="text" id="brokenscannerinput" placeholder="Enter Code" autocomplete="off" autocorrect="off" autocapitalize="off" style="padding-left: 1em; padding-right: 1em;" />
</div>
<a id="brokenscannercodeadd" onclick="brokenScannerAddTextEntry()" style="padding-right: 0.5em; padding-top: 0.3em;">
<i class="material-icons">keyboard_return</i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="fab fab-extended fab-left-bottom">
<a href="#" onclick="brokenScannerEsc()">
<div class="fab-text">ESC</div>
</a>
</div>
<div class="fab fab-extended fab-center-bottom">
<a href="#" onclick="brokenScannerScan()">
<div class="fab-text">Scan</div>
</a>
</div>
<div class="fab fab-extended fab-right-bottom">
<a href="#" onclick="chooseScanEvent()">
<div class="fab-text">Enter</div>
</a>
</div>
<div class="popup" id="scanEventPopup">
<div class="block">
<p>Select Event</p>
<div class="list tablet-inset">
<ul class="eventlist">
</ul>
</div>
</div>
<div class="fab fab-extended fab-left-bottom">
<a href="#" onclick="app.popup.close('#scanEventPopup');">
<div class="fab-text">ESC</div>
</a>
</div>
</div>
<div class="popup" id="scanEventTypePopup">
<div class="block">
<div class="list tablet-inset">
<ul class="eventlist">
</ul>
</div>
</div>
<div class="fab fab-extended fab-left-bottom">
<a href="#" onclick="app.popup.close('#scanEventTypePopup');">
<div class="fab-text">ESC</div>
</a>
</div>
</div>
<div class="page-content">
<div class="list no-hairlines tablet-inset">
<ul id="codelist">
</ul>
</div>
<div style="height: 3rem;"></div>
</div>
<script src="assets/js/toolbox_scanner.js"></script>
</div>

@ -52,9 +52,7 @@
</li>
<li>
<div class="item-content" style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
<svg class="barcode"
id="barcode">
</svg>
<svg class="barcode" id="trackingbarcode"></svg>
</div>
</li>
<li class="item-divider">History</li>
@ -81,7 +79,7 @@
</div>
<script>
JsBarcode(".barcode", "{{#if barcode}}{{barcode}}{{else}}{{code}}{{/if}}", {
JsBarcode("#trackingbarcode", "{{#if barcode}}{{escape barcode}}{{else}}{{escape code}}{{/if}}", {
format: "code128",
ean128: true,
width: 2,

@ -91,27 +91,78 @@ var routes = [
{
path: '/toolbox',
url: './pages/toolbox.html',
name: 'toolbox'
},
{
path: '/toolbox/track',
url: './pages/toolbox/track.html',
name: 'track'
},
{
path: '/toolbox/weather',
url: './pages/toolbox/weather.html',
name: 'weather',
on: {
pageAfterIn: function () {
loadWeather();
name: 'toolbox',
routes: [
{
path: '/scanner',
templateUrl: './pages/toolbox/scanner.html',
routes: [
{
path: '/scanner',
templateUrl: './pages/toolbox/scanner/scanner.html',
name: 'scanner'
},
{
path: '/entries',
name: 'entries',
async: function (routeTo, routeFrom, resolve, reject) {
if (localStorage.getItem("scanevents") != null && localStorage.getItem("scanevents") != "[]") {
var entries = JSON.parse(localStorage.getItem("scanevents"));
for (i in entries) {
entries[i].event = entries[i].event.join(' <i class="fas fa-chevron-right"></i> ');
}
} else {
var entries = false;
}
resolve({
templateUrl: './pages/toolbox/scanner/entries.html'
}, {
context: {
entries: entries
}
});
},
on: {
pageAfterIn: function () {
$(".barcode_entry").each(function () {
var code = $(this).data("barcode");
JsBarcode("#barcode_" + code, code, {
format: "code128",
ean128: true,
width: 2,
height: 40
});
});
}
}
}
]
},
{
path: '/track',
url: './pages/toolbox/track.html',
name: 'track',
routes: [
{
path: '/info',
templateUrl: './pages/toolbox/trackinginfo.html',
name: 'trackinginfo'
}
]
},
{
path: '/weather',
url: './pages/toolbox/weather.html',
name: 'weather',
on: {
pageAfterIn: function () {
loadWeather();
}
}
}
}
},
{
path: '/toolbox/track/info',
templateUrl: './pages/toolbox/trackinginfo.html',
name: 'trackinginfo'
]
},
{
path: '/credits',
@ -215,65 +266,67 @@ var routes = [
settings: settings
}
});
}
},
{
path: '/settings/alerts',
name: 'alertsettings',
async: function (routeTo, routeFrom, resolve, reject) {
var alertsounds = [];
for (var id in SETTINGS.alertsounds) {
if (SETTINGS.alertsounds.hasOwnProperty(id)) {
alertsounds.push({
value: id,
label: SETTINGS.alertsounds[id].name,
selected: localStorage.getItem("alertsound") == id
});
}
}
},
routes: [
{
path: '/alerts',
name: 'alertsettings',
async: function (routeTo, routeFrom, resolve, reject) {
var alertsounds = [];
for (var id in SETTINGS.alertsounds) {
if (SETTINGS.alertsounds.hasOwnProperty(id)) {
alertsounds.push({
value: id,
label: SETTINGS.alertsounds[id].name,
selected: localStorage.getItem("alertsound") == id
});
}
}
var settings = [{
setting: "alertsound",
title: "Alert sound",
text: "Select which sound to play when a package is nearby.",
select: true,
options: alertsounds
},
{
setting: "alertvolume",
title: "Alert volume",
min: 0,
max: 100,
step: 1,
value: localStorage.getItem("alertvolume"),
slider: true
},
{
setting: "alertradius",
title: "Alert radius (meters)",
min: 50,
max: 500,
step: 50,
value: localStorage.getItem("alertradius"),
slider: true
},
{
setting: "alertinterval",
title: "Alert interval (seconds)",
min: 15,
max: 120,
step: 15,
value: localStorage.getItem("alertinterval") == null ? 30 : localStorage.getItem("alertinterval"),
slider: true
}];
var settings = [{
setting: "alertsound",
title: "Alert sound",
text: "Select which sound to play when a package is nearby.",
select: true,
options: alertsounds
},
{
setting: "alertvolume",
title: "Alert volume",
min: 0,
max: 100,
step: 1,
value: localStorage.getItem("alertvolume"),
slider: true
},
{
setting: "alertradius",
title: "Alert radius (meters)",
min: 50,
max: 500,
step: 50,
value: localStorage.getItem("alertradius"),
slider: true
},
{
setting: "alertinterval",
title: "Alert interval (seconds)",
min: 15,
max: 120,
step: 15,
value: localStorage.getItem("alertinterval") == null ? 30 : localStorage.getItem("alertinterval"),
slider: true
}];
resolve({
templateUrl: './pages/alertsettings.html'
}, {
context: {
settings: settings
resolve({
templateUrl: './pages/alertsettings.html'
}, {
context: {
settings: settings
}
});
}
});
}
},
}
]
}
];

@ -94,6 +94,204 @@ var SETTINGS = {
"windy",
"none"
],
scannerevents: [
{
button: 1,
title: "Delivered",
type: "event",
after: [
{
button: 1,
title: "In/At Mailbox",
type: "type",
after: false
},
{
button: 2,
title: "Front Door/Porch",
type: "type",
after: false
},
{
button: 3,
title: "Left with Individual at Address",
type: "type",
after: false
},
{
button: 4,
title: "Front Desk/Reception/Mail Room",
type: "type",
after: false
},
{
button: 5,
title: "Parcel Locker",
type: "type",
after: false
},
{
button: 6,
title: "Garage or Other Location at Address",
type: "type",
after: false
},
{
button: 7,
title: "Left with Neighbor",
type: "type",
after: false
},
{
button: 'G',
title: "Authorized Agent",
type: "type",
after: false
},
{
button: 'U',
title: "Tendered to Authorized Agent",
type: "type",
after: false
}
]
},
{
button: 2,
title: "Attempted",
type: "event",
after: [
{
button: 2,
title: "No Secure Location Available",
type: "type",
after: "3849"
},
{
button: 3,
title: "No Access or Business Closed",
type: "type",
after: false
},
{
button: 4,
title: "Receptacle Full/Item Oversized",
type: "type",
after: "3849"
},
{
button: 5,
title: "Customer Hold",
type: "type",
after: false
},
{
button: 6,
title: "Animal Interference",
type: "type",
after: false
}
]
},
{
button: 3,
title: "Return to Sender or Forward",
type: "event",
after: [
{
button: 1,
title: "Forwarded",
type: "type",
after: false
},
{
button: 2,
title: "Insufficient Address",
type: "type",
after: false
},
{
button: 3,
title: "No Such Number",
type: "type",
after: false
},
{
button: 4,
title: "Addressee Unknown",
type: "type",
after: false
},
{
button: 5,
title: "Vacant",
type: "type",
after: false
},
{
button: 6,
title: "Unable to Forward / Forward Order Expired",
type: "type",
after: false
},
{
button: 7,
title: "Deceased",
type: "type",
after: false
},
{
button: 8,
title: "Refused",
type: "type",
after: false
},
{
button: 9,
title: "Returned for Other Reason",
type: "type",
after: false
}
]
},
{
button: 4,
title: "Other",
type: "event",
after: [
{
button: 'X',
title: "Dispatch to Military/Diplomatic PO",
type: "type",
after: false
},
{
button: 1,
title: "Return to Post Office Not Attempted / Delivery Delay",
type: "type",
after: false
},
{
button: 2,
title: "Local Weather Delay",
type: "type",
after: false
},
{
button: 3,
title: "Visible Damage",
type: "type",
after: false
},
{
button: 4,
title: "Out for Delivery",
type: "type",
after: false
}
]
}
],
geocodeapi: "https://apis.netsyms.net/packagehelper/geocode.php",
trackingapi: "https://apis.netsyms.net/packagehelper/track.php",
weatherapi: "https://apis.netsyms.net/packagehelper/weather.php",

Loading…
Cancel
Save