Add PTZ nudges, configurable monitoring wall and lunar family dates

This commit is contained in:
Codex
2026-10-03 18:29:18 +08:00
parent de6933c411
commit 52b5a6b389
18 changed files with 434 additions and 20 deletions
+38
View File
@@ -0,0 +1,38 @@
/* Chinese calendar conversion supplied by the browser's ICU calendar, offline. */
(function(root){
'use strict';
const fmt=new Intl.DateTimeFormat('en-u-ca-chinese',{year:'numeric',month:'numeric',day:'numeric',timeZone:'Asia/Shanghai'});
const cache=new Map();
function solarDate(value){
if(!/^\d{4}-\d{2}-\d{2}$/.test(value))throw Error('日期请填写 YYYY-MM-DD');
const d=new Date(value+'T12:00:00Z');
if(!Number.isFinite(+d)||d.toISOString().slice(0,10)!==value)throw Error('日期不存在');
return d;
}
function lunar(value){
const d=solarDate(value),year=d.getUTCFullYear();
if(year<1901||year>2100)throw Error('自动换算支持 1901—2100 年;更早日期可填写公历并在备注保留原记载');
if(fmt.resolvedOptions().calendar!=='chinese')throw Error('当前浏览器不支持农历换算');
const parts=Object.fromEntries(fmt.formatToParts(d).map(p=>[p.type,p.value]));
return {year:Number(parts.relatedYear),month:parseInt(parts.month,10),day:Number(parts.day),leap:parts.month.includes('bis')};
}
function solar(value,leap=false){
if(!/^\d{4}-\d{2}-\d{2}$/.test(value))throw Error('农历请填写 YYYY-MM-DD,例如 2023-02-01');
const [year,month,day]=value.split('-').map(Number);
if(year<1901||year>2099)throw Error('农历输入支持 1901—2099 年');
if(month<1||month>12||day<1||day>30)throw Error('农历日期不存在');
if(!cache.has(year)){
const days=new Map(),start=Date.UTC(year,0,1,12),end=Date.UTC(year+1,2,1,12);
for(let t=start;t<end;t+=86400000){const iso=new Date(t).toISOString().slice(0,10),l=lunar(iso);if(l.year===year)days.set(`${l.month}-${l.day}-${l.leap}`,iso);}
if(cache.size>8)cache.clear();cache.set(year,days);
}
const result=cache.get(year).get(`${month}-${day}-${!!leap}`);
if(!result)throw Error('该农历日期或闰月不存在');
return result;
}
const pad=n=>String(n).padStart(2,'0');
function iso(l){return `${l.year}-${pad(l.month)}-${pad(l.day)}`;}
function describe(value){if(!value)return '';try{const l=lunar(value);return `${value} · 农历 ${l.year}年${l.leap?'闰':''}${l.month}月${l.day}日`;}catch{return value+'(公历)';}}
root.ZhaoCalendar={solarDate,lunar,solar,iso,describe};
if(typeof module!=='undefined')module.exports=root.ZhaoCalendar;
})(typeof window==='undefined'?globalThis:window);