duo-map 0.0.2 β†’ 0.1.0

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/README.md CHANGED
@@ -3,13 +3,17 @@
3
3
  [![npm version](https://img.shields.io/npm/v/duo-map.svg)](https://www.npmjs.com/package/duo-map) [![npm downloads](http://img.shields.io/npm/dm/duo-map.svg)](https://npmcharts.com/compare/duo-map,token-types?start=1200&interval=30)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/59dd6795e61949fb97066ca52e6097ef)](https://www.codacy.com/app/Borewit/duo-map?utm_source=github.com&utm_medium=referral&utm_content=Borewit/duo-map&utm_campaign=Badge_Grade)
5
5
 
6
- A `Map` that maps **two keys to a single value**. Think of it as a nested `Map<Map>` with a flat API β€” no manual `get`/`set` bookkeeping of the inner map.
6
+
7
+ This package offers 2 containers:
8
+
9
+ - `DuoMap<K1, K2, V>`: A map with two keys.
10
+ - `TresMap<K1, K2, K3, V>`: A map with three keys.
7
11
 
8
12
  For more awesome packages, check out [my homepageπŸ’›](https://baendlorel.github.io/?repoType=npm)
9
13
 
10
14
  ## Features
11
15
 
12
- - πŸ—οΈ **Two keys, one lookup**: `get(key1, key2)` replaces the `map.get(a)?.get(b)` dance.
16
+ - πŸ—οΈ **Two/three keys, one lookup**: `duo.get(key1, key2)`/`tres.get(key1, key2, key3)` replaces the `map.get(a)?.get(b)`/`map.get(a)?.get(b)?.get(c)` dance.
13
17
  - 🌲 **Nested semantics**: entries are grouped by `key1`, but the API is flat.
14
18
  - 🧹 **Self-cleaning**: deleting the last pair of a `key1` group removes the group itself.
15
19
  - πŸ’€ **Lazy inserts**: `getOrInsertComputed` only computes when the pair is actually missing.
@@ -202,16 +206,16 @@ Keys are compared with **SameValueZero**, exactly like native `Map` β€” `NaN` ma
202
206
 
203
207
  ## Differences from native `Map`
204
208
 
205
- | Feature | `Map` | `DuoMap` |
206
- | --------------------- | --------------------- | -------------------------------------------- |
207
- | Keys per entry | 1 | 2 |
208
- | Read / write | `(key)` | `(key1, key2)` |
209
- | Iteration yields | `[key, value]` | `[key1, key2, value]` |
210
- | `forEach` callback | `(value, key, map)` | `(value, key1, key2)` |
211
- | `keys()` / `values()` | iterators | plain arrays |
212
- | `getOrInsert` | proposal only | shipped, with a lazy `getOrInsertComputed` |
213
- | Empty group cleanup | β€” | `key1` group dropped with its last `delete` |
214
- | `.size` | O(1) | O(number of `key1` groups) |
209
+ | Feature | `Map` | `DuoMap` |
210
+ | --------------------- | ------------------- | ------------------------------------------- |
211
+ | Keys per entry | 1 | 2 |
212
+ | Read / write | `(key)` | `(key1, key2)` |
213
+ | Iteration yields | `[key, value]` | `[key1, key2, value]` |
214
+ | `forEach` callback | `(value, key, map)` | `(value, key1, key2)` |
215
+ | `keys()` / `values()` | iterators | plain arrays |
216
+ | `getOrInsert` | proposal only | shipped, with a lazy `getOrInsertComputed` |
217
+ | Empty group cleanup | β€” | `key1` group dropped with its last `delete` |
218
+ | `.size` | O(1) | O(number of `key1` groups) |
215
219
 
216
220
  ## License
217
221
 
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=(e,t,n)=>(e.has(t)||e.set(t,n),e.get(t)),t=(e,t,n)=>(e.has(t)||e.set(t,n(t)),e.get(t)),n=()=>/* @__PURE__ */ new Map;var r=class{map=/* @__PURE__ */ new Map;get size(){let e=0;return this.map.forEach(t=>e+=t.size),e}set(e,r,i){return t(this.map,e,n).set(r,i),this}get(e,t){return this.map.get(e)?.get(t)}getOrInsert(r,i,a){let o=t(this.map,r,n);return e(o,i,a)}getOrInsertComputed(e,r,i){let a=t(this.map,e,n);return t(a,r,()=>i(e,r))}has(e,t){return this.map.get(e)?.has(t)??!1}delete(e,t){let n=this.map.get(e);if(!n)return!1;let r=n.delete(t);return n.size===0&&this.map.delete(e),r}clear(){this.map.clear()}forEach(e){this.map.forEach((t,n)=>t.forEach((t,r)=>e(t,n,r)))}keys(){let e=[];return this.map.forEach((t,n)=>t.forEach((t,r)=>e.push([n,r]))),e}values(){let e=[];return this.map.forEach(t=>t.forEach(t=>e.push(t))),e}entries(){let e=[];return this.map.forEach((t,n)=>t.forEach((t,r)=>e.push([n,r,t]))),e}[Symbol.iterator](){let e=this.entries(),t=0;return{next(){return t<e.length?{value:e[t++],done:!1}:{value:void 0,done:!0}}}}};exports.DuoMap=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=(e,t,n)=>(e.has(t)||e.set(t,n),e.get(t)),t=(e,t,n)=>(e.has(t)||e.set(t,n(t)),e.get(t)),n=()=>/* @__PURE__ */ new Map;var r=class{map=/* @__PURE__ */ new Map;get size(){let e=0;return this.map.forEach(t=>e+=t.size),e}set(e,r,i){return t(this.map,e,n).set(r,i),this}get(e,t){return this.map.get(e)?.get(t)}getOrInsert(r,i,a){let o=t(this.map,r,n);return e(o,i,a)}getOrInsertComputed(e,r,i){let a=t(this.map,e,n);return t(a,r,()=>i(e,r))}has(e,t){return this.map.get(e)?.has(t)??!1}delete(e,t){let n=this.map.get(e);if(!n)return!1;let r=n.delete(t);return n.size===0&&this.map.delete(e),r}clear(){this.map.clear()}forEach(e){this.map.forEach((t,n)=>t.forEach((t,r)=>e(t,n,r)))}*keys(){for(let[e,t]of this.map)for(let n of t.keys())yield[e,n]}*values(){for(let e of this.map.values())yield*e.values()}*entries(){for(let[e,t]of this.map)for(let[n,r]of t)yield[e,n,r]}*[Symbol.iterator](){yield*this.entries()}},i=class{map=/* @__PURE__ */ new Map;get size(){let e=0;return this.map.forEach(t=>t.forEach(t=>e+=t.size)),e}set(e,r,i,a){let o=t(this.map,e,n);return t(o,r,n).set(i,a),this}get(e,t,n){return this.map.get(e)?.get(t)?.get(n)}getOrInsert(r,i,a,o){let s=t(this.map,r,n),c=t(s,i,n);return e(c,a,o)}getOrInsertComputed(e,r,i,a){let o=t(this.map,e,n),s=t(o,r,n);return t(s,i,()=>a(e,r,i))}has(e,t,n){return this.map.get(e)?.get(t)?.has(n)??!1}delete(e,t,n){let r=this.map.get(e);if(!r)return!1;let i=r.get(t);if(!i)return!1;let a=i.delete(n);return i.size===0&&(r.delete(t),r.size===0&&this.map.delete(e)),a}clear(){this.map.clear()}forEach(e){this.map.forEach((t,n)=>t.forEach((t,r)=>t.forEach((t,i)=>e(t,n,r,i))))}*keys(){for(let[e,t]of this.map)for(let[n,r]of t)for(let t of r.keys())yield[e,n,t]}*values(){for(let e of this.map.values())for(let t of e.values())yield*t.values()}*entries(){for(let[e,t]of this.map)for(let[n,r]of t)for(let[t,i]of r)yield[e,n,t,i]}*[Symbol.iterator](){yield*this.entries()}};exports.DuoMap=r,exports.TresMap=i;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["_getOrInsert","map","key","value","_getOrInsertComputed","compute","MapConstruct","DuoMap","count","m","key1","key2","result","callback","entries","index"],"sources":["../../_shared/std/map.ts","../src/index.ts"],"sourcesContent":["// # Map\nexport const _getOrInsert = <K, V>(map: Map<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _getOrInsertComputed = <K, V>(map: Map<K, V>, key: K, compute: (key: K) => V): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n\n// # WeakMap\nexport const _weakGetOrInsert = <K extends WeakKey, V>(map: WeakMap<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _weakGetOrInsertComputed = <K extends WeakKey, V>(\n map: WeakMap<K, V>,\n key: K,\n compute: (key: K) => V,\n): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n","import { _getOrInsertComputed, _getOrInsert } from '@shared/std/map.js';\n\nconst MapConstruct = () => new Map();\n\nexport class DuoMap<K1 = any, K2 = any, V = any> {\n private map = new Map<K1, Map<K2, V>>();\n\n get size(): number {\n let count = 0;\n this.map.forEach((m) => (count += m.size));\n return count;\n }\n\n set(key1: K1, key2: K2, value: V): this {\n _getOrInsertComputed(this.map, key1, MapConstruct).set(key2, value);\n return this;\n }\n\n get(key1: K1, key2: K2): V | undefined {\n return this.map.get(key1)?.get(key2);\n }\n\n getOrInsert(key1: K1, key2: K2, value: V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsert(m, key2, value);\n }\n\n getOrInsertComputed(key1: K1, key2: K2, compute: (key1: K1, key2: K2) => V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsertComputed(m, key2, () => compute(key1, key2));\n }\n\n has(key1: K1, key2: K2): boolean {\n return this.map.get(key1)?.has(key2) ?? false;\n }\n\n delete(key1: K1, key2: K2): boolean {\n const m = this.map.get(key1);\n if (!m) {\n return false;\n }\n const result = m.delete(key2);\n if (m.size === 0) {\n this.map.delete(key1);\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n forEach(callback: (value: V, key1: K1, key2: K2) => void): void {\n this.map.forEach((m, key1) => m.forEach((value, key2) => callback(value, key1, key2)));\n }\n\n keys(): [K1, K2][] {\n const result: [K1, K2][] = [];\n this.map.forEach((m, key1) => m.forEach((_, key2) => result.push([key1, key2])));\n return result;\n }\n\n values(): V[] {\n const result: V[] = [];\n this.map.forEach((m) => m.forEach((value) => result.push(value)));\n return result;\n }\n\n entries(): [K1, K2, V][] {\n const result: [K1, K2, V][] = [];\n this.map.forEach((m, key1) => m.forEach((value, key2) => result.push([key1, key2, value])));\n return result;\n }\n\n [Symbol.iterator](): Iterator<[K1, K2, V]> {\n const entries = this.entries();\n let index = 0;\n return {\n next(): IteratorResult<[K1, K2, V]> {\n if (index < entries.length) {\n return { value: entries[index++], done: false };\n } else {\n return { value: undefined as any, done: true };\n }\n },\n };\n }\n}\n"],"mappings":"mEACA,MAAaA,GAAsB,EAAgB,EAAQ,KACpDC,EAAI,IAAIC,CAAG,GACdD,EAAI,IAAIC,EAAKC,CAAK,EAEbF,EAAI,IAAIC,CAAG,GAGPE,GAA8B,EAAgB,EAAQ,KAC5DH,EAAI,IAAIC,CAAG,GACdD,EAAI,IAAIC,EAAKG,EAAQH,CAAG,CAAC,EAEpBD,EAAI,IAAIC,CAAG,GCVdI,sBAAqB,IAAI,IAE/B,IAAaC,EAAb,KAAiD,CAC/C,oBAAc,IAAI,IAElB,IAAI,MAAe,CACjB,IAAIC,EAAQ,EAEZ,OADA,KAAK,IAAI,QAAS,GAAO,GAASC,EAAE,IAAK,EAClCD,CACT,CAEA,IAAI,EAAU,EAAU,EAAgB,CAEtC,OADAJ,EAAqB,KAAK,IAAKM,EAAMJ,CAAY,CAAC,CAAC,IAAIK,EAAMR,CAAK,EAC3D,IACT,CAEA,IAAI,EAAU,EAAyB,CACrC,OAAO,KAAK,IAAI,IAAIO,CAAI,CAAC,EAAE,IAAIC,CAAI,CACrC,CAEA,YAAY,EAAU,EAAU,EAAa,CAC3C,IAAMF,EAAIL,EAAqB,KAAK,IAAKM,EAAMJ,CAAY,EAC3D,OAAON,EAAaS,EAAGE,EAAMR,CAAK,CACpC,CAEA,oBAAoB,EAAU,EAAU,EAAuC,CAC7E,IAAMM,EAAIL,EAAqB,KAAK,IAAKM,EAAMJ,CAAY,EAC3D,OAAOF,EAAqBK,EAAGE,MAAYN,EAAQK,EAAMC,CAAI,CAAC,CAChE,CAEA,IAAI,EAAU,EAAmB,CAC/B,OAAO,KAAK,IAAI,IAAID,CAAI,CAAC,EAAE,IAAIC,CAAI,GAAK,EAC1C,CAEA,OAAO,EAAU,EAAmB,CAClC,IAAMF,EAAI,KAAK,IAAI,IAAIC,CAAI,EAC3B,GAAI,CAACD,EACH,MAAO,GAET,IAAMG,EAASH,EAAE,OAAOE,CAAI,EAI5B,OAHIF,EAAE,OAAS,GACb,KAAK,IAAI,OAAOC,CAAI,EAEfE,CACT,CAEA,OAAc,CACZ,KAAK,IAAI,MAAM,CACjB,CAEA,QAAQ,EAAwD,CAC9D,KAAK,IAAI,SAAS,EAAG,IAASH,EAAE,SAAS,EAAO,IAASI,EAASV,EAAOO,EAAMC,CAAI,CAAC,CAAC,CACvF,CAEA,MAAmB,CACjB,IAAMC,EAAqB,CAAC,EAE5B,OADA,KAAK,IAAI,SAAS,EAAG,IAASH,EAAE,SAAS,EAAG,IAASG,EAAO,KAAK,CAACF,EAAMC,CAAI,CAAC,CAAC,CAAC,EACxEC,CACT,CAEA,QAAc,CACZ,IAAMA,EAAc,CAAC,EAErB,OADA,KAAK,IAAI,QAAS,GAAMH,EAAE,QAAS,GAAUG,EAAO,KAAKT,CAAK,CAAC,CAAC,EACzDS,CACT,CAEA,SAAyB,CACvB,IAAMA,EAAwB,CAAC,EAE/B,OADA,KAAK,IAAI,SAAS,EAAG,IAASH,EAAE,SAAS,EAAO,IAASG,EAAO,KAAK,CAACF,EAAMC,EAAMR,CAAK,CAAC,CAAC,CAAC,EACnFS,CACT,CAEA,CAAC,OAAO,WAAmC,CACzC,IAAME,EAAU,KAAK,QAAQ,EACzBC,EAAQ,EACZ,MAAO,CACL,MAAoC,CAIhC,OAHEA,EAAQD,EAAQ,OACX,CAAE,MAAOA,EAAQ,KAAU,KAAM,EAAM,EAEvC,CAAE,MAAO,IAAA,GAAkB,KAAM,EAAK,CAEjD,CACF,CACF,CACF"}
1
+ {"version":3,"file":"index.cjs","names":["_getOrInsert","map","key","value","_getOrInsertComputed","compute","MapConstruct","DuoMap","count","m","key1","key2","result","callback","TresMap","m2","m1","key3"],"sources":["../../_shared/std/map.ts","../src/index.ts"],"sourcesContent":["// # Map\nexport const _getOrInsert = <K, V>(map: Map<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _getOrInsertComputed = <K, V>(map: Map<K, V>, key: K, compute: (key: K) => V): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n\n// # WeakMap\nexport const _weakGetOrInsert = <K extends WeakKey, V>(map: WeakMap<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _weakGetOrInsertComputed = <K extends WeakKey, V>(\n map: WeakMap<K, V>,\n key: K,\n compute: (key: K) => V,\n): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n","import { _getOrInsertComputed, _getOrInsert } from '@shared/std/map.js';\n\nconst MapConstruct = () => new Map();\n\n/**\n * Creates a two-keyed map structure.\n *\n * @template K1 - The type of the first-level keys.\n * @template K2 - The type of the second-level keys.\n * @template V - The type of the values.\n */\nexport class DuoMap<K1 = any, K2 = any, V = any> {\n private map = new Map<K1, Map<K2, V>>();\n\n get size(): number {\n let count = 0;\n this.map.forEach((m) => (count += m.size));\n return count;\n }\n\n set(key1: K1, key2: K2, value: V): this {\n _getOrInsertComputed(this.map, key1, MapConstruct).set(key2, value);\n return this;\n }\n\n get(key1: K1, key2: K2): V | undefined {\n return this.map.get(key1)?.get(key2);\n }\n\n getOrInsert(key1: K1, key2: K2, value: V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsert(m, key2, value);\n }\n\n getOrInsertComputed(key1: K1, key2: K2, compute: (key1: K1, key2: K2) => V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsertComputed(m, key2, () => compute(key1, key2));\n }\n\n has(key1: K1, key2: K2): boolean {\n return this.map.get(key1)?.has(key2) ?? false;\n }\n\n delete(key1: K1, key2: K2): boolean {\n const m = this.map.get(key1);\n if (!m) {\n return false;\n }\n const result = m.delete(key2);\n if (m.size === 0) {\n this.map.delete(key1);\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n forEach(callback: (value: V, key1: K1, key2: K2) => void): void {\n this.map.forEach((m, key1) => m.forEach((value, key2) => callback(value, key1, key2)));\n }\n\n *keys(): IterableIterator<[K1, K2]> {\n for (const [key1, m] of this.map) {\n for (const key2 of m.keys()) {\n yield [key1, key2];\n }\n }\n }\n\n *values(): IterableIterator<V> {\n for (const m of this.map.values()) {\n yield* m.values();\n }\n }\n\n *entries(): IterableIterator<[K1, K2, V]> {\n for (const [key1, m] of this.map) {\n for (const [key2, value] of m) {\n yield [key1, key2, value];\n }\n }\n }\n\n *[Symbol.iterator](): IterableIterator<[K1, K2, V]> {\n yield* this.entries();\n }\n}\n\n/**\n * Creates a three-keyed map structure.\n *\n * @template K1 - The type of the first-level keys.\n * @template K2 - The type of the second-level keys.\n * @template K3 - The type of the third-level keys.\n * @template V - The type of the values.\n */\nexport class TresMap<K1 = any, K2 = any, K3 = any, V = any> {\n private map = new Map<K1, Map<K2, Map<K3, V>>>();\n\n get size(): number {\n let count = 0;\n this.map.forEach((m) => m.forEach((m2) => (count += m2.size)));\n return count;\n }\n\n set(key1: K1, key2: K2, key3: K3, value: V): this {\n const m1 = _getOrInsertComputed(this.map, key1, MapConstruct);\n _getOrInsertComputed(m1, key2, MapConstruct).set(key3, value);\n return this;\n }\n\n get(key1: K1, key2: K2, key3: K3): V | undefined {\n return this.map.get(key1)?.get(key2)?.get(key3);\n }\n\n getOrInsert(key1: K1, key2: K2, key3: K3, value: V): V {\n const m1 = _getOrInsertComputed(this.map, key1, MapConstruct);\n const m2 = _getOrInsertComputed(m1, key2, MapConstruct);\n return _getOrInsert(m2, key3, value);\n }\n\n getOrInsertComputed(key1: K1, key2: K2, key3: K3, compute: (key1: K1, key2: K2, key3: K3) => V): V {\n const m1 = _getOrInsertComputed(this.map, key1, MapConstruct);\n const m2 = _getOrInsertComputed(m1, key2, MapConstruct);\n return _getOrInsertComputed(m2, key3, () => compute(key1, key2, key3));\n }\n\n has(key1: K1, key2: K2, key3: K3): boolean {\n return this.map.get(key1)?.get(key2)?.has(key3) ?? false;\n }\n\n delete(key1: K1, key2: K2, key3: K3): boolean {\n const m1 = this.map.get(key1);\n if (!m1) return false;\n const m2 = m1.get(key2);\n if (!m2) return false;\n const result = m2.delete(key3);\n if (m2.size === 0) {\n m1.delete(key2);\n if (m1.size === 0) {\n this.map.delete(key1);\n }\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n forEach(callback: (value: V, key1: K1, key2: K2, key3: K3) => void): void {\n this.map.forEach((m, key1) =>\n m.forEach((m2, key2) => m2.forEach((value, key3) => callback(value, key1, key2, key3))),\n );\n }\n\n *keys(): IterableIterator<[K1, K2, K3]> {\n for (const [key1, m1] of this.map) {\n for (const [key2, m2] of m1) {\n for (const key3 of m2.keys()) {\n yield [key1, key2, key3];\n }\n }\n }\n }\n\n *values(): IterableIterator<V> {\n for (const m1 of this.map.values()) {\n for (const m2 of m1.values()) {\n yield* m2.values();\n }\n }\n }\n\n *entries(): IterableIterator<[K1, K2, K3, V]> {\n for (const [key1, m1] of this.map) {\n for (const [key2, m2] of m1) {\n for (const [key3, value] of m2) {\n yield [key1, key2, key3, value];\n }\n }\n }\n }\n\n *[Symbol.iterator](): IterableIterator<[K1, K2, K3, V]> {\n yield* this.entries();\n }\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,11 @@
1
1
  //#region src/index.d.ts
2
+ /**
3
+ * Creates a two-keyed map structure.
4
+ *
5
+ * @template K1 - The type of the first-level keys.
6
+ * @template K2 - The type of the second-level keys.
7
+ * @template V - The type of the values.
8
+ */
2
9
  declare class DuoMap<K1 = any, K2 = any, V = any> {
3
10
  private map;
4
11
  get size(): number;
@@ -10,11 +17,35 @@ declare class DuoMap<K1 = any, K2 = any, V = any> {
10
17
  delete(key1: K1, key2: K2): boolean;
11
18
  clear(): void;
12
19
  forEach(callback: (value: V, key1: K1, key2: K2) => void): void;
13
- keys(): [K1, K2][];
14
- values(): V[];
15
- entries(): [K1, K2, V][];
16
- [Symbol.iterator](): Iterator<[K1, K2, V]>;
20
+ keys(): IterableIterator<[K1, K2]>;
21
+ values(): IterableIterator<V>;
22
+ entries(): IterableIterator<[K1, K2, V]>;
23
+ [Symbol.iterator](): IterableIterator<[K1, K2, V]>;
24
+ }
25
+ /**
26
+ * Creates a three-keyed map structure.
27
+ *
28
+ * @template K1 - The type of the first-level keys.
29
+ * @template K2 - The type of the second-level keys.
30
+ * @template K3 - The type of the third-level keys.
31
+ * @template V - The type of the values.
32
+ */
33
+ declare class TresMap<K1 = any, K2 = any, K3 = any, V = any> {
34
+ private map;
35
+ get size(): number;
36
+ set(key1: K1, key2: K2, key3: K3, value: V): this;
37
+ get(key1: K1, key2: K2, key3: K3): V | undefined;
38
+ getOrInsert(key1: K1, key2: K2, key3: K3, value: V): V;
39
+ getOrInsertComputed(key1: K1, key2: K2, key3: K3, compute: (key1: K1, key2: K2, key3: K3) => V): V;
40
+ has(key1: K1, key2: K2, key3: K3): boolean;
41
+ delete(key1: K1, key2: K2, key3: K3): boolean;
42
+ clear(): void;
43
+ forEach(callback: (value: V, key1: K1, key2: K2, key3: K3) => void): void;
44
+ keys(): IterableIterator<[K1, K2, K3]>;
45
+ values(): IterableIterator<V>;
46
+ entries(): IterableIterator<[K1, K2, K3, V]>;
47
+ [Symbol.iterator](): IterableIterator<[K1, K2, K3, V]>;
17
48
  }
18
49
  //#endregion
19
- export { DuoMap };
50
+ export { DuoMap, TresMap };
20
51
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.mts CHANGED
@@ -1,4 +1,11 @@
1
1
  //#region src/index.d.ts
2
+ /**
3
+ * Creates a two-keyed map structure.
4
+ *
5
+ * @template K1 - The type of the first-level keys.
6
+ * @template K2 - The type of the second-level keys.
7
+ * @template V - The type of the values.
8
+ */
2
9
  declare class DuoMap<K1 = any, K2 = any, V = any> {
3
10
  private map;
4
11
  get size(): number;
@@ -10,11 +17,35 @@ declare class DuoMap<K1 = any, K2 = any, V = any> {
10
17
  delete(key1: K1, key2: K2): boolean;
11
18
  clear(): void;
12
19
  forEach(callback: (value: V, key1: K1, key2: K2) => void): void;
13
- keys(): [K1, K2][];
14
- values(): V[];
15
- entries(): [K1, K2, V][];
16
- [Symbol.iterator](): Iterator<[K1, K2, V]>;
20
+ keys(): IterableIterator<[K1, K2]>;
21
+ values(): IterableIterator<V>;
22
+ entries(): IterableIterator<[K1, K2, V]>;
23
+ [Symbol.iterator](): IterableIterator<[K1, K2, V]>;
24
+ }
25
+ /**
26
+ * Creates a three-keyed map structure.
27
+ *
28
+ * @template K1 - The type of the first-level keys.
29
+ * @template K2 - The type of the second-level keys.
30
+ * @template K3 - The type of the third-level keys.
31
+ * @template V - The type of the values.
32
+ */
33
+ declare class TresMap<K1 = any, K2 = any, K3 = any, V = any> {
34
+ private map;
35
+ get size(): number;
36
+ set(key1: K1, key2: K2, key3: K3, value: V): this;
37
+ get(key1: K1, key2: K2, key3: K3): V | undefined;
38
+ getOrInsert(key1: K1, key2: K2, key3: K3, value: V): V;
39
+ getOrInsertComputed(key1: K1, key2: K2, key3: K3, compute: (key1: K1, key2: K2, key3: K3) => V): V;
40
+ has(key1: K1, key2: K2, key3: K3): boolean;
41
+ delete(key1: K1, key2: K2, key3: K3): boolean;
42
+ clear(): void;
43
+ forEach(callback: (value: V, key1: K1, key2: K2, key3: K3) => void): void;
44
+ keys(): IterableIterator<[K1, K2, K3]>;
45
+ values(): IterableIterator<V>;
46
+ entries(): IterableIterator<[K1, K2, K3, V]>;
47
+ [Symbol.iterator](): IterableIterator<[K1, K2, K3, V]>;
17
48
  }
18
49
  //#endregion
19
- export { DuoMap };
50
+ export { DuoMap, TresMap };
20
51
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=(e,t,n)=>(e.has(t)||e.set(t,n),e.get(t)),t=(e,t,n)=>(e.has(t)||e.set(t,n(t)),e.get(t)),n=()=>/* @__PURE__ */ new Map;var r=class{map=/* @__PURE__ */ new Map;get size(){let e=0;return this.map.forEach(t=>e+=t.size),e}set(e,r,i){return t(this.map,e,n).set(r,i),this}get(e,t){return this.map.get(e)?.get(t)}getOrInsert(r,i,a){let o=t(this.map,r,n);return e(o,i,a)}getOrInsertComputed(e,r,i){let a=t(this.map,e,n);return t(a,r,()=>i(e,r))}has(e,t){return this.map.get(e)?.has(t)??!1}delete(e,t){let n=this.map.get(e);if(!n)return!1;let r=n.delete(t);return n.size===0&&this.map.delete(e),r}clear(){this.map.clear()}forEach(e){this.map.forEach((t,n)=>t.forEach((t,r)=>e(t,n,r)))}keys(){let e=[];return this.map.forEach((t,n)=>t.forEach((t,r)=>e.push([n,r]))),e}values(){let e=[];return this.map.forEach(t=>t.forEach(t=>e.push(t))),e}entries(){let e=[];return this.map.forEach((t,n)=>t.forEach((t,r)=>e.push([n,r,t]))),e}[Symbol.iterator](){let e=this.entries(),t=0;return{next(){return t<e.length?{value:e[t++],done:!1}:{value:void 0,done:!0}}}}};export{r as DuoMap};
1
+ const e=(e,t,n)=>(e.has(t)||e.set(t,n),e.get(t)),t=(e,t,n)=>(e.has(t)||e.set(t,n(t)),e.get(t)),n=()=>/* @__PURE__ */ new Map;var r=class{map=/* @__PURE__ */ new Map;get size(){let e=0;return this.map.forEach(t=>e+=t.size),e}set(e,r,i){return t(this.map,e,n).set(r,i),this}get(e,t){return this.map.get(e)?.get(t)}getOrInsert(r,i,a){let o=t(this.map,r,n);return e(o,i,a)}getOrInsertComputed(e,r,i){let a=t(this.map,e,n);return t(a,r,()=>i(e,r))}has(e,t){return this.map.get(e)?.has(t)??!1}delete(e,t){let n=this.map.get(e);if(!n)return!1;let r=n.delete(t);return n.size===0&&this.map.delete(e),r}clear(){this.map.clear()}forEach(e){this.map.forEach((t,n)=>t.forEach((t,r)=>e(t,n,r)))}*keys(){for(let[e,t]of this.map)for(let n of t.keys())yield[e,n]}*values(){for(let e of this.map.values())yield*e.values()}*entries(){for(let[e,t]of this.map)for(let[n,r]of t)yield[e,n,r]}*[Symbol.iterator](){yield*this.entries()}},i=class{map=/* @__PURE__ */ new Map;get size(){let e=0;return this.map.forEach(t=>t.forEach(t=>e+=t.size)),e}set(e,r,i,a){let o=t(this.map,e,n);return t(o,r,n).set(i,a),this}get(e,t,n){return this.map.get(e)?.get(t)?.get(n)}getOrInsert(r,i,a,o){let s=t(this.map,r,n),c=t(s,i,n);return e(c,a,o)}getOrInsertComputed(e,r,i,a){let o=t(this.map,e,n),s=t(o,r,n);return t(s,i,()=>a(e,r,i))}has(e,t,n){return this.map.get(e)?.get(t)?.has(n)??!1}delete(e,t,n){let r=this.map.get(e);if(!r)return!1;let i=r.get(t);if(!i)return!1;let a=i.delete(n);return i.size===0&&(r.delete(t),r.size===0&&this.map.delete(e)),a}clear(){this.map.clear()}forEach(e){this.map.forEach((t,n)=>t.forEach((t,r)=>t.forEach((t,i)=>e(t,n,r,i))))}*keys(){for(let[e,t]of this.map)for(let[n,r]of t)for(let t of r.keys())yield[e,n,t]}*values(){for(let e of this.map.values())for(let t of e.values())yield*t.values()}*entries(){for(let[e,t]of this.map)for(let[n,r]of t)for(let[t,i]of r)yield[e,n,t,i]}*[Symbol.iterator](){yield*this.entries()}};export{r as DuoMap,i as TresMap};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["_getOrInsert","map","key","value","_getOrInsertComputed","compute","MapConstruct","DuoMap","count","m","key1","key2","result","callback","entries","index"],"sources":["../../_shared/std/map.ts","../src/index.ts"],"sourcesContent":["// # Map\nexport const _getOrInsert = <K, V>(map: Map<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _getOrInsertComputed = <K, V>(map: Map<K, V>, key: K, compute: (key: K) => V): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n\n// # WeakMap\nexport const _weakGetOrInsert = <K extends WeakKey, V>(map: WeakMap<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _weakGetOrInsertComputed = <K extends WeakKey, V>(\n map: WeakMap<K, V>,\n key: K,\n compute: (key: K) => V,\n): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n","import { _getOrInsertComputed, _getOrInsert } from '@shared/std/map.js';\n\nconst MapConstruct = () => new Map();\n\nexport class DuoMap<K1 = any, K2 = any, V = any> {\n private map = new Map<K1, Map<K2, V>>();\n\n get size(): number {\n let count = 0;\n this.map.forEach((m) => (count += m.size));\n return count;\n }\n\n set(key1: K1, key2: K2, value: V): this {\n _getOrInsertComputed(this.map, key1, MapConstruct).set(key2, value);\n return this;\n }\n\n get(key1: K1, key2: K2): V | undefined {\n return this.map.get(key1)?.get(key2);\n }\n\n getOrInsert(key1: K1, key2: K2, value: V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsert(m, key2, value);\n }\n\n getOrInsertComputed(key1: K1, key2: K2, compute: (key1: K1, key2: K2) => V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsertComputed(m, key2, () => compute(key1, key2));\n }\n\n has(key1: K1, key2: K2): boolean {\n return this.map.get(key1)?.has(key2) ?? false;\n }\n\n delete(key1: K1, key2: K2): boolean {\n const m = this.map.get(key1);\n if (!m) {\n return false;\n }\n const result = m.delete(key2);\n if (m.size === 0) {\n this.map.delete(key1);\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n forEach(callback: (value: V, key1: K1, key2: K2) => void): void {\n this.map.forEach((m, key1) => m.forEach((value, key2) => callback(value, key1, key2)));\n }\n\n keys(): [K1, K2][] {\n const result: [K1, K2][] = [];\n this.map.forEach((m, key1) => m.forEach((_, key2) => result.push([key1, key2])));\n return result;\n }\n\n values(): V[] {\n const result: V[] = [];\n this.map.forEach((m) => m.forEach((value) => result.push(value)));\n return result;\n }\n\n entries(): [K1, K2, V][] {\n const result: [K1, K2, V][] = [];\n this.map.forEach((m, key1) => m.forEach((value, key2) => result.push([key1, key2, value])));\n return result;\n }\n\n [Symbol.iterator](): Iterator<[K1, K2, V]> {\n const entries = this.entries();\n let index = 0;\n return {\n next(): IteratorResult<[K1, K2, V]> {\n if (index < entries.length) {\n return { value: entries[index++], done: false };\n } else {\n return { value: undefined as any, done: true };\n }\n },\n };\n }\n}\n"],"mappings":"AACA,MAAaA,GAAsB,EAAgB,EAAQ,KACpDC,EAAI,IAAIC,CAAG,GACdD,EAAI,IAAIC,EAAKC,CAAK,EAEbF,EAAI,IAAIC,CAAG,GAGPE,GAA8B,EAAgB,EAAQ,KAC5DH,EAAI,IAAIC,CAAG,GACdD,EAAI,IAAIC,EAAKG,EAAQH,CAAG,CAAC,EAEpBD,EAAI,IAAIC,CAAG,GCVdI,sBAAqB,IAAI,IAE/B,IAAaC,EAAb,KAAiD,CAC/C,oBAAc,IAAI,IAElB,IAAI,MAAe,CACjB,IAAIC,EAAQ,EAEZ,OADA,KAAK,IAAI,QAAS,GAAO,GAASC,EAAE,IAAK,EAClCD,CACT,CAEA,IAAI,EAAU,EAAU,EAAgB,CAEtC,OADAJ,EAAqB,KAAK,IAAKM,EAAMJ,CAAY,CAAC,CAAC,IAAIK,EAAMR,CAAK,EAC3D,IACT,CAEA,IAAI,EAAU,EAAyB,CACrC,OAAO,KAAK,IAAI,IAAIO,CAAI,CAAC,EAAE,IAAIC,CAAI,CACrC,CAEA,YAAY,EAAU,EAAU,EAAa,CAC3C,IAAMF,EAAIL,EAAqB,KAAK,IAAKM,EAAMJ,CAAY,EAC3D,OAAON,EAAaS,EAAGE,EAAMR,CAAK,CACpC,CAEA,oBAAoB,EAAU,EAAU,EAAuC,CAC7E,IAAMM,EAAIL,EAAqB,KAAK,IAAKM,EAAMJ,CAAY,EAC3D,OAAOF,EAAqBK,EAAGE,MAAYN,EAAQK,EAAMC,CAAI,CAAC,CAChE,CAEA,IAAI,EAAU,EAAmB,CAC/B,OAAO,KAAK,IAAI,IAAID,CAAI,CAAC,EAAE,IAAIC,CAAI,GAAK,EAC1C,CAEA,OAAO,EAAU,EAAmB,CAClC,IAAMF,EAAI,KAAK,IAAI,IAAIC,CAAI,EAC3B,GAAI,CAACD,EACH,MAAO,GAET,IAAMG,EAASH,EAAE,OAAOE,CAAI,EAI5B,OAHIF,EAAE,OAAS,GACb,KAAK,IAAI,OAAOC,CAAI,EAEfE,CACT,CAEA,OAAc,CACZ,KAAK,IAAI,MAAM,CACjB,CAEA,QAAQ,EAAwD,CAC9D,KAAK,IAAI,SAAS,EAAG,IAASH,EAAE,SAAS,EAAO,IAASI,EAASV,EAAOO,EAAMC,CAAI,CAAC,CAAC,CACvF,CAEA,MAAmB,CACjB,IAAMC,EAAqB,CAAC,EAE5B,OADA,KAAK,IAAI,SAAS,EAAG,IAASH,EAAE,SAAS,EAAG,IAASG,EAAO,KAAK,CAACF,EAAMC,CAAI,CAAC,CAAC,CAAC,EACxEC,CACT,CAEA,QAAc,CACZ,IAAMA,EAAc,CAAC,EAErB,OADA,KAAK,IAAI,QAAS,GAAMH,EAAE,QAAS,GAAUG,EAAO,KAAKT,CAAK,CAAC,CAAC,EACzDS,CACT,CAEA,SAAyB,CACvB,IAAMA,EAAwB,CAAC,EAE/B,OADA,KAAK,IAAI,SAAS,EAAG,IAASH,EAAE,SAAS,EAAO,IAASG,EAAO,KAAK,CAACF,EAAMC,EAAMR,CAAK,CAAC,CAAC,CAAC,EACnFS,CACT,CAEA,CAAC,OAAO,WAAmC,CACzC,IAAME,EAAU,KAAK,QAAQ,EACzBC,EAAQ,EACZ,MAAO,CACL,MAAoC,CAIhC,OAHEA,EAAQD,EAAQ,OACX,CAAE,MAAOA,EAAQ,KAAU,KAAM,EAAM,EAEvC,CAAE,MAAO,IAAA,GAAkB,KAAM,EAAK,CAEjD,CACF,CACF,CACF"}
1
+ {"version":3,"file":"index.mjs","names":["_getOrInsert","map","key","value","_getOrInsertComputed","compute","MapConstruct","DuoMap","count","m","key1","key2","result","callback","TresMap","m2","m1","key3"],"sources":["../../_shared/std/map.ts","../src/index.ts"],"sourcesContent":["// # Map\nexport const _getOrInsert = <K, V>(map: Map<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _getOrInsertComputed = <K, V>(map: Map<K, V>, key: K, compute: (key: K) => V): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n\n// # WeakMap\nexport const _weakGetOrInsert = <K extends WeakKey, V>(map: WeakMap<K, V>, key: K, value: V): V => {\n if (!map.has(key)) {\n map.set(key, value);\n }\n return map.get(key)!;\n};\n\nexport const _weakGetOrInsertComputed = <K extends WeakKey, V>(\n map: WeakMap<K, V>,\n key: K,\n compute: (key: K) => V,\n): V => {\n if (!map.has(key)) {\n map.set(key, compute(key));\n }\n return map.get(key)!;\n};\n","import { _getOrInsertComputed, _getOrInsert } from '@shared/std/map.js';\n\nconst MapConstruct = () => new Map();\n\n/**\n * Creates a two-keyed map structure.\n *\n * @template K1 - The type of the first-level keys.\n * @template K2 - The type of the second-level keys.\n * @template V - The type of the values.\n */\nexport class DuoMap<K1 = any, K2 = any, V = any> {\n private map = new Map<K1, Map<K2, V>>();\n\n get size(): number {\n let count = 0;\n this.map.forEach((m) => (count += m.size));\n return count;\n }\n\n set(key1: K1, key2: K2, value: V): this {\n _getOrInsertComputed(this.map, key1, MapConstruct).set(key2, value);\n return this;\n }\n\n get(key1: K1, key2: K2): V | undefined {\n return this.map.get(key1)?.get(key2);\n }\n\n getOrInsert(key1: K1, key2: K2, value: V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsert(m, key2, value);\n }\n\n getOrInsertComputed(key1: K1, key2: K2, compute: (key1: K1, key2: K2) => V): V {\n const m = _getOrInsertComputed(this.map, key1, MapConstruct);\n return _getOrInsertComputed(m, key2, () => compute(key1, key2));\n }\n\n has(key1: K1, key2: K2): boolean {\n return this.map.get(key1)?.has(key2) ?? false;\n }\n\n delete(key1: K1, key2: K2): boolean {\n const m = this.map.get(key1);\n if (!m) {\n return false;\n }\n const result = m.delete(key2);\n if (m.size === 0) {\n this.map.delete(key1);\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n forEach(callback: (value: V, key1: K1, key2: K2) => void): void {\n this.map.forEach((m, key1) => m.forEach((value, key2) => callback(value, key1, key2)));\n }\n\n *keys(): IterableIterator<[K1, K2]> {\n for (const [key1, m] of this.map) {\n for (const key2 of m.keys()) {\n yield [key1, key2];\n }\n }\n }\n\n *values(): IterableIterator<V> {\n for (const m of this.map.values()) {\n yield* m.values();\n }\n }\n\n *entries(): IterableIterator<[K1, K2, V]> {\n for (const [key1, m] of this.map) {\n for (const [key2, value] of m) {\n yield [key1, key2, value];\n }\n }\n }\n\n *[Symbol.iterator](): IterableIterator<[K1, K2, V]> {\n yield* this.entries();\n }\n}\n\n/**\n * Creates a three-keyed map structure.\n *\n * @template K1 - The type of the first-level keys.\n * @template K2 - The type of the second-level keys.\n * @template K3 - The type of the third-level keys.\n * @template V - The type of the values.\n */\nexport class TresMap<K1 = any, K2 = any, K3 = any, V = any> {\n private map = new Map<K1, Map<K2, Map<K3, V>>>();\n\n get size(): number {\n let count = 0;\n this.map.forEach((m) => m.forEach((m2) => (count += m2.size)));\n return count;\n }\n\n set(key1: K1, key2: K2, key3: K3, value: V): this {\n const m1 = _getOrInsertComputed(this.map, key1, MapConstruct);\n _getOrInsertComputed(m1, key2, MapConstruct).set(key3, value);\n return this;\n }\n\n get(key1: K1, key2: K2, key3: K3): V | undefined {\n return this.map.get(key1)?.get(key2)?.get(key3);\n }\n\n getOrInsert(key1: K1, key2: K2, key3: K3, value: V): V {\n const m1 = _getOrInsertComputed(this.map, key1, MapConstruct);\n const m2 = _getOrInsertComputed(m1, key2, MapConstruct);\n return _getOrInsert(m2, key3, value);\n }\n\n getOrInsertComputed(key1: K1, key2: K2, key3: K3, compute: (key1: K1, key2: K2, key3: K3) => V): V {\n const m1 = _getOrInsertComputed(this.map, key1, MapConstruct);\n const m2 = _getOrInsertComputed(m1, key2, MapConstruct);\n return _getOrInsertComputed(m2, key3, () => compute(key1, key2, key3));\n }\n\n has(key1: K1, key2: K2, key3: K3): boolean {\n return this.map.get(key1)?.get(key2)?.has(key3) ?? false;\n }\n\n delete(key1: K1, key2: K2, key3: K3): boolean {\n const m1 = this.map.get(key1);\n if (!m1) return false;\n const m2 = m1.get(key2);\n if (!m2) return false;\n const result = m2.delete(key3);\n if (m2.size === 0) {\n m1.delete(key2);\n if (m1.size === 0) {\n this.map.delete(key1);\n }\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n\n forEach(callback: (value: V, key1: K1, key2: K2, key3: K3) => void): void {\n this.map.forEach((m, key1) =>\n m.forEach((m2, key2) => m2.forEach((value, key3) => callback(value, key1, key2, key3))),\n );\n }\n\n *keys(): IterableIterator<[K1, K2, K3]> {\n for (const [key1, m1] of this.map) {\n for (const [key2, m2] of m1) {\n for (const key3 of m2.keys()) {\n yield [key1, key2, key3];\n }\n }\n }\n }\n\n *values(): IterableIterator<V> {\n for (const m1 of this.map.values()) {\n for (const m2 of m1.values()) {\n yield* m2.values();\n }\n }\n }\n\n *entries(): IterableIterator<[K1, K2, K3, V]> {\n for (const [key1, m1] of this.map) {\n for (const [key2, m2] of m1) {\n for (const [key3, value] of m2) {\n yield [key1, key2, key3, value];\n }\n }\n }\n }\n\n *[Symbol.iterator](): IterableIterator<[K1, K2, K3, V]> {\n yield* this.entries();\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "duo-map",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "author": {
5
5
  "name": "KasukabeTsumugi",
6
6
  "email": "futami16237@gmail.com"
@@ -46,4 +46,4 @@
46
46
  },
47
47
  "homepage": "https://github.com/baendlorel/tsumugi-lib/tree/main/packages/duo-map#readme",
48
48
  "devDependencies": {}
49
- }
49
+ }