diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 66d89ca4..96a565c6 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -17,7 +17,8 @@
"qrious": "^4.0.2",
"qs": "^6.13.1",
"vue": "^3.5.13",
- "vue-i18n": "^11.1.4"
+ "vue-i18n": "^11.1.4",
+ "vue3-persian-datetime-picker": "^1.2.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.6",
@@ -961,8 +962,7 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/boolbase": {
"version": "1.0.0",
@@ -974,7 +974,6 @@
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
"integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -1069,8 +1068,7 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/core-js": {
"version": "3.49.0",
@@ -1549,6 +1547,11 @@
"node": ">= 6"
}
},
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -1606,6 +1609,26 @@
"node": ">= 0.4"
}
},
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -1720,6 +1743,21 @@
"node": ">=0.8.19"
}
},
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -1755,6 +1793,11 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
+ "node_modules/jalaali-js": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.8.tgz",
+ "integrity": "sha512-Jl/EwY84JwjW2wsWqeU4pNd22VNQ7EkjI36bDuLw31wH98WQW4fPjD0+mG7cdCK+Y8D6s9R3zLiQ3LaKu6bD8A=="
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2142,7 +2185,6 @@
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -2158,6 +2200,28 @@
"node": "*"
}
},
+ "node_modules/moment-jalaali": {
+ "version": "0.9.6",
+ "resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.9.6.tgz",
+ "integrity": "sha512-v8wXjQplvk5ez+sUqgsWIrafwIf1BEXXvzTYwsg1wHcqh27nSgKPCJ6FnZRrCz03MoNyB9N31L0oms+vE8Rq7g==",
+ "dependencies": {
+ "jalaali-js": "^1.1.0",
+ "moment": "^2.22.2",
+ "moment-timezone": "^0.5.21",
+ "rimraf": "^3.0.2"
+ }
+ },
+ "node_modules/moment-timezone": {
+ "version": "0.5.48",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz",
+ "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
+ "dependencies": {
+ "moment": "^2.29.4"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -2215,6 +2279,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -2294,6 +2366,14 @@
"node": ">=8"
}
},
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -2419,6 +2499,21 @@
"node": ">=4"
}
},
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/rolldown": {
"version": "1.0.0-rc.18",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.18.tgz",
@@ -2879,6 +2974,14 @@
"vue": "^3.0.0"
}
},
+ "node_modules/vue3-persian-datetime-picker": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/vue3-persian-datetime-picker/-/vue3-persian-datetime-picker-1.2.2.tgz",
+ "integrity": "sha512-d7nkj5vgtUvEXZboSdRmP1uwBfXvXgXqdvsOOMQb34jiMZU/aBDrTYWTEe1N+XKF9pvTTJn8Rws9ttJmyhK/hw==",
+ "dependencies": {
+ "moment-jalaali": "^0.9.4"
+ }
+ },
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
@@ -2911,6 +3014,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
"node_modules/xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index c59727f5..a835827a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -20,7 +20,8 @@
"qrious": "^4.0.2",
"qs": "^6.13.1",
"vue": "^3.5.13",
- "vue-i18n": "^11.1.4"
+ "vue-i18n": "^11.1.4",
+ "vue3-persian-datetime-picker": "^1.2.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.6",
diff --git a/frontend/src/components/DateTimePicker.vue b/frontend/src/components/DateTimePicker.vue
new file mode 100644
index 00000000..c17bb457
--- /dev/null
+++ b/frontend/src/components/DateTimePicker.vue
@@ -0,0 +1,383 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/composables/useDatepicker.js b/frontend/src/composables/useDatepicker.js
new file mode 100644
index 00000000..03eba91c
--- /dev/null
+++ b/frontend/src/composables/useDatepicker.js
@@ -0,0 +1,45 @@
+// Module-scoped reactive ref for the panel's "Calendar Type" setting.
+// Loaded from /panel/setting/defaultSettings on first use, so any
+// component (modals, inbound forms, future pages) can read the same
+// value without prop-drilling and without re-fetching.
+//
+// useInbounds (which already reads defaultSettings for its own state)
+// calls setDatepicker() after its fetch so we don't issue a second
+// HTTP round-trip on the inbounds page.
+
+import { readonly, ref } from 'vue';
+import { HttpUtil } from '@/utils';
+
+const datepicker = ref('gregorian');
+let fetched = false;
+let pending = null;
+
+async function loadOnce() {
+ if (fetched) return;
+ if (pending) {
+ await pending;
+ return;
+ }
+ pending = (async () => {
+ try {
+ const msg = await HttpUtil.post('/panel/setting/defaultSettings');
+ if (msg?.success) {
+ datepicker.value = msg.obj?.datepicker || 'gregorian';
+ }
+ } finally {
+ fetched = true;
+ pending = null;
+ }
+ })();
+ await pending;
+}
+
+export function setDatepicker(value) {
+ fetched = true;
+ datepicker.value = value || 'gregorian';
+}
+
+export function useDatepicker() {
+ loadOnce();
+ return { datepicker: readonly(datepicker) };
+}
diff --git a/frontend/src/models/dbinbound.js b/frontend/src/models/dbinbound.js
index 404498eb..61e08c8b 100644
--- a/frontend/src/models/dbinbound.js
+++ b/frontend/src/models/dbinbound.js
@@ -1,3 +1,4 @@
+import dayjs from 'dayjs';
import { ObjectUtil, NumberFormatter, SizeFormatter } from '@/utils';
import { Inbound, Protocols } from './inbound.js';
@@ -78,7 +79,7 @@ export class DBInbound {
if (this.expiryTime === 0) {
return null;
}
- return moment(this.expiryTime);
+ return dayjs(this.expiryTime);
}
set _expiryTime(t) {
diff --git a/frontend/src/models/inbound.js b/frontend/src/models/inbound.js
index 791885e9..c17c894e 100644
--- a/frontend/src/models/inbound.js
+++ b/frontend/src/models/inbound.js
@@ -1,3 +1,4 @@
+import dayjs from 'dayjs';
import { ObjectUtil, RandomUtil, Base64, NumberFormatter, SizeFormatter, Wireguard } from '@/utils';
export const Protocols = {
@@ -2523,7 +2524,7 @@ Inbound.ClientBase = class extends XrayCommonClass {
if (this.expiryTime < 0) {
return this.expiryTime / -86400000;
}
- return moment(this.expiryTime);
+ return dayjs(this.expiryTime);
}
set _expiryTime(t) {
diff --git a/frontend/src/pages/inbounds/ClientBulkModal.vue b/frontend/src/pages/inbounds/ClientBulkModal.vue
index 8c94c849..1f9ca72f 100644
--- a/frontend/src/pages/inbounds/ClientBulkModal.vue
+++ b/frontend/src/pages/inbounds/ClientBulkModal.vue
@@ -13,6 +13,7 @@ import {
USERS_SECURITY,
TLS_FLOW_CONTROL,
} from '@/models/inbound.js';
+import DateTimePicker from '@/components/DateTimePicker.vue';
// Bulk-add up to 500 clients in one go. The legacy panel offers five
// generation modes — this component preserves them all:
@@ -250,8 +251,7 @@ async function submit() {
{{ t('pages.inbounds.expireDate')
}}
-
+
diff --git a/frontend/src/pages/inbounds/ClientFormModal.vue b/frontend/src/pages/inbounds/ClientFormModal.vue
index 2ae3d658..a70e69f0 100644
--- a/frontend/src/pages/inbounds/ClientFormModal.vue
+++ b/frontend/src/pages/inbounds/ClientFormModal.vue
@@ -11,6 +11,7 @@ import {
ColorUtils,
} from '@/utils';
import { Inbound, Protocols, USERS_SECURITY, TLS_FLOW_CONTROL } from '@/models/inbound.js';
+import DateTimePicker from '@/components/DateTimePicker.vue';
const { t } = useI18n();
@@ -363,8 +364,7 @@ const title = computed(() =>
{{ t('pages.inbounds.expireDate')
}}
-
+
{{ t('depleted') }}
diff --git a/frontend/src/pages/inbounds/InboundFormModal.vue b/frontend/src/pages/inbounds/InboundFormModal.vue
index f2fd332c..227ae68e 100644
--- a/frontend/src/pages/inbounds/InboundFormModal.vue
+++ b/frontend/src/pages/inbounds/InboundFormModal.vue
@@ -30,6 +30,7 @@ import {
} from '@/models/inbound.js';
import { DBInbound } from '@/models/dbinbound.js';
import FinalMaskForm from '@/components/FinalMaskForm.vue';
+import DateTimePicker from '@/components/DateTimePicker.vue';
const { t } = useI18n();
@@ -572,8 +573,7 @@ watch(
{{ t('pages.inbounds.expireDate')
}}
-
+
@@ -667,8 +667,7 @@ watch(
-
+
diff --git a/frontend/src/pages/inbounds/useInbounds.js b/frontend/src/pages/inbounds/useInbounds.js
index 3e6af2d2..d5bb982f 100644
--- a/frontend/src/pages/inbounds/useInbounds.js
+++ b/frontend/src/pages/inbounds/useInbounds.js
@@ -9,6 +9,7 @@ import { computed, ref, shallowRef } from 'vue';
import { HttpUtil, ObjectUtil } from '@/utils';
import { DBInbound } from '@/models/dbinbound.js';
import { Protocols } from '@/models/inbound.js';
+import { setDatepicker } from '@/composables/useDatepicker.js';
const ONLINE_GRACE_MS = 60_000;
@@ -146,6 +147,9 @@ export function useInbounds() {
pageSize.value = s.pageSize ?? 0;
remarkModel.value = s.remarkModel || '-ieo';
datepicker.value = s.datepicker || 'gregorian';
+ // Mirror into the global composable so date-pickers in modals can
+ // pick the right calendar without re-fetching the settings.
+ setDatepicker(datepicker.value);
ipLimitEnable.value = !!s.ipLimitEnable;
}
diff --git a/frontend/vite.config.js b/frontend/vite.config.js
index 663770ff..8f49efa9 100644
--- a/frontend/vite.config.js
+++ b/frontend/vite.config.js
@@ -127,6 +127,14 @@ export default defineConfig({
if (id.includes('dayjs')) return 'vendor-dayjs';
if (id.includes('qrious')) return 'vendor-qrious';
if (id.includes('axios')) return 'vendor-axios';
+ // The persian datepicker pulls in moment + moment-jalaali; bundle
+ // the trio together so unrelated pages don't pay the cost.
+ if (
+ id.includes('vue3-persian-datetime-picker')
+ || id.includes('moment-jalaali')
+ || id.includes('jalaali-js')
+ || id.includes('/node_modules/moment/')
+ ) return 'vendor-jalali';
return 'vendor';
},
},
diff --git a/web/assets/moment/moment-jalali.min.js b/web/assets/moment/moment-jalali.min.js
deleted file mode 100644
index 8b6ebfde..00000000
--- a/web/assets/moment/moment-jalali.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(){function t(e){var n=t.modules[e];if(!n)throw new Error('failed to require "'+e+'"');return"exports"in n||"function"!=typeof n.definition||(n.client=n.component=!0,n.definition.call(this,n.exports={},n),delete n.definition),n.exports}t.modules={moment:{exports:moment}},t.register=function(e,n){t.modules[e]={definition:n}},t.define=function(e,n){t.modules[e]={exports:n}},t.register("jalaali-js",(function(t,e){function n(t){return 0===a(t).leap}function r(t,e){return e<=6?31:e<=11||n(t)?30:29}function a(t){var e,n,r,a,i,s,o=[-61,9,38,199,426,686,756,818,1111,1181,1210,1635,2060,2097,2192,2262,2324,2394,2456,3178],u=o.length,f=t+621,l=-14,j=o[0];if(t=o[u-1])throw new Error("Invalid Jalaali year "+t);for(s=1;s=0){if(e<=185)return{jy:r,jm:1+c(e,31),jd:h(e,31)+1};e-=186}else r-=1,e+=179,1===i.leap&&(e+=1);return{jy:r,jm:7+c(e,30),jd:h(e,30)+1}}function o(t,e,n){var r=c(1461*(t+c(e-8,6)+100100),4)+c(153*h(e+9,12)+2,5)+n-34840408;return r=r-c(3*c(t+100100+c(e-8,6),100),4)+752}function u(t){var e,n,r,a;return e=(e=4*t+139361631)+4*c(3*c(4*t+183187720,146097),4)-3908,n=5*c(h(e,1461),4)+308,r=c(h(n,153),5)+1,a=h(c(n,153),12)+1,{gy:c(e,1461)-100100+c(8-a,6),gm:a,gd:r}}function c(t,e){return~~(t/e)}function h(t,e){return t-~~(t/e)*e}e.exports={toJalaali:function(t,e,n){"[object Date]"===Object.prototype.toString.call(t)&&(n=t.getDate(),e=t.getMonth()+1,t=t.getFullYear());return s(o(t,e,n))},toGregorian:function(t,e,n){return u(i(t,e,n))},isValidJalaaliDate:function(t,e,n){return t>=-61&&t<=3177&&e>=1&&e<=12&&n>=1&&n<=r(t,e)},isLeapJalaaliYear:n,jalaaliMonthLength:r,jalCal:a,j2d:i,d2j:s,g2d:o,d2g:u}})),t.register("moment-jalaali",(function(e,n){n.exports=W;var r,a=t("moment"),i=t("jalaali-js"),s=/(\[[^\[]*\])|(\\)?j(Mo|MM?M?M?|Do|DDDo|DD?D?D?|w[o|w]?|YYYYY|YYYY|YY|gg(ggg?)?|)|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,o=/(\[[^\[]*\])|(\\)?(LTS?|LL?L?L?|l{1,4})/g,u=/\d\d?/,c=/\d{1,3}/,h=/\d{3}/,f=/\d{1,4}/,l=/[+\-]?\d{1,6}/,j=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,_=/Z|[\+\-]\d\d:?\d\d/i,d=/T/i,D=/[\+\-]?\d+(\.\d{1,3})?/,M={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},Y={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},m={jm:"jmonth",jmonths:"jmonth",jy:"jyear",jyears:"jyear"},g={},p="DDD w M D".split(" "),y="M D w".split(" "),v={jM:function(){return this.jMonth()+1},jMMM:function(t){return this.localeData().jMonthsShort(this,t)},jMMMM:function(t){return this.localeData().jMonths(this,t)},jD:function(){return this.jDate()},jDDD:function(){return this.jDayOfYear()},jw:function(){return this.jWeek()},jYY:function(){return S(this.jYear()%100,2)},jYYYY:function(){return S(this.jYear(),4)},jYYYYY:function(){return S(this.jYear(),5)},jgg:function(){return S(this.jWeekYear()%100,2)},jgggg:function(){return this.jWeekYear()},jggggg:function(){return S(this.jWeekYear(),5)}};function w(t,e){return function(n){return S(t.call(this,n),e)}}function L(t,e){return function(n){return this.localeData().ordinal(t.call(this,n),e)}}function O(t,e){var n;for(n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}function S(t,e){for(var n=t+"";n.length47?1300:1400);break;case"jYYYY":case"jYYYYY":i[0]=~~e}null==e&&(n._isValid=!1)}function x(t){var e,n,r,a=t._f.match(s),i=t._i+"",o=a.length;for(t._a=[],e=0;eW.jDaysInMonth(r,a)||a<0||a>11)&&(t._isValid=!1),n=A((e=E(r,a,i)).gy,e.gm,e.gd),isNaN(e.gy)&&(t._isValid=!1),t._jDiff=0,~~n.jy!==r&&(t._jDiff+=1),~~n.jm!==a&&(t._jDiff+=1),~~n.jd!==i&&(t._jDiff+=1),[e.gy,e.gm,e.gd])}(t)}function P(t,e,n){var r,a=n-e,i=n-t.day();return i>a&&(i-=7),i57724432199999&&(c._isValid=!1),c}function W(t,e,n,r){return V(t,e,n,r,!1)}function C(t,e){for(var n=5,r=function(t){return e.localeData().longDateFormat(t)||t};n>0&&o.test(t);)n-=1,t=t.replace(o,r);return t}function A(t,e,n){try{var r=i.toJalaali(t,e+1,n);return r.jm-=1,r}catch(t){return{jy:NaN,jm:NaN,jd:NaN}}}function E(t,e,n){try{var r=i.toGregorian(t,e+1,n);return r.gm-=1,r}catch(t){return{gy:NaN,gm:NaN,gd:NaN}}}function H(t,e){return~~(t/e)}function G(t,e){return t-~~(t/e)*e}O(W,a),W.fn=F(a.fn),W.utc=function(t,e,n,r){return V(t,e,n,r,!0)},W.unix=function(t){return V(1e3*t)},W.fn.format=function(t){return t&&(t=C(t,this),g[t]||(g[t]=function(t){var e,n=t.match(s),r=n.length;for(e=0;e1&&void 0!==arguments[1]?arguments[1]:2,e=String(Math.abs(t)),i=e.length,o="";for(t<0&&(o+="-");i1999?u=o.year:ua.year&&(u=a.year),isNaN(h)||h<1||h>12?h=o.month:u<=r.year&&h=a.year&&h>a.month&&(h=a.month),isNaN(d)||d<1?d=o.day:h<=r.month&&d=a.month&&d>a.day&&(d=a.day),{year:parseInt(u),month:parseInt(h),day:parseInt(d)}},c=function(t,n,e){var i=s(n,e),o=t.initTime,a=t.options.maxTime,r=t.options.minTime,u=i.hour,h=i.minute,d=i.second;return isNaN(u)||u<0||u>23?u=o.hour:ua.hour&&(u=a.hour),isNaN(h)||h<0||h>59?h=o.minute:u<=r.hour&&h=a.hour&&h>a.minute&&(h=a.minute),isNaN(d)||d<0||d>59?d=o.second:u<=r.hour&&h<=r.minute&&d=a.hour&&h>=a.minute&&d>a.second&&(d=a.second),{hour:parseInt(u),minute:parseInt(h),second:parseInt(d)}},p=function(t,n,e,i){var o=t.options.minDate,a=t.options.maxDate,s=l(t,{year:n,month:e,day:i});return o=r(o)?s:l(t,{year:o.year,month:o.month,day:o.day}),s<=(a=r(a)?s:l(t,{year:a.year,month:a.month,day:a.day}))&&s>=o},m=function(t,n){var e=t.options.separatorChars,i=n.split(e.between),o=t.options.date?i[0].split(e.date):{},a=t.options.date?t.options.time&&i[1]?i[1].split(e.time):{}:i[0].split(e.time);return{year:parseInt(o[0]),month:parseInt(o[1]),day:parseInt(o[2]),hour:parseInt(a[0]),minute:parseInt(a[1]),second:parseInt(a[2])}},l=function(t,n){var e=t.options.separatorChars;return"".concat(n.year).concat(e.date).concat(h(n.month)).concat(e.date).concat(h(n.day))},y=function(t,n){if(!n)return!1;var e=n.substr(0,10).split(t.options.separatorChars.date);return 3===e.length&&4===e[0].length&&2===e[1].length&&2===e[2].length},f=function(t,n){if(!n)return!1;var e=n.substr(t.options.date?11:0,8).split(t.options.separatorChars.time);return e.length===(t.options.hasSecond?3:2)&&!e.find((function(t){return 2!==t.toString().length}))},v="jdp",g="".concat(v,"-container"),D="".concat(v,"-overlay"),w="div.".concat(v,"-years"),_="div.".concat(v,"-year"),b="div.".concat(v,"-months"),C="div.".concat(v,"-month"),T="div.".concat(v,"-days"),x="div.".concat(v,"-day"),I="div.".concat(v,"-day.not-in-month"),M="div.".concat(v,"-day.disabled-day"),S="".concat(I,".disabled-day"),A="div.".concat(v,"-day-name"),E="div.".concat(v,"-icon-plus"),O="div.".concat(v,"-icon-minus"),j="div.".concat(v,"-footer"),N="div.".concat(v,"-btn-today"),P="div.".concat(v,"-btn-empty"),V="div.".concat(v,"-btn-close"),B="div.".concat(v,"-time-container"),H="div.".concat(v,"-time"),Y="not-in-range",L="holly-day",k="".concat(v,":change"),z="click",R="focusin",J="today",W="attr",q="data-jdp-only-date",F="data-jdp-only-time",X=("data-".concat(v),"visible"),G="block",K="none",Q=function t(n){if(["html","body","#document"].indexOf((n.nodeName||"").toLowerCase())>=0)return window;if(n instanceof HTMLElement){var e=window.getComputedStyle(n),i=e.overflow,o=e.overflowX,a=e.overflowY;if(/auto|scroll|overlay/.test(i+a+o))return n}return t(n.parentNode)},U=function(t){var n=document.createEvent("Event");return n.initEvent(t,!0,!0),n},Z=function(t,n){t&&(t.dispatchEvent(U(n)),n===k&&(t.dispatchEvent(U("change")),t.dispatchEvent(U("input"))))},$=function(t,n,i,a,r){var s=t.split(".");t=s.shift()||"div";var u=s,h=window.document.createElement(t);return o(n)?window.document.querySelector(n).appendChild(h):n.appendChild(h),u.length&&(h.className=u.join(" ")),i&&a&&function(t,n,e){for(var i=n.split(" "),o=0,a=i.length;o2e3||t.yearChange(n.target.value)}));if(i)for(var a=function(t){function n(t){return 100*Math.round(t/100)}var e=t.initDate.year;return{min:t.options.minDate.year||n(e-200),max:t.options.maxDate.year||n(e+200)}}(t),r=a.min;r<=a.max;r++){var s=$("option",o);s.value=r,s.text=nt(r,t.options.persianDigits),s.selected=r===t.initDate.year}else o.tabIndex=-1,o.value=t.initDate.year,o.type="number"},mt=function(t){pt(t),function(t){var n=$(b,t.dpContainer);dt(t,n,!1);var e=$(C,n);ct(t,n,!1);var i=$("select",e,"change",(function(n){t.monthChange(n.target.value)}));i.tabIndex=-1;for(var o=function(t){var n=t.initDate.year,e=t.options.minDate,i=t.options.maxDate,o=[],a=1,r=12;n===e.year?(a=e.month,n===i.year&&(r=i.month)):n===i.year&&(a=1,r=i.month);for(var s=a;s<=r;s++)o.push(s);return o}(t),a=t.options.months,r=0;r=r+f,(a.inBeforeMonth||a.inAfterMonth)&&(a.inBeforeMonth?(v++,a.day=v,a.year=m,a.month=d):(g++,a.day=g,a.year=l,a.month=c)),a.isValid=p(t,a.year,a.month,a.day),a.className=ht(it(a.year,a.month,a.day)),t.inputValue.day===a.day&&t.inputValue.year===a.year&&t.inputValue.month===a.month&&(a.className+=".".concat("selected")),t.today.day===a.day&&t.today.year===a.year&&t.today.month===a.month&&(a.className+=".".concat("today")),i(t.options.dayRendering)&&s(a,t.options.dayRendering(a,t.input)),a.isHollyDay&&(a.className+=".".concat(L));var u=a.isValid?x:M;(a.inBeforeMonth||a.inAfterMonth)&&(u=I,a.isValid||(u=S));var h=$(u+a.className,n,null,null,nt(a.day,t.options.persianDigits));h.day=a.day,h.month=a.month,h.year=a.year,a.isValid&&h.addEventListener(z,(function(){t.setValue({year:h.year,month:h.month,day:h.day})})),o(a)},w=0;w<=h;w++)D(w)}(t)},lt=function(t){var n,e=$(j,t.dpContainer);if(t.options.showTodayBtn&&t.options.date){var i=function(t){return p(t,t.today.year,t.today.month,t.today.day)}(t);$(N+(i?"":".disabled-btn"),e,z,(function(){i&&t.setValue(t.today)}),"امروز")}t.options.date||!t.options.time||null!==(n=t.input)&&void 0!==n&&n.value||$(N,e,z,(function(){t.setValue(t.initTime),t.hide()}),"انتخاب"),t.options.showEmptyBtn&&$(P,e,z,(function(){t.input.value="",Z(t.input,k),t.options.hideAfterChange&&t.hide()}),"خالی"),t.options.showCloseBtn&&$(V,e,z,(function(){t.hide()}),"بستن")},yt=function(t){tt(t.dpContainer,""),t.options.date&&mt(t),t.options.time&&function(t){var n=B+(t.options.time&&!t.options.date?".jdp-only-time":""),e=$(n,t.dpContainer);t.options.hasSecond&&ut(t,e,"second"),ut(t,e,"minute"),ut(t,e,"hour")}(t),lt(t)};var ft=/iphone|ipod|android|ie|blackberry|fennec/.test(null===(at=window.navigator)||void 0===at||null===(rt=at.userAgent)||void 0===rt?void 0:rt.toLowerCase()),vt={init:function(t){var n;this.updateOptions(t),Element.prototype.matches=Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector,window.addEventListener("resize",(function(){vt.setPosition()})),this.options.autoHide&&document.body.addEventListener("click",(function(t){var n,e,o;vt.isShow&&(n=vt.dpContainer,!((o=(e=t).path||e.composedPath&&e.composedPath()||!1)?-1!==o.indexOf(n):n.outerHTML.indexOf(e.target.outerHTML)>-1))&&function(t){try{return i(t.composedPath)?t.composedPath()[0]:t.target}catch(n){return t.target}}(t)!==vt.input&&vt.hide()})),this.options.autoShow&&(n=this.options.selector,document.body.addEventListener(R,(function(t){t.target&&t.target.matches(n)&&vt.show(t.target)})))},updateOptions:function(t){this.options=Dt(t)},options:a({days:["ش","ی","د","س","چ","پ","ج"],months:["فروردین","اردیبهشت","خرداد","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"],initDate:null,today:null,initTime:null,hasSecond:!0,time:!1,date:!0,minDate:{},maxDate:{},minTime:{},maxTime:{},separatorChars:{date:"/",between:" ",time:":"},persianDigits:!1,zIndex:1e3,container:"body",selector:"input[data-jdp]",autoShow:!0,autoHide:!0,hideAfterChange:!0,plusHtml:'',minusHtml:'',changeMonthRotateYear:!1,showTodayBtn:!0,showEmptyBtn:!0,showCloseBtn:ft,autoReadOnlyInput:ft,useDropDownYears:!0,topSpace:0,bottomSpace:0}),input:null,get dpContainer(){return this._dpContainer||(this._dpContainer=$(g,this.options.container),this.overlayElm=$(D,this.options.container),this.dpContainer.style.zIndex=this.options.zIndex,this.overlayElm.style.zIndex=this.options.zIndex-1),this._dpContainer},get today(){return this._today=this._today||this.options.today||function(){var t,n,e=new Date,i=parseInt(e.getFullYear()),o=parseInt(e.getMonth())+1,a=parseInt(e.getDate());i>1600?(t=979,i-=1600):(t=0,i-=621);var r=o>2?i+1:i;return n=365*i+parseInt((r+3)/4)-parseInt((r+99)/100)+parseInt((r+399)/400)-80+a+[0,31,59,90,120,151,181,212,243,273,304,334][o-1],t+=33*parseInt(n/12053),n%=12053,t+=4*parseInt(n/1461),(n%=1461)>365&&(t+=parseInt((n-1)/365),n=(n-1)%365),{year:t,month:n<186?1+parseInt(n/31):7+parseInt((n-186)/30),day:1+(n<186?n%31:(n-186)%30)}}(),this._today},get inputValue(){var t=a(this.input.value);return t=function(t,n){if(!n)return!1;var e=t.options.separatorChars,i=t.options.date?"\\d{4}".concat(e.date,"\\d{2}").concat(e.date,"\\d{2}"):"",o=t.options.time?"\\d{2}".concat(e.time,"\\d{2}")+(t.options.hasSecond?"".concat(e.time,"\\d{2}"):""):"";return new RegExp(i+(i&&o?e.between:"")+o).test(n,"g")}(this,t)||o(t)&&y(this,t)?m(this,t):{}},get initDate(){return this.options.initDate?this.options.initDate:(this._initDate||(this._initDate=a(this.input.value)||{},r(this._initDate)?this._initDate=this.options.initDate||a(this.today):o(this._initDate)&&y(this,this._initDate)?this._initDate=m(this,this._initDate):this._initDate=a(this.today),this._initDate=d(this,this._initDate)),this._initDate)},get initTime(){if(this._initTime)return this._initTime;var t=new Date,n={hour:t.getHours(),minute:t.getMinutes(),second:0};return this._initTime=a(this.input.value)||this.options.initTime||n,o(this._initTime)&&(f(this,this._initTime)?this._initTime=m(this,this._initTime):this._initTime=n),this._initTime=c(this,this._initTime),this._initTime},_draw:function(){yt(this)},show:function(t){var n=this;this._initDate=null,this._initTime=null,this._value=null,this.input=t,this._draw(),function(t,n){n.autoReadOnlyInput&&!t.readOnly&&(t.setAttribute("readonly","readonly"),t.readOnly=!0)}(t,this.options),this.dpContainer.style.visibility=X,this.dpContainer.style.display=G,this.overlayElm.style.display=G,setTimeout((function(){n.dpContainer.style.visibility=X,n.dpContainer.style.display=G,n.overlayElm.style.display=G,n.isShow=!0}),300),this.setPosition(),function(t){Q(t).addEventListener("scroll",(function(){vt.setPosition()}),{passive:!0})}(t)},hide:function(){this.dpContainer.style.visibility="hidden",this.dpContainer.style.display=K,this.overlayElm.style.display=K,this.isShow=!1},setPosition:function(){if(this.dpContainer.style.visibility===X){var t=this.input.getBoundingClientRect(),n=t.height,e=t.left,i=t.top+n;i+=this.options.topSpace;var o=window.document.body.offsetWidth,a=this.dpContainer.offsetWidth,r=this.dpContainer.offsetHeight;e+a>=o&&(e-=e+a-(o+10)),i-n>=r&&i+r>=window.innerHeight&&(i-=r+n+this.options.bottomSpace+this.options.topSpace),this.dpContainer.style.position="fixed",this.dpContainer.style.left=e+"px",this.dpContainer.style.top=i+"px"}},get getValue(){return this._value=this._value||this.inputValue||{},this._value},setValue:function(t){var n,e,i,o,a;this._value=s({year:this.today.year,month:this.today.month,day:this.today.day,hour:this.initTime.hour,minute:this.initTime.minute,second:this.initTime.second},s(this._value,t)),this._initTime=null,this.input.value=(n=this,e=this._value,i=n.options.separatorChars,o=n.options.date?"".concat(e.year).concat(i.date).concat(h(e.month)).concat(i.date).concat(h(e.day)):"",a=n.options.time?"".concat(h(e.hour)).concat(i.time).concat(h(e.minute))+(n.options.hasSecond?i.time+h(e.second):""):"",o+(o&&a?i.between:"")+a),Z(this.input,k),!this.options.time&&this.options.hideAfterChange?this.hide():this._draw()},increaseMonth:function(){var t=12===this._initDate.month;this.options.changeMonthRotateYear&&t&&this.increaseYear(),this.monthChange(t?1:this._initDate.month+1)},decreaseMonth:function(){var t=1===this._initDate.month;this.options.changeMonthRotateYear&&t&&this.decreaseYear(),this.monthChange(t?12:this._initDate.month-1)},monthChange:function(t){this._initDate=d(this,this._initDate,{month:t}),this._draw()},increaseYear:function(){this.yearChange(this._initDate.year+1)},decreaseYear:function(){this.yearChange(this._initDate.year-1)},yearChange:function(t){this._initDate=d(this,this._initDate,{year:t}),this._draw()}},gt=function(t,n){var e,i=null===(e=vt.input)||void 0===e?void 0:e.getAttribute(t);if(!n&&i===J)return a(vt.today);if(!o(i))return{};try{i=document.querySelector(i).value}catch(t){}return i=n?f(vt,i)?m(vt,i):{}:y(vt,i)?m(vt,i):{}},Dt=function(t){return!e(vt.options._date)&&e(t.date)&&(t.date=vt.options._date),!e(vt.options._time)&&e(t.time)&&(t.time=vt.options._time),t.separatorChars=s(vt.options.separatorChars,t.separatorChars),(t=s({},vt.options,t)).minDate===J&&(t.minDate=a(vt.today)),t.maxDate===J&&(t.maxDate=a(vt.today)),(t.initDate===W||t._initDateIsAttr)&&(delete t.initDate,t._initDateIsAttr=!0,window.Object.defineProperty(t,"initDate",{get:function(){return gt("data-jdp-init-date")},enumerable:!0})),(t.minDate===W||t._minDateIsAttr)&&(delete t.minDate,t._minDateIsAttr=!0,window.Object.defineProperty(t,"minDate",{get:function(){return gt("data-jdp-min-date")},enumerable:!0})),(t.maxDate===W||t._maxDateIsAttr)&&(delete t.maxDate,t._maxDateIsAttr=!0,window.Object.defineProperty(t,"maxDate",{get:function(){return gt("data-jdp-max-date")},enumerable:!0})),(t.minTime===W||t._minTimeIsAttr)&&(delete t.minTime,t._minTimeIsAttr=!0,window.Object.defineProperty(t,"minTime",{get:function(){return gt("data-jdp-min-time",!0)},enumerable:!0})),(t.maxTime===W||t._maxTimeIsAttr)&&(delete t.maxTime,t._maxTimeIsAttr=!0,window.Object.defineProperty(t,"maxTime",{get:function(){return gt("data-jdp-max-time",!0)},enumerable:!0})),t._date=t.date,delete t.date,window.Object.defineProperty(t,"date",{get:function(){var n,e;return!(null!==(n=vt.input)&&void 0!==n&&n.hasAttribute(F))&&(t._date||(null===(e=vt.input)||void 0===e?void 0:e.hasAttribute(q)))},enumerable:!0}),t._time=t.time,delete t.time,window.Object.defineProperty(t,"time",{get:function(){var n,e;return!(null!==(n=vt.input)&&void 0!==n&&n.hasAttribute(q))&&(t._time||(null===(e=vt.input)||void 0===e?void 0:e.hasAttribute(F)))},enumerable:!0}),t};window.jalaliDatepicker={startWatch:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};vt.init(t)},show:function(t){vt.show(t)},hide:function(){vt.hide()},updateOptions:function(t){vt.updateOptions(t)}}}()}();
\ No newline at end of file
diff --git a/web/html/component/aPersianDatepicker.html b/web/html/component/aPersianDatepicker.html
deleted file mode 100644
index cb4c2918..00000000
--- a/web/html/component/aPersianDatepicker.html
+++ /dev/null
@@ -1,73 +0,0 @@
-{{define "component/persianDatepickerTemplate"}}
-
-
-
-{{end}}
-
-{{define "component/aPersianDatepicker"}}
-
-
-
-
-{{end}}
\ No newline at end of file