pin-diary-6
pin-diary-6/template
importを経由せずに自分のprojectのみで読み込んでテスト
https://scrapbox-bundler.vercel.app/?url=https://scrapbox.io/api/code/hoshihara/pin-diary-6/mod.ts&bundle&minify&run&output=newtab&reload
code:script.ts
import { launch } from "./mod.ts";
import {
makeDiary, isOldDiary,
} from "../pin-diary-6%2Ftemplate/mod.ts";
launch(
"hoshihara",
{
makeDiary,
isOldDiary,
},
);
$ deno check --remote -r=https://scrapbox.io https://scrapbox.io/api/code/villagepump/pin-diary-6/mod.ts
code:mod.ts
/// <reference no-default-lib="true"/>
/// <reference lib="esnext"/>
/// <reference lib="dom"/>
import {
pin,
unpin,
patch,
useStatusBar,
sleep,
makeSocket,
disconnect,
format,
} from "./deps.ts";
import { listPinnedPages } from "./list.ts";
import type { Scrapbox, Socket } from "./deps.ts";
declare const scrapbox: Scrapbox;
export interface DiaryInit {
/** 与えられた日付の日記ページのテンプレートを作る */
makeDiary: (date: Date) => {
title: string;
header: string[];
footer: string[];
},
code:mod.ts
/** 今日以外の日記ページかどうかを判断する函数
*
* @param title 判断対象のページタイトル
* @param today 今日の日付
* @param 今日以外の日記ページならtrue, それ以外のページは false
*/
isOldDiary: (title: string, today: Date) => boolean;
}
// initialize
export const launch = (
project: string,
init: DiaryInit & { interval?: number },
) => {
const interval = init.interval ?? 24 * 3600 * 1000;
const handleChange = () =>
scrapbox.Project.name === project ?
startObserve(project, interval, init) :
endObserve();
handleChange();
scrapbox.addListener("project:changed", handleChange);
};
let updateTimer: number | undefined;
const startObserve = async (
project: string,
interval: number,
init: DiaryInit,
) => {
endObserve();
await pinDiary(project, new Date(), init);
updateTimer = setInterval(
() => pinDiary(project, new Date(), init),
interval,
);
};
const endObserve = () => clearInterval(updateTimer);
code:mod.ts
export const pinDiary = async (
project: string,
date: Date,
{ makeDiary, isOldDiary, }: DiaryInit,
): Promise<void> => {
const { render, dispose } = useStatusBar();
let socket: Socket | undefined;
try {
// 今日以外の日付ページを外す
render(
{ type: "spinner" },
{ type: "text", text: unpin other diary pages...},
);
socket = await makeSocket();
for await (const { title } of listPinnedPages(project)) {
if (!isOldDiary(title, date)) continue;
await unpin(project, title, { socket });
}
// 今日の日付ページをピン留めする
const { title, header, footer } = makeDiary(date);
render(
{ type: "spinner" },
{ type: "text", text: pin "/${project}/${title}"...},
);
await pin(project, title, { socket, create: true });
// 今日の日付ページにtemplateを挿入する
render(
{ type: "spinner" },
{ type: "text", text: format "/${project}/${title}"...},
);
await patch(project, title, (lines) => [
lines0.text,
...format(
lines.slice(1).map(line => line.text),
header,
footer,
),
], { socket });
render(
{ type: "check-circle" },
{ type: "text", text: Pinned "/${project}/${title}".},
);
} catch(e: unknown) {
render(
{ type: "exclamation-triangle" },
{ type: "text", text: e instanceof Error ?
${e.name} ${e.message} :
Unknown error! (see developper console),
},
);
console.error(e);
} finally {
if (socket) await disconnect(socket);
await sleep(1000);
dispose();
}
};
code:list.ts
import { listPages, BasePage } from "./deps.ts";
/** 全てのピン留めされたページを取得する */
export async function* listPinnedPages(project: string, skip = 0): AsyncGenerator<BasePage> {
const { count, pages } = await ensureList(project, skip);
for (const page of pages) {
if (page.pin === 0) continue;
yield page;
}
// pinしたページこれ以上ないときは終了
if ((pages.at(-1)?.pin ?? 0) === 0) return;
yield* listPinnedPages(project, skip + 1000);
}
const ensureList = async (project: string, skip: number) => {
const result = await listPages(project, {
limit: 1000,
skip,
});
// login errorなどは全部例外として扱う
if (!result.ok) {
const error = new Error();
error.name = result.value.name;
error.message = result.value.message;
throw error;
}
return result.value;
};
code:deps.ts
export { patchTemplate as format } from "./format.ts";
export {
pin,
unpin,
patch,
useStatusBar,
makeSocket,
disconnect,
listPages,
} from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-std/0.26.1/mod.ts";
export type {
Socket,
} from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-std/0.26.1/mod.ts";
export {
sleep,
} from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-std/0.26.1/sleep.ts";
export type {
Scrapbox,
} from "https://raw.githubusercontent.com/scrapbox-jp/types/0.7.0/userscript.ts";
export type {
BasePage,
} from "https://raw.githubusercontent.com/scrapbox-jp/types/0.7.0/rest.ts";
https://scrapbox.io/api/code/villagepump/pin-diary-5/format.ts
code:format.ts
import { patchLines, findSplitIndex } from "./util.ts";
// linesにタイトルを入れないように
export function patchTemplate(lines: string[], headers: string[], footers: string[]): string[] {
// headerとfooterに相当する行を補う
const bodies = patchLines(
patchLines(lines, headers).reverse(),
...footers.reverse(),
).reverse();
// headerとfooterの間に余裕をもたせる
const headerStart = findSplitIndex(bodies, headers);
const footerStart = bodies.length - 1 - findSplitIndex(
...bodies.reverse(),
...footers.reverse(),
);
return [
...bodies.slice(0, headerStart + 1),
"",
...bodies.slice(headerStart + 1, footerStart).join("\n").trim().split("\n"),
"",
...bodies.slice(footerStart),
];
}
https://scrapbox.io/api/code/villagepump/pin-diary-5/util.ts
code:util.ts
export function patchLines(lines: string[], appends: string[]) {
let index = 0;
const result = [] as string[];
for (let i = 0; i < appends.length; i++) {
const pos = lines.findIndex((line, j) => j >= index && line.trim() === appendsi.trim());
if (pos < 0) {
result.push(appendsi);
continue;
}
result.push(...lines.slice(index, pos + 1));
index = pos + 1;
}
result.push(...lines.slice(index));
return result;
}
export function findSplitIndex(lines: string[], query: string[]) {
let index = -1;
for (const text of query) {
const pos = lines.findIndex((line, j) => j > index && line.trim() === text.trim());
if (pos < 0) return -1;
index = pos;
}
return index;
}
code:min.js
function H(e,t){let r=0,n=[];for(let o=0;o<t.length;o++){let s=e.findIndex((i,a)=>a>=r&&i.trim()===to.trim());if(s<0){n.push(to);continue}n.push(...e.slice(r,s+1)),r=s+1}return n.push(...e.slice(r)),n}function _(e,t){let r=-1;for(let n of t){let o=e.findIndex((s,i)=>i>r&&s.trim()===n.trim());if(o<0)return-1;r=o}return r}function K(e,t,r){let n=H(H(e,t).reverse(),...r.reverse()).reverse(),o=_(n,t),s=n.length-1-_(...n.reverse(),...r.reverse());return[...n.slice(0,o+1),"",...n.slice(o+1,s).join(`
).trim().split(
),"",...n.slice(s)]}var f=e=>{let{fetch:t=globalThis.fetch,hostName:r="scrapbox.io",...n}=e;return{fetch:t,hostName:r,...n}};var We=e=>typeof e=="object"&&e!==null,Je=e=>We(e)?(e.name===void 0||typeof e.name=="string")&&typeof e.message=="string":!1,ae=e=>{try{let t=typeof e=="string"?JSON.parse(e):e;return Je(t)?t:!1}catch(t){if(t instanceof SyntaxError)return!1;throw t}};var N=class e extends Error{constructor(r){super(${r.status} ${r.statusText} when fetching ${r.url});this.response=r;Error.captureStackTrace&&Error.captureStackTrace(this,e)}name="UnexpectedResponseError"},y=async e=>{let t=e.clone(),r=await t.text(),n=ae(r);if(!n)throw new N(t);return{ok:!1,value:n}};var G=async e=>{let{sid:t,hostName:r,fetch:n}=f(e??{}),o=new Request(https://${r}/api/users/me,t?{headers:{Cookie:x(t)}}:void 0),s=await n(o);if(!s.ok)throw new N(s);return await s.json()};var x=e=>connect.sid=${e};var L=e=>e.replaceAll(" ","_").toLowerCase();var T=e=>[...e].map((t,r)=>t===" "?"_":!Xe.includes(t)||r===e.length-1&&Ve.includes(t)?encodeURIComponent(t):t).join(""),Xe='@$&+=:;",',Ve=':;",';var ce=(e,t,r)=>{let{sid:n,hostName:o,followRename:s,projects:i}=f(r??{}),a=new URLSearchParams;a.append("followRename",${s??!0});for(let u of i??[])a.append("projects",u);let l=https://${o}/api/pages/${e}/${T(t)}?${a.toString()};return new Request(l,n?{headers:{Cookie:x(n)}}:void 0)},pe=async e=>e.ok?{ok:!0,value:await e.json()}:e.status===414?{ok:!1,value:{name:"TooLongURIError",message:"project ids may be too much."}}:y(e),F=async(e,t,r)=>{let{fetch:n}=f(r??{}),o=ce(e,t,r),s=await n(o);return await pe(s)};F.toRequest=ce;F.fromResponse=pe;var de=(e,t)=>{let{sid:r,hostName:n,sort:o,limit:s,skip:i}=f(t??{}),a=new URLSearchParams;o!==void 0&&a.append("sort",o),s!==void 0&&a.append("limit",${s}),i!==void 0&&a.append("skip",${i});let l=https://${n}/api/pages/${e}?${a.toString()};return new Request(l,r?{headers:{Cookie:x(r)}}:void 0)},le=async e=>e.ok?{ok:!0,value:await e.json()}:y(e),O=async(e,t)=>{let{fetch:r}=f(t??{}),n=await r(de(e,t));return await le(n)};O.toRequest=de;O.fromResponse=le;var ue=(e,t,r,n)=>{let{sid:o,hostName:s}=f(n??{}),i=https://${s}/api/table/${e}/${T(t)}/${encodeURIComponent(r)}.csv;return new Request(i,o?{headers:{Cookie:x(o)}}:void 0)},me=async e=>e.ok?{ok:!0,value:await e.text()}:e.status===404?{ok:!1,value:{name:"NotFoundError",message:"Table not found."}}:y(e),fe=async(e,t,r,n)=>{let{fetch:o}=f(n??{}),s=ue(e,t,r,n),i=await o(s);return await me(i)};fe.toRequest=ue;fe.fromResponse=me;var ge=(e,t)=>{let{sid:r,hostName:n}=f(t??{});return new Request(https://${n}/api/projects/${e},r?{headers:{Cookie:x(r)}}:void 0)},he=async e=>e.ok?{ok:!0,value:await e.json()}:y(e),j=async(e,t)=>{let{fetch:r}=f(t??{}),n=ge(e,t),o=await r(n);return he(o)};j.toRequest=ge;j.fromResponse=he;var xe=(e,t)=>{let{sid:r,hostName:n}=f(t??{}),o=new URLSearchParams;for(let s of e)o.append("ids",s);return new Request(https://${n}/api/projects?${o.toString()},r?{headers:{Cookie:x(r)}}:void 0)},ye=async e=>e.ok?{ok:!0,value:await e.json()}:y(e),Ee=async(e,t)=>{let{fetch:r}=f(t??{}),n=await r(xe(e,t));return ye(n)};Ee.toRequest=xe;Ee.fromResponse=ye;var A=async(e,t)=>{let r=await F(e,t);if(!r.ok)throw new Error(You have no privilege of editing "/${e}/${t}".);return r.value};var we=(e,t,r,n)=>{let{sid:o,hostName:s}=f(n??{}),i=https://${s}/api/code/${e}/${T(t)}/${T(r)};return new Request(i,o?{headers:{Cookie:x(o)}}:void 0)},be=async e=>e.ok?{ok:!0,value:await e.text()}:e.status===404&&e.headers.get("Content-Type")?.includes?.("text/plain")?{ok:!1,value:{name:"NotFoundError",message:"Code block is not found"}}:y(e),ve=async(e,t,r,n)=>{let{fetch:o}=f(n??{}),s=we(e,t,r,n),i=await o(s);return await be(i)};ve.toRequest=we;ve.fromResponse=be;var jo=new TextEncoder().encode("0123456789abcdef");var ke=!1;scrapbox.addListener("lines:changed",()=>ke=!1);scrapbox.addListener("layout:changed",()=>ke=!1);var Le=(e,t)=>{if(!(e instanceof HTMLDivElement))throw new TypeError("${t}" must be HTMLDivElememt but actual is "${e}")};var Te=(e,t)=>{if(!(e instanceof HTMLTextAreaElement))throw new TypeError("${t}" must be HTMLTextAreaElement but actual is "${e}")};var S=()=>{let e=document.getElementById("text-input");if(e)return Te(e,"textarea#text-input"),e};var Ce=()=>rt(document.getElementsByClassName("status-bar")?.[0],"div.status-bar"),rt=(e,t)=>{if(e)return Le(e,t),e};var P=e=>new Promise(t=>setTimeout(()=>t(),e));var z=()=>{let e=Ce();if(!e)throw new Error("div.status-bar can't be found");let t=document.createElement("div");return e.append(t),{render:(...r)=>{t.textContent="";let n=Pe(...r);n&&t.append(n)},dispose:()=>t.remove()}},Pe=(...e)=>{let t=e.flatMap(n=>{switch(n.type){case"spinner":return[pt()];case"check-circle":return[dt()];case"exclamation-triangle":return[lt()];case"text":return[$(n.text)];case"group":{let o=Pe(...n.items);return o?[o]:[]}}});if(t.length===0)return;if(t.length===1)return t[0];let r=document.createElement("span");return r.classList.add("item-group"),r.append(...t),r},$=e=>{let t=document.createElement("span");return t.classList.add("item"),t.append(e),t},pt=()=>{let e=document.createElement("i");return e.classList.add("fa","fa-spinner"),$(e)},dt=()=>{let e=document.createElement("i");return e.classList.add("kamon","kamon-check-circle"),$(e)},lt=()=>{let e=document.createElement("i");return e.classList.add("fas","fa-exclamation-triangle"),$(e)};var Re=e=>{if(e===0)return;let t={};return e&1&&(t.capture=!0),e&2&&(t.once=!0),e&4&&(t.passive=!0),t};var mt=new Map;scrapbox.on("layout:changed",()=>{let e=S();if(e)for(let[t,r]of mt)for(let[n,o]of r)for(let s of o)e.addEventListener(t,n,Re(s))});var Ne=e=>ft.includes(e.name),ft=["SocketIOError","DuplicateTitleError","NotFastForwardError"];var B=async()=>{let t=(await ht())("https://scrapbox.io",{reconnectionDelay:5e3,transports:["websocket"]});return await new Promise((r,n)=>{let o=s=>n(s);t.once("connect",()=>{t.off("disconnect",o),r()}),t.once("disconnect",o)}),t},gt="4.2.0",Se=https://cdnjs.cloudflare.com/ajax/libs/socket.io/${gt}/socket.io.min.js,Q,ht=async()=>{if(Q)throw Q;if(!document.querySelector(scriptsrc="${Se}")){let e=document.createElement("script");e.src=Se,await new Promise((t,r)=>{e.onload=()=>t(),e.onerror=n=>{Q=n,r(n)},document.head.append(e)})}return new Promise(e=>{let t=setInterval(()=>{io&&(clearInterval(t),e(io))},500)})};var Y=(e,t=9e4)=>{let r=(o,s)=>{let i;return new Promise((a,l)=>{let u=p=>{clearTimeout(i),l(new Error(p))};e.emit(o,s,p=>{switch(clearTimeout(i),e.off("disconnect",u),o){case"socket.io-request":"error"in p?typeof p.error=="object"&&p.error&&"name"in p.error&&typeof p.error.name=="string"&&Ne({name:p.error.name})?a({ok:!1,value:p.error}):a({ok:!1,value:{name:"UnexpectedError",value:p.error}}):"data"in p&&a({ok:!0,value:p.data});break;case"cursor":"error"in p?a({ok:!1,value:{name:"UnexpectedError",value:p.error}}):"data"in p&&a({ok:!0,value:p.data});break}l(new Error('Invalid response: missing "data" or "error" field'))}),i=setTimeout(()=>{e.off("disconnect",u),a({ok:!1,value:{name:"TimeoutError",message:Timeout: exceeded ${t}ms}})},t),e.once("disconnect",u)})};async function*n(...o){let s,i=()=>new Promise(l=>s=l),a=l=>{s?.(l)};for(let l of o)e.on(l,a);try{for(;;)yield await i()}finally{for(let l of o)e.off(l,a)}}return{request:r,response:n}};var W=()=>B(),J=async e=>{if(e.connected)return;let t=new Promise(r=>e.once("connect",()=>r()));e.connect(),await t},M=async e=>{if(e.disconnected)return;let t=new Promise(r=>{let n=o=>{o==="io client disconnect"&&(r(),e.off("disconnect",n))};e.on("disconnect",n)});e.disconnect(),await t};var X=(e,t)=>{let r=e.length>t.length,n=r?t:e,o=r?e:t,s=n.length+1,i=n.length+o.length+3,a=new Array(i);a.fill(-1);let l=[];function u(c,h,E){let k=Math.max(h,E),D=k-c;for(;D<n.length&&k<o.length&&n[D]===o[k];)++D,++k;return a[c+s]=l.length,l.push([{x:D,y:k},a[c+(h>E?-1:1)+s]]),k}let p=new Array(i);p.fill(-1);let m=-1,g=o.length-n.length;do{++m;for(let c=-m;c<=g-1;++c)p[c+s]=u(c,p[c-1+s]+1,p[c+1+s]);for(let c=g+m;c>=g+1;--c)p[c+s]=u(c,p[c-1+s]+1,p[c+1+s]);p[g+s]=u(g,p[g-1+s]+1,p[g+1+s])}while(p[g+s]!==o.length);let v=[],d=a[g+s];for(;d!==-1;)v.push(l[d][0]),d=l[d][1];return{from:e,to:t,editDistance:g+m*2,buildSES:function*(){let c=0,h=0;for(let{x:E,y:k}of xt(v))for(;c<E||h<k;)k-E>h-c?(yield{value:o[h],type:r?"deleted":"added"},++h):k-E<h-c?(yield{value:n[c],type:r?"added":"deleted"},++c):(yield{value:n[c],type:"common"},++c,++h)}}};function*V(e){let t=[],r=[];function*n(){if(t.length>r.length){for(let o=0;o<r.length;o++)yield Me(t[o],r[o]);for(let o=r.length;o<t.length;o++)yield t[o]}else{for(let o=0;o<t.length;o++)yield Me(t[o],r[o]);for(let o=t.length;o<r.length;o++)yield r[o]}t=[],r=[]}for(let o of e)switch(o.type){case"added":t.push(o);break;case"deleted":r.push(o);break;case"common":yield*n(),yield o;break}yield*n()}var Me=(e,t)=>({value:e.value,oldValue:t.value,type:"replaced"});function*xt(e){for(let t=e.length-1;t>=0;t--)yield e[t]}var q,De=async()=>{if(q!==void 0)return q;let e=await G();if(e.isGuest)throw new Error("this script can only be executed by Logged in users");return q=e.id,q},Oe=new Map,Z=async e=>{let t=Oe.get(e);if(t!==void 0)return t;let r=await j(e);if(!r.ok){let{name:o,message:s}=r.value;throw new Error(${o} ${s})}let{id:n}=r.value;return Oe.set(e,n),n},Be=e=>e.padStart(8,"0"),ee=e=>{let t=Math.floor(new Date().getTime()/1e3).toString(16),r=Math.floor(16777214*Math.random()).toString(16);return${Be(t).slice(-8)}${e.slice(-6)}0000${Be(r)}};function*te(e,t,{userId:r}){let{buildSES:n}=X(e.map(({text:i})=>i),t),o=0,s=e[0].id;for(let i of V(n())){switch(i.type){case"added":yield{_insert:s,lines:{id:ee(r),text:i.value}};continue;case"deleted":yield{_delete:s,lines:-1};break;case"replaced":yield{_update:s,lines:{text:i.value}};break}o++,s=e[o]?.id??"_end"}}var yt=e=>({type:"title",text:e.rows[0].text}),Et=e=>{let{rows:[t,...r]}=e,{indent:n=0,text:o=""}=t??{},s=o.replace(/^\s*code:/,"");return{indent:n,type:"codeBlock",fileName:s,content:r.map(i=>i.text.substring(n+1)).join(
)}},w=(e,{parseOnNested:t,parseOnQuoted:r,patterns:n})=>(o,s,i)=>{var a,l,u,p,m,g;if(!t&&s.nested)return(a=i?.())!==null&&a!==void 0?a:[];if(!r&&s.quoted)return(l=i?.())!==null&&l!==void 0?l:[];for(let v of n){let d=v.exec(o);if(d===null)continue;let c=o.substring(0,d.index),h=o.substring(d.index+((p=(u=d[0])===null||u===void 0?void 0:u.length)!==null&&p!==void 0?p:0)),E=e((m=d[0])!==null&&m!==void 0?m:"",s);return[...C(c,s),...E,...C(h,s)]}return(g=i?.())!==null&&g!==void 0?g:[]},b=e=>[{type:"plain",raw:e,text:e}],wt=w(b,{parseOnNested:!0,parseOnQuoted:!0,patterns:[/^()(.*)()$/]}),bt=/^>.*$/,vt=(e,t)=>t.context==="table"?b(e,t):[{type:"quote",raw:e,nodes:C(e.substring(1),{...t,quoted:!0})}],kt=w(vt,{parseOnNested:!1,parseOnQuoted:!1,patterns:[bt]}),Lt=/^\? .+$/,Tt=(e,t)=>t.context==="table"?b(e,t):[{type:"helpfeel",raw:e,text:e.substring(2)}],Ct=w(Tt,{parseOnNested:!1,parseOnQuoted:!1,patterns:[Lt]}),It=/\[\[https?:\/\/[^\s\]]+\.(?:png|jpe?g|gif|svg)\]\]/i,Pt=/\[\[https?:\/\/(?:[0-9a-z-]+\.)?gyazo\.com\/[0-9a-f]{32}\]\]/,Rt=(e,t)=>{if(t.context==="table")return b(e,t);let r=e.substring(2,e.length-2),n=/^https?:\/\/([0-9a-z-]\.)?gyazo\.com\/[0-9a-f]{32}$/.test(r);return[{type:"strongImage",raw:e,src:n?${r}/thumb/1000:r}]},Nt=w(Rt,{parseOnNested:!1,parseOnQuoted:!0,patterns:[It,Pt]}),St=/\[[^[\]]*\.icon(?:\*[1-9]\d*)?\]/;function je(e){return(t,r)=>{if(e==="strongIcon"&&r.context==="table")return b(t,r);let n=e==="icon"?t.substring(1,t.length-1):t.substring(2,t.length-2),o=n.lastIndexOf(".icon"),s=n.substring(0,o),i=s.startsWith("/")?"root":"relative",a=n.substring(o+5,n.length),l=a.startsWith("*")?parseInt(a.substring(1),10):1;return new Array(l).fill({}).map(()=>({path:s,pathType:i,type:e,raw:t}))}}var Mt=je("icon"),Ot=w(Mt,{parseOnNested:!0,parseOnQuoted:!0,patterns:[St]}),Bt=/\[\[[^[\]]*\.icon(?:\*\d+)?\]\]/,Dt=je("strongIcon"),Ft=w(Dt,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Bt]}),jt=/\[\[(?:[^[]|\[[^[]).*?\]*\]\]/,Ut=(e,t)=>t.context==="table"?b(e,t):[{type:"strong",raw:e,nodes:C(e.substring(2,e.length-2),{...t,nested:!0})}],At=w(Ut,{parseOnNested:!1,parseOnQuoted:!0,patterns:[jt]}),$t=/\[\$ .+? \]/,qt=/\[\$ [^\]]+\]/,Ht=(e,t)=>t.context==="table"?b(e,t):[{type:"formula",raw:e,formula:e.substring(3,e.length-(e.endsWith(" ]")?2:1))}],_t=w(Ht,{parseOnNested:!1,parseOnQuoted:!0,patterns:[$t,qt]}),Kt=/\[[!"#%&'()*+,\-./{|}<>_~]+ (?:\[[^[\]]+\]|[^\]])+\]/,Gt=(e,t)=>{if(t.context==="table")return b(e,t);let r=e.indexOf(" "),n=e.substring(1,r),o=e.substring(r+1,e.length-1),s=new Set(n);if(s.has("*")){let i=n.split("*").length-1;s.delete("*"),s.add(*-${Math.min(i,10)})}return[{type:"decoration",raw:e,rawDecos:n,decos:Array.from(s),nodes:C(o,{...t,nested:!0})}]},zt=w(Gt,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Kt]}),Qt=/.*?/,Yt=(e,t)=>t.context==="table"?b(e,t):[{type:"code",raw:e,text:e.substring(1,e.length-1)}],Wt=w(Yt,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Qt]}),Jt=/^[$%] .+$/,Xt=(e,t)=>{var r;if(t.context==="table")return b(e,t);let n=(r=e[0])!==null&&r!==void 0?r:"",o=e.substring(2);return[{type:"commandLine",raw:e,symbol:n,text:o}]},Vt=w(Xt,{parseOnNested:!1,parseOnQuoted:!1,patterns:[Jt]}),Zt=/\[\s+\]/,er=(e,t)=>t.context==="table"?b(e,t):[{type:"blank",raw:e,text:e.substring(1,e.length-1)}],tr=w(er,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Zt]}),rr=/\[https?:\/\/[^\s\]]+\.(?:png|jpe?g|gif|svg)(?:\?[^\]\s]+)?(?:\s+https?:\/\/[^\s\]]+)?\]/i,nr=/\[https?:\/\/[^\s\]]+\s+https?:\/\/[^\s\]]+\.(?:png|jpe?g|gif|svg)(?:\?[^\]\s]+)?\]/i,or=/\[https?:\/\/(?:[0-9a-z-]+\.)?gyazo\.com\/[0-9a-f]{32}(?:\/raw)?(?:\s+https?:\/\/[^\s\]]+)?\]/,sr=/\[https?:\/\/[^\s\]]+\s+https?:\/\/(?:[0-9a-z-]+\.)?gyazo\.com\/[0-9a-f]{32}(?:\/raw)?\]/,ir=e=>/^https?:\/\/[^\s\]]+\.(png|jpe?g|gif|svg)(\?[^\]\s]+)?$/i.test(e)||ar(e),ar=e=>/^https?:\/\/([0-9a-z-]\.)?gyazo\.com\/[0-9a-f]{32}(\/raw)?$/.test(e),cr=(e,t)=>{if(t.context==="table")return b(e,t);let r=e.search(/\s/),n=r!==-1?e.substring(1,r):e.substring(1,e.length-1),o=r!==-1?e.substring(r,e.length-1).trimLeft():"",[s,i]=ir(o)?[o,n]:[n,o];return[{type:"image",raw:e,src:/^https?:\/\/([0-9a-z-]\.)?gyazo\.com\/[0-9a-f]{32}$/.test(s)?${s}/thumb/1000:s,link:i}]},pr=w(cr,{parseOnNested:!0,parseOnQuoted:!0,patterns:[rr,nr,or,sr]}),dr=/\[https?:\/\/[^\s\]]+\s+[^\]]*[^\s]\]/,lr=/\[[^[\]]*[^\s]\s+https?:\/\/[^\s\]]+\]/,ur=/\[https?:\/\/[^\s\]]+\]/,mr=/https?:\/\/[^\s]+/,fr=(e,t)=>{if(t.context==="table")return b(e,t);let r=e.startsWith("[")&&e.endsWith("]")?e.substring(1,e.length-1):e,n=/^https?:\/\/[^\s\]]/.test(r),o=(n?/^https?:\/\/[^\s\]]+/:/https?:\/\/[^\s\]]+$/).exec(r);if(o?.[0]===void 0)return[];let s=n?r.substring(o[0].length):r.substring(0,o.index-1);return[{type:"link",raw:e,pathType:"absolute",href:o[0],content:s.trim()}]},gr=w(fr,{parseOnNested:!0,parseOnQuoted:!0,patterns:[dr,lr,ur,mr]}),Ue=/\[([^\]]*[^\s])\s+([NS]\d+(?:\.\d+)?,[EW]\d+(?:\.\d+)?(?:,Z\d+)?)\]/,Ae=/\[([NS]\d+(?:\.\d+)?,[EW]\d+(?:\.\d+)?(?:,Z\d+)?)(?:\s+([^\]]*[^\s]))?\]/,hr=e=>{let[t="",r="",n=""]=e.split(","),o=parseFloat(t.replace(/^N/,"").replace(/^S/,"-")),s=parseFloat(r.replace(/^E/,"").replace(/^W/,"-")),i=/^Z\d+$/.test(n)?parseInt(n.replace(/^Z/,""),10):14;return{latitude:o,longitude:s,zoom:i}},xr=(e,t)=>{var r;if(t.context==="table")return b(e,t);let n=(r=e.match(Ue))!==null&&r!==void 0?r:e.match(Ae);if(n===null)return[];let o=e.startsWith("[N")||e.startsWith("[S"),[,s="",i=""]=o?n:[n[0],n[2],n[1]],{latitude:a,longitude:l,zoom:u}=hr(s),p=i!==""?https://www.google.com/maps/place/${encodeURIComponent(i)}/@${a},${l},${u}z:https://www.google.com/maps/@${a},${l},${u}z;return[{type:"googleMap",raw:e,latitude:a,longitude:l,zoom:u,place:i,url:p}]},yr=w(xr,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Ue,Ae]}),Er=/\[\/?[^[\]]+\]/,wr=e=>{let t=e.substring(1,e.length-1);return[{type:"link",raw:e,pathType:t.startsWith("/")?"root":"relative",href:t,content:""}]},br=w(wr,{parseOnNested:!0,parseOnQuoted:!0,patterns:[Er]}),vr=/(?:^|\s)#\S+/,kr=(e,t)=>{if(t.context==="table")return b(e,t);if(e.startsWith("#"))return[{type:"hashTag",raw:e,href:e.substring(1)}];let r=e.substring(0,1),n=e.substring(1);return[...b(r,t),{type:"hashTag",raw:n,href:n.substring(1)}]},Lr=w(kr,{parseOnNested:!0,parseOnQuoted:!0,patterns:[vr]}),Tr=/^[0-9]+\. .*$/,Cr=(e,t)=>{if(t.context==="table")return b(e,t);let r=e.indexOf(" "),n=e.substring(0,r-1),o=parseInt(n,10),s=e.substring(r+1,e.length);return[{type:"numberList",raw:e,rawNumber:n,number:o,nodes:C(s,{...t,nested:!0})}]},Ir=w(Cr,{parseOnNested:!1,parseOnQuoted:!1,patterns:[Tr]}),Pr=(e,t,r)=>{var n;return e===""?[]:(n=r?.())!==null&&n!==void 0?n:[]},Rr=(...e)=>(t,r)=>e.reduceRight((n,o)=>()=>o(t,r,n),()=>wt(t,r))(),C=Rr(Pr,kt,Ct,Wt,Vt,_t,tr,zt,Nt,Ft,At,pr,gr,Ot,yr,br,Lr,Ir),Nr=e=>{let{rows:[t,...r]}=e,{indent:n=0,text:o=""}=t??{},s=o.replace(/^\s*table:/,"");return{indent:n,type:"table",fileName:s,cells:r.map(i=>i.text.substring(n+1)).map(i=>i.split(" ").map(a=>C(a,{nested:!1,quoted:!1,context:"table"})))}},Sr=e=>{let{indent:t,text:r}=e.rows[0];return{indent:t,type:"line",nodes:C(r.substring(t),{nested:!1,quoted:!1,context:"line"})}},Mr=e=>{switch(e.type){case"title":return yt(e);case"codeBlock":return Et(e);case"table":return Nr(e);case"line":return Sr(e)}},Or=e=>e.split(
).map(t=>{var r,n,o;return{indent:(o=(n=(r=/^\s+/.exec(t))===null||r===void 0?void 0:r[0])===null||n===void 0?void 0:n.length)!==null&&o!==void 0?o:0,text:t}}),Br=(e,t)=>{var r,n;return(e.type==="codeBlock"||e.type==="table")&&t.indent>((n=(r=e.rows[0])===null||r===void 0?void 0:r.indent)!==null&&n!==void 0?n:0)},Fe=(e,t)=>{let r=e[e.length-1];return r!==void 0&&Br(r,t)?(r.rows.push(t),e):(e.push({type:/^\s*code:/.test(t.text)?"codeBlock":/^\s*table:/.test(t.text)?"table":"line",rows:[t]}),e)},Dr=(e,t)=>{var r;if(!((r=t.hasTitle)!==null&&r!==void 0)||r){let[n,...o]=e;return n===void 0?[]:[{type:"title",rows:[n]},...o.reduce(Fe,[])]}return e.reduce(Fe,[])},$e=(e,t)=>{var r;let n=Or(e);return Dr(n,{hasTitle:(r=t?.hasTitle)!==null&&r!==void 0?r:!0}).map(Mr)};var Fr=/https?:\/\/(?:www\.|music\.|)youtube\.com\/watch/,jr=/https?:\/\/youtu\.be\/([a-zA-Z\d_-]+)(?:\?([^\s]{0,100})|)/,Ur=/https?:\/\/(?:www\.|)youtube\.com\/shorts\/([a-zA-Z\d_-]+)(?:\?([^\s]+)|)/,Ar=/https?:\/\/(?:www\.|music\.|)youtube\.com\/playlist\?((?:[^\s]+&|)list=([a-zA-Z\d_-]+)(?:&[^\s]+|))/,re=e=>{if(Fr.test(e)){let t=new URL(e).searchParams,r=t.get("v");if(r)return{pathType:"com",videoId:r,params:t}}{let t=e.match(jr);if(t){let[,r,n]=t;return{videoId:r,params:new URLSearchParams(n),pathType:"dotbe"}}}{let t=e.match(Ur);if(t){let[,r,n]=t;return{videoId:r,params:new URLSearchParams(n),pathType:"short"}}}{let t=e.match(Ar);if(t){let[,r,n]=t;return{listId:n,params:new URLSearchParams(r),pathType:"list"}}}};var He=e=>{let t=$e(e,{hasTitle:!0}).flatMap(d=>{switch(d.type){case"codeBlock":case"title":return[];case"line":case"table":return d}}),r=new Map,n=[],o=new Set,s=[],i=new Set,a=[],l=null,u=new Set,p=new Set,m=new RegExp(${location?.origin??"https://scrapbox.io"}/files/([a-z0-9]{24})(?:|\\.[a-zA-Z0-9]+)(?:|\\?[^\\s]*)$),g=d=>{switch(d.type){case"hashTag":if(r.has(L(d.href)))return;r.set(L(d.href),!1),n.push(d.href);return;case"link":switch(d.pathType){case"relative":{let c=qe(d.href);if(r.get(L(c)))return;r.set(L(c),!0),n.push(c);return}case"root":{let c=qe(d.href);if(/^\/[\w\d-]+\/?$/.test(c)||o.has(L(c)))return;o.add(L(c)),s.push(c);return}case"absolute":{if(d.content)return;let c=re(d.href);if(c&&c.pathType!=="list"){l??=https://i.ytimg.com/vi/${c.videoId}/mqdefault.jpg;return}let h=d.href.match(m)?.[1];h&&u.add(h);return}default:return}case"icon":case"strongIcon":{if(d.pathType==="root"||i.has(L(d.path)))return;i.add(L(d.path)),a.push(d.path);return}case"image":case"strongImage":{l??=d.src.endsWith("/thumb/1000")?d.src.replace(/\/thumb\/1000$/,"/raw"):d.src;{let c=d.src.match(m)?.[1];c&&u.add(c)}if(d.type==="image"){let c=d.link.match(m)?.[1];c&&u.add(c)}return}case"helpfeel":p.add(d.text);return;case"numberList":case"strong":case"quote":case"decoration":{for(let c of d.nodes)g(c);return}default:return}},v=[];for(let d of t)switch(d.type){case"line":for(let c of d.nodes)g(c);continue;case"table":{for(let c of d.cells)for(let h of c)for(let E of h)g(E);if(!["infobox","cosense"].includes(d.fileName))continue;v.push(...d.cells.map(c=>c.map(h=>h.map(E=>E.raw).join("")).join(" ").trim()));continue}}return[n,s,a,l,[...u],[...p],v]},qe=e=>e.replace(/#[a-f\d]{24,32}$/,""),_e=e=>e.flatMap(({text:t})=>/^\s*\? .*$/.test(t)?[t.trimStart().slice(2)]:[]);var R=(e,t)=>e.length===t.length&&e.every(r=>t.includes(r));function*Ke(e,t,r){let n=t.flatMap(v=>v.split(
));for(let v of te(e.lines,n,{userId:r}))yield v;(e.lines[0].text!==n[0]||!e.persistent)&&(yield{title:n[0]});let o=e.lines.slice(1,6).map(v=>v.text),s=n.slice(1,6);o.join("")!==s.join("")&&(yield{descriptions:s});let[i,a,l,u,p,m,g]=He(n.join(
));R(e.links,i)||(yield{links:i}),R(e.projectLinks,a)||(yield{projectLinks:a}),R(e.icons,l)||(yield{icons:l}),e.image!==u&&(yield{image:u}),R(e.files,p)||(yield{files:p}),R(_e(e.lines),m)||(yield{helpfeels:m}),R(e.infoboxDefinition,g)||(yield{infoboxDefinition:g})}var I=async(e,t,r,n)=>{let[o,s,i]=await Promise.all([A(e,t),Z(e),De()]),a={...o,projectId:s,userId:i},l=n?.socket,u=l??await B();await J(u);try{let{request:p}=Y(u),m=0,g=[],v;for(;n?.maxAttempts===void 0||m<n.maxAttempts;){let d=r(a,m,g,v);if(g=d instanceof Promise?await d:d,m++,g.length===0)return{ok:!0,value:a.commitId};let c={kind:"page",projectId:s,pageId:a.id,parentId:a.commitId,userId:i,changes:g,cursor:null,freeze:!0};for(;;){let h=await p("socket.io-request",{method:"commit",data:c});if(h.ok)return a.commitId=h.value.commitId,{ok:!0,value:a.commitId};let E=h.value.name;if(E==="UnexpectedError"){let k=new Error;throw k.name=h.value.name,k.message=JSON.stringify(h.value),k}if(E==="TimeoutError"||E==="SocketIOError"){await P(3e3);break}E==="NotFastForwardError"&&(a={...await A(e,t),projectId:s,userId:i}),v=E}}return{ok:!1,value:{name:"RetryError",attempts:m,message:Retrying exceeded the maxAttempts (${m}).}}}finally{l||await M(u)}};var Ge=e=>{let t=e.match(/(.+?)(?:_(\d+))?$/),r=t?.[1]??e,n=t?.[2]?parseInt(t[2])+1:2;return${r}_${n}};var ne=(e,t,r,n)=>I(e,t,async(o,s,i,a)=>{if(a==="DuplicateTitleError"){let p=Ge(t);return i.map(m=>("title"in m&&(m.title=p),m))}let l=r(o.lines,{...o,attempts:s}),u=l instanceof Promise?await l:l;return u===void 0?[]:u.length===0?[{deleted:!0}]:[...Ke(o,u,o.userId)]},n);var oe=(e,t,r)=>I(e,t,n=>{if(n.pin>0||!n.persistent&&!(r?.create??!1))return[];let o=[{pin:$r()}];return n.persistent||o.unshift({title:t}),o},r),se=(e,t,r)=>I(e,t,n=>n.pin==0||!n.persistent?[]:[{pin:0}],r),$r=()=>Number.MAX_SAFE_INTEGER-Math.floor(Date.now()/1e3);async function*ie(e,t=0){let{count:r,pages:n}=await Hr(e,t);for(let o of n)o.pin!==0&&(yield o);(n.at(-1)?.pin??0)!==0&&(yield*ie(e,t+1e3))}var Hr=async(e,t)=>{let r=await O(e,{limit:1e3,skip:t});if(!r.ok){let n=new Error;throw n.name=r.value.name,n.message=r.value.message,n}return r.value};var jp=(e,t)=>{let r=t.interval??864e5,n=()=>scrapbox.Project.name===e?_r(e,r,t):Ye();n(),scrapbox.addListener("project:changed",n)},Qe,_r=async(e,t,r)=>{Ye(),await ze(e,new Date,r),Qe=setInterval(()=>ze(e,new Date,r),t)},Ye=()=>clearInterval(Qe),ze=async(e,t,{makeDiary:r,isOldDiary:n})=>{let{render:o,dispose:s}=z(),i;try{o({type:"spinner"},{type:"text",text:"unpin other diary pages..."}),i=await W();for await(let{title:p}of ie(e))n(p,t)&&await se(e,p,{socket:i});let{title:a,header:l,footer:u}=r(t);o({type:"spinner"},{type:"text",text:pin "/${e}/${a}"...}),await oe(e,a,{socket:i,create:!0}),o({type:"spinner"},{type:"text",text:format "/${e}/${a}"...}),await ne(e,a,p=>[p[0].text,...K(p.slice(1).map(m=>m.text),l,u)],{socket:i}),o({type:"check-circle"},{type:"text",text:Pinned "/${e}/${a}".})}catch(a){o({type:"exclamation-triangle"},{type:"text",text:a instanceof Error?${a.name} ${a.message}`:"Unknown error! (see developper console)"}),console.error(a)}finally{i&&await M(i),await P(1e3),s()}};export{jp as launch,ze as pinDiary};