@sebbo2002/vestaboard 3.2.0-develop.1 → 4.0.0-develop.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- "use strict";var E=Object.create;var O=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var N=(a,r)=>{for(var e in r)O(a,e,{get:r[e],enumerable:!0})},M=(a,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of v(r))!T.call(a,s)&&s!==e&&O(a,s,{get:()=>r[s],enumerable:!(t=B(r,s))||t.enumerable});return a};var L=(a,r,e)=>(e=a!=null?E(P(a)):{},M(r||!a||!a.__esModule?O(e,"default",{value:a,enumerable:!0}):e,a)),k=a=>M(O({},"__esModule",{value:!0}),a);var I={};N(I,{BOARD_LINES:()=>w,BOARD_LINE_LENGTH:()=>c,LocalAPI:()=>g,Message:()=>l,MessageWritePosition:()=>A,MultipleBoards:()=>m,ReadWriteAPI:()=>b,SubscriptionAPI:()=>y});module.exports=k(I);var x=L(require("grapheme-splitter"),1);var c=22,w=6,A=(t=>(t[t.CURRENT=0]="CURRENT",t[t.NO_SPACE_BETWEEN=1]="NO_SPACE_BETWEEN",t[t.NEXT_LINE=2]="NEXT_LINE",t))(A||{});var S=[[" ",[0]],["A",[1]],["a",[1]],["b",[2]],["B",[2]],["C",[3]],["c",[3]],["d",[4]],["e",[5]],["f",[6]],["g",[7]],["h",[8]],["i",[9]],["j",[10]],["k",[11]],["l",[12]],["m",[13]],["n",[14]],["o",[15]],["p",[16]],["q",[17]],["r",[18]],["s",[19]],["t",[20]],["u",[21]],["v",[22]],["w",[23]],["x",[24]],["y",[25]],["z",[26]],["D",[4]],["E",[5]],["F",[6]],["G",[7]],["H",[8]],["I",[9]],["J",[10]],["K",[11]],["L",[12]],["M",[13]],["N",[14]],["O",[15]],["P",[16]],["Q",[17]],["R",[18]],["S",[19]],["T",[20]],["U",[21]],["V",[22]],["W",[23]],["X",[24]],["Y",[25]],["Z",[26]],["1",[27]],["2",[28]],["3",[29]],["4",[30]],["5",[31]],["6",[32]],["7",[33]],["8",[34]],["9",[35]],["0",[36]],["!",[37]],["@",[38]],["#",[39]],["$",[40]],["(",[41]],[")",[42]],["-",[44]],["+",[46]],["&",[47]],["=",[48]],[";",[49]],[":",[50]],["'",[52]],['"',[53]],["%",[54]],[",",[55]],[".",[56]],["/",[59]],["?",[60]],["\xB0",[62]],["\u20AC",[5,21,18]],["\u0192",[6]],["\u017D",[26]],["\u0161",[19]],["\xBC",[27,59,30]],["\xBD",[27,59,28]],["\xBE",[29,59,30]],["\xC0",[1]],["\xC1",[1]],["\xC2",[1]],["\xC3",[1]],["\xC4",[1,5]],["\xC5",[1]],["\xC6",[1,5]],["\xC7",[3]],["\xC8",[5]],["\xC9",[5]],["\xCA",[5]],["\xCB",[5]],["\xCC",[9]],["\xCD",[9]],["\xCE",[9]],["\xCF",[9]],["\xD0",[5,20,8]],["\xD1",[14]],["\xD2",[15]],["\xD3",[15]],["\xD4",[15]],["\xD5",[15]],["\xD6",[15,5]],["\xD7",[24]],["\xD9",[21]],["\xDA",[21]],["\xDB",[21]],["\xDC",[21,5]],["\xDD",[25]],["\xDF",[19,19]],["\xE0",[1]],["\xE1",[1]],["\xE2",[1]],["\xE3",[1]],["\xE4",[1,5]],["\xE5",[1]],["\xE6",[1,5]],["\xE7",[3]],["\xE8",[5]],["\xE9",[5]],["\xEA",[5]],["\xEB",[5]],["\xEC",[9]],["\xED",[9]],["\xEE",[9]],["\xEF",[9]],["\xF0",[15]],["\xF1",[14]],["\xF2",[15]],["\xF3",[15]],["\xF4",[15]],["\xF5",[15]],["\xF6",[15,5]],["\xF9",[21]],["\xFA",[21]],["\xFB",[21]],["\xFC",[21,5]],["\xFD",[25]],["\xFF",[25]],["\u{1F7E5}",[63]],["\u{1F7E7}",[64]],["\u{1F7E8}",[65]],["\u{1F7E9}",[66]],["\u{1F7E6}",[67]],["\u{1F7EA}",[68]],["\u2B1C\uFE0F",[69]],["\u2B1C",[69]],["\u2B1B\uFE0F",[-2]],["\u2B1B",[-2]],["\uFE6B",[38]],["\uFF20",[38]],["0\uFE0F\u20E3",[36]],["1\uFE0F\u20E3",[27]],["2\uFE0F\u20E3",[28]],["3\uFE0F\u20E3",[29]],["4\uFE0F\u20E3",[30]],["5\uFE0F\u20E3",[31]],["6\uFE0F\u20E3",[32]],["7\uFE0F\u20E3",[33]],["8\uFE0F\u20E3",[34]],["9\uFE0F\u20E3",[35]],["\u2755",[37]],["\u203C\uFE0F",[37,37]],["\u2757\uFE0F",[37]],["\u2049\uFE0F",[37,60]],["#\uFE0F\u20E3",[39]],["\u{1F4B2}",[40]],["$",[40]],["\uFE69",[40]],["\uFF04",[40]],["\u2190",[44]],["\u2192",[44]],["\u27A1",[44]],["\u2B05",[44]],["\u2794",[44]],["\u2194",[44]],["\u2013",[44]],["\u2795",[46]],["+",[46]],["\uFE6A",[54]],["\uFF05",[54]],["\u2753",[60]],["\u2754",[60]],["\u2103",[62,3]],["\u2109",[62,6]]],C=new Array(w).fill(new Array(c).fill(0)),l=class a{static splitter=new x.default;board;cursor=[0,0];constructor(r){typeof r=="string"&&r?(this.board=JSON.parse(JSON.stringify(C)),this.write(r),this.center()):Array.isArray(r)?this.board=r:this.board=JSON.parse(JSON.stringify(C))}static string2chars(r,e={}){let t=[],s=a.splitter.splitGraphemes(r);for(let n of s)t.push(...this.char2char(n));return e.removeUnsupportedWords!==!1&&(t=a.removeEmojisFromChars(t)),t=t.map(n=>n>=0?n:n===-2?0:typeof e.fallbackChar=="number"?e.fallbackChar:e.fallbackChar===null?-1:60).filter(n=>n>=0),t}static char2char(r){let e=S.find(([t])=>r===t);return e&&Array.isArray(e[1])?e[1]:[-1]}static charToString(r){let e=Object.values(S).filter(([t])=>t.length<=2).find(([,t])=>t[0]===r);return e?e[0].toUpperCase()+(e[0].length===1?" ":""):"\u26A1\uFE0E "}static splitCharsIntoLines(r,e){let t=[];for(let n of r){t.length||t.push([null,[]]);let o=t[t.length-1];n===0?t.push([0,[]]):n===44?(o[1].push(n),t.push([null,[]])):o[1].push(n)}let s=[];for(let[n,o]of t){s.length||s.push([]);let u=s[s.length-1],i=e[s.length===1?0:1]-u.length;if(!u.length&&o.length<=i)u.push(...o);else if(n!==null&&o.length+1<=i)u.push(0,...o);else if(o.length<=i)u.push(...o);else if(o.length<=e[1])u=[...o],i=e[1],s.push(u);else{i>=3&&!u.length||(i>=4&&u.length?(u.push(0),i--):(u=[],i=e[1],s.push(u)));for(let h of o)u.push(h),i--,i<=1&&(u.push(44),u=[],i=e[1],s.push(u))}}return s}static removeEmojisFromChars(r){let e=[];for(let s of r)e.length||e.push([]),s===0?e.push([]):e[e.length-1].push(s);e.forEach(s=>{if(s.length>0&&s[0]===-1)for(;s[0]<0;)s.splice(0,1);if(s.length>0&&s[s.length-1]===-1)for(;s.length>0&&s[s.length-1]<0;)s.splice(s.length-1,1)});let t=[];return e.filter(s=>s.length>0).forEach(s=>{t.length!==0&&t.push(0),t.push(...s)}),t}static getColumnSizesFromData(r,e={}){if(!r.length)return[];let t=r[0].length,s=[];r.forEach((h,p)=>{if(h.length!==t)throw new Error(`Unable to render table: Row ${p} has ${h.length} entries, but first row has ${t}!`);h.forEach((f,R)=>{s[R]=Math.max(s[R]||0,this.string2chars(f,e).length)})});let n=s.reduce((h,p)=>h+p,0),o=r[0].length-1,u=Math.max((c-o)/n,1),i=s.map(h=>Math.round(h*u));for(;;){let h=i.reduce((R,q)=>R+q,0)+o;if(h===c)break;let p=c-h<0?-1:1,f=i.indexOf(p<0?Math.max(...i):Math.min(...i));if(f<0)throw new Error("Unable to find max value in array\u2026");i[f]+=p}return i}get isEmpty(){return!this.board.find(r=>r.find(e=>e!==0))}fill(r=" "){let e=0,t=a.string2chars(r,{removeUnsupportedWords:!1});return this.board.forEach(s=>{s.forEach((n,o)=>{s[o]=t[e],e++,e>t.length-1&&(e=0)})}),this}write(r,e={}){if(!this.board[this.cursor[0]])return this;e.position===2&&(this.cursor[0]!==0||this.cursor[1]!==0)?(this.cursor[0]++,this.cursor[1]=0):typeof e.position=="object"&&(this.cursor[0]=e.position.line,this.cursor[1]=e.position.row||0),(e.position===void 0||e.position===0)&&this.cursor[1]!==0&&this.cursor[1]<c-1&&(this.board[this.cursor[0]].splice(this.cursor[1],1,0),this.cursor[1]+=1);let t=0;e.indent===!0?t=this.cursor[1]:typeof e.indent=="number"&&e.indent>=0&&e.indent<=c-5&&(t=e.indent);let s=r.split(`
2
- `),n=!0;for(let o of s){let u=a.string2chars(o,e),i=[c-this.cursor[1],c-t];n||(this.cursor[0]++,this.cursor[1]=t),typeof e.position=="object"&&e.position.width&&(i[0]=Math.min(i[0],e.position.width),i[1]=Math.min(i[1],e.position.width-t));let h=a.splitCharsIntoLines(u,i);for(let p of h){if(!this.board[this.cursor[0]])break;this.board[this.cursor[0]].splice(this.cursor[1],p.length,...p),this.cursor[1]+=p.length,p!==h[h.length-1]&&(this.cursor[0]++,this.cursor[1]=t)}n=!1}return this}table(r){let e=a.getColumnSizesFromData(r);return(this.cursor[0]!==0||this.cursor[1]!==0)&&(this.cursor[0]++,this.cursor[1]=0),r.forEach(t=>{let s=this.cursor[0],n=1;t.forEach((o,u)=>{let i=e[u],h=e.filter((p,f)=>f<u).reduce((p,f)=>p+f+1,0);this.write(o,{position:{line:s,row:h,width:i},indent:h}),n=Math.max(n,this.cursor[0]-s+1)}),this.cursor[0]=s+n+1,this.cursor[1]=0}),this}center(){let r=[this.board.findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.slice().reverse().findIndex(s=>s!==0):t.length)),this.board.slice().reverse().findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.findIndex(s=>s!==0):t.length))],e=[Math.floor((r[0]+r[2])/2),Math.floor((r[1]+r[3])/2)];if(r[0]!==e[0]){let t=e[0]-r[0];this.board.splice(t>0?0:this.board.length,0,...this.board.splice(t>0?this.board.length-t:0,Math.abs(t)))}if(r[3]!==e[1]){let t=e[1]-r[3];this.board.forEach(s=>{s.splice(t>0?0:s.length,0,...s.splice(t>0?s.length-t:0,Math.abs(t)))})}}toString(){return"#="+"=".repeat(c*2)+`=#
1
+ "use strict";var E=Object.create;var O=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var N=(a,r)=>{for(var e in r)O(a,e,{get:r[e],enumerable:!0})},M=(a,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of v(r))!T.call(a,s)&&s!==e&&O(a,s,{get:()=>r[s],enumerable:!(t=B(r,s))||t.enumerable});return a};var L=(a,r,e)=>(e=a!=null?E(P(a)):{},M(r||!a||!a.__esModule?O(e,"default",{value:a,enumerable:!0}):e,a)),k=a=>M(O({},"__esModule",{value:!0}),a);var j={};N(j,{BOARD_LINES:()=>w,BOARD_LINE_LENGTH:()=>l,LocalAPI:()=>b,Message:()=>c,MessageWritePosition:()=>A,MultipleBoards:()=>y,ReadWriteAPI:()=>m,SubscriptionAPI:()=>g});module.exports=k(j);var x=L(require("grapheme-splitter"),1);async function d(a,r,e,t={}){let s=e===void 0?"GET":"POST";e!==void 0&&Object.assign(r,{"Content-Type":"application/json"});let n={method:s,headers:r};e!==void 0&&typeof e=="string"?n.body=e:e!==void 0&&(n.body=JSON.stringify(e));let o=null;for(let i=0;i<10&&(o=await(t.fetch||fetch)(a,n),!o.ok);i++)await new Promise(p=>setTimeout(p,1e3));if(!o?.ok)throw new Error("HTTP Request failed");return t.parseResponse===!1?void 0:await o.json()}var g=class{key;secret;options;constructor(r,e,t){this.key=r,this.secret=e,this.options=t||{}}async request(r,e){return d(`https://platform.vestaboard.com${r}`,{"X-Vestaboard-Api-Key":this.key,"X-Vestaboard-Api-Secret":this.secret},e,this.options)}async getViewer(){return await this.request("/viewer")}async getSubscriptions(){return await this.request("/subscriptions")}async postMessage(r,e){let t=!1,s=[],n=typeof r=="string"?new c(r):r;if(typeof e=="string")t=!0,s.push(e);else if(Array.isArray(e))s.push(...e);else{let u=await this.getSubscriptions();s.push(...u.subscriptions.map(i=>i._id))}let o=[];for(let u of s)o.push(await this.request(`/subscriptions/${u}/message`,{characters:n.toCharArray()}));return t?o[0]:o}};var m=class{key;options;constructor(r,e){this.key=r,this.options=e||{}}async request(r,e){return d(`https://rw.vestaboard.com${r}`,{"X-Vestaboard-Read-Write-Key":this.key},e,this.options)}async getCurrentMessage(){let r=await this.request("/");return new c(JSON.parse(r.currentMessage.layout))}async postMessage(r){let e=typeof r=="string"?new c(r):r;await this.request("/",JSON.stringify(e.toCharArray()))}};var l=22,w=6,A=(t=>(t[t.CURRENT=0]="CURRENT",t[t.NO_SPACE_BETWEEN=1]="NO_SPACE_BETWEEN",t[t.NEXT_LINE=2]="NEXT_LINE",t))(A||{});var S=[[" ",[0]],["A",[1]],["a",[1]],["b",[2]],["B",[2]],["C",[3]],["c",[3]],["d",[4]],["e",[5]],["f",[6]],["g",[7]],["h",[8]],["i",[9]],["j",[10]],["k",[11]],["l",[12]],["m",[13]],["n",[14]],["o",[15]],["p",[16]],["q",[17]],["r",[18]],["s",[19]],["t",[20]],["u",[21]],["v",[22]],["w",[23]],["x",[24]],["y",[25]],["z",[26]],["D",[4]],["E",[5]],["F",[6]],["G",[7]],["H",[8]],["I",[9]],["J",[10]],["K",[11]],["L",[12]],["M",[13]],["N",[14]],["O",[15]],["P",[16]],["Q",[17]],["R",[18]],["S",[19]],["T",[20]],["U",[21]],["V",[22]],["W",[23]],["X",[24]],["Y",[25]],["Z",[26]],["1",[27]],["2",[28]],["3",[29]],["4",[30]],["5",[31]],["6",[32]],["7",[33]],["8",[34]],["9",[35]],["0",[36]],["!",[37]],["@",[38]],["#",[39]],["$",[40]],["(",[41]],[")",[42]],["-",[44]],["+",[46]],["&",[47]],["=",[48]],[";",[49]],[":",[50]],["'",[52]],['"',[53]],["%",[54]],[",",[55]],[".",[56]],["/",[59]],["?",[60]],["\xB0",[62]],["\u20AC",[5,21,18]],["\u0192",[6]],["\u017D",[26]],["\u0161",[19]],["\xBC",[27,59,30]],["\xBD",[27,59,28]],["\xBE",[29,59,30]],["\xC0",[1]],["\xC1",[1]],["\xC2",[1]],["\xC3",[1]],["\xC4",[1,5]],["\xC5",[1]],["\xC6",[1,5]],["\xC7",[3]],["\xC8",[5]],["\xC9",[5]],["\xCA",[5]],["\xCB",[5]],["\xCC",[9]],["\xCD",[9]],["\xCE",[9]],["\xCF",[9]],["\xD0",[5,20,8]],["\xD1",[14]],["\xD2",[15]],["\xD3",[15]],["\xD4",[15]],["\xD5",[15]],["\xD6",[15,5]],["\xD7",[24]],["\xD9",[21]],["\xDA",[21]],["\xDB",[21]],["\xDC",[21,5]],["\xDD",[25]],["\xDF",[19,19]],["\xE0",[1]],["\xE1",[1]],["\xE2",[1]],["\xE3",[1]],["\xE4",[1,5]],["\xE5",[1]],["\xE6",[1,5]],["\xE7",[3]],["\xE8",[5]],["\xE9",[5]],["\xEA",[5]],["\xEB",[5]],["\xEC",[9]],["\xED",[9]],["\xEE",[9]],["\xEF",[9]],["\xF0",[15]],["\xF1",[14]],["\xF2",[15]],["\xF3",[15]],["\xF4",[15]],["\xF5",[15]],["\xF6",[15,5]],["\xF9",[21]],["\xFA",[21]],["\xFB",[21]],["\xFC",[21,5]],["\xFD",[25]],["\xFF",[25]],["\u{1F7E5}",[63]],["\u{1F7E7}",[64]],["\u{1F7E8}",[65]],["\u{1F7E9}",[66]],["\u{1F7E6}",[67]],["\u{1F7EA}",[68]],["\u2B1C\uFE0F",[69]],["\u2B1C",[69]],["\u2B1B\uFE0F",[-2]],["\u2B1B",[-2]],["\uFE6B",[38]],["\uFF20",[38]],["0\uFE0F\u20E3",[36]],["1\uFE0F\u20E3",[27]],["2\uFE0F\u20E3",[28]],["3\uFE0F\u20E3",[29]],["4\uFE0F\u20E3",[30]],["5\uFE0F\u20E3",[31]],["6\uFE0F\u20E3",[32]],["7\uFE0F\u20E3",[33]],["8\uFE0F\u20E3",[34]],["9\uFE0F\u20E3",[35]],["\u2755",[37]],["\u203C\uFE0F",[37,37]],["\u2757\uFE0F",[37]],["\u2049\uFE0F",[37,60]],["#\uFE0F\u20E3",[39]],["\u{1F4B2}",[40]],["$",[40]],["\uFE69",[40]],["\uFF04",[40]],["\u2190",[44]],["\u2192",[44]],["\u27A1",[44]],["\u2B05",[44]],["\u2794",[44]],["\u2194",[44]],["\u2013",[44]],["\u2795",[46]],["+",[46]],["\uFE6A",[54]],["\uFF05",[54]],["\u2753",[60]],["\u2754",[60]],["\u2103",[62,3]],["\u2109",[62,6]]],C=new Array(w).fill(new Array(l).fill(0)),c=class a{static splitter=new x.default;board;cursor=[0,0];constructor(r){typeof r=="string"&&r?(this.board=JSON.parse(JSON.stringify(C)),this.write(r),this.center()):Array.isArray(r)?this.board=r:this.board=JSON.parse(JSON.stringify(C))}static string2chars(r,e={}){let t=[],s=a.splitter.splitGraphemes(r);for(let n of s)t.push(...this.char2char(n));return e.removeUnsupportedWords!==!1&&(t=a.removeEmojisFromChars(t)),t=t.map(n=>n>=0?n:n===-2?0:typeof e.fallbackChar=="number"?e.fallbackChar:e.fallbackChar===null?-1:60).filter(n=>n>=0),t}static char2char(r){let e=S.find(([t])=>r===t);return e&&Array.isArray(e[1])?e[1]:[-1]}static charToString(r){let e=Object.values(S).filter(([t])=>t.length<=2).find(([,t])=>t[0]===r);return e?e[0].toUpperCase()+(e[0].length===1?" ":""):"\u26A1\uFE0E "}static splitCharsIntoLines(r,e){let t=[];for(let n of r){t.length||t.push([null,[]]);let o=t[t.length-1];n===0?t.push([0,[]]):n===44?(o[1].push(n),t.push([null,[]])):o[1].push(n)}let s=[];for(let[n,o]of t){s.length||s.push([]);let u=s[s.length-1],i=e[s.length===1?0:1]-u.length;if(!u.length&&o.length<=i)u.push(...o);else if(n!==null&&o.length+1<=i)u.push(0,...o);else if(o.length<=i)u.push(...o);else if(o.length<=e[1])u=[...o],i=e[1],s.push(u);else{i>=3&&!u.length||(i>=4&&u.length?(u.push(0),i--):(u=[],i=e[1],s.push(u)));for(let p of o)u.push(p),i--,i<=1&&(u.push(44),u=[],i=e[1],s.push(u))}}return s}static removeEmojisFromChars(r){let e=[];for(let s of r)e.length||e.push([]),s===0?e.push([]):e[e.length-1].push(s);e.forEach(s=>{if(s.length>0&&s[0]===-1)for(;s[0]<0;)s.splice(0,1);if(s.length>0&&s[s.length-1]===-1)for(;s.length>0&&s[s.length-1]<0;)s.splice(s.length-1,1)});let t=[];return e.filter(s=>s.length>0).forEach(s=>{t.length!==0&&t.push(0),t.push(...s)}),t}static getColumnSizesFromData(r,e={}){if(!r.length)return[];let t=r[0].length,s=[];r.forEach((p,h)=>{if(p.length!==t)throw new Error(`Unable to render table: Row ${h} has ${p.length} entries, but first row has ${t}!`);p.forEach((f,R)=>{s[R]=Math.max(s[R]||0,this.string2chars(f,e).length)})});let n=s.reduce((p,h)=>p+h,0),o=r[0].length-1,u=Math.max((l-o)/n,1),i=s.map(p=>Math.round(p*u));for(;;){let p=i.reduce((R,q)=>R+q,0)+o;if(p===l)break;let h=l-p<0?-1:1,f=i.indexOf(h<0?Math.max(...i):Math.min(...i));if(f<0)throw new Error("Unable to find max value in array\u2026");i[f]+=h}return i}get isEmpty(){return!this.board.find(r=>r.find(e=>e!==0))}fill(r=" "){let e=0,t=a.string2chars(r,{removeUnsupportedWords:!1});return this.board.forEach(s=>{s.forEach((n,o)=>{s[o]=t[e],e++,e>t.length-1&&(e=0)})}),this}write(r,e={}){if(!this.board[this.cursor[0]])return this;e.position===2&&(this.cursor[0]!==0||this.cursor[1]!==0)?(this.cursor[0]++,this.cursor[1]=0):typeof e.position=="object"&&(this.cursor[0]=e.position.line,this.cursor[1]=e.position.row||0),(e.position===void 0||e.position===0)&&this.cursor[1]!==0&&this.cursor[1]<l-1&&(this.board[this.cursor[0]].splice(this.cursor[1],1,0),this.cursor[1]+=1);let t=0;e.indent===!0?t=this.cursor[1]:typeof e.indent=="number"&&e.indent>=0&&e.indent<=l-5&&(t=e.indent);let s=r.split(`
2
+ `),n=!0;for(let o of s){let u=a.string2chars(o,e),i=[l-this.cursor[1],l-t];n||(this.cursor[0]++,this.cursor[1]=t),typeof e.position=="object"&&e.position.width&&(i[0]=Math.min(i[0],e.position.width),i[1]=Math.min(i[1],e.position.width-t));let p=a.splitCharsIntoLines(u,i);for(let h of p){if(!this.board[this.cursor[0]])break;this.board[this.cursor[0]].splice(this.cursor[1],h.length,...h),this.cursor[1]+=h.length,h!==p[p.length-1]&&(this.cursor[0]++,this.cursor[1]=t)}n=!1}return this}table(r){let e=a.getColumnSizesFromData(r);return(this.cursor[0]!==0||this.cursor[1]!==0)&&(this.cursor[0]++,this.cursor[1]=0),r.forEach(t=>{let s=this.cursor[0],n=1;t.forEach((o,u)=>{let i=e[u],p=e.filter((h,f)=>f<u).reduce((h,f)=>h+f+1,0);this.write(o,{position:{line:s,row:p,width:i},indent:p}),n=Math.max(n,this.cursor[0]-s+1)}),this.cursor[0]=s+n+1,this.cursor[1]=0}),this}center(){let r=[this.board.findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.slice().reverse().findIndex(s=>s!==0):t.length)),this.board.slice().reverse().findIndex(t=>t.find(s=>s!==0)),Math.min(...this.board.map(t=>t.find(s=>s!==0)?t.findIndex(s=>s!==0):t.length))],e=[Math.floor((r[0]+r[2])/2),Math.floor((r[1]+r[3])/2)];if(r[0]!==e[0]){let t=e[0]-r[0];this.board.splice(t>0?0:this.board.length,0,...this.board.splice(t>0?this.board.length-t:0,Math.abs(t)))}if(r[3]!==e[1]){let t=e[1]-r[3];this.board.forEach(s=>{s.splice(t>0?0:s.length,0,...s.splice(t>0?s.length-t:0,Math.abs(t)))})}}toString(){return"#="+"=".repeat(l*2)+`=#
3
3
  `+this.board.map(r=>"# "+r.map(e=>a.charToString(e)).join("")+` #
4
- `).join("")+"#="+"=".repeat(c*2)+`=#
5
- `}toCharArray(){return JSON.parse(JSON.stringify(this.board))}};async function d(a,r,e,t={}){let s=e===void 0?"GET":"POST";e!==void 0&&Object.assign(r,{"Content-Type":"application/json"});let n={method:s,headers:r};e!==void 0&&typeof e=="string"?n.body=e:e!==void 0&&(n.body=JSON.stringify(e));let o=null;for(let i=0;i<10&&(o=await(t.fetch||fetch)(a,n),!o.ok);i++)await new Promise(h=>setTimeout(h,1e3));if(!o?.ok)throw new Error("HTTP Request failed");return t.parseResponse===!1?void 0:await o.json()}var g=class{key;host;options;constructor(r,e,t){this.key=r,this.host=e||"vestaboard.local",this.options=t||{}}async request(r,e,t={}){return d(`http://${this.host}:7000/local-api/message`,{"X-Vestaboard-Local-Api-Key":this.key},e,Object.assign({},this.options,t))}async getCurrentMessage(){let r=await this.request("/");return new l(Array.isArray(r)?r:r.message)}async postMessage(r){let e=typeof r=="string"?new l(r):r;await this.request("/",JSON.stringify(e.toCharArray()),{parseResponse:!1})}};var m=class{boards;constructor(r=[]){this.boards=r}push(...r){r.forEach(e=>this.boards.push(e))}async postMessage(r){for(let e of this.boards)await e.postMessage(r)}};var b=class{key;options;constructor(r,e){this.key=r,this.options=e||{}}async request(r,e){return d(`https://rw.vestaboard.com${r}`,{"X-Vestaboard-Read-Write-Key":this.key},e,this.options)}async getCurrentMessage(){let r=await this.request("/");return new l(JSON.parse(r.currentMessage.layout))}async postMessage(r){let e=typeof r=="string"?new l(r):r;await this.request("/",JSON.stringify(e.toCharArray()))}};var y=class{key;secret;options;constructor(r,e,t){this.key=r,this.secret=e,this.options=t||{}}async request(r,e){return d(`https://platform.vestaboard.com${r}`,{"X-Vestaboard-Api-Key":this.key,"X-Vestaboard-Api-Secret":this.secret},e,this.options)}async getViewer(){return await this.request("/viewer")}async getSubscriptions(){return await this.request("/subscriptions")}async postMessage(r,e){let t=!1,s=[],n=typeof r=="string"?new l(r):r;if(typeof e=="string")t=!0,s.push(e);else if(Array.isArray(e))s.push(...e);else{let u=await this.getSubscriptions();s.push(...u.subscriptions.map(i=>i._id))}let o=[];for(let u of s)o.push(await this.request(`/subscriptions/${u}/message`,{characters:n.toCharArray()}));return t?o[0]:o}};0&&(module.exports={BOARD_LINES,BOARD_LINE_LENGTH,LocalAPI,Message,MessageWritePosition,MultipleBoards,ReadWriteAPI,SubscriptionAPI});
4
+ `).join("")+"#="+"=".repeat(l*2)+`=#
5
+ `}toCharArray(){return JSON.parse(JSON.stringify(this.board))}};var b=class{key;host;options;constructor(r,e,t){this.key=r,this.host=e||"vestaboard.local",this.options=t||{}}async request(r,e,t={}){return d(`http://${this.host}:7000/local-api/message`,{"X-Vestaboard-Local-Api-Key":this.key},e,Object.assign({},this.options,t))}async getCurrentMessage(){let r=await this.request("/");return new c(Array.isArray(r)?r:r.message)}async postMessage(r){let e=typeof r=="string"?new c(r):r;await this.request("/",JSON.stringify(e.toCharArray()),{parseResponse:!1})}};var y=class{boards;constructor(r=[]){this.boards=r}push(...r){r.forEach(e=>this.boards.push(e))}async postMessage(r){for(let e of this.boards)await e.postMessage(r)}};0&&(module.exports={BOARD_LINES,BOARD_LINE_LENGTH,LocalAPI,Message,MessageWritePosition,MultipleBoards,ReadWriteAPI,SubscriptionAPI});
6
6
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/message.ts","../src/types.ts","../src/tools.ts","../src/local-api.ts","../src/multiple-boards.ts","../src/read-write-api.ts","../src/subscription-api.ts"],"sourcesContent":["export { default as LocalAPI } from './local-api.js';\nexport { default as Message } from './message.js';\nexport { default as MultipleBoards } from './multiple-boards.js';\nexport { default as ReadWriteAPI } from './read-write-api.js';\nexport { default as SubscriptionAPI } from './subscription-api.js';\nexport {\n BOARD_LINE_LENGTH,\n BOARD_LINES,\n BoardCharLine,\n BoardCharArray,\n MessageWriteCoords,\n MessageWritePosition,\n MessageWriteOptions,\n Installation,\n Viewer,\n Subscription,\n Subscriptions,\n SubscriptionPostResponse,\n RequestOptions,\n Boards\n} from './types.js';\n","import GraphemeSplitter from 'grapheme-splitter';\nimport { BOARD_LINE_LENGTH, BOARD_LINES, BoardCharArray, MessageWriteOptions, MessageWritePosition } from './types.js';\n\n\n/**\n * Map with all supported characters plus a few emojis\n * mapped to corresponding characters of the Vestaboard\n */\nexport const CHAR_MAP: Array<[string, number[]]> = [\n [' ', [0]],\n ['A', [1]],\n ['a', [1]],\n ['b', [2]],\n ['B', [2]],\n ['C', [3]],\n ['c', [3]],\n ['d', [4]],\n ['e', [5]],\n ['f', [6]],\n ['g', [7]],\n ['h', [8]],\n ['i', [9]],\n ['j', [10]],\n ['k', [11]],\n ['l', [12]],\n ['m', [13]],\n ['n', [14]],\n ['o', [15]],\n ['p', [16]],\n ['q', [17]],\n ['r', [18]],\n ['s', [19]],\n ['t', [20]],\n ['u', [21]],\n ['v', [22]],\n ['w', [23]],\n ['x', [24]],\n ['y', [25]],\n ['z', [26]],\n ['D', [4]],\n ['E', [5]],\n ['F', [6]],\n ['G', [7]],\n ['H', [8]],\n ['I', [9]],\n ['J', [10]],\n ['K', [11]],\n ['L', [12]],\n ['M', [13]],\n ['N', [14]],\n ['O', [15]],\n ['P', [16]],\n ['Q', [17]],\n ['R', [18]],\n ['S', [19]],\n ['T', [20]],\n ['U', [21]],\n ['V', [22]],\n ['W', [23]],\n ['X', [24]],\n ['Y', [25]],\n ['Z', [26]],\n ['1', [27]],\n ['2', [28]],\n ['3', [29]],\n ['4', [30]],\n ['5', [31]],\n ['6', [32]],\n ['7', [33]],\n ['8', [34]],\n ['9', [35]],\n ['0', [36]],\n ['!', [37]],\n ['@', [38]],\n ['#', [39]],\n ['$', [40]],\n ['(', [41]],\n [')', [42]],\n ['-', [44]],\n ['+', [46]],\n ['&', [47]],\n ['=', [48]],\n [';', [49]],\n [':', [50]],\n ['\\'', [52]],\n ['\"', [53]],\n ['%', [54]],\n [',', [55]],\n ['.', [56]],\n ['/', [59]],\n ['?', [60]],\n ['°', [62]],\n ['€', [5, 21, 18]],\n ['ƒ', [6]],\n ['Ž', [26]],\n ['š', [19]],\n ['¼', [27, 59, 30]],\n ['½', [27, 59, 28]],\n ['¾', [29, 59, 30]],\n ['À', [1]],\n ['Á', [1]],\n ['Â', [1]],\n ['Ã', [1]],\n ['Ä', [1, 5]],\n ['Å', [1]],\n ['Æ', [1, 5]],\n ['Ç', [3]],\n ['È', [5]],\n ['É', [5]],\n ['Ê', [5]],\n ['Ë', [5]],\n ['Ì', [9]],\n ['Í', [9]],\n ['Î', [9]],\n ['Ï', [9]],\n ['Ð', [5, 20, 8]],\n ['Ñ', [14]],\n ['Ò', [15]],\n ['Ó', [15]],\n ['Ô', [15]],\n ['Õ', [15]],\n ['Ö', [15, 5]],\n ['×', [24]],\n ['Ù', [21]],\n ['Ú', [21]],\n ['Û', [21]],\n ['Ü', [21, 5]],\n ['Ý', [25]],\n ['ß', [19, 19]],\n ['à', [1]],\n ['á', [1]],\n ['â', [1]],\n ['ã', [1]],\n ['ä', [1, 5]],\n ['å', [1]],\n ['æ', [1, 5]],\n ['ç', [3]],\n ['è', [5]],\n ['é', [5]],\n ['ê', [5]],\n ['ë', [5]],\n ['ì', [9]],\n ['í', [9]],\n ['î', [9]],\n ['ï', [9]],\n ['ð', [15]],\n ['ñ', [14]],\n ['ò', [15]],\n ['ó', [15]],\n ['ô', [15]],\n ['õ', [15]],\n ['ö', [15, 5]],\n ['ù', [21]],\n ['ú', [21]],\n ['û', [21]],\n ['ü', [21, 5]],\n ['ý', [25]],\n ['ÿ', [25]],\n ['🟥', [63]],\n ['🟧', [64]],\n ['🟨', [65]],\n ['🟩', [66]],\n ['🟦', [67]],\n ['🟪', [68]],\n ['⬜️', [69]],\n ['⬜', [69]],\n ['⬛️', [-2]],\n ['⬛', [-2]],\n ['﹫', [38]],\n ['@', [38]],\n ['0️⃣', [36]],\n ['1️⃣', [27]],\n ['2️⃣', [28]],\n ['3️⃣', [29]],\n ['4️⃣', [30]],\n ['5️⃣', [31]],\n ['6️⃣', [32]],\n ['7️⃣', [33]],\n ['8️⃣', [34]],\n ['9️⃣', [35]],\n ['❕', [37]],\n ['‼️', [37, 37]],\n ['❗️', [37]],\n ['⁉️', [37, 60]],\n ['#️⃣', [39]],\n ['💲', [40]],\n ['$', [40]],\n ['﹩', [40]],\n ['$', [40]],\n ['←', [44]],\n ['→', [44]],\n ['➡', [44]],\n ['⬅', [44]],\n ['➔', [44]],\n ['↔', [44]],\n ['–', [44]],\n ['➕', [46]],\n ['+', [46]],\n ['﹪', [54]],\n ['%', [54]],\n ['❓', [60]],\n ['❔', [60]],\n ['℃', [62, 3]],\n ['℉', [62, 6]]\n];\n\nconst EMPTY_BOARD: BoardCharArray = new Array(BOARD_LINES).fill(\n new Array(BOARD_LINE_LENGTH).fill(0)\n) as BoardCharArray;\n\n/**\n * You can build a message like this:\n *\n * ```javascript\n * import { Message } from '@sebbo2002/vestaboard';\n *\n * const myMessage = new Message('Hello World');\n *\n * // same as\n *\n * const myOtherMessage = new Message()\n * .write('Hello World')\n * .center();\n * ```\n */\nexport default class Message {\n private static readonly splitter = new GraphemeSplitter();\n private readonly board: BoardCharArray;\n private cursor = [0, 0];\n\n constructor (message?: BoardCharArray | string) {\n if(typeof message === 'string' && message) {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n this.write(message);\n this.center();\n }\n else if(Array.isArray(message)) {\n this.board = message;\n }\n else {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n }\n }\n\n static string2chars (word: string, options: MessageWriteOptions = {}): number[] {\n let chars: number[] = [];\n const singleCharStrings = Message.splitter.splitGraphemes(word);\n for (const char of singleCharStrings) {\n chars.push(...this.char2char(char));\n }\n\n // trim emoji words if not disabled\n if (options.removeUnsupportedWords !== false) {\n chars = Message.removeEmojisFromChars(chars);\n }\n\n // replace -1 with fallback char\n chars = chars.map(char => {\n if (char >= 0) {\n return char;\n } else if (char === -2) {\n return 0;\n } else if (typeof options.fallbackChar === 'number') {\n return options.fallbackChar;\n } else if (options.fallbackChar === null) {\n return -1;\n } else {\n return 60;\n }\n }).filter(char => char >= 0);\n\n return chars;\n }\n\n static char2char (char: string): number[] {\n const fromMap = CHAR_MAP\n .find(([mapChar]) => char === mapChar);\n\n if (fromMap && Array.isArray(fromMap[1])) {\n return fromMap[1];\n }\n\n return [-1];\n }\n\n static charToString (char: number): string {\n const entry = Object.values(CHAR_MAP)\n .filter(([name]) => name.length <= 2)\n .find(([, code]) => code[0] === char);\n\n if (entry) {\n return entry[0].toUpperCase() + (entry[0].length === 1 ? ' ' : '');\n }\n\n return '⚡︎ ';\n }\n\n static splitCharsIntoLines (chars: number[], lineLength: [number, number]): Array<number[]> {\n // Array with splitting char (if any) and chars of the word\n const words: Array<[number | null, number[]]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([null, []]);\n }\n\n const currentWord = words[words.length - 1];\n if (char === 0) {\n words.push([0, []]);\n } else if (char === 44) {\n currentWord[1].push(char);\n words.push([null, []]);\n } else {\n currentWord[1].push(char);\n }\n }\n\n const lines: Array<number[]> = [];\n for (const [separator, word] of words) {\n if (!lines.length) {\n lines.push([]);\n }\n\n let currentLine = lines[lines.length - 1];\n let charsLeft = lineLength[lines.length === 1 ? 0 : 1] - currentLine.length;\n\n // start of line, word fits\n if (!currentLine.length && word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // add separator and the whole word\n else if (separator !== null && word.length + 1 <= charsLeft) {\n currentLine.push(0, ...word);\n } else if (word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // no space for the word, write into next line\n else if (word.length <= lineLength[1]) {\n currentLine = [...word];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n // word too long for one line, start in\n // current line and continue in next line\n else {\n if (charsLeft >= 3 && !currentLine.length) {\n // No space required in front of long word\n } else if (charsLeft >= 4 && currentLine.length) {\n // Add space for next word\n currentLine.push(0);\n charsLeft--;\n } else {\n // No enough space for word, go to next line\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n for (const char of word) {\n currentLine.push(char);\n charsLeft--;\n\n if (charsLeft <= 1) {\n currentLine.push(44);\n\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n }\n }\n }\n\n return lines;\n }\n\n static removeEmojisFromChars (chars: number[]): number[] {\n const words: Array<number[]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([]);\n }\n\n if (char === 0) {\n words.push([]);\n } else {\n words[words.length - 1].push(char);\n }\n }\n\n words.forEach(chars => {\n if (chars.length > 0 && chars[0] === -1) {\n while (chars[0] < 0) {\n chars.splice(0, 1);\n }\n }\n if (chars.length > 0 && chars[chars.length - 1] === -1) {\n while (chars.length > 0 && chars[chars.length - 1] < 0) {\n chars.splice(chars.length - 1, 1);\n }\n }\n });\n\n const result: number[] = [];\n words\n .filter(chars => chars.length > 0)\n .forEach(chars => {\n if (result.length !== 0) {\n result.push(0);\n }\n\n result.push(...chars);\n });\n\n return result;\n }\n\n static getColumnSizesFromData (rows: Array<string[]>, options: MessageWriteOptions = {}): number[] {\n if (!rows.length) {\n return [];\n }\n\n const columns = rows[0].length;\n const columnDefaultSizes: number[] = [];\n rows.forEach((row, rowIndex) => {\n if (row.length !== columns) {\n throw new Error(`Unable to render table: Row ${rowIndex} has ${row.length} entries, but first row has ${columns}!`);\n }\n row.forEach((column, columnIndex) => {\n columnDefaultSizes[columnIndex] = Math.max(columnDefaultSizes[columnIndex] || 0, this.string2chars(column, options).length);\n });\n });\n\n const columnDefaultSum = columnDefaultSizes.reduce((a, b) => a + b, 0);\n const columnBorders = rows[0].length - 1;\n const factor = Math.max((BOARD_LINE_LENGTH - columnBorders) / columnDefaultSum, 1);\n const columnSizes = columnDefaultSizes.map(size => Math.round(size * factor));\n\n while (true) {\n const size = columnSizes.reduce((a, b) => a + b, 0) + columnBorders;\n if (size === BOARD_LINE_LENGTH) {\n break;\n }\n\n const diff = BOARD_LINE_LENGTH - size < 0 ? -1 : 1;\n const index = columnSizes.indexOf(diff < 0 ? Math.max(...columnSizes) : Math.min(...columnSizes));\n if(index < 0) {\n // This can actually never be achieved...\n throw new Error('Unable to find max value in array…');\n }\n\n columnSizes[index] += diff;\n }\n\n\n return columnSizes;\n }\n\n get isEmpty (): boolean {\n return !this.board.find(line =>\n line.find(char => char !== 0)\n );\n }\n\n /**\n * Fills the board with the passed character or text. The text\n * is repeated again and again until the board is completely filled.\n */\n fill (text = ' '): this {\n let pointer = 0;\n const chars = Message.string2chars(text, {removeUnsupportedWords: false});\n this.board.forEach((line) => {\n line.forEach((char, charIndex) => {\n line[charIndex] = chars[pointer];\n pointer++;\n\n if(pointer > chars.length - 1) {\n pointer = 0;\n }\n });\n });\n return this;\n }\n\n /**\n * Write a text on your new message. If your message is not empty it will continue\n * where you last left off (`position: MessageWritePosition.CURRENT`). Alternatively\n * you can continue on the next line or give an exact position.\n *\n * @param text\n * @param options\n */\n write (text: string, options: MessageWriteOptions = {}): this {\n\n // Cursor blow board length? Just return…\n if (!this.board[this.cursor[0]]) {\n return this;\n }\n\n // Add new line if NEXT_LINE is set (except it's already in the first line)\n if (options.position === MessageWritePosition.NEXT_LINE && (this.cursor[0] !== 0 || this.cursor[1] !== 0)) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n // Set cursor to given position\n else if (typeof options.position === 'object') {\n this.cursor[0] = options.position.line;\n this.cursor[1] = options.position.row || 0;\n }\n\n // Add space before text as it\n // will be rendered in the same line\n if (\n (options.position === undefined || options.position === MessageWritePosition.CURRENT) &&\n this.cursor[1] !== 0 && this.cursor[1] < BOARD_LINE_LENGTH - 1\n ) {\n this.board[this.cursor[0]].splice(this.cursor[1], 1, 0);\n this.cursor[1] += 1;\n }\n\n // Figure out left indent\n let indent = 0;\n if (options.indent === true) {\n indent = this.cursor[1];\n } else if (typeof options.indent === 'number' && options.indent >= 0 && options.indent <= BOARD_LINE_LENGTH - 5) {\n indent = options.indent;\n }\n\n const linesOfText = text.split('\\n');\n let isFirstLine = true;\n for (const lineOfText of linesOfText) {\n const chars = Message.string2chars(lineOfText, options);\n const charsLeftInLine: [number, number] = [\n BOARD_LINE_LENGTH - this.cursor[1],\n BOARD_LINE_LENGTH - indent\n ];\n\n if(!isFirstLine) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n\n if(typeof options.position === 'object' && options.position.width) {\n charsLeftInLine[0] = Math.min(charsLeftInLine[0], options.position.width);\n charsLeftInLine[1] = Math.min(charsLeftInLine[1], options.position.width - indent);\n }\n\n const linesOfChars = Message.splitCharsIntoLines(chars, charsLeftInLine);\n for (const chars of linesOfChars) {\n\n // Board is over, skip line…\n if (!this.board[this.cursor[0]]) {\n break;\n }\n\n // Add chars to current line and update cursor\n this.board[this.cursor[0]].splice(this.cursor[1], chars.length, ...chars);\n this.cursor[1] += chars.length;\n\n // Add new line (and update cursor),\n // if this wasn't the last line\n if (chars !== linesOfChars[linesOfChars.length - 1]) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n }\n\n isFirstLine = false;\n }\n\n return this;\n }\n\n /**\n * Generate a table with the given data\n *\n * @example new Message().table([\n * ['now', 'Daily'],\n * ['13:00', 'Super Secret Meeting'],\n * ['16:30', 'Awesome Presentation']\n * ])\n *\n * #==============================================#\n * # N O W D A I L Y #\n * # #\n * # 1 3 : 0 0 S U P E R S E C R E T #\n * # M E E T I N G #\n * # #\n * # 1 6 : 3 0 A W E S O M E P R E S E N T - #\n * #==============================================#\n */\n table (rows: Array<string[]>): this {\n const columnWidths = Message.getColumnSizesFromData(rows);\n if (this.cursor[0] !== 0 || this.cursor[1] !== 0) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n rows.forEach(line => {\n const lineStart = this.cursor[0];\n let lineHeight = 1;\n\n line.forEach((column, columnIndex) => {\n const columnWidth = columnWidths[columnIndex];\n const indent = columnWidths\n .filter((width, index) => index < columnIndex)\n .reduce((a, b) => a + b + 1, 0);\n\n this.write(column, {\n position: {\n line: lineStart,\n row: indent,\n width: columnWidth\n },\n indent\n });\n\n lineHeight = Math.max(lineHeight, this.cursor[0] - lineStart + 1);\n });\n\n this.cursor[0] = lineStart + lineHeight + 1;\n this.cursor[1] = 0;\n });\n\n return this;\n }\n\n /**\n * Center the current message content\n */\n center(): void {\n const space = [\n this.board.findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.slice().reverse().findIndex(c => c !== 0) : l.length)),\n this.board.slice().reverse().findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.findIndex(c => c !== 0) : l.length)),\n ];\n\n const padding = [\n Math.floor((space[0] + space[2]) / 2),\n Math.floor((space[1] + space[3]) / 2)\n ];\n\n // Move up/down\n if(space[0] !== padding[0]) {\n const add = padding[0] - space[0];\n this.board.splice(add > 0 ? 0 : this.board.length, 0,\n ...this.board.splice(add > 0 ? this.board.length - add : 0, Math.abs(add))\n );\n }\n\n // Move left/right\n if(space[3] !== padding[1]) {\n const add = padding[1] - space[3];\n this.board.forEach(line => {\n line.splice(add > 0 ? 0 : line.length, 0,\n ...line.splice(add > 0 ? line.length - add : 0, Math.abs(add))\n );\n });\n }\n }\n\n toString (): string {\n return '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n' +\n this.board.map(line => '# ' + line.map(char =>\n Message.charToString(char)\n ).join('') + ' #\\n').join('') +\n '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n';\n }\n\n toCharArray (): BoardCharArray {\n return JSON.parse(JSON.stringify(this.board));\n }\n}\n","import SubscriptionAPI from './subscription-api.js';\nimport ReadWriteAPI from './read-write-api.js';\nimport LocalAPI from './local-api.js';\n\nexport const BOARD_LINE_LENGTH = 22;\nexport const BOARD_LINES = 6;\n\nexport type BoardCharLine = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number\n];\n\nexport type BoardCharArray = [\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine\n];\n\nexport interface MessageWriteCoords {\n line: number;\n row?: number;\n width?: number;\n}\n\nexport enum MessageWritePosition {\n CURRENT,\n NO_SPACE_BETWEEN,\n NEXT_LINE\n}\n\nexport interface MessageWriteOptions {\n position?: MessageWriteCoords | MessageWritePosition;\n indent?: boolean | number;\n fallbackChar?: number | null;\n removeUnsupportedWords?: boolean;\n}\n\nexport interface RequestFetchOptions {\n body?: string;\n headers?: Record<string, string>;\n method?: string;\n}\n\nexport interface RequestFetchResponse {\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n json(): Promise<unknown>;\n}\n\nexport type RequestOptionsFetch = (url: string, init?: RequestFetchOptions) => Promise<RequestFetchResponse>;\n\nexport interface RequestOptions {\n fetch?: RequestOptionsFetch;\n parseResponse?: boolean;\n}\n\nexport interface Installation {\n _id: string;\n installable?: {\n _id: string;\n };\n}\n\nexport interface Viewer {\n type: string;\n _id: string;\n _created: string;\n installation: {\n _id: string;\n };\n}\n\nexport interface Subscription {\n _id: string;\n _created: string;\n installation: Installation;\n boards: Array<{_id: string}>;\n}\n\nexport interface Subscriptions {\n subscriptions: Subscription[];\n}\n\nexport interface SubscriptionPostResponse {\n message: {\n id: string;\n created: number;\n }\n}\n\nexport interface ReadWriteGetMessageResponse {\n currentMessage: {\n layout: string;\n }\n}\n\nexport type Boards = Array<LocalAPI | ReadWriteAPI | SubscriptionAPI>;\n","import { RequestFetchOptions, RequestFetchResponse, RequestOptions } from './types.js';\n\nexport async function request<T> (\n url: string,\n headers: Record<string, string>,\n data?: Record<string, unknown> | string,\n options: RequestOptions = {}\n): Promise<T> {\n const method = data === undefined ? 'GET' : 'POST';\n if (data !== undefined) {\n Object.assign(headers, {\n 'Content-Type': 'application/json'\n });\n }\n\n const init: RequestFetchOptions = {\n method,\n headers\n };\n if(data !== undefined && typeof data === 'string') {\n init.body = data;\n }\n else if(data !== undefined) {\n init.body = JSON.stringify(data);\n }\n\n let response: RequestFetchResponse | null = null;\n for (let i = 0; i < 10; i++) {\n response = await (options.fetch || fetch)(url, init);\n if(response.ok) {\n break;\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n\n if(!response?.ok) {\n throw new Error('HTTP Request failed');\n }\n\n if(options.parseResponse === false) {\n return undefined as unknown as T;\n }\n\n const json = await response.json();\n return json as T;\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { BoardCharArray, RequestOptions } from './types.js';\n\nexport default class LocalAPI {\n private readonly key: string;\n private readonly host: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, host?: string, options?: RequestOptions) {\n this.key = key;\n this.host = host || 'vestaboard.local';\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string, options: RequestOptions = {}): Promise<T> {\n return request(`http://${this.host}:7000/local-api/message`, {\n 'X-Vestaboard-Local-Api-Key': this.key\n }, data, Object.assign({}, this.options, options));\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<{message: BoardCharArray} | BoardCharArray>('/');\n return new Message(Array.isArray(response) ? response : response.message);\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray()),\n { parseResponse: false }\n );\n }\n}\n","import { Boards } from './types.js';\nimport Message from './message.js';\n\nexport default class MultipleBoards {\n private readonly boards: Boards;\n\n constructor (boards: Boards = []) {\n this.boards = boards;\n }\n\n push(...boards: Boards): void {\n boards.forEach(board => this.boards.push(board));\n }\n\n async postMessage (message: Message | string): Promise<void> {\n for(const board of this.boards) {\n await board.postMessage(message);\n }\n }\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { ReadWriteGetMessageResponse, RequestOptions } from './types.js';\n\nexport default class ReadWriteAPI {\n private readonly key: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, options?: RequestOptions) {\n this.key = key;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string): Promise<T> {\n return request(`https://rw.vestaboard.com${path}`, {\n 'X-Vestaboard-Read-Write-Key': this.key\n }, data, this.options);\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<ReadWriteGetMessageResponse>('/');\n return new Message(JSON.parse(response.currentMessage.layout));\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray())\n );\n }\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { SubscriptionPostResponse, Subscriptions, Viewer } from './types.js';\nimport { RequestOptions } from './types.js';\n\nexport default class SubscriptionAPI {\n private readonly key: string;\n private readonly secret: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, secret: string, options?: RequestOptions) {\n this.key = key;\n this.secret = secret;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: Record<string, unknown>): Promise<T> {\n return request(`https://platform.vestaboard.com${path}`, {\n 'X-Vestaboard-Api-Key': this.key,\n 'X-Vestaboard-Api-Secret': this.secret\n }, data, this.options);\n }\n\n async getViewer (): Promise<Viewer> {\n return await this.request<Viewer>('/viewer');\n }\n\n async getSubscriptions (): Promise<Subscriptions> {\n return await this.request<Subscriptions>('/subscriptions');\n }\n\n async postMessage (message: Message | string): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionId: string): Promise<SubscriptionPostResponse>;\n async postMessage (message: Message | string, subscriptionIds: string[]): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionIds?: string | string[]) {\n let singleMode = false;\n const ids: string[] = [];\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n\n if (typeof subscriptionIds === 'string') {\n singleMode = true;\n ids.push(subscriptionIds);\n } else if (Array.isArray(subscriptionIds)) {\n ids.push(...subscriptionIds);\n } else {\n const subscriptions = await this.getSubscriptions();\n ids.push(...subscriptions.subscriptions.map(subscription => subscription._id));\n }\n\n const results: SubscriptionPostResponse[] = [];\n for (const id of ids) {\n results.push(\n await this.request<SubscriptionPostResponse>(`/subscriptions/${id}/message`, {\n characters: msgObj.toCharArray()\n })\n );\n }\n if (singleMode) {\n return results[0];\n }\n\n return results;\n }\n}"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,EAAA,sBAAAC,EAAA,aAAAC,EAAA,YAAAC,EAAA,yBAAAC,EAAA,mBAAAC,EAAA,iBAAAC,EAAA,oBAAAC,IAAA,eAAAC,EAAAV,GCAA,IAAAW,EAA6B,kCCItB,IAAMC,EAAoB,GACpBC,EAAc,EA0CfC,OACRA,IAAA,qBACAA,IAAA,uCACAA,IAAA,yBAHQA,OAAA,IDvCL,IAAMC,EAAsC,CAC/C,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAM,CAAC,EAAE,CAAC,EACX,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAG,GAAI,EAAE,CAAC,EACjB,CAAC,SAAK,CAAC,CAAC,CAAC,EACT,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,GAAI,EAAE,CAAC,EAClB,CAAC,OAAK,CAAC,GAAI,GAAI,EAAE,CAAC,EAClB,CAAC,OAAK,CAAC,GAAI,GAAI,EAAE,CAAC,EAClB,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,GAAI,CAAC,CAAC,EAChB,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,EAAE,CAAC,EACd,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,eAAM,CAAC,EAAE,CAAC,EACX,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,eAAM,CAAC,EAAE,CAAC,EACX,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,eAAM,CAAC,GAAI,EAAE,CAAC,EACf,CAAC,eAAM,CAAC,EAAE,CAAC,EACX,CAAC,eAAM,CAAC,GAAI,EAAE,CAAC,EACf,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,SAAK,CAAC,GAAI,CAAC,CAAC,CACjB,EAEMC,EAA8B,IAAI,MAAMC,CAAW,EAAE,KACvD,IAAI,MAAMC,CAAiB,EAAE,KAAK,CAAC,CACvC,EAiBqBC,EAArB,MAAqBC,CAAQ,CACzB,OAAwB,SAAW,IAAI,EAAAC,QACtB,MACT,OAAS,CAAC,EAAG,CAAC,EAEtB,YAAaC,EAAmC,CACzC,OAAOA,GAAY,UAAYA,GAC9B,KAAK,MAAQ,KAAK,MAAM,KAAK,UAAUN,CAAW,CAAC,EACnD,KAAK,MAAMM,CAAO,EAClB,KAAK,OAAO,GAER,MAAM,QAAQA,CAAO,EACzB,KAAK,MAAQA,EAGb,KAAK,MAAQ,KAAK,MAAM,KAAK,UAAUN,CAAW,CAAC,CAE3D,CAEA,OAAO,aAAcO,EAAcC,EAA+B,CAAC,EAAa,CAC5E,IAAIC,EAAkB,CAAC,EACjBC,EAAoBN,EAAQ,SAAS,eAAeG,CAAI,EAC9D,QAAWI,KAAQD,EACfD,EAAM,KAAK,GAAG,KAAK,UAAUE,CAAI,CAAC,EAItC,OAAIH,EAAQ,yBAA2B,KACnCC,EAAQL,EAAQ,sBAAsBK,CAAK,GAI/CA,EAAQA,EAAM,IAAIE,GACVA,GAAQ,EACDA,EACAA,IAAS,GACT,EACA,OAAOH,EAAQ,cAAiB,SAChCA,EAAQ,aACRA,EAAQ,eAAiB,KACzB,GAEA,EAEd,EAAE,OAAOG,GAAQA,GAAQ,CAAC,EAEpBF,CACX,CAEA,OAAO,UAAWE,EAAwB,CACtC,IAAMC,EAAUb,EACX,KAAK,CAAC,CAACc,CAAO,IAAMF,IAASE,CAAO,EAEzC,OAAID,GAAW,MAAM,QAAQA,EAAQ,CAAC,CAAC,EAC5BA,EAAQ,CAAC,EAGb,CAAC,EAAE,CACd,CAEA,OAAO,aAAcD,EAAsB,CACvC,IAAMG,EAAQ,OAAO,OAAOf,CAAQ,EAC/B,OAAO,CAAC,CAACgB,CAAI,IAAMA,EAAK,QAAU,CAAC,EACnC,KAAK,CAAC,CAAC,CAAEC,CAAI,IAAMA,EAAK,CAAC,IAAML,CAAI,EAExC,OAAIG,EACOA,EAAM,CAAC,EAAE,YAAY,GAAKA,EAAM,CAAC,EAAE,SAAW,EAAI,IAAM,IAG5D,eACX,CAEA,OAAO,oBAAqBL,EAAiBQ,EAA+C,CAExF,IAAMC,EAA0C,CAAC,EACjD,QAAWP,KAAQF,EAAO,CACjBS,EAAM,QACPA,EAAM,KAAK,CAAC,KAAM,CAAC,CAAC,CAAC,EAGzB,IAAMC,EAAcD,EAAMA,EAAM,OAAS,CAAC,EACtCP,IAAS,EACTO,EAAM,KAAK,CAAC,EAAG,CAAC,CAAC,CAAC,EACXP,IAAS,IAChBQ,EAAY,CAAC,EAAE,KAAKR,CAAI,EACxBO,EAAM,KAAK,CAAC,KAAM,CAAC,CAAC,CAAC,GAErBC,EAAY,CAAC,EAAE,KAAKR,CAAI,CAEhC,CAEA,IAAMS,EAAyB,CAAC,EAChC,OAAW,CAACC,EAAWd,CAAI,IAAKW,EAAO,CAC9BE,EAAM,QACPA,EAAM,KAAK,CAAC,CAAC,EAGjB,IAAIE,EAAcF,EAAMA,EAAM,OAAS,CAAC,EACpCG,EAAYN,EAAWG,EAAM,SAAW,EAAI,EAAI,CAAC,EAAIE,EAAY,OAGrE,GAAI,CAACA,EAAY,QAAUf,EAAK,QAAUgB,EACtCD,EAAY,KAAK,GAAGf,CAAI,UAInBc,IAAc,MAAQd,EAAK,OAAS,GAAKgB,EAC9CD,EAAY,KAAK,EAAG,GAAGf,CAAI,UACpBA,EAAK,QAAUgB,EACtBD,EAAY,KAAK,GAAGf,CAAI,UAInBA,EAAK,QAAUU,EAAW,CAAC,EAChCK,EAAc,CAAC,GAAGf,CAAI,EACtBgB,EAAYN,EAAW,CAAC,EACxBG,EAAM,KAAKE,CAAW,MAKrB,CACGC,GAAa,GAAK,CAACD,EAAY,SAExBC,GAAa,GAAKD,EAAY,QAErCA,EAAY,KAAK,CAAC,EAClBC,MAGAD,EAAc,CAAC,EACfC,EAAYN,EAAW,CAAC,EACxBG,EAAM,KAAKE,CAAW,IAG1B,QAAWX,KAAQJ,EACfe,EAAY,KAAKX,CAAI,EACrBY,IAEIA,GAAa,IACbD,EAAY,KAAK,EAAE,EAEnBA,EAAc,CAAC,EACfC,EAAYN,EAAW,CAAC,EACxBG,EAAM,KAAKE,CAAW,EAGlC,CACJ,CAEA,OAAOF,CACX,CAEA,OAAO,sBAAuBX,EAA2B,CACrD,IAAMS,EAAyB,CAAC,EAChC,QAAWP,KAAQF,EACVS,EAAM,QACPA,EAAM,KAAK,CAAC,CAAC,EAGbP,IAAS,EACTO,EAAM,KAAK,CAAC,CAAC,EAEbA,EAAMA,EAAM,OAAS,CAAC,EAAE,KAAKP,CAAI,EAIzCO,EAAM,QAAQT,GAAS,CACnB,GAAIA,EAAM,OAAS,GAAKA,EAAM,CAAC,IAAM,GACjC,KAAOA,EAAM,CAAC,EAAI,GACdA,EAAM,OAAO,EAAG,CAAC,EAGzB,GAAIA,EAAM,OAAS,GAAKA,EAAMA,EAAM,OAAS,CAAC,IAAM,GAChD,KAAOA,EAAM,OAAS,GAAKA,EAAMA,EAAM,OAAS,CAAC,EAAI,GACjDA,EAAM,OAAOA,EAAM,OAAS,EAAG,CAAC,CAG5C,CAAC,EAED,IAAMe,EAAmB,CAAC,EAC1B,OAAAN,EACK,OAAOT,GAASA,EAAM,OAAS,CAAC,EAChC,QAAQA,GAAS,CACVe,EAAO,SAAW,GAClBA,EAAO,KAAK,CAAC,EAGjBA,EAAO,KAAK,GAAGf,CAAK,CACxB,CAAC,EAEEe,CACX,CAEA,OAAO,uBAAwBC,EAAuBjB,EAA+B,CAAC,EAAa,CAC/F,GAAI,CAACiB,EAAK,OACN,MAAO,CAAC,EAGZ,IAAMC,EAAUD,EAAK,CAAC,EAAE,OAClBE,EAA+B,CAAC,EACtCF,EAAK,QAAQ,CAACG,EAAKC,IAAa,CAC5B,GAAID,EAAI,SAAWF,EACf,MAAM,IAAI,MAAM,+BAA+BG,CAAQ,QAAQD,EAAI,MAAM,+BAA+BF,CAAO,GAAG,EAEtHE,EAAI,QAAQ,CAACE,EAAQC,IAAgB,CACjCJ,EAAmBI,CAAW,EAAI,KAAK,IAAIJ,EAAmBI,CAAW,GAAK,EAAG,KAAK,aAAaD,EAAQtB,CAAO,EAAE,MAAM,CAC9H,CAAC,CACL,CAAC,EAED,IAAMwB,EAAmBL,EAAmB,OAAO,CAACM,EAAGC,IAAMD,EAAIC,EAAG,CAAC,EAC/DC,EAAgBV,EAAK,CAAC,EAAE,OAAS,EACjCW,EAAS,KAAK,KAAKlC,EAAoBiC,GAAiBH,EAAkB,CAAC,EAC3EK,EAAcV,EAAmB,IAAIW,GAAQ,KAAK,MAAMA,EAAOF,CAAM,CAAC,EAE5E,OAAa,CACT,IAAME,EAAOD,EAAY,OAAO,CAACJ,EAAGC,IAAMD,EAAIC,EAAG,CAAC,EAAIC,EACtD,GAAIG,IAASpC,EACT,MAGJ,IAAMqC,EAAOrC,EAAoBoC,EAAO,EAAI,GAAK,EAC3CE,EAAQH,EAAY,QAAQE,EAAO,EAAI,KAAK,IAAI,GAAGF,CAAW,EAAI,KAAK,IAAI,GAAGA,CAAW,CAAC,EAChG,GAAGG,EAAQ,EAEP,MAAM,IAAI,MAAM,yCAAoC,EAGxDH,EAAYG,CAAK,GAAKD,CAC1B,CAGA,OAAOF,CACX,CAEA,IAAI,SAAoB,CACpB,MAAO,CAAC,KAAK,MAAM,KAAKI,GACpBA,EAAK,KAAK9B,GAAQA,IAAS,CAAC,CAChC,CACJ,CAMA,KAAM+B,EAAO,IAAW,CACpB,IAAIC,EAAU,EACRlC,EAAQL,EAAQ,aAAasC,EAAM,CAAC,uBAAwB,EAAK,CAAC,EACxE,YAAK,MAAM,QAASD,GAAS,CACzBA,EAAK,QAAQ,CAAC9B,EAAMiC,IAAc,CAC9BH,EAAKG,CAAS,EAAInC,EAAMkC,CAAO,EAC/BA,IAEGA,EAAUlC,EAAM,OAAS,IACxBkC,EAAU,EAElB,CAAC,CACL,CAAC,EACM,IACX,CAUA,MAAOD,EAAclC,EAA+B,CAAC,EAAS,CAG1D,GAAI,CAAC,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAC1B,OAAO,KAIPA,EAAQ,WAAa,IAAmC,KAAK,OAAO,CAAC,IAAM,GAAK,KAAK,OAAO,CAAC,IAAM,IACnG,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAI,GAIZ,OAAOA,EAAQ,UAAa,WACjC,KAAK,OAAO,CAAC,EAAIA,EAAQ,SAAS,KAClC,KAAK,OAAO,CAAC,EAAIA,EAAQ,SAAS,KAAO,IAMxCA,EAAQ,WAAa,QAAaA,EAAQ,WAAa,IACxD,KAAK,OAAO,CAAC,IAAM,GAAK,KAAK,OAAO,CAAC,EAAIN,EAAoB,IAE7D,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,EAAG,EAAG,CAAC,EACtD,KAAK,OAAO,CAAC,GAAK,GAItB,IAAI2C,EAAS,EACTrC,EAAQ,SAAW,GACnBqC,EAAS,KAAK,OAAO,CAAC,EACf,OAAOrC,EAAQ,QAAW,UAAYA,EAAQ,QAAU,GAAKA,EAAQ,QAAUN,EAAoB,IAC1G2C,EAASrC,EAAQ,QAGrB,IAAMsC,EAAcJ,EAAK,MAAM;AAAA,CAAI,EAC/BK,EAAc,GAClB,QAAWC,KAAcF,EAAa,CAClC,IAAMrC,EAAQL,EAAQ,aAAa4C,EAAYxC,CAAO,EAChDyC,EAAoC,CACtC/C,EAAoB,KAAK,OAAO,CAAC,EACjCA,EAAoB2C,CACxB,EAEIE,IACA,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAIF,GAGlB,OAAOrC,EAAQ,UAAa,UAAYA,EAAQ,SAAS,QACxDyC,EAAgB,CAAC,EAAI,KAAK,IAAIA,EAAgB,CAAC,EAAGzC,EAAQ,SAAS,KAAK,EACxEyC,EAAgB,CAAC,EAAI,KAAK,IAAIA,EAAgB,CAAC,EAAGzC,EAAQ,SAAS,MAAQqC,CAAM,GAGrF,IAAMK,EAAe9C,EAAQ,oBAAoBK,EAAOwC,CAAe,EACvE,QAAWxC,KAASyC,EAAc,CAG9B,GAAI,CAAC,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAC1B,MAIJ,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,EAAGzC,EAAM,OAAQ,GAAGA,CAAK,EACxE,KAAK,OAAO,CAAC,GAAKA,EAAM,OAIpBA,IAAUyC,EAAaA,EAAa,OAAS,CAAC,IAC9C,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAIL,EAEzB,CAEAE,EAAc,EAClB,CAEA,OAAO,IACX,CAoBA,MAAOtB,EAA6B,CAChC,IAAM0B,EAAe/C,EAAQ,uBAAuBqB,CAAI,EACxD,OAAI,KAAK,OAAO,CAAC,IAAM,GAAK,KAAK,OAAO,CAAC,IAAM,KAC3C,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAI,GAGrBA,EAAK,QAAQgB,GAAQ,CACjB,IAAMW,EAAY,KAAK,OAAO,CAAC,EAC3BC,EAAa,EAEjBZ,EAAK,QAAQ,CAACX,EAAQC,IAAgB,CAClC,IAAMuB,EAAcH,EAAapB,CAAW,EACtCc,EAASM,EACV,OAAO,CAACI,EAAOf,IAAUA,EAAQT,CAAW,EAC5C,OAAO,CAACE,EAAGC,IAAMD,EAAIC,EAAI,EAAG,CAAC,EAElC,KAAK,MAAMJ,EAAQ,CACf,SAAU,CACN,KAAMsB,EACN,IAAKP,EACL,MAAOS,CACX,EACA,OAAAT,CACJ,CAAC,EAEDQ,EAAa,KAAK,IAAIA,EAAY,KAAK,OAAO,CAAC,EAAID,EAAY,CAAC,CACpE,CAAC,EAED,KAAK,OAAO,CAAC,EAAIA,EAAYC,EAAa,EAC1C,KAAK,OAAO,CAAC,EAAI,CACrB,CAAC,EAEM,IACX,CAKA,QAAe,CACX,IAAMG,EAAQ,CACV,KAAK,MAAM,UAAUC,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,CAAC,EAC9C,KAAK,IAAI,GAAG,KAAK,MAAM,IAAID,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,EAAID,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAUC,GAAKA,IAAM,CAAC,EAAID,EAAE,MAAM,CAAC,EAC9G,KAAK,MAAM,MAAM,EAAE,QAAQ,EAAE,UAAUA,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,CAAC,EAChE,KAAK,IAAI,GAAG,KAAK,MAAM,IAAID,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,EAAID,EAAE,UAAUC,GAAKA,IAAM,CAAC,EAAID,EAAE,MAAM,CAAC,CAChG,EAEME,EAAU,CACZ,KAAK,OAAOH,EAAM,CAAC,EAAIA,EAAM,CAAC,GAAK,CAAC,EACpC,KAAK,OAAOA,EAAM,CAAC,EAAIA,EAAM,CAAC,GAAK,CAAC,CACxC,EAGA,GAAGA,EAAM,CAAC,IAAMG,EAAQ,CAAC,EAAG,CACxB,IAAMC,EAAMD,EAAQ,CAAC,EAAIH,EAAM,CAAC,EAChC,KAAK,MAAM,OAAOI,EAAM,EAAI,EAAI,KAAK,MAAM,OAAQ,EAC/C,GAAG,KAAK,MAAM,OAAOA,EAAM,EAAI,KAAK,MAAM,OAASA,EAAM,EAAG,KAAK,IAAIA,CAAG,CAAC,CAC7E,CACJ,CAGA,GAAGJ,EAAM,CAAC,IAAMG,EAAQ,CAAC,EAAG,CACxB,IAAMC,EAAMD,EAAQ,CAAC,EAAIH,EAAM,CAAC,EAChC,KAAK,MAAM,QAAQf,GAAQ,CACvBA,EAAK,OAAOmB,EAAM,EAAI,EAAInB,EAAK,OAAQ,EACnC,GAAGA,EAAK,OAAOmB,EAAM,EAAInB,EAAK,OAASmB,EAAM,EAAG,KAAK,IAAIA,CAAG,CAAC,CACjE,CACJ,CAAC,CACL,CACJ,CAEA,UAAoB,CAChB,MAAO,KAAO,IAAI,OAAO1D,EAAoB,CAAC,EAAI;AAAA,EAC9C,KAAK,MAAM,IAAIuC,GAAQ,KAAOA,EAAK,IAAI9B,GACnCP,EAAQ,aAAaO,CAAI,CAC7B,EAAE,KAAK,EAAE,EAAI;AAAA,CAAM,EAAE,KAAK,EAAE,EAC5B,KAAO,IAAI,OAAOT,EAAoB,CAAC,EAAI;AAAA,CACnD,CAEA,aAA+B,CAC3B,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,KAAK,CAAC,CAChD,CACJ,EElqBA,eAAsB2D,EAClBC,EACAC,EACAC,EACAC,EAA0B,CAAC,EACjB,CACV,IAAMC,EAASF,IAAS,OAAY,MAAQ,OACxCA,IAAS,QACT,OAAO,OAAOD,EAAS,CACnB,eAAgB,kBACpB,CAAC,EAGL,IAAMI,EAA4B,CAC9B,OAAAD,EACA,QAAAH,CACJ,EACGC,IAAS,QAAa,OAAOA,GAAS,SACrCG,EAAK,KAAOH,EAERA,IAAS,SACbG,EAAK,KAAO,KAAK,UAAUH,CAAI,GAGnC,IAAII,EAAwC,KAC5C,QAAS,EAAI,EAAG,EAAI,KAChBA,EAAW,MAAOH,EAAQ,OAAS,OAAOH,EAAKK,CAAI,EAChD,CAAAC,EAAS,IAFQ,IAMpB,MAAM,IAAI,QAAQC,GAAW,WAAWA,EAAS,GAAI,CAAC,EAG1D,GAAG,CAACD,GAAU,GACV,MAAM,IAAI,MAAM,qBAAqB,EAGzC,OAAGH,EAAQ,gBAAkB,GACzB,OAGS,MAAMG,EAAS,KAAK,CAErC,CC1CA,IAAqBE,EAArB,KAA8B,CACT,IACA,KACA,QAEjB,YAAaC,EAAaC,EAAeC,EAA0B,CAC/D,KAAK,IAAMF,EACX,KAAK,KAAOC,GAAQ,mBACpB,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAAeF,EAA0B,CAAC,EAAe,CAC7F,OAAOG,EAAQ,UAAU,KAAK,IAAI,0BAA2B,CACzD,6BAA8B,KAAK,GACvC,EAAGD,EAAM,OAAO,OAAO,CAAC,EAAG,KAAK,QAASF,CAAO,CAAC,CACrD,CAEA,MAAM,mBAAuC,CACzC,IAAMI,EAAW,MAAM,KAAK,QAAoD,GAAG,EACnF,OAAO,IAAIC,EAAQ,MAAM,QAAQD,CAAQ,EAAIA,EAAWA,EAAS,OAAO,CAC5E,CAEA,MAAM,YAAaE,EAA2B,CAC1C,IAAMC,EAAS,OAAOD,GAAY,SAAW,IAAID,EAAQC,CAAO,EAAIA,EACpE,MAAM,KAAK,QAAc,IACrB,KAAK,UAAUC,EAAO,YAAY,CAAC,EACnC,CAAE,cAAe,EAAM,CAC3B,CACJ,CACJ,EC9BA,IAAqBC,EAArB,KAAoC,CACf,OAEjB,YAAaC,EAAiB,CAAC,EAAG,CAC9B,KAAK,OAASA,CAClB,CAEA,QAAQA,EAAsB,CAC1BA,EAAO,QAAQC,GAAS,KAAK,OAAO,KAAKA,CAAK,CAAC,CACnD,CAEA,MAAM,YAAaC,EAA0C,CACzD,QAAUD,KAAS,KAAK,OACpB,MAAMA,EAAM,YAAYC,CAAO,CAEvC,CACJ,ECfA,IAAqBC,EAArB,KAAkC,CACb,IACA,QAEjB,YAAaC,EAAaC,EAA0B,CAChD,KAAK,IAAMD,EACX,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAA2B,CAC/D,OAAOC,EAAQ,4BAA4BF,CAAI,GAAI,CAC/C,8BAA+B,KAAK,GACxC,EAAGC,EAAM,KAAK,OAAO,CACzB,CAEA,MAAM,mBAAuC,CACzC,IAAME,EAAW,MAAM,KAAK,QAAqC,GAAG,EACpE,OAAO,IAAIC,EAAQ,KAAK,MAAMD,EAAS,eAAe,MAAM,CAAC,CACjE,CAEA,MAAM,YAAaE,EAA2B,CAC1C,IAAMC,EAAS,OAAOD,GAAY,SAAW,IAAID,EAAQC,CAAO,EAAIA,EACpE,MAAM,KAAK,QAAc,IACrB,KAAK,UAAUC,EAAO,YAAY,CAAC,CACvC,CACJ,CACJ,ECzBA,IAAqBC,EAArB,KAAqC,CAChB,IACA,OACA,QAEjB,YAAaC,EAAaC,EAAgBC,EAA0B,CAChE,KAAK,IAAMF,EACX,KAAK,OAASC,EACd,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAA4C,CAChF,OAAOC,EAAQ,kCAAkCF,CAAI,GAAI,CACrD,uBAAwB,KAAK,IAC7B,0BAA2B,KAAK,MACpC,EAAGC,EAAM,KAAK,OAAO,CACzB,CAEA,MAAM,WAA8B,CAChC,OAAO,MAAM,KAAK,QAAgB,SAAS,CAC/C,CAEA,MAAM,kBAA4C,CAC9C,OAAO,MAAM,KAAK,QAAuB,gBAAgB,CAC7D,CAKA,MAAM,YAAaE,EAA2BC,EAAqC,CAC/E,IAAIC,EAAa,GACXC,EAAgB,CAAC,EACjBC,EAAS,OAAOJ,GAAY,SAAW,IAAIK,EAAQL,CAAO,EAAIA,EAEpE,GAAI,OAAOC,GAAoB,SAC3BC,EAAa,GACbC,EAAI,KAAKF,CAAe,UACjB,MAAM,QAAQA,CAAe,EACpCE,EAAI,KAAK,GAAGF,CAAe,MACxB,CACH,IAAMK,EAAgB,MAAM,KAAK,iBAAiB,EAClDH,EAAI,KAAK,GAAGG,EAAc,cAAc,IAAIC,GAAgBA,EAAa,GAAG,CAAC,CACjF,CAEA,IAAMC,EAAsC,CAAC,EAC7C,QAAWC,KAAMN,EACbK,EAAQ,KACJ,MAAM,KAAK,QAAkC,kBAAkBC,CAAE,WAAY,CACzE,WAAYL,EAAO,YAAY,CACnC,CAAC,CACL,EAEJ,OAAIF,EACOM,EAAQ,CAAC,EAGbA,CACX,CACJ","names":["src_exports","__export","BOARD_LINES","BOARD_LINE_LENGTH","LocalAPI","Message","MessageWritePosition","MultipleBoards","ReadWriteAPI","SubscriptionAPI","__toCommonJS","import_grapheme_splitter","BOARD_LINE_LENGTH","BOARD_LINES","MessageWritePosition","CHAR_MAP","EMPTY_BOARD","BOARD_LINES","BOARD_LINE_LENGTH","Message","_Message","GraphemeSplitter","message","word","options","chars","singleCharStrings","char","fromMap","mapChar","entry","name","code","lineLength","words","currentWord","lines","separator","currentLine","charsLeft","result","rows","columns","columnDefaultSizes","row","rowIndex","column","columnIndex","columnDefaultSum","a","b","columnBorders","factor","columnSizes","size","diff","index","line","text","pointer","charIndex","indent","linesOfText","isFirstLine","lineOfText","charsLeftInLine","linesOfChars","columnWidths","lineStart","lineHeight","columnWidth","width","space","l","c","padding","add","request","url","headers","data","options","method","init","response","resolve","LocalAPI","key","host","options","path","data","request","response","Message","message","msgObj","MultipleBoards","boards","board","message","ReadWriteAPI","key","options","path","data","request","response","Message","message","msgObj","SubscriptionAPI","key","secret","options","path","data","request","message","subscriptionIds","singleMode","ids","msgObj","Message","subscriptions","subscription","results","id"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/message.ts","../src/tools.ts","../src/subscription-api.ts","../src/read-write-api.ts","../src/types.ts","../src/local-api.ts","../src/multiple-boards.ts"],"sourcesContent":["export { default as LocalAPI } from './local-api.js';\nexport { default as Message } from './message.js';\nexport { default as MultipleBoards } from './multiple-boards.js';\nexport { default as ReadWriteAPI } from './read-write-api.js';\nexport { default as SubscriptionAPI } from './subscription-api.js';\nexport {\n BOARD_LINES,\n BOARD_LINE_LENGTH,\n MessageWritePosition,\n type BoardCharArray,\n type BoardCharLine,\n type Boards,\n type Installation,\n type MessageWriteCoords,\n type MessageWriteOptions,\n type RequestOptions,\n type Subscription,\n type SubscriptionPostResponse,\n type Subscriptions,\n type Viewer,\n} from './types.js';\n","import GraphemeSplitter from 'grapheme-splitter';\nimport {\n BOARD_LINES,\n BOARD_LINE_LENGTH,\n MessageWritePosition,\n type BoardCharArray,\n type MessageWriteOptions,\n} from './types.js';\n\n\n/**\n * Map with all supported characters plus a few emojis\n * mapped to corresponding characters of the Vestaboard\n */\nexport const CHAR_MAP: Array<[string, number[]]> = [\n [' ', [0]],\n ['A', [1]],\n ['a', [1]],\n ['b', [2]],\n ['B', [2]],\n ['C', [3]],\n ['c', [3]],\n ['d', [4]],\n ['e', [5]],\n ['f', [6]],\n ['g', [7]],\n ['h', [8]],\n ['i', [9]],\n ['j', [10]],\n ['k', [11]],\n ['l', [12]],\n ['m', [13]],\n ['n', [14]],\n ['o', [15]],\n ['p', [16]],\n ['q', [17]],\n ['r', [18]],\n ['s', [19]],\n ['t', [20]],\n ['u', [21]],\n ['v', [22]],\n ['w', [23]],\n ['x', [24]],\n ['y', [25]],\n ['z', [26]],\n ['D', [4]],\n ['E', [5]],\n ['F', [6]],\n ['G', [7]],\n ['H', [8]],\n ['I', [9]],\n ['J', [10]],\n ['K', [11]],\n ['L', [12]],\n ['M', [13]],\n ['N', [14]],\n ['O', [15]],\n ['P', [16]],\n ['Q', [17]],\n ['R', [18]],\n ['S', [19]],\n ['T', [20]],\n ['U', [21]],\n ['V', [22]],\n ['W', [23]],\n ['X', [24]],\n ['Y', [25]],\n ['Z', [26]],\n ['1', [27]],\n ['2', [28]],\n ['3', [29]],\n ['4', [30]],\n ['5', [31]],\n ['6', [32]],\n ['7', [33]],\n ['8', [34]],\n ['9', [35]],\n ['0', [36]],\n ['!', [37]],\n ['@', [38]],\n ['#', [39]],\n ['$', [40]],\n ['(', [41]],\n [')', [42]],\n ['-', [44]],\n ['+', [46]],\n ['&', [47]],\n ['=', [48]],\n [';', [49]],\n [':', [50]],\n ['\\'', [52]],\n ['\"', [53]],\n ['%', [54]],\n [',', [55]],\n ['.', [56]],\n ['/', [59]],\n ['?', [60]],\n ['°', [62]],\n ['€', [5, 21, 18]],\n ['ƒ', [6]],\n ['Ž', [26]],\n ['š', [19]],\n ['¼', [27, 59, 30]],\n ['½', [27, 59, 28]],\n ['¾', [29, 59, 30]],\n ['À', [1]],\n ['Á', [1]],\n ['Â', [1]],\n ['Ã', [1]],\n ['Ä', [1, 5]],\n ['Å', [1]],\n ['Æ', [1, 5]],\n ['Ç', [3]],\n ['È', [5]],\n ['É', [5]],\n ['Ê', [5]],\n ['Ë', [5]],\n ['Ì', [9]],\n ['Í', [9]],\n ['Î', [9]],\n ['Ï', [9]],\n ['Ð', [5, 20, 8]],\n ['Ñ', [14]],\n ['Ò', [15]],\n ['Ó', [15]],\n ['Ô', [15]],\n ['Õ', [15]],\n ['Ö', [15, 5]],\n ['×', [24]],\n ['Ù', [21]],\n ['Ú', [21]],\n ['Û', [21]],\n ['Ü', [21, 5]],\n ['Ý', [25]],\n ['ß', [19, 19]],\n ['à', [1]],\n ['á', [1]],\n ['â', [1]],\n ['ã', [1]],\n ['ä', [1, 5]],\n ['å', [1]],\n ['æ', [1, 5]],\n ['ç', [3]],\n ['è', [5]],\n ['é', [5]],\n ['ê', [5]],\n ['ë', [5]],\n ['ì', [9]],\n ['í', [9]],\n ['î', [9]],\n ['ï', [9]],\n ['ð', [15]],\n ['ñ', [14]],\n ['ò', [15]],\n ['ó', [15]],\n ['ô', [15]],\n ['õ', [15]],\n ['ö', [15, 5]],\n ['ù', [21]],\n ['ú', [21]],\n ['û', [21]],\n ['ü', [21, 5]],\n ['ý', [25]],\n ['ÿ', [25]],\n ['🟥', [63]],\n ['🟧', [64]],\n ['🟨', [65]],\n ['🟩', [66]],\n ['🟦', [67]],\n ['🟪', [68]],\n ['⬜️', [69]],\n ['⬜', [69]],\n ['⬛️', [-2]],\n ['⬛', [-2]],\n ['﹫', [38]],\n ['@', [38]],\n ['0️⃣', [36]],\n ['1️⃣', [27]],\n ['2️⃣', [28]],\n ['3️⃣', [29]],\n ['4️⃣', [30]],\n ['5️⃣', [31]],\n ['6️⃣', [32]],\n ['7️⃣', [33]],\n ['8️⃣', [34]],\n ['9️⃣', [35]],\n ['❕', [37]],\n ['‼️', [37, 37]],\n ['❗️', [37]],\n ['⁉️', [37, 60]],\n ['#️⃣', [39]],\n ['💲', [40]],\n ['$', [40]],\n ['﹩', [40]],\n ['$', [40]],\n ['←', [44]],\n ['→', [44]],\n ['➡', [44]],\n ['⬅', [44]],\n ['➔', [44]],\n ['↔', [44]],\n ['–', [44]],\n ['➕', [46]],\n ['+', [46]],\n ['﹪', [54]],\n ['%', [54]],\n ['❓', [60]],\n ['❔', [60]],\n ['℃', [62, 3]],\n ['℉', [62, 6]]\n];\n\nconst EMPTY_BOARD: BoardCharArray = new Array(BOARD_LINES).fill(\n new Array(BOARD_LINE_LENGTH).fill(0)\n) as BoardCharArray;\n\n/**\n * You can build a message like this:\n *\n * ```javascript\n * import { Message } from '@sebbo2002/vestaboard';\n *\n * const myMessage = new Message('Hello World');\n *\n * // same as\n *\n * const myOtherMessage = new Message()\n * .write('Hello World')\n * .center();\n * ```\n */\nexport default class Message {\n private static readonly splitter = new GraphemeSplitter();\n private readonly board: BoardCharArray;\n private cursor = [0, 0];\n\n constructor (message?: BoardCharArray | string) {\n if(typeof message === 'string' && message) {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n this.write(message);\n this.center();\n }\n else if(Array.isArray(message)) {\n this.board = message;\n }\n else {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n }\n }\n\n static string2chars (word: string, options: MessageWriteOptions = {}): number[] {\n let chars: number[] = [];\n const singleCharStrings = Message.splitter.splitGraphemes(word);\n for (const char of singleCharStrings) {\n chars.push(...this.char2char(char));\n }\n\n // trim emoji words if not disabled\n if (options.removeUnsupportedWords !== false) {\n chars = Message.removeEmojisFromChars(chars);\n }\n\n // replace -1 with fallback char\n chars = chars.map(char => {\n if (char >= 0) {\n return char;\n } else if (char === -2) {\n return 0;\n } else if (typeof options.fallbackChar === 'number') {\n return options.fallbackChar;\n } else if (options.fallbackChar === null) {\n return -1;\n } else {\n return 60;\n }\n }).filter(char => char >= 0);\n\n return chars;\n }\n\n static char2char (char: string): number[] {\n const fromMap = CHAR_MAP\n .find(([mapChar]) => char === mapChar);\n\n if (fromMap && Array.isArray(fromMap[1])) {\n return fromMap[1];\n }\n\n return [-1];\n }\n\n static charToString (char: number): string {\n const entry = Object.values(CHAR_MAP)\n .filter(([name]) => name.length <= 2)\n .find(([, code]) => code[0] === char);\n\n if (entry) {\n return entry[0].toUpperCase() + (entry[0].length === 1 ? ' ' : '');\n }\n\n return '⚡︎ ';\n }\n\n static splitCharsIntoLines (chars: number[], lineLength: [number, number]): Array<number[]> {\n // Array with splitting char (if any) and chars of the word\n const words: Array<[number | null, number[]]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([null, []]);\n }\n\n const currentWord = words[words.length - 1];\n if (char === 0) {\n words.push([0, []]);\n } else if (char === 44) {\n currentWord[1].push(char);\n words.push([null, []]);\n } else {\n currentWord[1].push(char);\n }\n }\n\n const lines: Array<number[]> = [];\n for (const [separator, word] of words) {\n if (!lines.length) {\n lines.push([]);\n }\n\n let currentLine = lines[lines.length - 1];\n let charsLeft = lineLength[lines.length === 1 ? 0 : 1] - currentLine.length;\n\n // start of line, word fits\n if (!currentLine.length && word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // add separator and the whole word\n else if (separator !== null && word.length + 1 <= charsLeft) {\n currentLine.push(0, ...word);\n } else if (word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // no space for the word, write into next line\n else if (word.length <= lineLength[1]) {\n currentLine = [...word];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n // word too long for one line, start in\n // current line and continue in next line\n else {\n if (charsLeft >= 3 && !currentLine.length) {\n // No space required in front of long word\n } else if (charsLeft >= 4 && currentLine.length) {\n // Add space for next word\n currentLine.push(0);\n charsLeft--;\n } else {\n // No enough space for word, go to next line\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n for (const char of word) {\n currentLine.push(char);\n charsLeft--;\n\n if (charsLeft <= 1) {\n currentLine.push(44);\n\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n }\n }\n }\n\n return lines;\n }\n\n static removeEmojisFromChars (chars: number[]): number[] {\n const words: Array<number[]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([]);\n }\n\n if (char === 0) {\n words.push([]);\n } else {\n words[words.length - 1].push(char);\n }\n }\n\n words.forEach(chars => {\n if (chars.length > 0 && chars[0] === -1) {\n while (chars[0] < 0) {\n chars.splice(0, 1);\n }\n }\n if (chars.length > 0 && chars[chars.length - 1] === -1) {\n while (chars.length > 0 && chars[chars.length - 1] < 0) {\n chars.splice(chars.length - 1, 1);\n }\n }\n });\n\n const result: number[] = [];\n words\n .filter(chars => chars.length > 0)\n .forEach(chars => {\n if (result.length !== 0) {\n result.push(0);\n }\n\n result.push(...chars);\n });\n\n return result;\n }\n\n static getColumnSizesFromData (rows: Array<string[]>, options: MessageWriteOptions = {}): number[] {\n if (!rows.length) {\n return [];\n }\n\n const columns = rows[0].length;\n const columnDefaultSizes: number[] = [];\n rows.forEach((row, rowIndex) => {\n if (row.length !== columns) {\n throw new Error(`Unable to render table: Row ${rowIndex} has ${row.length} entries, but first row has ${columns}!`);\n }\n row.forEach((column, columnIndex) => {\n columnDefaultSizes[columnIndex] = Math.max(columnDefaultSizes[columnIndex] || 0, this.string2chars(column, options).length);\n });\n });\n\n const columnDefaultSum = columnDefaultSizes.reduce((a, b) => a + b, 0);\n const columnBorders = rows[0].length - 1;\n const factor = Math.max((BOARD_LINE_LENGTH - columnBorders) / columnDefaultSum, 1);\n const columnSizes = columnDefaultSizes.map(size => Math.round(size * factor));\n\n while (true) {\n const size = columnSizes.reduce((a, b) => a + b, 0) + columnBorders;\n if (size === BOARD_LINE_LENGTH) {\n break;\n }\n\n const diff = BOARD_LINE_LENGTH - size < 0 ? -1 : 1;\n const index = columnSizes.indexOf(diff < 0 ? Math.max(...columnSizes) : Math.min(...columnSizes));\n if(index < 0) {\n // This can actually never be achieved...\n throw new Error('Unable to find max value in array…');\n }\n\n columnSizes[index] += diff;\n }\n\n\n return columnSizes;\n }\n\n get isEmpty (): boolean {\n return !this.board.find(line =>\n line.find(char => char !== 0)\n );\n }\n\n /**\n * Fills the board with the passed character or text. The text\n * is repeated again and again until the board is completely filled.\n */\n fill (text = ' '): this {\n let pointer = 0;\n const chars = Message.string2chars(text, {removeUnsupportedWords: false});\n this.board.forEach((line) => {\n line.forEach((char, charIndex) => {\n line[charIndex] = chars[pointer];\n pointer++;\n\n if(pointer > chars.length - 1) {\n pointer = 0;\n }\n });\n });\n return this;\n }\n\n /**\n * Write a text on your new message. If your message is not empty it will continue\n * where you last left off (`position: MessageWritePosition.CURRENT`). Alternatively\n * you can continue on the next line or give an exact position.\n *\n * @param text\n * @param options\n */\n write (text: string, options: MessageWriteOptions = {}): this {\n\n // Cursor blow board length? Just return…\n if (!this.board[this.cursor[0]]) {\n return this;\n }\n\n // Add new line if NEXT_LINE is set (except it's already in the first line)\n if (options.position === MessageWritePosition.NEXT_LINE && (this.cursor[0] !== 0 || this.cursor[1] !== 0)) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n // Set cursor to given position\n else if (typeof options.position === 'object') {\n this.cursor[0] = options.position.line;\n this.cursor[1] = options.position.row || 0;\n }\n\n // Add space before text as it\n // will be rendered in the same line\n if (\n (options.position === undefined || options.position === MessageWritePosition.CURRENT) &&\n this.cursor[1] !== 0 && this.cursor[1] < BOARD_LINE_LENGTH - 1\n ) {\n this.board[this.cursor[0]].splice(this.cursor[1], 1, 0);\n this.cursor[1] += 1;\n }\n\n // Figure out left indent\n let indent = 0;\n if (options.indent === true) {\n indent = this.cursor[1];\n } else if (typeof options.indent === 'number' && options.indent >= 0 && options.indent <= BOARD_LINE_LENGTH - 5) {\n indent = options.indent;\n }\n\n const linesOfText = text.split('\\n');\n let isFirstLine = true;\n for (const lineOfText of linesOfText) {\n const chars = Message.string2chars(lineOfText, options);\n const charsLeftInLine: [number, number] = [\n BOARD_LINE_LENGTH - this.cursor[1],\n BOARD_LINE_LENGTH - indent\n ];\n\n if(!isFirstLine) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n\n if(typeof options.position === 'object' && options.position.width) {\n charsLeftInLine[0] = Math.min(charsLeftInLine[0], options.position.width);\n charsLeftInLine[1] = Math.min(charsLeftInLine[1], options.position.width - indent);\n }\n\n const linesOfChars = Message.splitCharsIntoLines(chars, charsLeftInLine);\n for (const chars of linesOfChars) {\n\n // Board is over, skip line…\n if (!this.board[this.cursor[0]]) {\n break;\n }\n\n // Add chars to current line and update cursor\n this.board[this.cursor[0]].splice(this.cursor[1], chars.length, ...chars);\n this.cursor[1] += chars.length;\n\n // Add new line (and update cursor),\n // if this wasn't the last line\n if (chars !== linesOfChars[linesOfChars.length - 1]) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n }\n\n isFirstLine = false;\n }\n\n return this;\n }\n\n /**\n * Generate a table with the given data\n *\n * @example new Message().table([\n * ['now', 'Daily'],\n * ['13:00', 'Super Secret Meeting'],\n * ['16:30', 'Awesome Presentation']\n * ])\n *\n * #==============================================#\n * # N O W D A I L Y #\n * # #\n * # 1 3 : 0 0 S U P E R S E C R E T #\n * # M E E T I N G #\n * # #\n * # 1 6 : 3 0 A W E S O M E P R E S E N T - #\n * #==============================================#\n */\n table (rows: Array<string[]>): this {\n const columnWidths = Message.getColumnSizesFromData(rows);\n if (this.cursor[0] !== 0 || this.cursor[1] !== 0) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n rows.forEach(line => {\n const lineStart = this.cursor[0];\n let lineHeight = 1;\n\n line.forEach((column, columnIndex) => {\n const columnWidth = columnWidths[columnIndex];\n const indent = columnWidths\n .filter((width, index) => index < columnIndex)\n .reduce((a, b) => a + b + 1, 0);\n\n this.write(column, {\n position: {\n line: lineStart,\n row: indent,\n width: columnWidth\n },\n indent\n });\n\n lineHeight = Math.max(lineHeight, this.cursor[0] - lineStart + 1);\n });\n\n this.cursor[0] = lineStart + lineHeight + 1;\n this.cursor[1] = 0;\n });\n\n return this;\n }\n\n /**\n * Center the current message content\n */\n center(): void {\n const space = [\n this.board.findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.slice().reverse().findIndex(c => c !== 0) : l.length)),\n this.board.slice().reverse().findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.findIndex(c => c !== 0) : l.length)),\n ];\n\n const padding = [\n Math.floor((space[0] + space[2]) / 2),\n Math.floor((space[1] + space[3]) / 2)\n ];\n\n // Move up/down\n if(space[0] !== padding[0]) {\n const add = padding[0] - space[0];\n this.board.splice(add > 0 ? 0 : this.board.length, 0,\n ...this.board.splice(add > 0 ? this.board.length - add : 0, Math.abs(add))\n );\n }\n\n // Move left/right\n if(space[3] !== padding[1]) {\n const add = padding[1] - space[3];\n this.board.forEach(line => {\n line.splice(add > 0 ? 0 : line.length, 0,\n ...line.splice(add > 0 ? line.length - add : 0, Math.abs(add))\n );\n });\n }\n }\n\n toString (): string {\n return '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n' +\n this.board.map(line => '# ' + line.map(char =>\n Message.charToString(char)\n ).join('') + ' #\\n').join('') +\n '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n';\n }\n\n toCharArray (): BoardCharArray {\n return JSON.parse(JSON.stringify(this.board));\n }\n}\n","import type { RequestFetchOptions, RequestFetchResponse, RequestOptions } from './types.js';\n\nexport async function request<T> (\n url: string,\n headers: Record<string, string>,\n data?: Record<string, unknown> | string,\n options: RequestOptions = {}\n): Promise<T> {\n const method = data === undefined ? 'GET' : 'POST';\n if (data !== undefined) {\n Object.assign(headers, {\n 'Content-Type': 'application/json'\n });\n }\n\n const init: RequestFetchOptions = {\n method,\n headers\n };\n if(data !== undefined && typeof data === 'string') {\n init.body = data;\n }\n else if(data !== undefined) {\n init.body = JSON.stringify(data);\n }\n\n let response: RequestFetchResponse | null = null;\n for (let i = 0; i < 10; i++) {\n response = await (options.fetch || fetch)(url, init);\n if(response.ok) {\n break;\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n\n if(!response?.ok) {\n throw new Error('HTTP Request failed');\n }\n\n if(options.parseResponse === false) {\n return undefined as unknown as T;\n }\n\n const json = await response.json();\n return json as T;\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { SubscriptionPostResponse, Subscriptions, Viewer } from './types.js';\nimport type { RequestOptions } from './types.js';\n\nexport default class SubscriptionAPI {\n private readonly key: string;\n private readonly secret: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, secret: string, options?: RequestOptions) {\n this.key = key;\n this.secret = secret;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: Record<string, unknown>): Promise<T> {\n return request(`https://platform.vestaboard.com${path}`, {\n 'X-Vestaboard-Api-Key': this.key,\n 'X-Vestaboard-Api-Secret': this.secret\n }, data, this.options);\n }\n\n async getViewer (): Promise<Viewer> {\n return await this.request<Viewer>('/viewer');\n }\n\n async getSubscriptions (): Promise<Subscriptions> {\n return await this.request<Subscriptions>('/subscriptions');\n }\n\n async postMessage (message: Message | string): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionId: string): Promise<SubscriptionPostResponse>;\n async postMessage (message: Message | string, subscriptionIds: string[]): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionIds?: string | string[]) {\n let singleMode = false;\n const ids: string[] = [];\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n\n if (typeof subscriptionIds === 'string') {\n singleMode = true;\n ids.push(subscriptionIds);\n } else if (Array.isArray(subscriptionIds)) {\n ids.push(...subscriptionIds);\n } else {\n const subscriptions = await this.getSubscriptions();\n ids.push(...subscriptions.subscriptions.map(subscription => subscription._id));\n }\n\n const results: SubscriptionPostResponse[] = [];\n for (const id of ids) {\n results.push(\n await this.request<SubscriptionPostResponse>(`/subscriptions/${id}/message`, {\n characters: msgObj.toCharArray()\n })\n );\n }\n if (singleMode) {\n return results[0];\n }\n\n return results;\n }\n}","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { ReadWriteGetMessageResponse, RequestOptions } from './types.js';\n\nexport default class ReadWriteAPI {\n private readonly key: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, options?: RequestOptions) {\n this.key = key;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string): Promise<T> {\n return request(`https://rw.vestaboard.com${path}`, {\n 'X-Vestaboard-Read-Write-Key': this.key\n }, data, this.options);\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<ReadWriteGetMessageResponse>('/');\n return new Message(JSON.parse(response.currentMessage.layout));\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray())\n );\n }\n}\n","import SubscriptionAPI from './subscription-api.js';\nimport ReadWriteAPI from './read-write-api.js';\nimport LocalAPI from './local-api.js';\n\nexport const BOARD_LINE_LENGTH = 22;\nexport const BOARD_LINES = 6;\n\nexport type BoardCharLine = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number\n];\n\nexport type BoardCharArray = [\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine\n];\n\nexport interface MessageWriteCoords {\n line: number;\n row?: number;\n width?: number;\n}\n\nexport enum MessageWritePosition {\n CURRENT,\n NO_SPACE_BETWEEN,\n NEXT_LINE\n}\n\nexport interface MessageWriteOptions {\n position?: MessageWriteCoords | MessageWritePosition;\n indent?: boolean | number;\n fallbackChar?: number | null;\n removeUnsupportedWords?: boolean;\n}\n\nexport interface RequestFetchOptions {\n body?: string;\n headers?: Record<string, string>;\n method?: string;\n}\n\nexport interface RequestFetchResponse {\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n json(): Promise<unknown>;\n}\n\nexport type RequestOptionsFetch = (url: string, init?: RequestFetchOptions) => Promise<RequestFetchResponse>;\n\nexport interface RequestOptions {\n fetch?: RequestOptionsFetch;\n parseResponse?: boolean;\n}\n\nexport interface Installation {\n _id: string;\n installable?: {\n _id: string;\n };\n}\n\nexport interface Viewer {\n type: string;\n _id: string;\n _created: string;\n installation: {\n _id: string;\n };\n}\n\nexport interface Subscription {\n _id: string;\n _created: string;\n installation: Installation;\n boards: Array<{_id: string}>;\n}\n\nexport interface Subscriptions {\n subscriptions: Subscription[];\n}\n\nexport interface SubscriptionPostResponse {\n message: {\n id: string;\n created: number;\n }\n}\n\nexport interface ReadWriteGetMessageResponse {\n currentMessage: {\n layout: string;\n }\n}\n\nexport type Boards = Array<LocalAPI | ReadWriteAPI | SubscriptionAPI>;\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { BoardCharArray, RequestOptions } from './types.js';\n\nexport default class LocalAPI {\n private readonly key: string;\n private readonly host: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, host?: string, options?: RequestOptions) {\n this.key = key;\n this.host = host || 'vestaboard.local';\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string, options: RequestOptions = {}): Promise<T> {\n return request(`http://${this.host}:7000/local-api/message`, {\n 'X-Vestaboard-Local-Api-Key': this.key\n }, data, Object.assign({}, this.options, options));\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<{message: BoardCharArray} | BoardCharArray>('/');\n return new Message(Array.isArray(response) ? response : response.message);\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray()),\n { parseResponse: false }\n );\n }\n}\n","import { type Boards } from './types.js';\nimport Message from './message.js';\n\nexport default class MultipleBoards {\n private readonly boards: Boards;\n\n constructor (boards: Boards = []) {\n this.boards = boards;\n }\n\n push(...boards: Boards): void {\n boards.forEach(board => this.boards.push(board));\n }\n\n async postMessage (message: Message | string): Promise<void> {\n for(const board of this.boards) {\n await board.postMessage(message);\n }\n }\n}\n"],"mappings":"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,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE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","names":["src_exports","__export","BOARD_LINES","BOARD_LINE_LENGTH","LocalAPI","Message","MessageWritePosition","MultipleBoards","ReadWriteAPI","SubscriptionAPI","__toCommonJS","import_grapheme_splitter","request","url","headers","data","options","method","init","response","resolve","SubscriptionAPI","key","secret","options","path","data","request","message","subscriptionIds","singleMode","ids","msgObj","Message","subscriptions","subscription","results","id","ReadWriteAPI","key","options","path","data","request","response","Message","message","msgObj","BOARD_LINE_LENGTH","BOARD_LINES","MessageWritePosition","CHAR_MAP","EMPTY_BOARD","BOARD_LINES","BOARD_LINE_LENGTH","Message","_Message","GraphemeSplitter","message","word","options","chars","singleCharStrings","char","fromMap","mapChar","entry","name","code","lineLength","words","currentWord","lines","separator","currentLine","charsLeft","result","rows","columns","columnDefaultSizes","row","rowIndex","column","columnIndex","columnDefaultSum","a","b","columnBorders","factor","columnSizes","size","diff","index","line","text","pointer","charIndex","indent","linesOfText","isFirstLine","lineOfText","charsLeftInLine","linesOfChars","columnWidths","lineStart","lineHeight","columnWidth","width","space","l","c","padding","add","LocalAPI","key","host","options","path","data","request","response","Message","message","msgObj","MultipleBoards","boards","board","message"]}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import C from"grapheme-splitter";var c=22,O=6,w=(r=>(r[r.CURRENT=0]="CURRENT",r[r.NO_SPACE_BETWEEN=1]="NO_SPACE_BETWEEN",r[r.NEXT_LINE=2]="NEXT_LINE",r))(w||{});var A=[[" ",[0]],["A",[1]],["a",[1]],["b",[2]],["B",[2]],["C",[3]],["c",[3]],["d",[4]],["e",[5]],["f",[6]],["g",[7]],["h",[8]],["i",[9]],["j",[10]],["k",[11]],["l",[12]],["m",[13]],["n",[14]],["o",[15]],["p",[16]],["q",[17]],["r",[18]],["s",[19]],["t",[20]],["u",[21]],["v",[22]],["w",[23]],["x",[24]],["y",[25]],["z",[26]],["D",[4]],["E",[5]],["F",[6]],["G",[7]],["H",[8]],["I",[9]],["J",[10]],["K",[11]],["L",[12]],["M",[13]],["N",[14]],["O",[15]],["P",[16]],["Q",[17]],["R",[18]],["S",[19]],["T",[20]],["U",[21]],["V",[22]],["W",[23]],["X",[24]],["Y",[25]],["Z",[26]],["1",[27]],["2",[28]],["3",[29]],["4",[30]],["5",[31]],["6",[32]],["7",[33]],["8",[34]],["9",[35]],["0",[36]],["!",[37]],["@",[38]],["#",[39]],["$",[40]],["(",[41]],[")",[42]],["-",[44]],["+",[46]],["&",[47]],["=",[48]],[";",[49]],[":",[50]],["'",[52]],['"',[53]],["%",[54]],[",",[55]],[".",[56]],["/",[59]],["?",[60]],["\xB0",[62]],["\u20AC",[5,21,18]],["\u0192",[6]],["\u017D",[26]],["\u0161",[19]],["\xBC",[27,59,30]],["\xBD",[27,59,28]],["\xBE",[29,59,30]],["\xC0",[1]],["\xC1",[1]],["\xC2",[1]],["\xC3",[1]],["\xC4",[1,5]],["\xC5",[1]],["\xC6",[1,5]],["\xC7",[3]],["\xC8",[5]],["\xC9",[5]],["\xCA",[5]],["\xCB",[5]],["\xCC",[9]],["\xCD",[9]],["\xCE",[9]],["\xCF",[9]],["\xD0",[5,20,8]],["\xD1",[14]],["\xD2",[15]],["\xD3",[15]],["\xD4",[15]],["\xD5",[15]],["\xD6",[15,5]],["\xD7",[24]],["\xD9",[21]],["\xDA",[21]],["\xDB",[21]],["\xDC",[21,5]],["\xDD",[25]],["\xDF",[19,19]],["\xE0",[1]],["\xE1",[1]],["\xE2",[1]],["\xE3",[1]],["\xE4",[1,5]],["\xE5",[1]],["\xE6",[1,5]],["\xE7",[3]],["\xE8",[5]],["\xE9",[5]],["\xEA",[5]],["\xEB",[5]],["\xEC",[9]],["\xED",[9]],["\xEE",[9]],["\xEF",[9]],["\xF0",[15]],["\xF1",[14]],["\xF2",[15]],["\xF3",[15]],["\xF4",[15]],["\xF5",[15]],["\xF6",[15,5]],["\xF9",[21]],["\xFA",[21]],["\xFB",[21]],["\xFC",[21,5]],["\xFD",[25]],["\xFF",[25]],["\u{1F7E5}",[63]],["\u{1F7E7}",[64]],["\u{1F7E8}",[65]],["\u{1F7E9}",[66]],["\u{1F7E6}",[67]],["\u{1F7EA}",[68]],["\u2B1C\uFE0F",[69]],["\u2B1C",[69]],["\u2B1B\uFE0F",[-2]],["\u2B1B",[-2]],["\uFE6B",[38]],["\uFF20",[38]],["0\uFE0F\u20E3",[36]],["1\uFE0F\u20E3",[27]],["2\uFE0F\u20E3",[28]],["3\uFE0F\u20E3",[29]],["4\uFE0F\u20E3",[30]],["5\uFE0F\u20E3",[31]],["6\uFE0F\u20E3",[32]],["7\uFE0F\u20E3",[33]],["8\uFE0F\u20E3",[34]],["9\uFE0F\u20E3",[35]],["\u2755",[37]],["\u203C\uFE0F",[37,37]],["\u2757\uFE0F",[37]],["\u2049\uFE0F",[37,60]],["#\uFE0F\u20E3",[39]],["\u{1F4B2}",[40]],["$",[40]],["\uFE69",[40]],["\uFF04",[40]],["\u2190",[44]],["\u2192",[44]],["\u27A1",[44]],["\u2B05",[44]],["\u2794",[44]],["\u2194",[44]],["\u2013",[44]],["\u2795",[46]],["+",[46]],["\uFE6A",[54]],["\uFF05",[54]],["\u2753",[60]],["\u2754",[60]],["\u2103",[62,3]],["\u2109",[62,6]]],M=new Array(O).fill(new Array(c).fill(0)),l=class p{static splitter=new C;board;cursor=[0,0];constructor(t){typeof t=="string"&&t?(this.board=JSON.parse(JSON.stringify(M)),this.write(t),this.center()):Array.isArray(t)?this.board=t:this.board=JSON.parse(JSON.stringify(M))}static string2chars(t,e={}){let r=[],s=p.splitter.splitGraphemes(t);for(let n of s)r.push(...this.char2char(n));return e.removeUnsupportedWords!==!1&&(r=p.removeEmojisFromChars(r)),r=r.map(n=>n>=0?n:n===-2?0:typeof e.fallbackChar=="number"?e.fallbackChar:e.fallbackChar===null?-1:60).filter(n=>n>=0),r}static char2char(t){let e=A.find(([r])=>t===r);return e&&Array.isArray(e[1])?e[1]:[-1]}static charToString(t){let e=Object.values(A).filter(([r])=>r.length<=2).find(([,r])=>r[0]===t);return e?e[0].toUpperCase()+(e[0].length===1?" ":""):"\u26A1\uFE0E "}static splitCharsIntoLines(t,e){let r=[];for(let n of t){r.length||r.push([null,[]]);let o=r[r.length-1];n===0?r.push([0,[]]):n===44?(o[1].push(n),r.push([null,[]])):o[1].push(n)}let s=[];for(let[n,o]of r){s.length||s.push([]);let a=s[s.length-1],i=e[s.length===1?0:1]-a.length;if(!a.length&&o.length<=i)a.push(...o);else if(n!==null&&o.length+1<=i)a.push(0,...o);else if(o.length<=i)a.push(...o);else if(o.length<=e[1])a=[...o],i=e[1],s.push(a);else{i>=3&&!a.length||(i>=4&&a.length?(a.push(0),i--):(a=[],i=e[1],s.push(a)));for(let u of o)a.push(u),i--,i<=1&&(a.push(44),a=[],i=e[1],s.push(a))}}return s}static removeEmojisFromChars(t){let e=[];for(let s of t)e.length||e.push([]),s===0?e.push([]):e[e.length-1].push(s);e.forEach(s=>{if(s.length>0&&s[0]===-1)for(;s[0]<0;)s.splice(0,1);if(s.length>0&&s[s.length-1]===-1)for(;s.length>0&&s[s.length-1]<0;)s.splice(s.length-1,1)});let r=[];return e.filter(s=>s.length>0).forEach(s=>{r.length!==0&&r.push(0),r.push(...s)}),r}static getColumnSizesFromData(t,e={}){if(!t.length)return[];let r=t[0].length,s=[];t.forEach((u,h)=>{if(u.length!==r)throw new Error(`Unable to render table: Row ${h} has ${u.length} entries, but first row has ${r}!`);u.forEach((f,g)=>{s[g]=Math.max(s[g]||0,this.string2chars(f,e).length)})});let n=s.reduce((u,h)=>u+h,0),o=t[0].length-1,a=Math.max((c-o)/n,1),i=s.map(u=>Math.round(u*a));for(;;){let u=i.reduce((g,S)=>g+S,0)+o;if(u===c)break;let h=c-u<0?-1:1,f=i.indexOf(h<0?Math.max(...i):Math.min(...i));if(f<0)throw new Error("Unable to find max value in array\u2026");i[f]+=h}return i}get isEmpty(){return!this.board.find(t=>t.find(e=>e!==0))}fill(t=" "){let e=0,r=p.string2chars(t,{removeUnsupportedWords:!1});return this.board.forEach(s=>{s.forEach((n,o)=>{s[o]=r[e],e++,e>r.length-1&&(e=0)})}),this}write(t,e={}){if(!this.board[this.cursor[0]])return this;e.position===2&&(this.cursor[0]!==0||this.cursor[1]!==0)?(this.cursor[0]++,this.cursor[1]=0):typeof e.position=="object"&&(this.cursor[0]=e.position.line,this.cursor[1]=e.position.row||0),(e.position===void 0||e.position===0)&&this.cursor[1]!==0&&this.cursor[1]<c-1&&(this.board[this.cursor[0]].splice(this.cursor[1],1,0),this.cursor[1]+=1);let r=0;e.indent===!0?r=this.cursor[1]:typeof e.indent=="number"&&e.indent>=0&&e.indent<=c-5&&(r=e.indent);let s=t.split(`
2
- `),n=!0;for(let o of s){let a=p.string2chars(o,e),i=[c-this.cursor[1],c-r];n||(this.cursor[0]++,this.cursor[1]=r),typeof e.position=="object"&&e.position.width&&(i[0]=Math.min(i[0],e.position.width),i[1]=Math.min(i[1],e.position.width-r));let u=p.splitCharsIntoLines(a,i);for(let h of u){if(!this.board[this.cursor[0]])break;this.board[this.cursor[0]].splice(this.cursor[1],h.length,...h),this.cursor[1]+=h.length,h!==u[u.length-1]&&(this.cursor[0]++,this.cursor[1]=r)}n=!1}return this}table(t){let e=p.getColumnSizesFromData(t);return(this.cursor[0]!==0||this.cursor[1]!==0)&&(this.cursor[0]++,this.cursor[1]=0),t.forEach(r=>{let s=this.cursor[0],n=1;r.forEach((o,a)=>{let i=e[a],u=e.filter((h,f)=>f<a).reduce((h,f)=>h+f+1,0);this.write(o,{position:{line:s,row:u,width:i},indent:u}),n=Math.max(n,this.cursor[0]-s+1)}),this.cursor[0]=s+n+1,this.cursor[1]=0}),this}center(){let t=[this.board.findIndex(r=>r.find(s=>s!==0)),Math.min(...this.board.map(r=>r.find(s=>s!==0)?r.slice().reverse().findIndex(s=>s!==0):r.length)),this.board.slice().reverse().findIndex(r=>r.find(s=>s!==0)),Math.min(...this.board.map(r=>r.find(s=>s!==0)?r.findIndex(s=>s!==0):r.length))],e=[Math.floor((t[0]+t[2])/2),Math.floor((t[1]+t[3])/2)];if(t[0]!==e[0]){let r=e[0]-t[0];this.board.splice(r>0?0:this.board.length,0,...this.board.splice(r>0?this.board.length-r:0,Math.abs(r)))}if(t[3]!==e[1]){let r=e[1]-t[3];this.board.forEach(s=>{s.splice(r>0?0:s.length,0,...s.splice(r>0?s.length-r:0,Math.abs(r)))})}}toString(){return"#="+"=".repeat(c*2)+`=#
3
- `+this.board.map(t=>"# "+t.map(e=>p.charToString(e)).join("")+` #
4
- `).join("")+"#="+"=".repeat(c*2)+`=#
5
- `}toCharArray(){return JSON.parse(JSON.stringify(this.board))}};async function d(p,t,e,r={}){let s=e===void 0?"GET":"POST";e!==void 0&&Object.assign(t,{"Content-Type":"application/json"});let n={method:s,headers:t};e!==void 0&&typeof e=="string"?n.body=e:e!==void 0&&(n.body=JSON.stringify(e));let o=null;for(let i=0;i<10&&(o=await(r.fetch||fetch)(p,n),!o.ok);i++)await new Promise(u=>setTimeout(u,1e3));if(!o?.ok)throw new Error("HTTP Request failed");return r.parseResponse===!1?void 0:await o.json()}var m=class{key;host;options;constructor(t,e,r){this.key=t,this.host=e||"vestaboard.local",this.options=r||{}}async request(t,e,r={}){return d(`http://${this.host}:7000/local-api/message`,{"X-Vestaboard-Local-Api-Key":this.key},e,Object.assign({},this.options,r))}async getCurrentMessage(){let t=await this.request("/");return new l(Array.isArray(t)?t:t.message)}async postMessage(t){let e=typeof t=="string"?new l(t):t;await this.request("/",JSON.stringify(e.toCharArray()),{parseResponse:!1})}};var b=class{boards;constructor(t=[]){this.boards=t}push(...t){t.forEach(e=>this.boards.push(e))}async postMessage(t){for(let e of this.boards)await e.postMessage(t)}};var y=class{key;options;constructor(t,e){this.key=t,this.options=e||{}}async request(t,e){return d(`https://rw.vestaboard.com${t}`,{"X-Vestaboard-Read-Write-Key":this.key},e,this.options)}async getCurrentMessage(){let t=await this.request("/");return new l(JSON.parse(t.currentMessage.layout))}async postMessage(t){let e=typeof t=="string"?new l(t):t;await this.request("/",JSON.stringify(e.toCharArray()))}};var R=class{key;secret;options;constructor(t,e,r){this.key=t,this.secret=e,this.options=r||{}}async request(t,e){return d(`https://platform.vestaboard.com${t}`,{"X-Vestaboard-Api-Key":this.key,"X-Vestaboard-Api-Secret":this.secret},e,this.options)}async getViewer(){return await this.request("/viewer")}async getSubscriptions(){return await this.request("/subscriptions")}async postMessage(t,e){let r=!1,s=[],n=typeof t=="string"?new l(t):t;if(typeof e=="string")r=!0,s.push(e);else if(Array.isArray(e))s.push(...e);else{let a=await this.getSubscriptions();s.push(...a.subscriptions.map(i=>i._id))}let o=[];for(let a of s)o.push(await this.request(`/subscriptions/${a}/message`,{characters:n.toCharArray()}));return r?o[0]:o}};export{O as BOARD_LINES,c as BOARD_LINE_LENGTH,m as LocalAPI,l as Message,w as MessageWritePosition,b as MultipleBoards,y as ReadWriteAPI,R as SubscriptionAPI};
1
+ import C from"grapheme-splitter";async function d(h,t,e,r={}){let s=e===void 0?"GET":"POST";e!==void 0&&Object.assign(t,{"Content-Type":"application/json"});let n={method:s,headers:t};e!==void 0&&typeof e=="string"?n.body=e:e!==void 0&&(n.body=JSON.stringify(e));let o=null;for(let i=0;i<10&&(o=await(r.fetch||fetch)(h,n),!o.ok);i++)await new Promise(u=>setTimeout(u,1e3));if(!o?.ok)throw new Error("HTTP Request failed");return r.parseResponse===!1?void 0:await o.json()}var m=class{key;secret;options;constructor(t,e,r){this.key=t,this.secret=e,this.options=r||{}}async request(t,e){return d(`https://platform.vestaboard.com${t}`,{"X-Vestaboard-Api-Key":this.key,"X-Vestaboard-Api-Secret":this.secret},e,this.options)}async getViewer(){return await this.request("/viewer")}async getSubscriptions(){return await this.request("/subscriptions")}async postMessage(t,e){let r=!1,s=[],n=typeof t=="string"?new c(t):t;if(typeof e=="string")r=!0,s.push(e);else if(Array.isArray(e))s.push(...e);else{let a=await this.getSubscriptions();s.push(...a.subscriptions.map(i=>i._id))}let o=[];for(let a of s)o.push(await this.request(`/subscriptions/${a}/message`,{characters:n.toCharArray()}));return r?o[0]:o}};var b=class{key;options;constructor(t,e){this.key=t,this.options=e||{}}async request(t,e){return d(`https://rw.vestaboard.com${t}`,{"X-Vestaboard-Read-Write-Key":this.key},e,this.options)}async getCurrentMessage(){let t=await this.request("/");return new c(JSON.parse(t.currentMessage.layout))}async postMessage(t){let e=typeof t=="string"?new c(t):t;await this.request("/",JSON.stringify(e.toCharArray()))}};var l=22,O=6,w=(r=>(r[r.CURRENT=0]="CURRENT",r[r.NO_SPACE_BETWEEN=1]="NO_SPACE_BETWEEN",r[r.NEXT_LINE=2]="NEXT_LINE",r))(w||{});var A=[[" ",[0]],["A",[1]],["a",[1]],["b",[2]],["B",[2]],["C",[3]],["c",[3]],["d",[4]],["e",[5]],["f",[6]],["g",[7]],["h",[8]],["i",[9]],["j",[10]],["k",[11]],["l",[12]],["m",[13]],["n",[14]],["o",[15]],["p",[16]],["q",[17]],["r",[18]],["s",[19]],["t",[20]],["u",[21]],["v",[22]],["w",[23]],["x",[24]],["y",[25]],["z",[26]],["D",[4]],["E",[5]],["F",[6]],["G",[7]],["H",[8]],["I",[9]],["J",[10]],["K",[11]],["L",[12]],["M",[13]],["N",[14]],["O",[15]],["P",[16]],["Q",[17]],["R",[18]],["S",[19]],["T",[20]],["U",[21]],["V",[22]],["W",[23]],["X",[24]],["Y",[25]],["Z",[26]],["1",[27]],["2",[28]],["3",[29]],["4",[30]],["5",[31]],["6",[32]],["7",[33]],["8",[34]],["9",[35]],["0",[36]],["!",[37]],["@",[38]],["#",[39]],["$",[40]],["(",[41]],[")",[42]],["-",[44]],["+",[46]],["&",[47]],["=",[48]],[";",[49]],[":",[50]],["'",[52]],['"',[53]],["%",[54]],[",",[55]],[".",[56]],["/",[59]],["?",[60]],["\xB0",[62]],["\u20AC",[5,21,18]],["\u0192",[6]],["\u017D",[26]],["\u0161",[19]],["\xBC",[27,59,30]],["\xBD",[27,59,28]],["\xBE",[29,59,30]],["\xC0",[1]],["\xC1",[1]],["\xC2",[1]],["\xC3",[1]],["\xC4",[1,5]],["\xC5",[1]],["\xC6",[1,5]],["\xC7",[3]],["\xC8",[5]],["\xC9",[5]],["\xCA",[5]],["\xCB",[5]],["\xCC",[9]],["\xCD",[9]],["\xCE",[9]],["\xCF",[9]],["\xD0",[5,20,8]],["\xD1",[14]],["\xD2",[15]],["\xD3",[15]],["\xD4",[15]],["\xD5",[15]],["\xD6",[15,5]],["\xD7",[24]],["\xD9",[21]],["\xDA",[21]],["\xDB",[21]],["\xDC",[21,5]],["\xDD",[25]],["\xDF",[19,19]],["\xE0",[1]],["\xE1",[1]],["\xE2",[1]],["\xE3",[1]],["\xE4",[1,5]],["\xE5",[1]],["\xE6",[1,5]],["\xE7",[3]],["\xE8",[5]],["\xE9",[5]],["\xEA",[5]],["\xEB",[5]],["\xEC",[9]],["\xED",[9]],["\xEE",[9]],["\xEF",[9]],["\xF0",[15]],["\xF1",[14]],["\xF2",[15]],["\xF3",[15]],["\xF4",[15]],["\xF5",[15]],["\xF6",[15,5]],["\xF9",[21]],["\xFA",[21]],["\xFB",[21]],["\xFC",[21,5]],["\xFD",[25]],["\xFF",[25]],["\u{1F7E5}",[63]],["\u{1F7E7}",[64]],["\u{1F7E8}",[65]],["\u{1F7E9}",[66]],["\u{1F7E6}",[67]],["\u{1F7EA}",[68]],["\u2B1C\uFE0F",[69]],["\u2B1C",[69]],["\u2B1B\uFE0F",[-2]],["\u2B1B",[-2]],["\uFE6B",[38]],["\uFF20",[38]],["0\uFE0F\u20E3",[36]],["1\uFE0F\u20E3",[27]],["2\uFE0F\u20E3",[28]],["3\uFE0F\u20E3",[29]],["4\uFE0F\u20E3",[30]],["5\uFE0F\u20E3",[31]],["6\uFE0F\u20E3",[32]],["7\uFE0F\u20E3",[33]],["8\uFE0F\u20E3",[34]],["9\uFE0F\u20E3",[35]],["\u2755",[37]],["\u203C\uFE0F",[37,37]],["\u2757\uFE0F",[37]],["\u2049\uFE0F",[37,60]],["#\uFE0F\u20E3",[39]],["\u{1F4B2}",[40]],["$",[40]],["\uFE69",[40]],["\uFF04",[40]],["\u2190",[44]],["\u2192",[44]],["\u27A1",[44]],["\u2B05",[44]],["\u2794",[44]],["\u2194",[44]],["\u2013",[44]],["\u2795",[46]],["+",[46]],["\uFE6A",[54]],["\uFF05",[54]],["\u2753",[60]],["\u2754",[60]],["\u2103",[62,3]],["\u2109",[62,6]]],M=new Array(O).fill(new Array(l).fill(0)),c=class h{static splitter=new C;board;cursor=[0,0];constructor(t){typeof t=="string"&&t?(this.board=JSON.parse(JSON.stringify(M)),this.write(t),this.center()):Array.isArray(t)?this.board=t:this.board=JSON.parse(JSON.stringify(M))}static string2chars(t,e={}){let r=[],s=h.splitter.splitGraphemes(t);for(let n of s)r.push(...this.char2char(n));return e.removeUnsupportedWords!==!1&&(r=h.removeEmojisFromChars(r)),r=r.map(n=>n>=0?n:n===-2?0:typeof e.fallbackChar=="number"?e.fallbackChar:e.fallbackChar===null?-1:60).filter(n=>n>=0),r}static char2char(t){let e=A.find(([r])=>t===r);return e&&Array.isArray(e[1])?e[1]:[-1]}static charToString(t){let e=Object.values(A).filter(([r])=>r.length<=2).find(([,r])=>r[0]===t);return e?e[0].toUpperCase()+(e[0].length===1?" ":""):"\u26A1\uFE0E "}static splitCharsIntoLines(t,e){let r=[];for(let n of t){r.length||r.push([null,[]]);let o=r[r.length-1];n===0?r.push([0,[]]):n===44?(o[1].push(n),r.push([null,[]])):o[1].push(n)}let s=[];for(let[n,o]of r){s.length||s.push([]);let a=s[s.length-1],i=e[s.length===1?0:1]-a.length;if(!a.length&&o.length<=i)a.push(...o);else if(n!==null&&o.length+1<=i)a.push(0,...o);else if(o.length<=i)a.push(...o);else if(o.length<=e[1])a=[...o],i=e[1],s.push(a);else{i>=3&&!a.length||(i>=4&&a.length?(a.push(0),i--):(a=[],i=e[1],s.push(a)));for(let u of o)a.push(u),i--,i<=1&&(a.push(44),a=[],i=e[1],s.push(a))}}return s}static removeEmojisFromChars(t){let e=[];for(let s of t)e.length||e.push([]),s===0?e.push([]):e[e.length-1].push(s);e.forEach(s=>{if(s.length>0&&s[0]===-1)for(;s[0]<0;)s.splice(0,1);if(s.length>0&&s[s.length-1]===-1)for(;s.length>0&&s[s.length-1]<0;)s.splice(s.length-1,1)});let r=[];return e.filter(s=>s.length>0).forEach(s=>{r.length!==0&&r.push(0),r.push(...s)}),r}static getColumnSizesFromData(t,e={}){if(!t.length)return[];let r=t[0].length,s=[];t.forEach((u,p)=>{if(u.length!==r)throw new Error(`Unable to render table: Row ${p} has ${u.length} entries, but first row has ${r}!`);u.forEach((f,g)=>{s[g]=Math.max(s[g]||0,this.string2chars(f,e).length)})});let n=s.reduce((u,p)=>u+p,0),o=t[0].length-1,a=Math.max((l-o)/n,1),i=s.map(u=>Math.round(u*a));for(;;){let u=i.reduce((g,S)=>g+S,0)+o;if(u===l)break;let p=l-u<0?-1:1,f=i.indexOf(p<0?Math.max(...i):Math.min(...i));if(f<0)throw new Error("Unable to find max value in array\u2026");i[f]+=p}return i}get isEmpty(){return!this.board.find(t=>t.find(e=>e!==0))}fill(t=" "){let e=0,r=h.string2chars(t,{removeUnsupportedWords:!1});return this.board.forEach(s=>{s.forEach((n,o)=>{s[o]=r[e],e++,e>r.length-1&&(e=0)})}),this}write(t,e={}){if(!this.board[this.cursor[0]])return this;e.position===2&&(this.cursor[0]!==0||this.cursor[1]!==0)?(this.cursor[0]++,this.cursor[1]=0):typeof e.position=="object"&&(this.cursor[0]=e.position.line,this.cursor[1]=e.position.row||0),(e.position===void 0||e.position===0)&&this.cursor[1]!==0&&this.cursor[1]<l-1&&(this.board[this.cursor[0]].splice(this.cursor[1],1,0),this.cursor[1]+=1);let r=0;e.indent===!0?r=this.cursor[1]:typeof e.indent=="number"&&e.indent>=0&&e.indent<=l-5&&(r=e.indent);let s=t.split(`
2
+ `),n=!0;for(let o of s){let a=h.string2chars(o,e),i=[l-this.cursor[1],l-r];n||(this.cursor[0]++,this.cursor[1]=r),typeof e.position=="object"&&e.position.width&&(i[0]=Math.min(i[0],e.position.width),i[1]=Math.min(i[1],e.position.width-r));let u=h.splitCharsIntoLines(a,i);for(let p of u){if(!this.board[this.cursor[0]])break;this.board[this.cursor[0]].splice(this.cursor[1],p.length,...p),this.cursor[1]+=p.length,p!==u[u.length-1]&&(this.cursor[0]++,this.cursor[1]=r)}n=!1}return this}table(t){let e=h.getColumnSizesFromData(t);return(this.cursor[0]!==0||this.cursor[1]!==0)&&(this.cursor[0]++,this.cursor[1]=0),t.forEach(r=>{let s=this.cursor[0],n=1;r.forEach((o,a)=>{let i=e[a],u=e.filter((p,f)=>f<a).reduce((p,f)=>p+f+1,0);this.write(o,{position:{line:s,row:u,width:i},indent:u}),n=Math.max(n,this.cursor[0]-s+1)}),this.cursor[0]=s+n+1,this.cursor[1]=0}),this}center(){let t=[this.board.findIndex(r=>r.find(s=>s!==0)),Math.min(...this.board.map(r=>r.find(s=>s!==0)?r.slice().reverse().findIndex(s=>s!==0):r.length)),this.board.slice().reverse().findIndex(r=>r.find(s=>s!==0)),Math.min(...this.board.map(r=>r.find(s=>s!==0)?r.findIndex(s=>s!==0):r.length))],e=[Math.floor((t[0]+t[2])/2),Math.floor((t[1]+t[3])/2)];if(t[0]!==e[0]){let r=e[0]-t[0];this.board.splice(r>0?0:this.board.length,0,...this.board.splice(r>0?this.board.length-r:0,Math.abs(r)))}if(t[3]!==e[1]){let r=e[1]-t[3];this.board.forEach(s=>{s.splice(r>0?0:s.length,0,...s.splice(r>0?s.length-r:0,Math.abs(r)))})}}toString(){return"#="+"=".repeat(l*2)+`=#
3
+ `+this.board.map(t=>"# "+t.map(e=>h.charToString(e)).join("")+` #
4
+ `).join("")+"#="+"=".repeat(l*2)+`=#
5
+ `}toCharArray(){return JSON.parse(JSON.stringify(this.board))}};var y=class{key;host;options;constructor(t,e,r){this.key=t,this.host=e||"vestaboard.local",this.options=r||{}}async request(t,e,r={}){return d(`http://${this.host}:7000/local-api/message`,{"X-Vestaboard-Local-Api-Key":this.key},e,Object.assign({},this.options,r))}async getCurrentMessage(){let t=await this.request("/");return new c(Array.isArray(t)?t:t.message)}async postMessage(t){let e=typeof t=="string"?new c(t):t;await this.request("/",JSON.stringify(e.toCharArray()),{parseResponse:!1})}};var R=class{boards;constructor(t=[]){this.boards=t}push(...t){t.forEach(e=>this.boards.push(e))}async postMessage(t){for(let e of this.boards)await e.postMessage(t)}};export{O as BOARD_LINES,l as BOARD_LINE_LENGTH,y as LocalAPI,c as Message,w as MessageWritePosition,R as MultipleBoards,b as ReadWriteAPI,m as SubscriptionAPI};
6
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/message.ts","../src/types.ts","../src/tools.ts","../src/local-api.ts","../src/multiple-boards.ts","../src/read-write-api.ts","../src/subscription-api.ts"],"sourcesContent":["import GraphemeSplitter from 'grapheme-splitter';\nimport { BOARD_LINE_LENGTH, BOARD_LINES, BoardCharArray, MessageWriteOptions, MessageWritePosition } from './types.js';\n\n\n/**\n * Map with all supported characters plus a few emojis\n * mapped to corresponding characters of the Vestaboard\n */\nexport const CHAR_MAP: Array<[string, number[]]> = [\n [' ', [0]],\n ['A', [1]],\n ['a', [1]],\n ['b', [2]],\n ['B', [2]],\n ['C', [3]],\n ['c', [3]],\n ['d', [4]],\n ['e', [5]],\n ['f', [6]],\n ['g', [7]],\n ['h', [8]],\n ['i', [9]],\n ['j', [10]],\n ['k', [11]],\n ['l', [12]],\n ['m', [13]],\n ['n', [14]],\n ['o', [15]],\n ['p', [16]],\n ['q', [17]],\n ['r', [18]],\n ['s', [19]],\n ['t', [20]],\n ['u', [21]],\n ['v', [22]],\n ['w', [23]],\n ['x', [24]],\n ['y', [25]],\n ['z', [26]],\n ['D', [4]],\n ['E', [5]],\n ['F', [6]],\n ['G', [7]],\n ['H', [8]],\n ['I', [9]],\n ['J', [10]],\n ['K', [11]],\n ['L', [12]],\n ['M', [13]],\n ['N', [14]],\n ['O', [15]],\n ['P', [16]],\n ['Q', [17]],\n ['R', [18]],\n ['S', [19]],\n ['T', [20]],\n ['U', [21]],\n ['V', [22]],\n ['W', [23]],\n ['X', [24]],\n ['Y', [25]],\n ['Z', [26]],\n ['1', [27]],\n ['2', [28]],\n ['3', [29]],\n ['4', [30]],\n ['5', [31]],\n ['6', [32]],\n ['7', [33]],\n ['8', [34]],\n ['9', [35]],\n ['0', [36]],\n ['!', [37]],\n ['@', [38]],\n ['#', [39]],\n ['$', [40]],\n ['(', [41]],\n [')', [42]],\n ['-', [44]],\n ['+', [46]],\n ['&', [47]],\n ['=', [48]],\n [';', [49]],\n [':', [50]],\n ['\\'', [52]],\n ['\"', [53]],\n ['%', [54]],\n [',', [55]],\n ['.', [56]],\n ['/', [59]],\n ['?', [60]],\n ['°', [62]],\n ['€', [5, 21, 18]],\n ['ƒ', [6]],\n ['Ž', [26]],\n ['š', [19]],\n ['¼', [27, 59, 30]],\n ['½', [27, 59, 28]],\n ['¾', [29, 59, 30]],\n ['À', [1]],\n ['Á', [1]],\n ['Â', [1]],\n ['Ã', [1]],\n ['Ä', [1, 5]],\n ['Å', [1]],\n ['Æ', [1, 5]],\n ['Ç', [3]],\n ['È', [5]],\n ['É', [5]],\n ['Ê', [5]],\n ['Ë', [5]],\n ['Ì', [9]],\n ['Í', [9]],\n ['Î', [9]],\n ['Ï', [9]],\n ['Ð', [5, 20, 8]],\n ['Ñ', [14]],\n ['Ò', [15]],\n ['Ó', [15]],\n ['Ô', [15]],\n ['Õ', [15]],\n ['Ö', [15, 5]],\n ['×', [24]],\n ['Ù', [21]],\n ['Ú', [21]],\n ['Û', [21]],\n ['Ü', [21, 5]],\n ['Ý', [25]],\n ['ß', [19, 19]],\n ['à', [1]],\n ['á', [1]],\n ['â', [1]],\n ['ã', [1]],\n ['ä', [1, 5]],\n ['å', [1]],\n ['æ', [1, 5]],\n ['ç', [3]],\n ['è', [5]],\n ['é', [5]],\n ['ê', [5]],\n ['ë', [5]],\n ['ì', [9]],\n ['í', [9]],\n ['î', [9]],\n ['ï', [9]],\n ['ð', [15]],\n ['ñ', [14]],\n ['ò', [15]],\n ['ó', [15]],\n ['ô', [15]],\n ['õ', [15]],\n ['ö', [15, 5]],\n ['ù', [21]],\n ['ú', [21]],\n ['û', [21]],\n ['ü', [21, 5]],\n ['ý', [25]],\n ['ÿ', [25]],\n ['🟥', [63]],\n ['🟧', [64]],\n ['🟨', [65]],\n ['🟩', [66]],\n ['🟦', [67]],\n ['🟪', [68]],\n ['⬜️', [69]],\n ['⬜', [69]],\n ['⬛️', [-2]],\n ['⬛', [-2]],\n ['﹫', [38]],\n ['@', [38]],\n ['0️⃣', [36]],\n ['1️⃣', [27]],\n ['2️⃣', [28]],\n ['3️⃣', [29]],\n ['4️⃣', [30]],\n ['5️⃣', [31]],\n ['6️⃣', [32]],\n ['7️⃣', [33]],\n ['8️⃣', [34]],\n ['9️⃣', [35]],\n ['❕', [37]],\n ['‼️', [37, 37]],\n ['❗️', [37]],\n ['⁉️', [37, 60]],\n ['#️⃣', [39]],\n ['💲', [40]],\n ['$', [40]],\n ['﹩', [40]],\n ['$', [40]],\n ['←', [44]],\n ['→', [44]],\n ['➡', [44]],\n ['⬅', [44]],\n ['➔', [44]],\n ['↔', [44]],\n ['–', [44]],\n ['➕', [46]],\n ['+', [46]],\n ['﹪', [54]],\n ['%', [54]],\n ['❓', [60]],\n ['❔', [60]],\n ['℃', [62, 3]],\n ['℉', [62, 6]]\n];\n\nconst EMPTY_BOARD: BoardCharArray = new Array(BOARD_LINES).fill(\n new Array(BOARD_LINE_LENGTH).fill(0)\n) as BoardCharArray;\n\n/**\n * You can build a message like this:\n *\n * ```javascript\n * import { Message } from '@sebbo2002/vestaboard';\n *\n * const myMessage = new Message('Hello World');\n *\n * // same as\n *\n * const myOtherMessage = new Message()\n * .write('Hello World')\n * .center();\n * ```\n */\nexport default class Message {\n private static readonly splitter = new GraphemeSplitter();\n private readonly board: BoardCharArray;\n private cursor = [0, 0];\n\n constructor (message?: BoardCharArray | string) {\n if(typeof message === 'string' && message) {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n this.write(message);\n this.center();\n }\n else if(Array.isArray(message)) {\n this.board = message;\n }\n else {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n }\n }\n\n static string2chars (word: string, options: MessageWriteOptions = {}): number[] {\n let chars: number[] = [];\n const singleCharStrings = Message.splitter.splitGraphemes(word);\n for (const char of singleCharStrings) {\n chars.push(...this.char2char(char));\n }\n\n // trim emoji words if not disabled\n if (options.removeUnsupportedWords !== false) {\n chars = Message.removeEmojisFromChars(chars);\n }\n\n // replace -1 with fallback char\n chars = chars.map(char => {\n if (char >= 0) {\n return char;\n } else if (char === -2) {\n return 0;\n } else if (typeof options.fallbackChar === 'number') {\n return options.fallbackChar;\n } else if (options.fallbackChar === null) {\n return -1;\n } else {\n return 60;\n }\n }).filter(char => char >= 0);\n\n return chars;\n }\n\n static char2char (char: string): number[] {\n const fromMap = CHAR_MAP\n .find(([mapChar]) => char === mapChar);\n\n if (fromMap && Array.isArray(fromMap[1])) {\n return fromMap[1];\n }\n\n return [-1];\n }\n\n static charToString (char: number): string {\n const entry = Object.values(CHAR_MAP)\n .filter(([name]) => name.length <= 2)\n .find(([, code]) => code[0] === char);\n\n if (entry) {\n return entry[0].toUpperCase() + (entry[0].length === 1 ? ' ' : '');\n }\n\n return '⚡︎ ';\n }\n\n static splitCharsIntoLines (chars: number[], lineLength: [number, number]): Array<number[]> {\n // Array with splitting char (if any) and chars of the word\n const words: Array<[number | null, number[]]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([null, []]);\n }\n\n const currentWord = words[words.length - 1];\n if (char === 0) {\n words.push([0, []]);\n } else if (char === 44) {\n currentWord[1].push(char);\n words.push([null, []]);\n } else {\n currentWord[1].push(char);\n }\n }\n\n const lines: Array<number[]> = [];\n for (const [separator, word] of words) {\n if (!lines.length) {\n lines.push([]);\n }\n\n let currentLine = lines[lines.length - 1];\n let charsLeft = lineLength[lines.length === 1 ? 0 : 1] - currentLine.length;\n\n // start of line, word fits\n if (!currentLine.length && word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // add separator and the whole word\n else if (separator !== null && word.length + 1 <= charsLeft) {\n currentLine.push(0, ...word);\n } else if (word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // no space for the word, write into next line\n else if (word.length <= lineLength[1]) {\n currentLine = [...word];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n // word too long for one line, start in\n // current line and continue in next line\n else {\n if (charsLeft >= 3 && !currentLine.length) {\n // No space required in front of long word\n } else if (charsLeft >= 4 && currentLine.length) {\n // Add space for next word\n currentLine.push(0);\n charsLeft--;\n } else {\n // No enough space for word, go to next line\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n for (const char of word) {\n currentLine.push(char);\n charsLeft--;\n\n if (charsLeft <= 1) {\n currentLine.push(44);\n\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n }\n }\n }\n\n return lines;\n }\n\n static removeEmojisFromChars (chars: number[]): number[] {\n const words: Array<number[]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([]);\n }\n\n if (char === 0) {\n words.push([]);\n } else {\n words[words.length - 1].push(char);\n }\n }\n\n words.forEach(chars => {\n if (chars.length > 0 && chars[0] === -1) {\n while (chars[0] < 0) {\n chars.splice(0, 1);\n }\n }\n if (chars.length > 0 && chars[chars.length - 1] === -1) {\n while (chars.length > 0 && chars[chars.length - 1] < 0) {\n chars.splice(chars.length - 1, 1);\n }\n }\n });\n\n const result: number[] = [];\n words\n .filter(chars => chars.length > 0)\n .forEach(chars => {\n if (result.length !== 0) {\n result.push(0);\n }\n\n result.push(...chars);\n });\n\n return result;\n }\n\n static getColumnSizesFromData (rows: Array<string[]>, options: MessageWriteOptions = {}): number[] {\n if (!rows.length) {\n return [];\n }\n\n const columns = rows[0].length;\n const columnDefaultSizes: number[] = [];\n rows.forEach((row, rowIndex) => {\n if (row.length !== columns) {\n throw new Error(`Unable to render table: Row ${rowIndex} has ${row.length} entries, but first row has ${columns}!`);\n }\n row.forEach((column, columnIndex) => {\n columnDefaultSizes[columnIndex] = Math.max(columnDefaultSizes[columnIndex] || 0, this.string2chars(column, options).length);\n });\n });\n\n const columnDefaultSum = columnDefaultSizes.reduce((a, b) => a + b, 0);\n const columnBorders = rows[0].length - 1;\n const factor = Math.max((BOARD_LINE_LENGTH - columnBorders) / columnDefaultSum, 1);\n const columnSizes = columnDefaultSizes.map(size => Math.round(size * factor));\n\n while (true) {\n const size = columnSizes.reduce((a, b) => a + b, 0) + columnBorders;\n if (size === BOARD_LINE_LENGTH) {\n break;\n }\n\n const diff = BOARD_LINE_LENGTH - size < 0 ? -1 : 1;\n const index = columnSizes.indexOf(diff < 0 ? Math.max(...columnSizes) : Math.min(...columnSizes));\n if(index < 0) {\n // This can actually never be achieved...\n throw new Error('Unable to find max value in array…');\n }\n\n columnSizes[index] += diff;\n }\n\n\n return columnSizes;\n }\n\n get isEmpty (): boolean {\n return !this.board.find(line =>\n line.find(char => char !== 0)\n );\n }\n\n /**\n * Fills the board with the passed character or text. The text\n * is repeated again and again until the board is completely filled.\n */\n fill (text = ' '): this {\n let pointer = 0;\n const chars = Message.string2chars(text, {removeUnsupportedWords: false});\n this.board.forEach((line) => {\n line.forEach((char, charIndex) => {\n line[charIndex] = chars[pointer];\n pointer++;\n\n if(pointer > chars.length - 1) {\n pointer = 0;\n }\n });\n });\n return this;\n }\n\n /**\n * Write a text on your new message. If your message is not empty it will continue\n * where you last left off (`position: MessageWritePosition.CURRENT`). Alternatively\n * you can continue on the next line or give an exact position.\n *\n * @param text\n * @param options\n */\n write (text: string, options: MessageWriteOptions = {}): this {\n\n // Cursor blow board length? Just return…\n if (!this.board[this.cursor[0]]) {\n return this;\n }\n\n // Add new line if NEXT_LINE is set (except it's already in the first line)\n if (options.position === MessageWritePosition.NEXT_LINE && (this.cursor[0] !== 0 || this.cursor[1] !== 0)) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n // Set cursor to given position\n else if (typeof options.position === 'object') {\n this.cursor[0] = options.position.line;\n this.cursor[1] = options.position.row || 0;\n }\n\n // Add space before text as it\n // will be rendered in the same line\n if (\n (options.position === undefined || options.position === MessageWritePosition.CURRENT) &&\n this.cursor[1] !== 0 && this.cursor[1] < BOARD_LINE_LENGTH - 1\n ) {\n this.board[this.cursor[0]].splice(this.cursor[1], 1, 0);\n this.cursor[1] += 1;\n }\n\n // Figure out left indent\n let indent = 0;\n if (options.indent === true) {\n indent = this.cursor[1];\n } else if (typeof options.indent === 'number' && options.indent >= 0 && options.indent <= BOARD_LINE_LENGTH - 5) {\n indent = options.indent;\n }\n\n const linesOfText = text.split('\\n');\n let isFirstLine = true;\n for (const lineOfText of linesOfText) {\n const chars = Message.string2chars(lineOfText, options);\n const charsLeftInLine: [number, number] = [\n BOARD_LINE_LENGTH - this.cursor[1],\n BOARD_LINE_LENGTH - indent\n ];\n\n if(!isFirstLine) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n\n if(typeof options.position === 'object' && options.position.width) {\n charsLeftInLine[0] = Math.min(charsLeftInLine[0], options.position.width);\n charsLeftInLine[1] = Math.min(charsLeftInLine[1], options.position.width - indent);\n }\n\n const linesOfChars = Message.splitCharsIntoLines(chars, charsLeftInLine);\n for (const chars of linesOfChars) {\n\n // Board is over, skip line…\n if (!this.board[this.cursor[0]]) {\n break;\n }\n\n // Add chars to current line and update cursor\n this.board[this.cursor[0]].splice(this.cursor[1], chars.length, ...chars);\n this.cursor[1] += chars.length;\n\n // Add new line (and update cursor),\n // if this wasn't the last line\n if (chars !== linesOfChars[linesOfChars.length - 1]) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n }\n\n isFirstLine = false;\n }\n\n return this;\n }\n\n /**\n * Generate a table with the given data\n *\n * @example new Message().table([\n * ['now', 'Daily'],\n * ['13:00', 'Super Secret Meeting'],\n * ['16:30', 'Awesome Presentation']\n * ])\n *\n * #==============================================#\n * # N O W D A I L Y #\n * # #\n * # 1 3 : 0 0 S U P E R S E C R E T #\n * # M E E T I N G #\n * # #\n * # 1 6 : 3 0 A W E S O M E P R E S E N T - #\n * #==============================================#\n */\n table (rows: Array<string[]>): this {\n const columnWidths = Message.getColumnSizesFromData(rows);\n if (this.cursor[0] !== 0 || this.cursor[1] !== 0) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n rows.forEach(line => {\n const lineStart = this.cursor[0];\n let lineHeight = 1;\n\n line.forEach((column, columnIndex) => {\n const columnWidth = columnWidths[columnIndex];\n const indent = columnWidths\n .filter((width, index) => index < columnIndex)\n .reduce((a, b) => a + b + 1, 0);\n\n this.write(column, {\n position: {\n line: lineStart,\n row: indent,\n width: columnWidth\n },\n indent\n });\n\n lineHeight = Math.max(lineHeight, this.cursor[0] - lineStart + 1);\n });\n\n this.cursor[0] = lineStart + lineHeight + 1;\n this.cursor[1] = 0;\n });\n\n return this;\n }\n\n /**\n * Center the current message content\n */\n center(): void {\n const space = [\n this.board.findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.slice().reverse().findIndex(c => c !== 0) : l.length)),\n this.board.slice().reverse().findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.findIndex(c => c !== 0) : l.length)),\n ];\n\n const padding = [\n Math.floor((space[0] + space[2]) / 2),\n Math.floor((space[1] + space[3]) / 2)\n ];\n\n // Move up/down\n if(space[0] !== padding[0]) {\n const add = padding[0] - space[0];\n this.board.splice(add > 0 ? 0 : this.board.length, 0,\n ...this.board.splice(add > 0 ? this.board.length - add : 0, Math.abs(add))\n );\n }\n\n // Move left/right\n if(space[3] !== padding[1]) {\n const add = padding[1] - space[3];\n this.board.forEach(line => {\n line.splice(add > 0 ? 0 : line.length, 0,\n ...line.splice(add > 0 ? line.length - add : 0, Math.abs(add))\n );\n });\n }\n }\n\n toString (): string {\n return '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n' +\n this.board.map(line => '# ' + line.map(char =>\n Message.charToString(char)\n ).join('') + ' #\\n').join('') +\n '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n';\n }\n\n toCharArray (): BoardCharArray {\n return JSON.parse(JSON.stringify(this.board));\n }\n}\n","import SubscriptionAPI from './subscription-api.js';\nimport ReadWriteAPI from './read-write-api.js';\nimport LocalAPI from './local-api.js';\n\nexport const BOARD_LINE_LENGTH = 22;\nexport const BOARD_LINES = 6;\n\nexport type BoardCharLine = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number\n];\n\nexport type BoardCharArray = [\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine\n];\n\nexport interface MessageWriteCoords {\n line: number;\n row?: number;\n width?: number;\n}\n\nexport enum MessageWritePosition {\n CURRENT,\n NO_SPACE_BETWEEN,\n NEXT_LINE\n}\n\nexport interface MessageWriteOptions {\n position?: MessageWriteCoords | MessageWritePosition;\n indent?: boolean | number;\n fallbackChar?: number | null;\n removeUnsupportedWords?: boolean;\n}\n\nexport interface RequestFetchOptions {\n body?: string;\n headers?: Record<string, string>;\n method?: string;\n}\n\nexport interface RequestFetchResponse {\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n json(): Promise<unknown>;\n}\n\nexport type RequestOptionsFetch = (url: string, init?: RequestFetchOptions) => Promise<RequestFetchResponse>;\n\nexport interface RequestOptions {\n fetch?: RequestOptionsFetch;\n parseResponse?: boolean;\n}\n\nexport interface Installation {\n _id: string;\n installable?: {\n _id: string;\n };\n}\n\nexport interface Viewer {\n type: string;\n _id: string;\n _created: string;\n installation: {\n _id: string;\n };\n}\n\nexport interface Subscription {\n _id: string;\n _created: string;\n installation: Installation;\n boards: Array<{_id: string}>;\n}\n\nexport interface Subscriptions {\n subscriptions: Subscription[];\n}\n\nexport interface SubscriptionPostResponse {\n message: {\n id: string;\n created: number;\n }\n}\n\nexport interface ReadWriteGetMessageResponse {\n currentMessage: {\n layout: string;\n }\n}\n\nexport type Boards = Array<LocalAPI | ReadWriteAPI | SubscriptionAPI>;\n","import { RequestFetchOptions, RequestFetchResponse, RequestOptions } from './types.js';\n\nexport async function request<T> (\n url: string,\n headers: Record<string, string>,\n data?: Record<string, unknown> | string,\n options: RequestOptions = {}\n): Promise<T> {\n const method = data === undefined ? 'GET' : 'POST';\n if (data !== undefined) {\n Object.assign(headers, {\n 'Content-Type': 'application/json'\n });\n }\n\n const init: RequestFetchOptions = {\n method,\n headers\n };\n if(data !== undefined && typeof data === 'string') {\n init.body = data;\n }\n else if(data !== undefined) {\n init.body = JSON.stringify(data);\n }\n\n let response: RequestFetchResponse | null = null;\n for (let i = 0; i < 10; i++) {\n response = await (options.fetch || fetch)(url, init);\n if(response.ok) {\n break;\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n\n if(!response?.ok) {\n throw new Error('HTTP Request failed');\n }\n\n if(options.parseResponse === false) {\n return undefined as unknown as T;\n }\n\n const json = await response.json();\n return json as T;\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { BoardCharArray, RequestOptions } from './types.js';\n\nexport default class LocalAPI {\n private readonly key: string;\n private readonly host: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, host?: string, options?: RequestOptions) {\n this.key = key;\n this.host = host || 'vestaboard.local';\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string, options: RequestOptions = {}): Promise<T> {\n return request(`http://${this.host}:7000/local-api/message`, {\n 'X-Vestaboard-Local-Api-Key': this.key\n }, data, Object.assign({}, this.options, options));\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<{message: BoardCharArray} | BoardCharArray>('/');\n return new Message(Array.isArray(response) ? response : response.message);\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray()),\n { parseResponse: false }\n );\n }\n}\n","import { Boards } from './types.js';\nimport Message from './message.js';\n\nexport default class MultipleBoards {\n private readonly boards: Boards;\n\n constructor (boards: Boards = []) {\n this.boards = boards;\n }\n\n push(...boards: Boards): void {\n boards.forEach(board => this.boards.push(board));\n }\n\n async postMessage (message: Message | string): Promise<void> {\n for(const board of this.boards) {\n await board.postMessage(message);\n }\n }\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { ReadWriteGetMessageResponse, RequestOptions } from './types.js';\n\nexport default class ReadWriteAPI {\n private readonly key: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, options?: RequestOptions) {\n this.key = key;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string): Promise<T> {\n return request(`https://rw.vestaboard.com${path}`, {\n 'X-Vestaboard-Read-Write-Key': this.key\n }, data, this.options);\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<ReadWriteGetMessageResponse>('/');\n return new Message(JSON.parse(response.currentMessage.layout));\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray())\n );\n }\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { SubscriptionPostResponse, Subscriptions, Viewer } from './types.js';\nimport { RequestOptions } from './types.js';\n\nexport default class SubscriptionAPI {\n private readonly key: string;\n private readonly secret: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, secret: string, options?: RequestOptions) {\n this.key = key;\n this.secret = secret;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: Record<string, unknown>): Promise<T> {\n return request(`https://platform.vestaboard.com${path}`, {\n 'X-Vestaboard-Api-Key': this.key,\n 'X-Vestaboard-Api-Secret': this.secret\n }, data, this.options);\n }\n\n async getViewer (): Promise<Viewer> {\n return await this.request<Viewer>('/viewer');\n }\n\n async getSubscriptions (): Promise<Subscriptions> {\n return await this.request<Subscriptions>('/subscriptions');\n }\n\n async postMessage (message: Message | string): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionId: string): Promise<SubscriptionPostResponse>;\n async postMessage (message: Message | string, subscriptionIds: string[]): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionIds?: string | string[]) {\n let singleMode = false;\n const ids: string[] = [];\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n\n if (typeof subscriptionIds === 'string') {\n singleMode = true;\n ids.push(subscriptionIds);\n } else if (Array.isArray(subscriptionIds)) {\n ids.push(...subscriptionIds);\n } else {\n const subscriptions = await this.getSubscriptions();\n ids.push(...subscriptions.subscriptions.map(subscription => subscription._id));\n }\n\n const results: SubscriptionPostResponse[] = [];\n for (const id of ids) {\n results.push(\n await this.request<SubscriptionPostResponse>(`/subscriptions/${id}/message`, {\n characters: msgObj.toCharArray()\n })\n );\n }\n if (singleMode) {\n return results[0];\n }\n\n return results;\n }\n}"],"mappings":"AAAA,OAAOA,MAAsB,oBCItB,IAAMC,EAAoB,GACpBC,EAAc,EA0CfC,OACRA,IAAA,qBACAA,IAAA,uCACAA,IAAA,yBAHQA,OAAA,IDvCL,IAAMC,EAAsC,CAC/C,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAM,CAAC,EAAE,CAAC,EACX,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAG,GAAI,EAAE,CAAC,EACjB,CAAC,SAAK,CAAC,CAAC,CAAC,EACT,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,GAAI,EAAE,CAAC,EAClB,CAAC,OAAK,CAAC,GAAI,GAAI,EAAE,CAAC,EAClB,CAAC,OAAK,CAAC,GAAI,GAAI,EAAE,CAAC,EAClB,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,GAAI,CAAC,CAAC,EAChB,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,EAAE,CAAC,EACd,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAG,CAAC,CAAC,EACZ,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,CAAC,CAAC,EACT,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,OAAK,CAAC,EAAE,CAAC,EACV,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,eAAM,CAAC,EAAE,CAAC,EACX,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,eAAM,CAAC,EAAE,CAAC,EACX,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,eAAM,CAAC,GAAI,EAAE,CAAC,EACf,CAAC,eAAM,CAAC,EAAE,CAAC,EACX,CAAC,eAAM,CAAC,GAAI,EAAE,CAAC,EACf,CAAC,gBAAO,CAAC,EAAE,CAAC,EACZ,CAAC,YAAM,CAAC,EAAE,CAAC,EACX,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,EAAE,CAAC,EACV,CAAC,SAAK,CAAC,GAAI,CAAC,CAAC,EACb,CAAC,SAAK,CAAC,GAAI,CAAC,CAAC,CACjB,EAEMC,EAA8B,IAAI,MAAMC,CAAW,EAAE,KACvD,IAAI,MAAMC,CAAiB,EAAE,KAAK,CAAC,CACvC,EAiBqBC,EAArB,MAAqBC,CAAQ,CACzB,OAAwB,SAAW,IAAIC,EACtB,MACT,OAAS,CAAC,EAAG,CAAC,EAEtB,YAAaC,EAAmC,CACzC,OAAOA,GAAY,UAAYA,GAC9B,KAAK,MAAQ,KAAK,MAAM,KAAK,UAAUN,CAAW,CAAC,EACnD,KAAK,MAAMM,CAAO,EAClB,KAAK,OAAO,GAER,MAAM,QAAQA,CAAO,EACzB,KAAK,MAAQA,EAGb,KAAK,MAAQ,KAAK,MAAM,KAAK,UAAUN,CAAW,CAAC,CAE3D,CAEA,OAAO,aAAcO,EAAcC,EAA+B,CAAC,EAAa,CAC5E,IAAIC,EAAkB,CAAC,EACjBC,EAAoBN,EAAQ,SAAS,eAAeG,CAAI,EAC9D,QAAWI,KAAQD,EACfD,EAAM,KAAK,GAAG,KAAK,UAAUE,CAAI,CAAC,EAItC,OAAIH,EAAQ,yBAA2B,KACnCC,EAAQL,EAAQ,sBAAsBK,CAAK,GAI/CA,EAAQA,EAAM,IAAIE,GACVA,GAAQ,EACDA,EACAA,IAAS,GACT,EACA,OAAOH,EAAQ,cAAiB,SAChCA,EAAQ,aACRA,EAAQ,eAAiB,KACzB,GAEA,EAEd,EAAE,OAAOG,GAAQA,GAAQ,CAAC,EAEpBF,CACX,CAEA,OAAO,UAAWE,EAAwB,CACtC,IAAMC,EAAUb,EACX,KAAK,CAAC,CAACc,CAAO,IAAMF,IAASE,CAAO,EAEzC,OAAID,GAAW,MAAM,QAAQA,EAAQ,CAAC,CAAC,EAC5BA,EAAQ,CAAC,EAGb,CAAC,EAAE,CACd,CAEA,OAAO,aAAcD,EAAsB,CACvC,IAAMG,EAAQ,OAAO,OAAOf,CAAQ,EAC/B,OAAO,CAAC,CAACgB,CAAI,IAAMA,EAAK,QAAU,CAAC,EACnC,KAAK,CAAC,CAAC,CAAEC,CAAI,IAAMA,EAAK,CAAC,IAAML,CAAI,EAExC,OAAIG,EACOA,EAAM,CAAC,EAAE,YAAY,GAAKA,EAAM,CAAC,EAAE,SAAW,EAAI,IAAM,IAG5D,eACX,CAEA,OAAO,oBAAqBL,EAAiBQ,EAA+C,CAExF,IAAMC,EAA0C,CAAC,EACjD,QAAWP,KAAQF,EAAO,CACjBS,EAAM,QACPA,EAAM,KAAK,CAAC,KAAM,CAAC,CAAC,CAAC,EAGzB,IAAMC,EAAcD,EAAMA,EAAM,OAAS,CAAC,EACtCP,IAAS,EACTO,EAAM,KAAK,CAAC,EAAG,CAAC,CAAC,CAAC,EACXP,IAAS,IAChBQ,EAAY,CAAC,EAAE,KAAKR,CAAI,EACxBO,EAAM,KAAK,CAAC,KAAM,CAAC,CAAC,CAAC,GAErBC,EAAY,CAAC,EAAE,KAAKR,CAAI,CAEhC,CAEA,IAAMS,EAAyB,CAAC,EAChC,OAAW,CAACC,EAAWd,CAAI,IAAKW,EAAO,CAC9BE,EAAM,QACPA,EAAM,KAAK,CAAC,CAAC,EAGjB,IAAIE,EAAcF,EAAMA,EAAM,OAAS,CAAC,EACpCG,EAAYN,EAAWG,EAAM,SAAW,EAAI,EAAI,CAAC,EAAIE,EAAY,OAGrE,GAAI,CAACA,EAAY,QAAUf,EAAK,QAAUgB,EACtCD,EAAY,KAAK,GAAGf,CAAI,UAInBc,IAAc,MAAQd,EAAK,OAAS,GAAKgB,EAC9CD,EAAY,KAAK,EAAG,GAAGf,CAAI,UACpBA,EAAK,QAAUgB,EACtBD,EAAY,KAAK,GAAGf,CAAI,UAInBA,EAAK,QAAUU,EAAW,CAAC,EAChCK,EAAc,CAAC,GAAGf,CAAI,EACtBgB,EAAYN,EAAW,CAAC,EACxBG,EAAM,KAAKE,CAAW,MAKrB,CACGC,GAAa,GAAK,CAACD,EAAY,SAExBC,GAAa,GAAKD,EAAY,QAErCA,EAAY,KAAK,CAAC,EAClBC,MAGAD,EAAc,CAAC,EACfC,EAAYN,EAAW,CAAC,EACxBG,EAAM,KAAKE,CAAW,IAG1B,QAAWX,KAAQJ,EACfe,EAAY,KAAKX,CAAI,EACrBY,IAEIA,GAAa,IACbD,EAAY,KAAK,EAAE,EAEnBA,EAAc,CAAC,EACfC,EAAYN,EAAW,CAAC,EACxBG,EAAM,KAAKE,CAAW,EAGlC,CACJ,CAEA,OAAOF,CACX,CAEA,OAAO,sBAAuBX,EAA2B,CACrD,IAAMS,EAAyB,CAAC,EAChC,QAAWP,KAAQF,EACVS,EAAM,QACPA,EAAM,KAAK,CAAC,CAAC,EAGbP,IAAS,EACTO,EAAM,KAAK,CAAC,CAAC,EAEbA,EAAMA,EAAM,OAAS,CAAC,EAAE,KAAKP,CAAI,EAIzCO,EAAM,QAAQT,GAAS,CACnB,GAAIA,EAAM,OAAS,GAAKA,EAAM,CAAC,IAAM,GACjC,KAAOA,EAAM,CAAC,EAAI,GACdA,EAAM,OAAO,EAAG,CAAC,EAGzB,GAAIA,EAAM,OAAS,GAAKA,EAAMA,EAAM,OAAS,CAAC,IAAM,GAChD,KAAOA,EAAM,OAAS,GAAKA,EAAMA,EAAM,OAAS,CAAC,EAAI,GACjDA,EAAM,OAAOA,EAAM,OAAS,EAAG,CAAC,CAG5C,CAAC,EAED,IAAMe,EAAmB,CAAC,EAC1B,OAAAN,EACK,OAAOT,GAASA,EAAM,OAAS,CAAC,EAChC,QAAQA,GAAS,CACVe,EAAO,SAAW,GAClBA,EAAO,KAAK,CAAC,EAGjBA,EAAO,KAAK,GAAGf,CAAK,CACxB,CAAC,EAEEe,CACX,CAEA,OAAO,uBAAwBC,EAAuBjB,EAA+B,CAAC,EAAa,CAC/F,GAAI,CAACiB,EAAK,OACN,MAAO,CAAC,EAGZ,IAAMC,EAAUD,EAAK,CAAC,EAAE,OAClBE,EAA+B,CAAC,EACtCF,EAAK,QAAQ,CAACG,EAAKC,IAAa,CAC5B,GAAID,EAAI,SAAWF,EACf,MAAM,IAAI,MAAM,+BAA+BG,CAAQ,QAAQD,EAAI,MAAM,+BAA+BF,CAAO,GAAG,EAEtHE,EAAI,QAAQ,CAACE,EAAQC,IAAgB,CACjCJ,EAAmBI,CAAW,EAAI,KAAK,IAAIJ,EAAmBI,CAAW,GAAK,EAAG,KAAK,aAAaD,EAAQtB,CAAO,EAAE,MAAM,CAC9H,CAAC,CACL,CAAC,EAED,IAAMwB,EAAmBL,EAAmB,OAAO,CAACM,EAAGC,IAAMD,EAAIC,EAAG,CAAC,EAC/DC,EAAgBV,EAAK,CAAC,EAAE,OAAS,EACjCW,EAAS,KAAK,KAAKlC,EAAoBiC,GAAiBH,EAAkB,CAAC,EAC3EK,EAAcV,EAAmB,IAAIW,GAAQ,KAAK,MAAMA,EAAOF,CAAM,CAAC,EAE5E,OAAa,CACT,IAAME,EAAOD,EAAY,OAAO,CAACJ,EAAGC,IAAMD,EAAIC,EAAG,CAAC,EAAIC,EACtD,GAAIG,IAASpC,EACT,MAGJ,IAAMqC,EAAOrC,EAAoBoC,EAAO,EAAI,GAAK,EAC3CE,EAAQH,EAAY,QAAQE,EAAO,EAAI,KAAK,IAAI,GAAGF,CAAW,EAAI,KAAK,IAAI,GAAGA,CAAW,CAAC,EAChG,GAAGG,EAAQ,EAEP,MAAM,IAAI,MAAM,yCAAoC,EAGxDH,EAAYG,CAAK,GAAKD,CAC1B,CAGA,OAAOF,CACX,CAEA,IAAI,SAAoB,CACpB,MAAO,CAAC,KAAK,MAAM,KAAKI,GACpBA,EAAK,KAAK9B,GAAQA,IAAS,CAAC,CAChC,CACJ,CAMA,KAAM+B,EAAO,IAAW,CACpB,IAAIC,EAAU,EACRlC,EAAQL,EAAQ,aAAasC,EAAM,CAAC,uBAAwB,EAAK,CAAC,EACxE,YAAK,MAAM,QAASD,GAAS,CACzBA,EAAK,QAAQ,CAAC9B,EAAMiC,IAAc,CAC9BH,EAAKG,CAAS,EAAInC,EAAMkC,CAAO,EAC/BA,IAEGA,EAAUlC,EAAM,OAAS,IACxBkC,EAAU,EAElB,CAAC,CACL,CAAC,EACM,IACX,CAUA,MAAOD,EAAclC,EAA+B,CAAC,EAAS,CAG1D,GAAI,CAAC,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAC1B,OAAO,KAIPA,EAAQ,WAAa,IAAmC,KAAK,OAAO,CAAC,IAAM,GAAK,KAAK,OAAO,CAAC,IAAM,IACnG,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAI,GAIZ,OAAOA,EAAQ,UAAa,WACjC,KAAK,OAAO,CAAC,EAAIA,EAAQ,SAAS,KAClC,KAAK,OAAO,CAAC,EAAIA,EAAQ,SAAS,KAAO,IAMxCA,EAAQ,WAAa,QAAaA,EAAQ,WAAa,IACxD,KAAK,OAAO,CAAC,IAAM,GAAK,KAAK,OAAO,CAAC,EAAIN,EAAoB,IAE7D,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,EAAG,EAAG,CAAC,EACtD,KAAK,OAAO,CAAC,GAAK,GAItB,IAAI2C,EAAS,EACTrC,EAAQ,SAAW,GACnBqC,EAAS,KAAK,OAAO,CAAC,EACf,OAAOrC,EAAQ,QAAW,UAAYA,EAAQ,QAAU,GAAKA,EAAQ,QAAUN,EAAoB,IAC1G2C,EAASrC,EAAQ,QAGrB,IAAMsC,EAAcJ,EAAK,MAAM;AAAA,CAAI,EAC/BK,EAAc,GAClB,QAAWC,KAAcF,EAAa,CAClC,IAAMrC,EAAQL,EAAQ,aAAa4C,EAAYxC,CAAO,EAChDyC,EAAoC,CACtC/C,EAAoB,KAAK,OAAO,CAAC,EACjCA,EAAoB2C,CACxB,EAEIE,IACA,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAIF,GAGlB,OAAOrC,EAAQ,UAAa,UAAYA,EAAQ,SAAS,QACxDyC,EAAgB,CAAC,EAAI,KAAK,IAAIA,EAAgB,CAAC,EAAGzC,EAAQ,SAAS,KAAK,EACxEyC,EAAgB,CAAC,EAAI,KAAK,IAAIA,EAAgB,CAAC,EAAGzC,EAAQ,SAAS,MAAQqC,CAAM,GAGrF,IAAMK,EAAe9C,EAAQ,oBAAoBK,EAAOwC,CAAe,EACvE,QAAWxC,KAASyC,EAAc,CAG9B,GAAI,CAAC,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAC1B,MAIJ,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,EAAGzC,EAAM,OAAQ,GAAGA,CAAK,EACxE,KAAK,OAAO,CAAC,GAAKA,EAAM,OAIpBA,IAAUyC,EAAaA,EAAa,OAAS,CAAC,IAC9C,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAIL,EAEzB,CAEAE,EAAc,EAClB,CAEA,OAAO,IACX,CAoBA,MAAOtB,EAA6B,CAChC,IAAM0B,EAAe/C,EAAQ,uBAAuBqB,CAAI,EACxD,OAAI,KAAK,OAAO,CAAC,IAAM,GAAK,KAAK,OAAO,CAAC,IAAM,KAC3C,KAAK,OAAO,CAAC,IACb,KAAK,OAAO,CAAC,EAAI,GAGrBA,EAAK,QAAQgB,GAAQ,CACjB,IAAMW,EAAY,KAAK,OAAO,CAAC,EAC3BC,EAAa,EAEjBZ,EAAK,QAAQ,CAACX,EAAQC,IAAgB,CAClC,IAAMuB,EAAcH,EAAapB,CAAW,EACtCc,EAASM,EACV,OAAO,CAACI,EAAOf,IAAUA,EAAQT,CAAW,EAC5C,OAAO,CAACE,EAAGC,IAAMD,EAAIC,EAAI,EAAG,CAAC,EAElC,KAAK,MAAMJ,EAAQ,CACf,SAAU,CACN,KAAMsB,EACN,IAAKP,EACL,MAAOS,CACX,EACA,OAAAT,CACJ,CAAC,EAEDQ,EAAa,KAAK,IAAIA,EAAY,KAAK,OAAO,CAAC,EAAID,EAAY,CAAC,CACpE,CAAC,EAED,KAAK,OAAO,CAAC,EAAIA,EAAYC,EAAa,EAC1C,KAAK,OAAO,CAAC,EAAI,CACrB,CAAC,EAEM,IACX,CAKA,QAAe,CACX,IAAMG,EAAQ,CACV,KAAK,MAAM,UAAUC,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,CAAC,EAC9C,KAAK,IAAI,GAAG,KAAK,MAAM,IAAID,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,EAAID,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAUC,GAAKA,IAAM,CAAC,EAAID,EAAE,MAAM,CAAC,EAC9G,KAAK,MAAM,MAAM,EAAE,QAAQ,EAAE,UAAUA,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,CAAC,EAChE,KAAK,IAAI,GAAG,KAAK,MAAM,IAAID,GAAKA,EAAE,KAAKC,GAAKA,IAAM,CAAC,EAAID,EAAE,UAAUC,GAAKA,IAAM,CAAC,EAAID,EAAE,MAAM,CAAC,CAChG,EAEME,EAAU,CACZ,KAAK,OAAOH,EAAM,CAAC,EAAIA,EAAM,CAAC,GAAK,CAAC,EACpC,KAAK,OAAOA,EAAM,CAAC,EAAIA,EAAM,CAAC,GAAK,CAAC,CACxC,EAGA,GAAGA,EAAM,CAAC,IAAMG,EAAQ,CAAC,EAAG,CACxB,IAAMC,EAAMD,EAAQ,CAAC,EAAIH,EAAM,CAAC,EAChC,KAAK,MAAM,OAAOI,EAAM,EAAI,EAAI,KAAK,MAAM,OAAQ,EAC/C,GAAG,KAAK,MAAM,OAAOA,EAAM,EAAI,KAAK,MAAM,OAASA,EAAM,EAAG,KAAK,IAAIA,CAAG,CAAC,CAC7E,CACJ,CAGA,GAAGJ,EAAM,CAAC,IAAMG,EAAQ,CAAC,EAAG,CACxB,IAAMC,EAAMD,EAAQ,CAAC,EAAIH,EAAM,CAAC,EAChC,KAAK,MAAM,QAAQf,GAAQ,CACvBA,EAAK,OAAOmB,EAAM,EAAI,EAAInB,EAAK,OAAQ,EACnC,GAAGA,EAAK,OAAOmB,EAAM,EAAInB,EAAK,OAASmB,EAAM,EAAG,KAAK,IAAIA,CAAG,CAAC,CACjE,CACJ,CAAC,CACL,CACJ,CAEA,UAAoB,CAChB,MAAO,KAAO,IAAI,OAAO1D,EAAoB,CAAC,EAAI;AAAA,EAC9C,KAAK,MAAM,IAAIuC,GAAQ,KAAOA,EAAK,IAAI9B,GACnCP,EAAQ,aAAaO,CAAI,CAC7B,EAAE,KAAK,EAAE,EAAI;AAAA,CAAM,EAAE,KAAK,EAAE,EAC5B,KAAO,IAAI,OAAOT,EAAoB,CAAC,EAAI;AAAA,CACnD,CAEA,aAA+B,CAC3B,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,KAAK,CAAC,CAChD,CACJ,EElqBA,eAAsB2D,EAClBC,EACAC,EACAC,EACAC,EAA0B,CAAC,EACjB,CACV,IAAMC,EAASF,IAAS,OAAY,MAAQ,OACxCA,IAAS,QACT,OAAO,OAAOD,EAAS,CACnB,eAAgB,kBACpB,CAAC,EAGL,IAAMI,EAA4B,CAC9B,OAAAD,EACA,QAAAH,CACJ,EACGC,IAAS,QAAa,OAAOA,GAAS,SACrCG,EAAK,KAAOH,EAERA,IAAS,SACbG,EAAK,KAAO,KAAK,UAAUH,CAAI,GAGnC,IAAII,EAAwC,KAC5C,QAAS,EAAI,EAAG,EAAI,KAChBA,EAAW,MAAOH,EAAQ,OAAS,OAAOH,EAAKK,CAAI,EAChD,CAAAC,EAAS,IAFQ,IAMpB,MAAM,IAAI,QAAQC,GAAW,WAAWA,EAAS,GAAI,CAAC,EAG1D,GAAG,CAACD,GAAU,GACV,MAAM,IAAI,MAAM,qBAAqB,EAGzC,OAAGH,EAAQ,gBAAkB,GACzB,OAGS,MAAMG,EAAS,KAAK,CAErC,CC1CA,IAAqBE,EAArB,KAA8B,CACT,IACA,KACA,QAEjB,YAAaC,EAAaC,EAAeC,EAA0B,CAC/D,KAAK,IAAMF,EACX,KAAK,KAAOC,GAAQ,mBACpB,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAAeF,EAA0B,CAAC,EAAe,CAC7F,OAAOG,EAAQ,UAAU,KAAK,IAAI,0BAA2B,CACzD,6BAA8B,KAAK,GACvC,EAAGD,EAAM,OAAO,OAAO,CAAC,EAAG,KAAK,QAASF,CAAO,CAAC,CACrD,CAEA,MAAM,mBAAuC,CACzC,IAAMI,EAAW,MAAM,KAAK,QAAoD,GAAG,EACnF,OAAO,IAAIC,EAAQ,MAAM,QAAQD,CAAQ,EAAIA,EAAWA,EAAS,OAAO,CAC5E,CAEA,MAAM,YAAaE,EAA2B,CAC1C,IAAMC,EAAS,OAAOD,GAAY,SAAW,IAAID,EAAQC,CAAO,EAAIA,EACpE,MAAM,KAAK,QAAc,IACrB,KAAK,UAAUC,EAAO,YAAY,CAAC,EACnC,CAAE,cAAe,EAAM,CAC3B,CACJ,CACJ,EC9BA,IAAqBC,EAArB,KAAoC,CACf,OAEjB,YAAaC,EAAiB,CAAC,EAAG,CAC9B,KAAK,OAASA,CAClB,CAEA,QAAQA,EAAsB,CAC1BA,EAAO,QAAQC,GAAS,KAAK,OAAO,KAAKA,CAAK,CAAC,CACnD,CAEA,MAAM,YAAaC,EAA0C,CACzD,QAAUD,KAAS,KAAK,OACpB,MAAMA,EAAM,YAAYC,CAAO,CAEvC,CACJ,ECfA,IAAqBC,EAArB,KAAkC,CACb,IACA,QAEjB,YAAaC,EAAaC,EAA0B,CAChD,KAAK,IAAMD,EACX,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAA2B,CAC/D,OAAOC,EAAQ,4BAA4BF,CAAI,GAAI,CAC/C,8BAA+B,KAAK,GACxC,EAAGC,EAAM,KAAK,OAAO,CACzB,CAEA,MAAM,mBAAuC,CACzC,IAAME,EAAW,MAAM,KAAK,QAAqC,GAAG,EACpE,OAAO,IAAIC,EAAQ,KAAK,MAAMD,EAAS,eAAe,MAAM,CAAC,CACjE,CAEA,MAAM,YAAaE,EAA2B,CAC1C,IAAMC,EAAS,OAAOD,GAAY,SAAW,IAAID,EAAQC,CAAO,EAAIA,EACpE,MAAM,KAAK,QAAc,IACrB,KAAK,UAAUC,EAAO,YAAY,CAAC,CACvC,CACJ,CACJ,ECzBA,IAAqBC,EAArB,KAAqC,CAChB,IACA,OACA,QAEjB,YAAaC,EAAaC,EAAgBC,EAA0B,CAChE,KAAK,IAAMF,EACX,KAAK,OAASC,EACd,KAAK,QAAUC,GAAW,CAAC,CAC/B,CAEA,MAAc,QAAYC,EAAcC,EAA4C,CAChF,OAAOC,EAAQ,kCAAkCF,CAAI,GAAI,CACrD,uBAAwB,KAAK,IAC7B,0BAA2B,KAAK,MACpC,EAAGC,EAAM,KAAK,OAAO,CACzB,CAEA,MAAM,WAA8B,CAChC,OAAO,MAAM,KAAK,QAAgB,SAAS,CAC/C,CAEA,MAAM,kBAA4C,CAC9C,OAAO,MAAM,KAAK,QAAuB,gBAAgB,CAC7D,CAKA,MAAM,YAAaE,EAA2BC,EAAqC,CAC/E,IAAIC,EAAa,GACXC,EAAgB,CAAC,EACjBC,EAAS,OAAOJ,GAAY,SAAW,IAAIK,EAAQL,CAAO,EAAIA,EAEpE,GAAI,OAAOC,GAAoB,SAC3BC,EAAa,GACbC,EAAI,KAAKF,CAAe,UACjB,MAAM,QAAQA,CAAe,EACpCE,EAAI,KAAK,GAAGF,CAAe,MACxB,CACH,IAAMK,EAAgB,MAAM,KAAK,iBAAiB,EAClDH,EAAI,KAAK,GAAGG,EAAc,cAAc,IAAIC,GAAgBA,EAAa,GAAG,CAAC,CACjF,CAEA,IAAMC,EAAsC,CAAC,EAC7C,QAAWC,KAAMN,EACbK,EAAQ,KACJ,MAAM,KAAK,QAAkC,kBAAkBC,CAAE,WAAY,CACzE,WAAYL,EAAO,YAAY,CACnC,CAAC,CACL,EAEJ,OAAIF,EACOM,EAAQ,CAAC,EAGbA,CACX,CACJ","names":["GraphemeSplitter","BOARD_LINE_LENGTH","BOARD_LINES","MessageWritePosition","CHAR_MAP","EMPTY_BOARD","BOARD_LINES","BOARD_LINE_LENGTH","Message","_Message","GraphemeSplitter","message","word","options","chars","singleCharStrings","char","fromMap","mapChar","entry","name","code","lineLength","words","currentWord","lines","separator","currentLine","charsLeft","result","rows","columns","columnDefaultSizes","row","rowIndex","column","columnIndex","columnDefaultSum","a","b","columnBorders","factor","columnSizes","size","diff","index","line","text","pointer","charIndex","indent","linesOfText","isFirstLine","lineOfText","charsLeftInLine","linesOfChars","columnWidths","lineStart","lineHeight","columnWidth","width","space","l","c","padding","add","request","url","headers","data","options","method","init","response","resolve","LocalAPI","key","host","options","path","data","request","response","Message","message","msgObj","MultipleBoards","boards","board","message","ReadWriteAPI","key","options","path","data","request","response","Message","message","msgObj","SubscriptionAPI","key","secret","options","path","data","request","message","subscriptionIds","singleMode","ids","msgObj","Message","subscriptions","subscription","results","id"]}
1
+ {"version":3,"sources":["../src/message.ts","../src/tools.ts","../src/subscription-api.ts","../src/read-write-api.ts","../src/types.ts","../src/local-api.ts","../src/multiple-boards.ts"],"sourcesContent":["import GraphemeSplitter from 'grapheme-splitter';\nimport {\n BOARD_LINES,\n BOARD_LINE_LENGTH,\n MessageWritePosition,\n type BoardCharArray,\n type MessageWriteOptions,\n} from './types.js';\n\n\n/**\n * Map with all supported characters plus a few emojis\n * mapped to corresponding characters of the Vestaboard\n */\nexport const CHAR_MAP: Array<[string, number[]]> = [\n [' ', [0]],\n ['A', [1]],\n ['a', [1]],\n ['b', [2]],\n ['B', [2]],\n ['C', [3]],\n ['c', [3]],\n ['d', [4]],\n ['e', [5]],\n ['f', [6]],\n ['g', [7]],\n ['h', [8]],\n ['i', [9]],\n ['j', [10]],\n ['k', [11]],\n ['l', [12]],\n ['m', [13]],\n ['n', [14]],\n ['o', [15]],\n ['p', [16]],\n ['q', [17]],\n ['r', [18]],\n ['s', [19]],\n ['t', [20]],\n ['u', [21]],\n ['v', [22]],\n ['w', [23]],\n ['x', [24]],\n ['y', [25]],\n ['z', [26]],\n ['D', [4]],\n ['E', [5]],\n ['F', [6]],\n ['G', [7]],\n ['H', [8]],\n ['I', [9]],\n ['J', [10]],\n ['K', [11]],\n ['L', [12]],\n ['M', [13]],\n ['N', [14]],\n ['O', [15]],\n ['P', [16]],\n ['Q', [17]],\n ['R', [18]],\n ['S', [19]],\n ['T', [20]],\n ['U', [21]],\n ['V', [22]],\n ['W', [23]],\n ['X', [24]],\n ['Y', [25]],\n ['Z', [26]],\n ['1', [27]],\n ['2', [28]],\n ['3', [29]],\n ['4', [30]],\n ['5', [31]],\n ['6', [32]],\n ['7', [33]],\n ['8', [34]],\n ['9', [35]],\n ['0', [36]],\n ['!', [37]],\n ['@', [38]],\n ['#', [39]],\n ['$', [40]],\n ['(', [41]],\n [')', [42]],\n ['-', [44]],\n ['+', [46]],\n ['&', [47]],\n ['=', [48]],\n [';', [49]],\n [':', [50]],\n ['\\'', [52]],\n ['\"', [53]],\n ['%', [54]],\n [',', [55]],\n ['.', [56]],\n ['/', [59]],\n ['?', [60]],\n ['°', [62]],\n ['€', [5, 21, 18]],\n ['ƒ', [6]],\n ['Ž', [26]],\n ['š', [19]],\n ['¼', [27, 59, 30]],\n ['½', [27, 59, 28]],\n ['¾', [29, 59, 30]],\n ['À', [1]],\n ['Á', [1]],\n ['Â', [1]],\n ['Ã', [1]],\n ['Ä', [1, 5]],\n ['Å', [1]],\n ['Æ', [1, 5]],\n ['Ç', [3]],\n ['È', [5]],\n ['É', [5]],\n ['Ê', [5]],\n ['Ë', [5]],\n ['Ì', [9]],\n ['Í', [9]],\n ['Î', [9]],\n ['Ï', [9]],\n ['Ð', [5, 20, 8]],\n ['Ñ', [14]],\n ['Ò', [15]],\n ['Ó', [15]],\n ['Ô', [15]],\n ['Õ', [15]],\n ['Ö', [15, 5]],\n ['×', [24]],\n ['Ù', [21]],\n ['Ú', [21]],\n ['Û', [21]],\n ['Ü', [21, 5]],\n ['Ý', [25]],\n ['ß', [19, 19]],\n ['à', [1]],\n ['á', [1]],\n ['â', [1]],\n ['ã', [1]],\n ['ä', [1, 5]],\n ['å', [1]],\n ['æ', [1, 5]],\n ['ç', [3]],\n ['è', [5]],\n ['é', [5]],\n ['ê', [5]],\n ['ë', [5]],\n ['ì', [9]],\n ['í', [9]],\n ['î', [9]],\n ['ï', [9]],\n ['ð', [15]],\n ['ñ', [14]],\n ['ò', [15]],\n ['ó', [15]],\n ['ô', [15]],\n ['õ', [15]],\n ['ö', [15, 5]],\n ['ù', [21]],\n ['ú', [21]],\n ['û', [21]],\n ['ü', [21, 5]],\n ['ý', [25]],\n ['ÿ', [25]],\n ['🟥', [63]],\n ['🟧', [64]],\n ['🟨', [65]],\n ['🟩', [66]],\n ['🟦', [67]],\n ['🟪', [68]],\n ['⬜️', [69]],\n ['⬜', [69]],\n ['⬛️', [-2]],\n ['⬛', [-2]],\n ['﹫', [38]],\n ['@', [38]],\n ['0️⃣', [36]],\n ['1️⃣', [27]],\n ['2️⃣', [28]],\n ['3️⃣', [29]],\n ['4️⃣', [30]],\n ['5️⃣', [31]],\n ['6️⃣', [32]],\n ['7️⃣', [33]],\n ['8️⃣', [34]],\n ['9️⃣', [35]],\n ['❕', [37]],\n ['‼️', [37, 37]],\n ['❗️', [37]],\n ['⁉️', [37, 60]],\n ['#️⃣', [39]],\n ['💲', [40]],\n ['$', [40]],\n ['﹩', [40]],\n ['$', [40]],\n ['←', [44]],\n ['→', [44]],\n ['➡', [44]],\n ['⬅', [44]],\n ['➔', [44]],\n ['↔', [44]],\n ['–', [44]],\n ['➕', [46]],\n ['+', [46]],\n ['﹪', [54]],\n ['%', [54]],\n ['❓', [60]],\n ['❔', [60]],\n ['℃', [62, 3]],\n ['℉', [62, 6]]\n];\n\nconst EMPTY_BOARD: BoardCharArray = new Array(BOARD_LINES).fill(\n new Array(BOARD_LINE_LENGTH).fill(0)\n) as BoardCharArray;\n\n/**\n * You can build a message like this:\n *\n * ```javascript\n * import { Message } from '@sebbo2002/vestaboard';\n *\n * const myMessage = new Message('Hello World');\n *\n * // same as\n *\n * const myOtherMessage = new Message()\n * .write('Hello World')\n * .center();\n * ```\n */\nexport default class Message {\n private static readonly splitter = new GraphemeSplitter();\n private readonly board: BoardCharArray;\n private cursor = [0, 0];\n\n constructor (message?: BoardCharArray | string) {\n if(typeof message === 'string' && message) {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n this.write(message);\n this.center();\n }\n else if(Array.isArray(message)) {\n this.board = message;\n }\n else {\n this.board = JSON.parse(JSON.stringify(EMPTY_BOARD));\n }\n }\n\n static string2chars (word: string, options: MessageWriteOptions = {}): number[] {\n let chars: number[] = [];\n const singleCharStrings = Message.splitter.splitGraphemes(word);\n for (const char of singleCharStrings) {\n chars.push(...this.char2char(char));\n }\n\n // trim emoji words if not disabled\n if (options.removeUnsupportedWords !== false) {\n chars = Message.removeEmojisFromChars(chars);\n }\n\n // replace -1 with fallback char\n chars = chars.map(char => {\n if (char >= 0) {\n return char;\n } else if (char === -2) {\n return 0;\n } else if (typeof options.fallbackChar === 'number') {\n return options.fallbackChar;\n } else if (options.fallbackChar === null) {\n return -1;\n } else {\n return 60;\n }\n }).filter(char => char >= 0);\n\n return chars;\n }\n\n static char2char (char: string): number[] {\n const fromMap = CHAR_MAP\n .find(([mapChar]) => char === mapChar);\n\n if (fromMap && Array.isArray(fromMap[1])) {\n return fromMap[1];\n }\n\n return [-1];\n }\n\n static charToString (char: number): string {\n const entry = Object.values(CHAR_MAP)\n .filter(([name]) => name.length <= 2)\n .find(([, code]) => code[0] === char);\n\n if (entry) {\n return entry[0].toUpperCase() + (entry[0].length === 1 ? ' ' : '');\n }\n\n return '⚡︎ ';\n }\n\n static splitCharsIntoLines (chars: number[], lineLength: [number, number]): Array<number[]> {\n // Array with splitting char (if any) and chars of the word\n const words: Array<[number | null, number[]]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([null, []]);\n }\n\n const currentWord = words[words.length - 1];\n if (char === 0) {\n words.push([0, []]);\n } else if (char === 44) {\n currentWord[1].push(char);\n words.push([null, []]);\n } else {\n currentWord[1].push(char);\n }\n }\n\n const lines: Array<number[]> = [];\n for (const [separator, word] of words) {\n if (!lines.length) {\n lines.push([]);\n }\n\n let currentLine = lines[lines.length - 1];\n let charsLeft = lineLength[lines.length === 1 ? 0 : 1] - currentLine.length;\n\n // start of line, word fits\n if (!currentLine.length && word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // add separator and the whole word\n else if (separator !== null && word.length + 1 <= charsLeft) {\n currentLine.push(0, ...word);\n } else if (word.length <= charsLeft) {\n currentLine.push(...word);\n }\n\n // no space for the word, write into next line\n else if (word.length <= lineLength[1]) {\n currentLine = [...word];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n // word too long for one line, start in\n // current line and continue in next line\n else {\n if (charsLeft >= 3 && !currentLine.length) {\n // No space required in front of long word\n } else if (charsLeft >= 4 && currentLine.length) {\n // Add space for next word\n currentLine.push(0);\n charsLeft--;\n } else {\n // No enough space for word, go to next line\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n\n for (const char of word) {\n currentLine.push(char);\n charsLeft--;\n\n if (charsLeft <= 1) {\n currentLine.push(44);\n\n currentLine = [];\n charsLeft = lineLength[1];\n lines.push(currentLine);\n }\n }\n }\n }\n\n return lines;\n }\n\n static removeEmojisFromChars (chars: number[]): number[] {\n const words: Array<number[]> = [];\n for (const char of chars) {\n if (!words.length) {\n words.push([]);\n }\n\n if (char === 0) {\n words.push([]);\n } else {\n words[words.length - 1].push(char);\n }\n }\n\n words.forEach(chars => {\n if (chars.length > 0 && chars[0] === -1) {\n while (chars[0] < 0) {\n chars.splice(0, 1);\n }\n }\n if (chars.length > 0 && chars[chars.length - 1] === -1) {\n while (chars.length > 0 && chars[chars.length - 1] < 0) {\n chars.splice(chars.length - 1, 1);\n }\n }\n });\n\n const result: number[] = [];\n words\n .filter(chars => chars.length > 0)\n .forEach(chars => {\n if (result.length !== 0) {\n result.push(0);\n }\n\n result.push(...chars);\n });\n\n return result;\n }\n\n static getColumnSizesFromData (rows: Array<string[]>, options: MessageWriteOptions = {}): number[] {\n if (!rows.length) {\n return [];\n }\n\n const columns = rows[0].length;\n const columnDefaultSizes: number[] = [];\n rows.forEach((row, rowIndex) => {\n if (row.length !== columns) {\n throw new Error(`Unable to render table: Row ${rowIndex} has ${row.length} entries, but first row has ${columns}!`);\n }\n row.forEach((column, columnIndex) => {\n columnDefaultSizes[columnIndex] = Math.max(columnDefaultSizes[columnIndex] || 0, this.string2chars(column, options).length);\n });\n });\n\n const columnDefaultSum = columnDefaultSizes.reduce((a, b) => a + b, 0);\n const columnBorders = rows[0].length - 1;\n const factor = Math.max((BOARD_LINE_LENGTH - columnBorders) / columnDefaultSum, 1);\n const columnSizes = columnDefaultSizes.map(size => Math.round(size * factor));\n\n while (true) {\n const size = columnSizes.reduce((a, b) => a + b, 0) + columnBorders;\n if (size === BOARD_LINE_LENGTH) {\n break;\n }\n\n const diff = BOARD_LINE_LENGTH - size < 0 ? -1 : 1;\n const index = columnSizes.indexOf(diff < 0 ? Math.max(...columnSizes) : Math.min(...columnSizes));\n if(index < 0) {\n // This can actually never be achieved...\n throw new Error('Unable to find max value in array…');\n }\n\n columnSizes[index] += diff;\n }\n\n\n return columnSizes;\n }\n\n get isEmpty (): boolean {\n return !this.board.find(line =>\n line.find(char => char !== 0)\n );\n }\n\n /**\n * Fills the board with the passed character or text. The text\n * is repeated again and again until the board is completely filled.\n */\n fill (text = ' '): this {\n let pointer = 0;\n const chars = Message.string2chars(text, {removeUnsupportedWords: false});\n this.board.forEach((line) => {\n line.forEach((char, charIndex) => {\n line[charIndex] = chars[pointer];\n pointer++;\n\n if(pointer > chars.length - 1) {\n pointer = 0;\n }\n });\n });\n return this;\n }\n\n /**\n * Write a text on your new message. If your message is not empty it will continue\n * where you last left off (`position: MessageWritePosition.CURRENT`). Alternatively\n * you can continue on the next line or give an exact position.\n *\n * @param text\n * @param options\n */\n write (text: string, options: MessageWriteOptions = {}): this {\n\n // Cursor blow board length? Just return…\n if (!this.board[this.cursor[0]]) {\n return this;\n }\n\n // Add new line if NEXT_LINE is set (except it's already in the first line)\n if (options.position === MessageWritePosition.NEXT_LINE && (this.cursor[0] !== 0 || this.cursor[1] !== 0)) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n // Set cursor to given position\n else if (typeof options.position === 'object') {\n this.cursor[0] = options.position.line;\n this.cursor[1] = options.position.row || 0;\n }\n\n // Add space before text as it\n // will be rendered in the same line\n if (\n (options.position === undefined || options.position === MessageWritePosition.CURRENT) &&\n this.cursor[1] !== 0 && this.cursor[1] < BOARD_LINE_LENGTH - 1\n ) {\n this.board[this.cursor[0]].splice(this.cursor[1], 1, 0);\n this.cursor[1] += 1;\n }\n\n // Figure out left indent\n let indent = 0;\n if (options.indent === true) {\n indent = this.cursor[1];\n } else if (typeof options.indent === 'number' && options.indent >= 0 && options.indent <= BOARD_LINE_LENGTH - 5) {\n indent = options.indent;\n }\n\n const linesOfText = text.split('\\n');\n let isFirstLine = true;\n for (const lineOfText of linesOfText) {\n const chars = Message.string2chars(lineOfText, options);\n const charsLeftInLine: [number, number] = [\n BOARD_LINE_LENGTH - this.cursor[1],\n BOARD_LINE_LENGTH - indent\n ];\n\n if(!isFirstLine) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n\n if(typeof options.position === 'object' && options.position.width) {\n charsLeftInLine[0] = Math.min(charsLeftInLine[0], options.position.width);\n charsLeftInLine[1] = Math.min(charsLeftInLine[1], options.position.width - indent);\n }\n\n const linesOfChars = Message.splitCharsIntoLines(chars, charsLeftInLine);\n for (const chars of linesOfChars) {\n\n // Board is over, skip line…\n if (!this.board[this.cursor[0]]) {\n break;\n }\n\n // Add chars to current line and update cursor\n this.board[this.cursor[0]].splice(this.cursor[1], chars.length, ...chars);\n this.cursor[1] += chars.length;\n\n // Add new line (and update cursor),\n // if this wasn't the last line\n if (chars !== linesOfChars[linesOfChars.length - 1]) {\n this.cursor[0]++;\n this.cursor[1] = indent;\n }\n }\n\n isFirstLine = false;\n }\n\n return this;\n }\n\n /**\n * Generate a table with the given data\n *\n * @example new Message().table([\n * ['now', 'Daily'],\n * ['13:00', 'Super Secret Meeting'],\n * ['16:30', 'Awesome Presentation']\n * ])\n *\n * #==============================================#\n * # N O W D A I L Y #\n * # #\n * # 1 3 : 0 0 S U P E R S E C R E T #\n * # M E E T I N G #\n * # #\n * # 1 6 : 3 0 A W E S O M E P R E S E N T - #\n * #==============================================#\n */\n table (rows: Array<string[]>): this {\n const columnWidths = Message.getColumnSizesFromData(rows);\n if (this.cursor[0] !== 0 || this.cursor[1] !== 0) {\n this.cursor[0]++;\n this.cursor[1] = 0;\n }\n\n rows.forEach(line => {\n const lineStart = this.cursor[0];\n let lineHeight = 1;\n\n line.forEach((column, columnIndex) => {\n const columnWidth = columnWidths[columnIndex];\n const indent = columnWidths\n .filter((width, index) => index < columnIndex)\n .reduce((a, b) => a + b + 1, 0);\n\n this.write(column, {\n position: {\n line: lineStart,\n row: indent,\n width: columnWidth\n },\n indent\n });\n\n lineHeight = Math.max(lineHeight, this.cursor[0] - lineStart + 1);\n });\n\n this.cursor[0] = lineStart + lineHeight + 1;\n this.cursor[1] = 0;\n });\n\n return this;\n }\n\n /**\n * Center the current message content\n */\n center(): void {\n const space = [\n this.board.findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.slice().reverse().findIndex(c => c !== 0) : l.length)),\n this.board.slice().reverse().findIndex(l => l.find(c => c !== 0)),\n Math.min(...this.board.map(l => l.find(c => c !== 0) ? l.findIndex(c => c !== 0) : l.length)),\n ];\n\n const padding = [\n Math.floor((space[0] + space[2]) / 2),\n Math.floor((space[1] + space[3]) / 2)\n ];\n\n // Move up/down\n if(space[0] !== padding[0]) {\n const add = padding[0] - space[0];\n this.board.splice(add > 0 ? 0 : this.board.length, 0,\n ...this.board.splice(add > 0 ? this.board.length - add : 0, Math.abs(add))\n );\n }\n\n // Move left/right\n if(space[3] !== padding[1]) {\n const add = padding[1] - space[3];\n this.board.forEach(line => {\n line.splice(add > 0 ? 0 : line.length, 0,\n ...line.splice(add > 0 ? line.length - add : 0, Math.abs(add))\n );\n });\n }\n }\n\n toString (): string {\n return '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n' +\n this.board.map(line => '# ' + line.map(char =>\n Message.charToString(char)\n ).join('') + ' #\\n').join('') +\n '#=' + '='.repeat(BOARD_LINE_LENGTH * 2) + '=#\\n';\n }\n\n toCharArray (): BoardCharArray {\n return JSON.parse(JSON.stringify(this.board));\n }\n}\n","import type { RequestFetchOptions, RequestFetchResponse, RequestOptions } from './types.js';\n\nexport async function request<T> (\n url: string,\n headers: Record<string, string>,\n data?: Record<string, unknown> | string,\n options: RequestOptions = {}\n): Promise<T> {\n const method = data === undefined ? 'GET' : 'POST';\n if (data !== undefined) {\n Object.assign(headers, {\n 'Content-Type': 'application/json'\n });\n }\n\n const init: RequestFetchOptions = {\n method,\n headers\n };\n if(data !== undefined && typeof data === 'string') {\n init.body = data;\n }\n else if(data !== undefined) {\n init.body = JSON.stringify(data);\n }\n\n let response: RequestFetchResponse | null = null;\n for (let i = 0; i < 10; i++) {\n response = await (options.fetch || fetch)(url, init);\n if(response.ok) {\n break;\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n\n if(!response?.ok) {\n throw new Error('HTTP Request failed');\n }\n\n if(options.parseResponse === false) {\n return undefined as unknown as T;\n }\n\n const json = await response.json();\n return json as T;\n}\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { SubscriptionPostResponse, Subscriptions, Viewer } from './types.js';\nimport type { RequestOptions } from './types.js';\n\nexport default class SubscriptionAPI {\n private readonly key: string;\n private readonly secret: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, secret: string, options?: RequestOptions) {\n this.key = key;\n this.secret = secret;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: Record<string, unknown>): Promise<T> {\n return request(`https://platform.vestaboard.com${path}`, {\n 'X-Vestaboard-Api-Key': this.key,\n 'X-Vestaboard-Api-Secret': this.secret\n }, data, this.options);\n }\n\n async getViewer (): Promise<Viewer> {\n return await this.request<Viewer>('/viewer');\n }\n\n async getSubscriptions (): Promise<Subscriptions> {\n return await this.request<Subscriptions>('/subscriptions');\n }\n\n async postMessage (message: Message | string): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionId: string): Promise<SubscriptionPostResponse>;\n async postMessage (message: Message | string, subscriptionIds: string[]): Promise<SubscriptionPostResponse[]>;\n async postMessage (message: Message | string, subscriptionIds?: string | string[]) {\n let singleMode = false;\n const ids: string[] = [];\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n\n if (typeof subscriptionIds === 'string') {\n singleMode = true;\n ids.push(subscriptionIds);\n } else if (Array.isArray(subscriptionIds)) {\n ids.push(...subscriptionIds);\n } else {\n const subscriptions = await this.getSubscriptions();\n ids.push(...subscriptions.subscriptions.map(subscription => subscription._id));\n }\n\n const results: SubscriptionPostResponse[] = [];\n for (const id of ids) {\n results.push(\n await this.request<SubscriptionPostResponse>(`/subscriptions/${id}/message`, {\n characters: msgObj.toCharArray()\n })\n );\n }\n if (singleMode) {\n return results[0];\n }\n\n return results;\n }\n}","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { ReadWriteGetMessageResponse, RequestOptions } from './types.js';\n\nexport default class ReadWriteAPI {\n private readonly key: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, options?: RequestOptions) {\n this.key = key;\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string): Promise<T> {\n return request(`https://rw.vestaboard.com${path}`, {\n 'X-Vestaboard-Read-Write-Key': this.key\n }, data, this.options);\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<ReadWriteGetMessageResponse>('/');\n return new Message(JSON.parse(response.currentMessage.layout));\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray())\n );\n }\n}\n","import SubscriptionAPI from './subscription-api.js';\nimport ReadWriteAPI from './read-write-api.js';\nimport LocalAPI from './local-api.js';\n\nexport const BOARD_LINE_LENGTH = 22;\nexport const BOARD_LINES = 6;\n\nexport type BoardCharLine = [\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number,\n number\n];\n\nexport type BoardCharArray = [\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine,\n BoardCharLine\n];\n\nexport interface MessageWriteCoords {\n line: number;\n row?: number;\n width?: number;\n}\n\nexport enum MessageWritePosition {\n CURRENT,\n NO_SPACE_BETWEEN,\n NEXT_LINE\n}\n\nexport interface MessageWriteOptions {\n position?: MessageWriteCoords | MessageWritePosition;\n indent?: boolean | number;\n fallbackChar?: number | null;\n removeUnsupportedWords?: boolean;\n}\n\nexport interface RequestFetchOptions {\n body?: string;\n headers?: Record<string, string>;\n method?: string;\n}\n\nexport interface RequestFetchResponse {\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n json(): Promise<unknown>;\n}\n\nexport type RequestOptionsFetch = (url: string, init?: RequestFetchOptions) => Promise<RequestFetchResponse>;\n\nexport interface RequestOptions {\n fetch?: RequestOptionsFetch;\n parseResponse?: boolean;\n}\n\nexport interface Installation {\n _id: string;\n installable?: {\n _id: string;\n };\n}\n\nexport interface Viewer {\n type: string;\n _id: string;\n _created: string;\n installation: {\n _id: string;\n };\n}\n\nexport interface Subscription {\n _id: string;\n _created: string;\n installation: Installation;\n boards: Array<{_id: string}>;\n}\n\nexport interface Subscriptions {\n subscriptions: Subscription[];\n}\n\nexport interface SubscriptionPostResponse {\n message: {\n id: string;\n created: number;\n }\n}\n\nexport interface ReadWriteGetMessageResponse {\n currentMessage: {\n layout: string;\n }\n}\n\nexport type Boards = Array<LocalAPI | ReadWriteAPI | SubscriptionAPI>;\n","import Message from './message.js';\nimport { request } from './tools.js';\nimport type { BoardCharArray, RequestOptions } from './types.js';\n\nexport default class LocalAPI {\n private readonly key: string;\n private readonly host: string;\n private readonly options: RequestOptions;\n\n constructor (key: string, host?: string, options?: RequestOptions) {\n this.key = key;\n this.host = host || 'vestaboard.local';\n this.options = options || {};\n }\n\n private async request<T> (path: string, data?: string, options: RequestOptions = {}): Promise<T> {\n return request(`http://${this.host}:7000/local-api/message`, {\n 'X-Vestaboard-Local-Api-Key': this.key\n }, data, Object.assign({}, this.options, options));\n }\n\n async getCurrentMessage (): Promise<Message> {\n const response = await this.request<{message: BoardCharArray} | BoardCharArray>('/');\n return new Message(Array.isArray(response) ? response : response.message);\n }\n\n async postMessage (message: Message | string) {\n const msgObj = typeof message === 'string' ? new Message(message) : message;\n await this.request<void>('/',\n JSON.stringify(msgObj.toCharArray()),\n { parseResponse: false }\n );\n }\n}\n","import { type Boards } from './types.js';\nimport Message from './message.js';\n\nexport default class MultipleBoards {\n private readonly boards: Boards;\n\n constructor (boards: Boards = []) {\n this.boards = boards;\n }\n\n push(...boards: Boards): void {\n boards.forEach(board => this.boards.push(board));\n }\n\n async postMessage (message: Message | string): Promise<void> {\n for(const board of this.boards) {\n await board.postMessage(message);\n }\n }\n}\n"],"mappings":"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CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,CAAC,CAAC,EACT,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,CAAC,EAAE,CAAC,EACV,CAAC,IAAK,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","names":["GraphemeSplitter","request","url","headers","data","options","method","init","response","resolve","SubscriptionAPI","key","secret","options","path","data","request","message","subscriptionIds","singleMode","ids","msgObj","Message","subscriptions","subscription","results","id","ReadWriteAPI","key","options","path","data","request","response","Message","message","msgObj","BOARD_LINE_LENGTH","BOARD_LINES","MessageWritePosition","CHAR_MAP","EMPTY_BOARD","BOARD_LINES","BOARD_LINE_LENGTH","Message","_Message","GraphemeSplitter","message","word","options","chars","singleCharStrings","char","fromMap","mapChar","entry","name","code","lineLength","words","currentWord","lines","separator","currentLine","charsLeft","result","rows","columns","columnDefaultSizes","row","rowIndex","column","columnIndex","columnDefaultSum","a","b","columnBorders","factor","columnSizes","size","diff","index","line","text","pointer","charIndex","indent","linesOfText","isFirstLine","lineOfText","charsLeftInLine","linesOfChars","columnWidths","lineStart","lineHeight","columnWidth","width","space","l","c","padding","add","LocalAPI","key","host","options","path","data","request","response","Message","message","msgObj","MultipleBoards","boards","board","message"]}
package/package.json CHANGED
@@ -16,10 +16,10 @@
16
16
  "@semantic-release/npm": "^12.0.1",
17
17
  "@types/eslint__js": "^8.42.3",
18
18
  "@types/mocha": "^10.0.7",
19
- "@types/node": "^22.1.0",
19
+ "@types/node": "^22.5.0",
20
20
  "c8": "^10.1.2",
21
21
  "dotenv": "^16.4.5",
22
- "eslint": "^9.8.0",
22
+ "eslint": "^9.9.0",
23
23
  "eslint-plugin-jsonc": "^2.16.0",
24
24
  "esm": "^3.2.25",
25
25
  "license-checker": "^25.0.1",
@@ -27,14 +27,14 @@
27
27
  "mochawesome": "^7.1.3",
28
28
  "semantic-release-license": "^1.0.3",
29
29
  "source-map-support": "^0.5.21",
30
- "ts-node": "^10.9.2",
31
30
  "tsup": "^8.1.0",
32
- "typedoc": "^0.26.3",
31
+ "tsx": "^4.16.2",
32
+ "typedoc": "^0.26.6",
33
33
  "typescript": "^5.5.4",
34
- "typescript-eslint": "^8.0.0-alpha.62"
34
+ "typescript-eslint": "^8.2.0"
35
35
  },
36
36
  "engines": {
37
- "node": ">=18.0.0"
37
+ "node": "18 || 20 || >=22.0.0"
38
38
  },
39
39
  "exports": {
40
40
  "import": "./dist/index.js",
@@ -56,12 +56,12 @@
56
56
  "build": "tsup && cp ./dist/index.d.ts ./dist/index.d.cts",
57
57
  "build-all": "./.github/workflows/build.sh",
58
58
  "coverage": "c8 mocha",
59
- "develop": "TS_NODE_TRANSPILE_ONLY=true node --no-warnings --enable-source-maps --loader ts-node/esm src/bin/start.ts",
59
+ "develop": "tsx src/bin/start.ts",
60
60
  "license-check": "license-checker --production --summary",
61
61
  "lint": "eslint .",
62
62
  "start": "node ./dist/bin/start.js",
63
63
  "test": "mocha"
64
64
  },
65
65
  "type": "module",
66
- "version": "3.2.0-develop.1"
66
+ "version": "4.0.0-develop.1"
67
67
  }