ajo 0.1.14 → 0.1.16

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/html.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const{assign:p,entries:$,hasOwn:g}=Object,f=e=>typeof e!="string"&&typeof(e==null?void 0:e[Symbol.iterator])=="function",c=e=>[...y(e)].join(""),y=function*(e){for(e of d(e))if(typeof e=="string")yield m(e);else{const{nodeName:t,skip:o,children:i=""}=e;let n="";for(const[l,r]of $(e))v.has(l)||l.startsWith("set:")||r==null||r===!1||(n+=r===!0?`${n} ${l}`:`${n} ${l}="${m(String(r))}"`);k.has(t)?yield`<${t}${n}>`:o?yield`<${t}${n}></${t}>`:typeof i=="string"?yield`<${t}${n}>${i}</${t}>`:(yield`<${t}${n}>`,yield*y(i),yield`</${t}>`)}},d=function*(e,t={value:""},o=!0){for(e of f(e)?e:[e])if(!(e==null||typeof e=="boolean"))if(g(e,"nodeName")){const{value:i}=t,{nodeName:n}=e,l=typeof n;if(i&&(yield i,t.value=""),l==="function")if(delete e.nodeName,n.constructor.name==="GeneratorFunction"){const r={},s=p({},n.attrs);for(const a in e){const u=e[a];a.startsWith("attr:")?s[a.slice(5)]=u:r[a]=u}s.nodeName=n.is??"div",s.children=w(n,r),yield s}else delete e.nodeName,yield*d(n(e),t,!1);else l==="string"&&(yield e)}else f(e)?yield*d(e,t,!1):t.value+=e;o&&t.value&&(yield t.value)},k=new Set("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",")),v=new Set("nodeName,key,skip,memo,ref,children".split(",")),m=e=>e.replace(/[&<>"']/g,t=>`&#${t.charCodeAt(0)};`),w=(e,t)=>{let o,i;try{const n=e.call(o={$args:t,*[Symbol.iterator](){for(;;)yield t},refresh(){},next(){i=c(n.next().value)},throw(l){i=c(n.throw(l).value)},return(){n.return()}},t);o.next()}catch(n){o.throw(n)}finally{o.return()}return i};exports.html=y;exports.render=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const{assign:$,entries:f,hasOwn:p}=Object,{isArray:u}=Array,a=e=>[...d(e)].join(""),d=function*(e){for(e of c(e))if(typeof e=="string")yield m(e);else{const{nodeName:t,skip:r,children:l=""}=e;let n="";for(const[i,o]of f(e))g.has(i)||i.startsWith("set:")||o==null||o===!1||(n+=o===!0?`${n} ${i}`:`${n} ${i}="${m(String(o))}"`);v.has(t)?yield`<${t}${n}>`:r?yield`<${t}${n}></${t}>`:typeof l=="string"?yield`<${t}${n}>${l}</${t}>`:(yield`<${t}${n}>`,yield*d(l),yield`</${t}>`)}},c=function*(e,t={value:""},r=!0){for(e of u(e)?e:[e])if(!(e==null||typeof e=="boolean"))if(p(e,"nodeName")){const{value:l}=t,{nodeName:n}=e;if(l&&(yield l,t.value=""),typeof n=="function")if(delete e.nodeName,n.constructor.name==="GeneratorFunction"){const i={},o=$({},n.attrs);for(const s in e){const y=e[s];s.startsWith("attr:")?o[s.slice(5)]=y:i[s]=y}o.nodeName=n.is??"div",o.children=k(n,i),yield o}else delete e.nodeName,yield*c(n(e),t,!1);else yield e}else u(e)?yield*c(e,t,!1):t.value+=e;r&&t.value&&(yield t.value)},v=new Set("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",")),g=new Set("nodeName,key,skip,memo,ref,children".split(",")),m=e=>e.replace(/[&<>"']/g,t=>`&#${t.charCodeAt(0)};`),k=(e,t)=>{let r,l;try{const n=e.call(r={$args:t,*[Symbol.iterator](){for(;;)yield t},$next(){l=a(n.next().value)},$throw(i){l=a(n.throw(i).value)},$return(){n.return()}},t);r.$next()}catch(n){r.$throw(n)}finally{r.$return()}return l};exports.html=d;exports.render=a;
package/dist/html.js CHANGED
@@ -1,64 +1,57 @@
1
- const { assign: p, entries: $, hasOwn: g } = Object, y = (e) => typeof e != "string" && typeof (e == null ? void 0 : e[Symbol.iterator]) == "function", f = (e) => [...m(e)].join(""), m = function* (e) {
2
- for (e of c(e))
3
- if (typeof e == "string")
4
- yield u(e);
1
+ const { assign: f, entries: m, hasOwn: p } = Object, { isArray: d } = Array, y = (e) => [...$(e)].join(""), $ = function* (e) {
2
+ for (e of a(e))
3
+ if (typeof e == "string") yield u(e);
5
4
  else {
6
- const { nodeName: t, skip: o, children: i = "" } = e;
5
+ const { nodeName: t, skip: r, children: l = "" } = e;
7
6
  let n = "";
8
- for (const [l, s] of $(e))
9
- w.has(l) || l.startsWith("set:") || s == null || s === !1 || (n += s === !0 ? `${n} ${l}` : `${n} ${l}="${u(String(s))}"`);
10
- k.has(t) ? yield `<${t}${n}>` : o ? yield `<${t}${n}></${t}>` : typeof i == "string" ? yield `<${t}${n}>${i}</${t}>` : (yield `<${t}${n}>`, yield* m(i), yield `</${t}>`);
7
+ for (const [i, o] of m(e))
8
+ k.has(i) || i.startsWith("set:") || o == null || o === !1 || (n += o === !0 ? `${n} ${i}` : `${n} ${i}="${u(String(o))}"`);
9
+ v.has(t) ? yield `<${t}${n}>` : r ? yield `<${t}${n}></${t}>` : typeof l == "string" ? yield `<${t}${n}>${l}</${t}>` : (yield `<${t}${n}>`, yield* $(l), yield `</${t}>`);
11
10
  }
12
- }, c = function* (e, t = { value: "" }, o = !0) {
13
- for (e of y(e) ? e : [e])
11
+ }, a = function* (e, t = { value: "" }, r = !0) {
12
+ for (e of d(e) ? e : [e])
14
13
  if (!(e == null || typeof e == "boolean"))
15
- if (g(e, "nodeName")) {
16
- const { value: i } = t, { nodeName: n } = e, l = typeof n;
17
- if (i && (yield i, t.value = ""), l === "function")
14
+ if (p(e, "nodeName")) {
15
+ const { value: l } = t, { nodeName: n } = e;
16
+ if (l && (yield l, t.value = ""), typeof n == "function")
18
17
  if (delete e.nodeName, n.constructor.name === "GeneratorFunction") {
19
- const s = {}, r = p({}, n.attrs);
20
- for (const a in e) {
21
- const d = e[a];
22
- a.startsWith("attr:") ? r[a.slice(5)] = d : s[a] = d;
18
+ const i = {}, o = f({}, n.attrs);
19
+ for (const s in e) {
20
+ const c = e[s];
21
+ s.startsWith("attr:") ? o[s.slice(5)] = c : i[s] = c;
23
22
  }
24
- r.nodeName = n.is ?? "div", r.children = v(n, s), yield r;
25
- } else
26
- delete e.nodeName, yield* c(n(e), t, !1);
27
- else
28
- l === "string" && (yield e);
29
- } else
30
- y(e) ? yield* c(e, t, !1) : t.value += e;
31
- o && t.value && (yield t.value);
32
- }, k = new Set("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",")), w = new Set("nodeName,key,skip,memo,ref,children".split(",")), u = (e) => e.replace(/[&<>"']/g, (t) => `&#${t.charCodeAt(0)};`), v = (e, t) => {
33
- let o, i;
23
+ o.nodeName = n.is ?? "div", o.children = w(n, i), yield o;
24
+ } else delete e.nodeName, yield* a(n(e), t, !1);
25
+ else yield e;
26
+ } else d(e) ? yield* a(e, t, !1) : t.value += e;
27
+ r && t.value && (yield t.value);
28
+ }, v = new Set("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",")), k = new Set("nodeName,key,skip,memo,ref,children".split(",")), u = (e) => e.replace(/[&<>"']/g, (t) => `&#${t.charCodeAt(0)};`), w = (e, t) => {
29
+ let r, l;
34
30
  try {
35
- const n = e.call(o = {
31
+ const n = e.call(r = {
36
32
  $args: t,
37
33
  *[Symbol.iterator]() {
38
- for (; ; )
39
- yield t;
34
+ for (; ; ) yield t;
40
35
  },
41
- refresh() {
36
+ $next() {
37
+ l = y(n.next().value);
42
38
  },
43
- next() {
44
- i = f(n.next().value);
39
+ $throw(i) {
40
+ l = y(n.throw(i).value);
45
41
  },
46
- throw(l) {
47
- i = f(n.throw(l).value);
48
- },
49
- return() {
42
+ $return() {
50
43
  n.return();
51
44
  }
52
45
  }, t);
53
- o.next();
46
+ r.$next();
54
47
  } catch (n) {
55
- o.throw(n);
48
+ r.$throw(n);
56
49
  } finally {
57
- o.return();
50
+ r.$return();
58
51
  }
59
- return i;
52
+ return l;
60
53
  };
61
54
  export {
62
- m as html,
63
- f as render
55
+ $ as html,
56
+ y as render
64
57
  };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=({children:e})=>e,A=function(e,t){const{length:i}=arguments;return(t??(t=C(null))).nodeName=e,"children"in t||i<3||(t.children=i===3?arguments[2]:O.call(arguments,2)),t},y=(e,t)=>{let i=t.firstChild;for(e of p(e)){let n=i;if(typeof e=="string"){for(;n&&n.nodeType!=3;)n=n.nextSibling;n?n.data!=e&&(n.data=e):n=document.createTextNode(e)}else if(e instanceof Node)n=e;else{const{nodeName:o,key:a,skip:m,memo:r,ref:s,children:u}=e;for(;n&&!(n.localName===o&&(n.$key??(n.$key=a))==a);)n=n.nextSibling;if(n??(n=g(document.createElementNS(e.xmlns??o==="svg"?T:t.namespaceURI,o),{$key:a})),r==null||P(n.$memo,n.$memo=r)){const{$props:d}=n,w={};for(const c of h(g({},d,e))){if(q.has(c))continue;const f=w[c]=e[c];f!==(d==null?void 0:d[c])&&(c.startsWith("set:")?n[c.slice(4)]=f:f==null||f===!1?n.removeAttribute(c):n.setAttribute(c,f===!0?"":f))}n.$props=w,m||y(u,n),typeof s=="function"&&(n.$ref=s)(n)}}n===i?i=i.nextSibling:E(t,n,i)}for(;i;){const n=i.nextSibling;i.nodeType===1&&N(i),t.removeChild(i),i=n}},{isArray:$,prototype:{slice:O}}=Array,{create:C,keys:h,assign:g,hasOwn:F,setPrototypeOf:x,getPrototypeOf:v}=Object,T="http://www.w3.org/2000/svg",q=new Set("nodeName,key,skip,memo,ref,children".split(",")),S=e=>typeof e!="string"&&typeof(e==null?void 0:e[Symbol.iterator])=="function",P=(e,t)=>$(e)&&$(t)?e.some((i,n)=>i!==t[n]):e!==t,p=function*(e,t={value:""},i=!0){for(e of S(e)?e:[e])if(!(e==null||typeof e=="boolean"))if(F(e,"nodeName")){const{value:n}=t,{nodeName:o}=e,a=typeof o;if(n&&(yield n,t.value=""),a==="function")if(delete e.nodeName,o.constructor.name==="GeneratorFunction"){const m={},r=g({},o.attrs);for(const s of h(e)){const u=e[s];s.startsWith("attr:")&&(r[s.slice(5)]=u),s==="key"||s==="memo"?r[s]=u:m[s]=u}r.nodeName=o.is??"div",r.skip=!0,r.ref=j.bind(null,o,m),yield r}else yield*p(o(e),t,!1);else a==="string"&&(yield e)}else S(e)?yield*p(e,t,!1):t.value+=e;i&&t.value&&(yield t.value)},j=(e,t,i)=>{i&&(i.$gen??(i.$gen=(new I(i),e)),i.$ref=B.bind(null,i),i.$args=t,i.next())},B=(e,t)=>t??e.return(),E=(e,t,i)=>{if(t.contains(document.activeElement)){const n=t.nextSibling;for(;i&&i!=t;){const o=i.nextSibling;e.insertBefore(i,n),i=o}}else e.insertBefore(t,i)},N=e=>{for(const i of e.children)N(i);const{$ref:t}=e;typeof t=="function"&&t(null);for(const i of h(e))e[i]=null};class I{constructor(t){x(t,x(v(this),v(t)))}*[Symbol.iterator](){for(;;)yield this.$args??{}}refresh(){W(this)}next(){try{y((this.$it??(this.$it=this.$gen.call(this,this.$args??{}))).next().value,this),typeof this.$ref=="function"&&this.$ref(this)}catch(t){this.throw(t)}}throw(t){var i;for(let n=this;n;n=n.parentNode)if(typeof((i=n.$it)==null?void 0:i.throw)=="function")try{return y(n.$it.throw(t).value,n)}catch{}throw t}return(){var t;try{(t=this.$it)==null||t.return()}catch(i){this.throw(i)}finally{this.$it=null}}}let l,k;const W=e=>{(l??(l=new Set)).has(e)&&l.delete(e);for(const t of l){if(t.contains(e))return;e.contains(t)&&l.delete(t)}l.add(e),k??(k=requestAnimationFrame(z))},z=()=>{for(const e of l)e.isConnected&&e.next();l.clear(),k=null};exports.Fragment=b;exports.h=A;exports.render=y;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=({children:e})=>e,k=function(e,t){const{length:n}=arguments;return(t??(t={})).nodeName=e,"children"in t||n<3||(t.children=n===3?arguments[2]:S.call(arguments,2)),t},m=(e,t)=>{let n=t.firstChild;for(e of g(e)){let i=n;if(typeof e=="string"){for(;i&&i.nodeType!=3;)i=i.nextSibling;i?i.data!=e&&(i.data=e):i=document.createTextNode(e)}else{const{nodeName:o,key:a,skip:r,memo:s,ref:l,children:x}=e;for(;i&&!(i.localName===o&&(i.$key??(i.$key=a))==a);)i=i.nextSibling;if(i??(i=d(document.createElementNS(e.xmlns??o==="svg"?O:t.namespaceURI,o),{$key:a})),s==null||T(i.$memo,i.$memo=s)){const{$props:u}=i,$={};for(const c of w(d({},u,e))){if(A.has(c))continue;const f=$[c]=e[c];f!==(u==null?void 0:u[c])&&(c.startsWith("set:")?i[c.slice(4)]=f:f==null||f===!1?i.removeAttribute(c):i.setAttribute(c,f===!0?"":f))}i.$props=$,r||m(x,i),typeof l=="function"&&(i.$ref=l)(i)}}i===n?n=n.nextSibling:P(t,i,n)}for(;n;){const i=n.nextSibling;n.nodeType===1&&h(n),t.removeChild(n),n=i}},{isArray:y,prototype:{slice:S}}=Array,{keys:w,assign:d,hasOwn:b,setPrototypeOf:p,getPrototypeOf:v}=Object,O="http://www.w3.org/2000/svg",A=new Set("nodeName,key,skip,memo,ref,children".split(",")),T=(e,t)=>y(e)&&y(t)?e.some((n,i)=>n!==t[i]):e!==t,g=function*(e,t={value:""},n=!0){for(e of y(e)?e:[e])if(!(e==null||typeof e=="boolean"))if(b(e,"nodeName")){const{value:i}=t,{nodeName:o}=e;if(i&&(yield i,t.value=""),typeof o=="function")if(delete e.nodeName,o.constructor.name==="GeneratorFunction"){const a={},r=d({},o.attrs);for(const s of w(e)){const l=e[s];s.startsWith("attr:")?r[s.slice(5)]=l:s==="key"||s==="memo"?r[s]=l:a[s]=l}r.nodeName=o.is??"div",r.skip=!0,r.ref=C.bind(null,o,a),yield r}else yield*g(o(e),t,!1);else yield e}else y(e)?yield*g(e,t,!1):t.value+=e;n&&t.value&&(yield t.value)},C=(e,t,n)=>{n&&(n.$gen??(n.$gen=(new j(n),e)),n.$ref=F.bind(null,n),d(n.$args??(n.$args={}),t),n.$next())},F=(e,t)=>t??e.$return(),P=(e,t,n)=>{if(t.contains(document.activeElement)){const i=t.nextSibling;for(;n&&n!=t;){const o=n.nextSibling;e.insertBefore(n,i),n=o}}else e.insertBefore(t,n)},h=e=>{for(const n of e.children)h(n);const{$ref:t}=e;typeof t=="function"&&t(null)};class j{constructor(t){p(t,p(v(this),v(t)))}$next(){try{m((this.$it??(this.$it=this.$gen.call(this,this.$args))).next().value,this),typeof this.$ref=="function"&&this.$ref(this)}catch(t){this.$throw(t)}}$throw(t){var n;for(let i=this;i;i=i.parentNode)if(typeof((n=i.$it)==null?void 0:n.throw)=="function")try{return m(i.$it.throw(t).value,i)}catch{}throw t}$return(){var t;try{(t=this.$it)==null||t.return()}catch(n){this.$throw(n)}finally{this.$it=null}}}exports.Fragment=N;exports.h=k;exports.render=m;
package/dist/index.js CHANGED
@@ -1,131 +1,96 @@
1
- const j = ({ children: e }) => e, z = function(e, t) {
2
- const { length: i } = arguments;
3
- return (t ?? (t = A(null))).nodeName = e, "children" in t || i < 3 || (t.children = i === 3 ? arguments[2] : b.call(arguments, 2)), t;
1
+ const E = ({ children: e }) => e, F = function(e, t) {
2
+ const { length: n } = arguments;
3
+ return (t ?? (t = {})).nodeName = e, "children" in t || n < 3 || (t.children = n === 3 ? arguments[2] : N.call(arguments, 2)), t;
4
4
  }, d = (e, t) => {
5
- let i = t.firstChild;
6
- for (e of p(e)) {
7
- let n = i;
5
+ let n = t.firstChild;
6
+ for (e of $(e)) {
7
+ let i = n;
8
8
  if (typeof e == "string") {
9
- for (; n && n.nodeType != 3; )
10
- n = n.nextSibling;
11
- n ? n.data != e && (n.data = e) : n = document.createTextNode(e);
12
- } else if (e instanceof Node)
13
- n = e;
14
- else {
15
- const { nodeName: o, key: a, skip: m, memo: r, ref: s, children: u } = e;
16
- for (; n && !(n.localName === o && (n.$key ?? (n.$key = a)) == a); )
17
- n = n.nextSibling;
18
- if (n ?? (n = g(document.createElementNS(e.xmlns ?? o === "svg" ? O : t.namespaceURI, o), { $key: a })), r == null || F(n.$memo, n.$memo = r)) {
19
- const { $props: y } = n, $ = {};
20
- for (const c of w(g({}, y, e))) {
21
- if (q.has(c))
22
- continue;
23
- const f = $[c] = e[c];
24
- f !== (y == null ? void 0 : y[c]) && (c.startsWith("set:") ? n[c.slice(4)] = f : f == null || f === !1 ? n.removeAttribute(c) : n.setAttribute(c, f === !0 ? "" : f));
9
+ for (; i && i.nodeType != 3; ) i = i.nextSibling;
10
+ i ? i.data != e && (i.data = e) : i = document.createTextNode(e);
11
+ } else {
12
+ const { nodeName: o, key: a, skip: r, memo: s, ref: l, children: h } = e;
13
+ for (; i && !(i.localName === o && (i.$key ?? (i.$key = a)) == a); ) i = i.nextSibling;
14
+ if (i ?? (i = y(document.createElementNS(e.xmlns ?? o === "svg" ? S : t.namespaceURI, o), { $key: a })), s == null || A(i.$memo, i.$memo = s)) {
15
+ const { $props: u } = i, g = {};
16
+ for (const c of w(y({}, u, e))) {
17
+ if (b.has(c)) continue;
18
+ const f = g[c] = e[c];
19
+ f !== (u == null ? void 0 : u[c]) && (c.startsWith("set:") ? i[c.slice(4)] = f : f == null || f === !1 ? i.removeAttribute(c) : i.setAttribute(c, f === !0 ? "" : f));
25
20
  }
26
- n.$props = $, m || d(u, n), typeof s == "function" && (n.$ref = s)(n);
21
+ i.$props = g, r || d(h, i), typeof l == "function" && (i.$ref = l)(i);
27
22
  }
28
23
  }
29
- n === i ? i = i.nextSibling : E(t, n, i);
24
+ i === n ? n = n.nextSibling : T(t, i, n);
30
25
  }
31
- for (; i; ) {
32
- const n = i.nextSibling;
33
- i.nodeType === 1 && k(i), t.removeChild(i), i = n;
26
+ for (; n; ) {
27
+ const i = n.nextSibling;
28
+ n.nodeType === 1 && x(n), t.removeChild(n), n = i;
34
29
  }
35
- }, { isArray: h, prototype: { slice: b } } = Array, { create: A, keys: w, assign: g, hasOwn: C, setPrototypeOf: x, getPrototypeOf: v } = Object, O = "http://www.w3.org/2000/svg", q = new Set("nodeName,key,skip,memo,ref,children".split(",")), N = (e) => typeof e != "string" && typeof (e == null ? void 0 : e[Symbol.iterator]) == "function", F = (e, t) => h(e) && h(t) ? e.some((i, n) => i !== t[n]) : e !== t, p = function* (e, t = { value: "" }, i = !0) {
36
- for (e of N(e) ? e : [e])
30
+ }, { isArray: m, prototype: { slice: N } } = Array, { keys: w, assign: y, hasOwn: k, setPrototypeOf: p, getPrototypeOf: v } = Object, S = "http://www.w3.org/2000/svg", b = new Set("nodeName,key,skip,memo,ref,children".split(",")), A = (e, t) => m(e) && m(t) ? e.some((n, i) => n !== t[i]) : e !== t, $ = function* (e, t = { value: "" }, n = !0) {
31
+ for (e of m(e) ? e : [e])
37
32
  if (!(e == null || typeof e == "boolean"))
38
- if (C(e, "nodeName")) {
39
- const { value: n } = t, { nodeName: o } = e, a = typeof o;
40
- if (n && (yield n, t.value = ""), a === "function")
33
+ if (k(e, "nodeName")) {
34
+ const { value: i } = t, { nodeName: o } = e;
35
+ if (i && (yield i, t.value = ""), typeof o == "function")
41
36
  if (delete e.nodeName, o.constructor.name === "GeneratorFunction") {
42
- const m = {}, r = g({}, o.attrs);
37
+ const a = {}, r = y({}, o.attrs);
43
38
  for (const s of w(e)) {
44
- const u = e[s];
45
- s.startsWith("attr:") && (r[s.slice(5)] = u), s === "key" || s === "memo" ? r[s] = u : m[s] = u;
39
+ const l = e[s];
40
+ s.startsWith("attr:") ? r[s.slice(5)] = l : s === "key" || s === "memo" ? r[s] = l : a[s] = l;
46
41
  }
47
- r.nodeName = o.is ?? "div", r.skip = !0, r.ref = T.bind(null, o, m), yield r;
48
- } else
49
- yield* p(o(e), t, !1);
50
- else
51
- a === "string" && (yield e);
52
- } else
53
- N(e) ? yield* p(e, t, !1) : t.value += e;
54
- i && t.value && (yield t.value);
55
- }, T = (e, t, i) => {
56
- i && (i.$gen ?? (i.$gen = (new I(i), e)), i.$ref = B.bind(null, i), i.$args = t, i.next());
57
- }, B = (e, t) => t ?? e.return(), E = (e, t, i) => {
42
+ r.nodeName = o.is ?? "div", r.skip = !0, r.ref = O.bind(null, o, a), yield r;
43
+ } else yield* $(o(e), t, !1);
44
+ else yield e;
45
+ } else m(e) ? yield* $(e, t, !1) : t.value += e;
46
+ n && t.value && (yield t.value);
47
+ }, O = (e, t, n) => {
48
+ n && (n.$gen ?? (n.$gen = (new B(n), e)), n.$ref = C.bind(null, n), y(n.$args ?? (n.$args = {}), t), n.$next());
49
+ }, C = (e, t) => t ?? e.$return(), T = (e, t, n) => {
58
50
  if (t.contains(document.activeElement)) {
59
- const n = t.nextSibling;
60
- for (; i && i != t; ) {
61
- const o = i.nextSibling;
62
- e.insertBefore(i, n), i = o;
51
+ const i = t.nextSibling;
52
+ for (; n && n != t; ) {
53
+ const o = n.nextSibling;
54
+ e.insertBefore(n, i), n = o;
63
55
  }
64
- } else
65
- e.insertBefore(t, i);
66
- }, k = (e) => {
67
- for (const i of e.children)
68
- k(i);
56
+ } else e.insertBefore(t, n);
57
+ }, x = (e) => {
58
+ for (const n of e.children) x(n);
69
59
  const { $ref: t } = e;
70
60
  typeof t == "function" && t(null);
71
- for (const i of w(e))
72
- e[i] = null;
73
61
  };
74
- class I {
62
+ class B {
75
63
  constructor(t) {
76
- x(t, x(v(this), v(t)));
64
+ p(t, p(v(this), v(t)));
77
65
  }
78
- *[Symbol.iterator]() {
79
- for (; ; )
80
- yield this.$args ?? {};
81
- }
82
- refresh() {
83
- P(this);
84
- }
85
- next() {
66
+ $next() {
86
67
  try {
87
- d((this.$it ?? (this.$it = this.$gen.call(this, this.$args ?? {}))).next().value, this), typeof this.$ref == "function" && this.$ref(this);
68
+ d((this.$it ?? (this.$it = this.$gen.call(this, this.$args))).next().value, this), typeof this.$ref == "function" && this.$ref(this);
88
69
  } catch (t) {
89
- this.throw(t);
70
+ this.$throw(t);
90
71
  }
91
72
  }
92
- throw(t) {
93
- var i;
94
- for (let n = this; n; n = n.parentNode)
95
- if (typeof ((i = n.$it) == null ? void 0 : i.throw) == "function")
96
- try {
97
- return d(n.$it.throw(t).value, n);
98
- } catch {
99
- }
73
+ $throw(t) {
74
+ var n;
75
+ for (let i = this; i; i = i.parentNode) if (typeof ((n = i.$it) == null ? void 0 : n.throw) == "function") try {
76
+ return d(i.$it.throw(t).value, i);
77
+ } catch {
78
+ }
100
79
  throw t;
101
80
  }
102
- return() {
81
+ $return() {
103
82
  var t;
104
83
  try {
105
84
  (t = this.$it) == null || t.return();
106
- } catch (i) {
107
- this.throw(i);
85
+ } catch (n) {
86
+ this.$throw(n);
108
87
  } finally {
109
88
  this.$it = null;
110
89
  }
111
90
  }
112
91
  }
113
- let l, S;
114
- const P = (e) => {
115
- (l ?? (l = /* @__PURE__ */ new Set())).has(e) && l.delete(e);
116
- for (const t of l) {
117
- if (t.contains(e))
118
- return;
119
- e.contains(t) && l.delete(t);
120
- }
121
- l.add(e), S ?? (S = requestAnimationFrame(W));
122
- }, W = () => {
123
- for (const e of l)
124
- e.isConnected && e.next();
125
- l.clear(), S = null;
126
- };
127
92
  export {
128
- j as Fragment,
129
- z as h,
93
+ E as Fragment,
94
+ F as h,
130
95
  d as render
131
96
  };
package/license CHANGED
@@ -1,6 +1,6 @@
1
1
  ISC License
2
2
 
3
- Copyright (c) 2023, Cristian Falcone
3
+ Copyright (c) 2024, Cristian Falcone
4
4
 
5
5
  Permission to use, copy, modify, and/or distribute this software for any
6
6
  purpose with or without fee is hereby granted, provided that the above
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ajo",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "ajo is a JavaScript view library for building user interfaces",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -9,11 +9,13 @@
9
9
  "exports": {
10
10
  ".": {
11
11
  "import": "./dist/index.js",
12
- "require": "./dist/index.cjs"
12
+ "require": "./dist/index.cjs",
13
+ "types": "./types.ts"
13
14
  },
14
15
  "./html": {
15
16
  "import": "./dist/html.js",
16
- "require": "./dist/html.umd.cjs"
17
+ "require": "./dist/html.cjs",
18
+ "types": "./types.ts"
17
19
  }
18
20
  },
19
21
  "files": [
@@ -21,9 +23,10 @@
21
23
  "types.ts"
22
24
  ],
23
25
  "devDependencies": {
24
- "jsdom": "24.0.0",
25
- "vite": "5.0.12",
26
- "vitest": "1.2.1"
26
+ "@types/node": "^20.14.10",
27
+ "jsdom": "24.1.0",
28
+ "vite": "5.3.3",
29
+ "vitest": "2.0.1"
27
30
  },
28
31
  "keywords": [
29
32
  "ui",
package/readme.md CHANGED
@@ -68,7 +68,7 @@ function* Counter() {
68
68
 
69
69
  const handleClick = () => {
70
70
  count++
71
- this.refresh()
71
+ this.$next()
72
72
  }
73
73
 
74
74
  while (true) yield (
@@ -254,7 +254,7 @@ Stateful components in Ajo are defined using generator functions. These componen
254
254
  The following example demonstrates key features of stateful components in Ajo:
255
255
 
256
256
  ```jsx
257
- function* ChatComponent({ user = 'Anonymous', room }) { // Receive arguments initial values.
257
+ function* ChatComponent(props) {
258
258
 
259
259
  // Define mutable state variables.
260
260
  let message = '', connected = false
@@ -264,36 +264,33 @@ function* ChatComponent({ user = 'Anonymous', room }) { // Receive arguments ini
264
264
 
265
265
  message = event.target.value
266
266
 
267
- // Render synchronously.
268
- this.next()
267
+ this.$next()
269
268
  }
270
269
 
271
270
  const send = () => {
272
271
 
273
272
  if (message) {
274
273
 
275
- // Access current arguments values with 'this.$args'.
276
- connection.send(JSON.stringify({ user: this.$args.user, message }))
274
+ connection.send(JSON.stringify({ user: props.user ?? 'Anonymous', message }))
277
275
 
278
276
  message = ''
279
277
 
280
- // Render asynchronously.
281
- this.refresh()
278
+ this.$next()
282
279
  }
283
280
  }
284
281
 
285
282
  const handleConnectionOpen = () => {
286
283
  connected = true
287
- this.refresh()
284
+ this.$next()
288
285
  }
289
286
 
290
287
  const handleConnectionError = error => {
291
288
  // Throw error to be caught by the component itself or a parent component.
292
- this.throw(new Error('Connection error: ' + error.message))
289
+ this.$throw(new Error('Connection error: ' + error.message))
293
290
  }
294
291
 
295
292
  // Setup resources.
296
- const server = `ws://chat.com/${room}`
293
+ const server = `ws://chat.com/${props.room}`
297
294
  const connection = new WebSocket(server)
298
295
 
299
296
  connection.onopen = handleConnectionOpen
@@ -304,12 +301,12 @@ function* ChatComponent({ user = 'Anonymous', room }) { // Receive arguments ini
304
301
 
305
302
  try { // Optional try/finally block for cleanup logic.
306
303
 
307
- for ({ user } of this) { // Iterates over generator, optionally receiving updated arguments.
304
+ while (true) {
308
305
 
309
306
  try { // Optional try/catch block for error handling.
310
307
 
311
308
  // Compute derived values.
312
- const status = connected ? `You are connected as ${user}.` : "Connecting to chat..."
309
+ const status = connected ? `You are connected as ${props.user ?? 'Anonymous'}.` : "Connecting to chat..."
313
310
 
314
311
  // Render the component UI.
315
312
  yield (
@@ -401,7 +398,7 @@ function* ParentComponent() {
401
398
  />
402
399
  }
403
400
 
404
- function* ChildComponent({ data, onEvent }) {
401
+ function* ChildComponent(props) { // props is an object containing data and onEvent
405
402
  // ...
406
403
  }
407
404
  ```
@@ -417,95 +414,76 @@ In the context of Server-Side Rendering (SSR), this features allows Ajo to grace
417
414
 
418
415
  Stateful components in Ajo are equipped with several methods that allow for advanced control over component behavior, error handling, and rendering processes. These methods are called lifecycle methods and are invoked at different stages of the component's lifecycle.
419
416
 
420
- ### `this.refresh()`
417
+ ### `this.$next()`
421
418
 
422
- The `refresh` method is used to asynchronously trigger a re-render of a stateful component in Ajo. It schedules a render using `requestAnimationFrame`, ensuring that the rendering aligns with the browser's paint cycle.
419
+ The `$next` method is used within stateful components in Ajo to advance the component's generator function to its next yield point. This method is crucial for rendering the next state of the component.
423
420
 
424
421
  #### Purpose:
425
422
 
426
- - **Asynchronous Rendering:** `this.refresh()` queues a render of the component in the next animation frame, making it asynchronous.
427
- - **Single Render:** If called multiple times before the browser paints, `this.refresh()` schedules only one render, ensuring that the component is rendered only once.
423
+ - **Synchronous Rendering:** `this.$next()` is used to render the next state of the component. It advances the generator function to the next yield, reflecting any changes in state or props right away.
428
424
 
429
425
  #### Usage:
430
426
 
431
- - **For Performance Optimization:** Ideal in scenarios where multiple state updates occur in quick succession.
432
- - **In Event Handlers and Async Operations:** Useful in event handlers or after asynchronous operations where you need to update the UI in response to changes.
427
+ - **In Response to State Changes:** Typically, `this.$next()` is called in scenarios where the component's state has changed and an update to the DOM is required.
433
428
 
434
429
  #### Example:
435
430
 
436
431
  ```jsx
437
- function* DataFetcher() {
432
+ function* Counter() {
438
433
 
439
- let data = null
434
+ let count = 0
440
435
 
441
- const fetchData = async () => {
436
+ const increment = () => {
442
437
 
443
- data = await fetchSomeData()
438
+ count++
444
439
 
445
- // Queue a re-render to update the component with the fetched data:
446
- this.refresh()
440
+ this.$next()
447
441
  }
448
442
 
449
443
  while (true) {
450
- yield (
451
- <div>
452
- <button set:onclick={fetchData}>Fetch Data</button>
453
- {data && <DisplayData data={data} />}
454
- </div>
455
- )
444
+ yield <button set:onclick={increment}>{count}</button>
456
445
  }
457
446
  }
458
447
  ```
459
- > In this example, `DataFetcher` uses `this.refresh()` to update its display after data is fetched. The use of `this.refresh()` ensures that the rendering is efficient and aligned with the browser's rendering cycle.
460
-
461
- ### `this.next()`
462
- > **Note:** `this.next()` is called asynchronously when calling `this.refresh()`.
463
-
464
- The `next` method is used within stateful components in Ajo to manually advance the component's generator function to its next yield point. This method is crucial for synchronously rendering the next state of the component.
465
-
466
- #### Purpose:
467
-
468
- - **Synchronous Rendering:** `this.next()` is used to immediately render the next state of the component. It advances the generator function to the next yield, reflecting any changes in state or props right away.
469
-
470
- #### Usage:
471
-
472
- - **In Response to State Changes:** Typically, `this.next()` is called in scenarios where the component's state has changed and an immediate update to the DOM is required.
473
- - **For Controlled Updates:** It allows for more controlled and predictable updates, as it bypasses the asynchronous rendering cycle from `this.refresh()`.
474
-
475
- #### Example:
448
+ > In this example, `Counter` uses `this.$next()` in its `increment` function to render the updated count whenever the button is clicked.
476
449
 
477
450
  ```jsx
478
- function* Counter() {
451
+ function* DataFetcher() {
479
452
 
480
- let count = 0
453
+ let data = null
481
454
 
482
- const increment = () => {
455
+ const fetchData = async () => {
483
456
 
484
- count++
457
+ data = await fetchSomeData()
485
458
 
486
- // Immediately render the updated count
487
- this.next()
459
+ // Queue a re-render to update the component with the fetched data:
460
+ this.$next()
488
461
  }
489
462
 
490
463
  while (true) {
491
- yield <button set:onclick={increment}>{count}</button>
464
+ yield (
465
+ <div>
466
+ <button set:onclick={fetchData}>Fetch Data</button>
467
+ {data && <DisplayData data={data} />}
468
+ </div>
469
+ )
492
470
  }
493
471
  }
494
472
  ```
495
- > In this example, `Counter` uses `this.next()` in its `increment` function to immediately render the updated count whenever the button is clicked.
473
+ > In this example, `DataFetcher` uses `this.$next()` to update its display after data is fetched.
496
474
 
497
- ### `this.throw()`
498
- > **Note:** `this.throw()` is automatically called when an error is thrown from a component's generator function.
475
+ ### `this.$throw()`
476
+ > **Note:** `this.$throw()` is automatically called when an error is thrown from a component's generator function.
499
477
 
500
- The `throw` method in Ajo stateful components is designed for error propagation within the component hierarchy. It allows developers to throw errors from a child component to be caught and handled by itself or a parent component, facilitating a structured approach to error management.
478
+ The `$throw` method in Ajo stateful components is designed for error propagation within the component hierarchy. It allows developers to throw errors from a child component to be caught and handled by itself or a parent component, facilitating a structured approach to error management.
501
479
 
502
480
  #### Purpose:
503
481
 
504
- - **Error Propagation:** `this.throw()` is used to send errors from the current component up to its parents component, akin to creating an error boundary.
482
+ - **Error Propagation:** `this.$throw()` is used to send errors from the current component up to its parents component, akin to creating an error boundary.
505
483
 
506
484
  #### Usage:
507
485
 
508
- - **Handling Uncaught Exceptions:** Typically used within event handlers or asynchronous operations where errors might occur. Instead of handling these errors locally within the component, `this.throw()` sends them to the parent component for a more centralized handling approach.
486
+ - **Handling Uncaught Exceptions:** Typically used within event handlers or asynchronous operations where errors might occur. Instead of handling these errors locally within the component, `this.$throw()` sends them to the parent component for a more centralized handling approach.
509
487
  - **Creating Error Boundaries:** Useful in scenarios where a parent component is designed to handle errors from its child components, maintaining separation of concerns and cleaner code.
510
488
 
511
489
  #### Example:
@@ -522,7 +500,7 @@ function* ChildComponent() {
522
500
  } catch (err) {
523
501
 
524
502
  // Propagate error to parent component
525
- this.throw(err)
503
+ this.$throw(err)
526
504
  }
527
505
  }
528
506
 
@@ -541,16 +519,16 @@ function* ParentComponent() {
541
519
  }
542
520
  }
543
521
  ```
544
- > In this example, `ChildComponent` uses `this.throw()` within an event handler to propagate errors upwards to its parent component, `ParentComponent`. The parent component then catches the error and renders it to the DOM.
522
+ > In this example, `ChildComponent` uses `this.$throw()` within an event handler to propagate errors upwards to its parent component, `ParentComponent`. The parent component then catches the error and renders it to the DOM.
545
523
 
546
- ### `this.return()`
547
- > **Note:** `this.return()` is automatically called when a stateful component is unmounted.
524
+ ### `this.$return()`
525
+ > **Note:** `this.$return()` is automatically called when a stateful component is unmounted.
548
526
 
549
- The `return` method in Ajo is used to reset and restart the generator function of a stateful component. It effectively ends the current execution of the component's generator function, and optionally re-execute it from scratch allowing for a complete reset of the component's state and behavior.
527
+ The `$return` method in Ajo is used to reset and restart the generator function of a stateful component. It effectively ends the current execution of the component's generator function, and optionally re-execute it from scratch allowing for a complete reset of the component's state and behavior.
550
528
 
551
529
  #### Purpose:
552
530
 
553
- - **Component Reset:** `this.return()` is used to restart a component's generator function from the beginning, resetting its internal state and re-initializing it as needed.
531
+ - **Component Reset:** `this.$return()` is used to restart a component's generator function from the beginning, resetting its internal state and re-initializing it as needed.
554
532
 
555
533
  #### Usage:
556
534
 
@@ -571,16 +549,16 @@ function* MultiStepForm({ initialData }) {
571
549
  currentStep++
572
550
 
573
551
  // Re-render with the next step
574
- this.refresh()
552
+ this.$next()
575
553
  }
576
554
 
577
555
  const handleRestart = () => {
578
556
 
579
557
  // Reset the generator function
580
- this.return()
558
+ this.$return()
581
559
 
582
560
  // Re-render the component in its initial state
583
- this.refresh()
561
+ this.$next()
584
562
  }
585
563
 
586
564
  while (true) {
@@ -608,7 +586,7 @@ function* MultiStepForm({ initialData }) {
608
586
  }
609
587
  }
610
588
  ```
611
- > In `handleRestart`, `this.return()` is first called to reset the generator function. This effectively ends the current execution of the component's generator function and prepares it to start from the beginning. Immediately after, `this.refresh()` is called to trigger a re-render of the component. This ensures that after the state is reset, the component's UI is also updated to reflect its initial state.
589
+ > In `handleRestart`, `this.$return()` is first called to reset the generator function. This effectively ends the current execution of the component's generator function and prepares it to start from the beginning. Immediately after, `this.$next()` is called to trigger a re-render of the component. This ensures that after the state is reset, the component's UI is also updated to reflect its initial state.
612
590
 
613
591
  ## Server-Side Rendering (SSR)
614
592
 
package/types.ts CHANGED
@@ -1,69 +1,83 @@
1
- declare namespace Ajo {
2
-
3
- interface VNode<TTag = Tag> extends Partial<AjoProps<ElementType<TTag>>> {
4
- nodeName: TTag,
5
- [key: string]: unknown,
6
- }
7
-
8
- type Child = null | undefined | boolean | bigint | number | string | symbol | Node | VNode | Iterable<Child>
9
-
10
- type Tag = keyof (HTMLElementTagNameMap & SVGElementTagNameMap)
11
-
12
- type ElementType<TTag> =
13
- TTag extends keyof HTMLElementTagNameMap
14
- ? HTMLElementTagNameMap[TTag]
15
- : TTag extends keyof SVGElementTagNameMap
16
- ? SVGElementTagNameMap[TTag]
17
- : HTMLElement
18
-
19
- type AjoProps<TElement> = {
20
- key: unknown,
21
- skip: boolean,
22
- memo: unknown,
23
- ref: (el: TElement | null) => void,
24
- children: Child,
25
- }
26
-
27
- type SetProps<TTag> = {
28
- [K in keyof ElementType<TTag> as `set:${Exclude<K, symbol>}`]: ElementType<TTag>[K]
29
- }
30
-
31
- type AttrProps<T> = {
32
- [K in keyof T as `attr:${Exclude<K, symbol>}`]: T[K]
33
- }
34
-
35
- type Context<TArgs> = {
36
- $args: TArgs
37
- next: () => void
38
- throw: (error?: unknown) => void
39
- return: () => void
40
- refresh: () => void
41
- [Symbol.iterator]: () => Generator<TArgs, void, TArgs>
42
- }
43
-
44
- type Function<TArgs = {}> = (args: TArgs) => Child
45
-
46
- type Component<TArgs = {}, TTag extends Tag = 'div'> = {
47
- (this: ElementType<TTag> & Context<TArgs>, args: TArgs): Generator<Child, void, Child>
48
- } & (TTag extends 'div' ? { is?: TTag } : { is: TTag })
49
- }
1
+ declare module 'ajo' {
50
2
 
51
- declare namespace JSX {
3
+ type Tag = keyof (HTMLElementTagNameMap & SVGElementTagNameMap)
4
+
5
+ type Type = Tag | Function | Component
6
+
7
+ type Props = Record<string, unknown>
8
+
9
+ type AjoNode<TTag extends Type> = { nodeName: TTag } & TagProps<TTag>
10
+
11
+ type Children = any
12
+
13
+ type ElementType<TTag = Tag> = TTag extends keyof HTMLElementTagNameMap
14
+ ? HTMLElementTagNameMap[TTag]
15
+ : TTag extends keyof SVGElementTagNameMap
16
+ ? SVGElementTagNameMap[TTag]
17
+ : never
18
+
19
+ type AjoProps<TElement> = {
20
+ key: unknown
21
+ skip: boolean
22
+ memo: unknown
23
+ ref: (el: TElement | null) => void
24
+ } & ElementChildrenAttribute
25
+
26
+ type SetProps<TTag = Tag> = {
27
+ [K in keyof ElementType<TTag> as `set:${Exclude<K, symbol>}`]: ElementType<TTag>[K]
28
+ }
29
+
30
+ type AttrProps<TAttribute = Props> = {
31
+ [K in keyof TAttribute as `attr:${Exclude<K, symbol>}`]: TAttribute[K]
32
+ }
52
33
 
53
- type IntrinsicElements = {
54
- [TTag in Ajo.Tag]: Partial<Ajo.SetProps<TTag> & Ajo.AjoProps<Ajo.ElementType<TTag>>>
55
- }
34
+ type Context<TArguments = Props> = {
35
+ $args: TArguments
36
+ $next: () => void
37
+ $throw: (value?: unknown) => void
38
+ $return: () => void
39
+ [Symbol.iterator]: () => Iterator<TArguments, unknown, unknown>
40
+ }
56
41
 
57
- type IntrinsicAttributes = Partial<Ajo.AttrProps<any> & Omit<Ajo.AjoProps<any>, "skip" | "ref">>
42
+ type Function<TArguments = Props> = (args: TArguments) => Children
43
+
44
+ type Component<TArguments = Props, TTag extends Tag = 'div'> = {
45
+ (this: ElementType<TTag> & Context<TArguments>, args: TArguments): Iterator<Children, unknown, unknown>
46
+ } & (TTag extends 'div' ? { is?: TTag } : { is: TTag })
47
+
48
+ type Ref<TComponent> = TComponent extends Component<infer TArguments, infer TTag>
49
+ ? Component<TArguments & { ref: (el: ThisParameterType<Ref<TComponent>> | null) => void }, TTag>
50
+ : never
51
+
52
+ type IntrinsicElements = {
53
+ [TTag in Tag]: Partial<SetProps<TTag> & AjoProps<ElementType<TTag>>> & Props
54
+ }
55
+
56
+ type IntrinsicAttributes = Partial<Omit<AjoProps<ElementType<Tag>>, 'skip' | 'ref'>> & AttrProps
57
+
58
+ type ElementChildrenAttribute = { children: Children }
59
+
60
+ type TagProps<TTag extends Type> = TTag extends Tag
61
+ ? IntrinsicElements[TTag] & IntrinsicAttributes
62
+ : TTag extends Function<infer TArguments>
63
+ ? TArguments
64
+ : TTag extends Component<infer TArguments>
65
+ ? TArguments
66
+ : never
67
+
68
+ function Fragment({ children }: ElementChildrenAttribute): typeof children
69
+ function h<TTag extends Tag>(tag: TTag, props?: TagProps<TTag> | null, ...children: Array<unknown>): AjoNode<TTag>
70
+ function render(h: Children, el: Element): void
58
71
  }
59
72
 
60
- declare namespace React {
61
- export const createElement: typeof import('ajo').h
62
- export const Fragment: typeof import('ajo').Fragment
73
+ declare namespace JSX {
74
+ type ElementChildrenAttribute = import('ajo').ElementChildrenAttribute
75
+ type IntrinsicElements = import('ajo').IntrinsicElements
76
+ type IntrinsicAttributes = import('ajo').IntrinsicAttributes
63
77
  }
64
78
 
65
- declare module 'ajo' {
66
- function Fragment({ children }: { children: Ajo.Child }): typeof children
67
- function h<TProps = {}>(type: Ajo.Tag | Ajo.Function<TProps> | Ajo.Component<TProps>, props?: TProps | null, ...children: Ajo.Child[]): Ajo.VNode<typeof type>
68
- function render(h: Ajo.Child, el: Element): void
79
+ declare namespace React {
80
+ const createElement: typeof import('ajo').h
81
+ const Fragment: typeof import('ajo').Fragment
82
+ type ReactNode = import('ajo').Children
69
83
  }