ygopro-deck-encode 1.0.9 → 1.0.10

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
@@ -48,7 +48,29 @@ function countItems(arr) {
48
48
  for (const item of arr) {
49
49
  map.set(item, (map.get(item) || 0) + 1);
50
50
  }
51
- return map;
51
+ const blocks = [];
52
+ for (const [item, count] of map.entries()) {
53
+ blocks.push({ item, count });
54
+ }
55
+ return blocks;
56
+ }
57
+ function countConsecutiveItems(arr) {
58
+ const result = [];
59
+ if (arr.length === 0)
60
+ return result;
61
+ let currentItem = arr[0];
62
+ let count = 1;
63
+ for (let i = 1; i < arr.length; i++) {
64
+ if (arr[i] === currentItem) {
65
+ count++;
66
+ } else {
67
+ result.push({ item: currentItem, count });
68
+ currentItem = arr[i];
69
+ count = 1;
70
+ }
71
+ }
72
+ result.push({ item: currentItem, count });
73
+ return result;
52
74
  }
53
75
  var BufferCursor = class {
54
76
  constructor(bufOrLength) {
@@ -351,32 +373,32 @@ var YGOProDeck = class {
351
373
  this.extra = [];
352
374
  this.side = [];
353
375
  }
354
- bufferLength() {
355
- const counted = [this.main, this.extra, this.side].map(countItems);
356
- return counted.reduce((a, b) => a + b.size * 4, 0);
376
+ bufferLength(noCompact = false) {
377
+ const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
378
+ return counted.reduce((a, b) => a + b.length * 4, 0);
357
379
  }
358
- toUint8Array() {
359
- const counted = [this.main, this.extra, this.side].map(countItems);
380
+ toUint8Array(noCompact = false) {
381
+ const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
360
382
  const writer = new BufferWriter(
361
- counted.reduce((a, b) => a + b.size * 4, 0)
383
+ counted.reduce((a, b) => a + b.length * 4, 0)
362
384
  );
363
385
  const writeCards = (countMap, type) => {
364
- for (const [id, count] of countMap.entries()) {
386
+ for (const { item, count } of countMap) {
365
387
  if (count > 4) {
366
- throw new Error(`Too many cards: ${id}`);
388
+ throw new Error(`Too many cards: ${item}`);
367
389
  }
368
- const value = id & 268435455 | type << 28 | count - 1 << 30;
390
+ const value = item & 268435455 | type << 28 | count - 1 << 30;
369
391
  writer.writeUint32LE(value);
370
392
  }
371
393
  };
372
394
  counted.forEach(writeCards);
373
395
  return writer.buffer;
374
396
  }
375
- toEncodedString() {
376
- return toBase64Url(this.toUint8Array());
397
+ toEncodedString(noCompact = false) {
398
+ return toBase64Url(this.toUint8Array(noCompact));
377
399
  }
378
- toString() {
379
- return this.toEncodedString();
400
+ toString(noCompact = false) {
401
+ return this.toEncodedString(noCompact);
380
402
  }
381
403
  fromUint8Array(buf) {
382
404
  for (let i = 0; i < buf.length - 3; i += 4) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../index.ts", "../src/base64.ts", "../src/utils.ts", "../src/ydke.ts", "../src/ygom.ts"],
4
- "sourcesContent": ["import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferReader, BufferWriter, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n return counted.reduce((a, b) => a + b.size * 4, 0);\n }\n\n toUint8Array() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.size * 4, 0),\n );\n const writeCards = (countMap: Map<number, number>, type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const [id, count] of countMap.entries()) {\n if (count > 4) {\n throw new Error(`Too many cards: ${id}`);\n }\n const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString() {\n return toBase64Url(this.toUint8Array());\n }\n\n toString() {\n return this.toEncodedString();\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number, i: number, mainc: number) => boolean = () => false) {\n const reader = new BufferReader(buf);\n const mainc = reader.readUint32LE();\n const sidec = reader.readUint32LE();\n this.main = [];\n this.extra = [];\n this.side = [];\n for(let i = 0; i < mainc; i++) {\n const id = reader.readUint32LE();\n if (isExtraDeckCard(id, i, mainc)) {\n this.extra.push(id);\n } else {\n this.main.push(id);\n }\n }\n for(let i = 0; i < sidec; i++) {\n const id = reader.readUint32LE();\n this.side.push(id);\n }\n return this;\n }\n\n static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number) => boolean = () => false) { \n return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n", "export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n return map;\n}\nabstract class BufferCursor {\n buffer: Uint8Array;\n pointer = 0;\n\n constructor(bufOrLength: Uint8Array | number) {\n if (typeof bufOrLength === 'number') {\n this.buffer = new Uint8Array(bufOrLength);\n } else {\n this.buffer = bufOrLength;\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5C06 pointer \u5411\u524D\u79FB\u52A8\u6307\u5B9A\u5B57\u8282\u6570\u3002\n * @param bytes \u8981\u79FB\u52A8\u7684\u5B57\u8282\u6570\n * @returns \u539F\u6765 pointer \u7684\u503C\n * @throws RangeError \u5982\u679C\u8D8A\u754C\n */\n protected increasePointer(bytes: number): number {\n const old = this.pointer;\n const next = old + bytes;\n if (next > this.buffer.length) {\n throw new RangeError(\n `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`\n );\n }\n this.pointer = next;\n return old;\n }\n}\n\nexport class BufferWriter extends BufferCursor {\n constructor(length: number) {\n super(length);\n }\n\n writeUint32LE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n this.buffer[idx + 2] = (value >>> 16) & 0xff;\n this.buffer[idx + 3] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = (value >>> 24) & 0xff;\n this.buffer[idx + 1] = (value >>> 16) & 0xff;\n this.buffer[idx + 2] = (value >>> 8) & 0xff;\n this.buffer[idx + 3] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = (value >>> 8) & 0xff;\n this.buffer[idx + 1] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = str.charCodeAt(i);\n }\n return this;\n }\n}\n\nexport class BufferReader extends BufferCursor {\n constructor(buf: Uint8Array) {\n super(buf);\n }\n\n readUint32LE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n // >>>0 \u4FDD\u8BC1\u65E0\u7B26\u53F7\u8F93\u51FA\n return (\n (b[idx ] ) |\n (b[idx + 1] << 8) |\n (b[idx + 2] << 16) |\n (b[idx + 3] << 24)\n ) >>> 0;\n }\n\n readUint32BE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n return (\n (b[idx ] << 24) |\n (b[idx + 1] << 16) |\n (b[idx + 2] << 8) |\n (b[idx + 3] )\n ) >>> 0;\n }\n\n readUint16LE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return (b[idx] | (b[idx + 1] << 8));\n }\n\n readUint16BE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return ((b[idx] << 8) | b[idx + 1]);\n }\n\n readUint8(): number {\n const idx = this.increasePointer(1);\n return this.buffer[idx];\n }\n\n readString(length: number): string {\n let s = '';\n for (let i = 0; i < length; i++) {\n const idx = this.increasePointer(1);\n s += String.fromCharCode(this.buffer[idx]);\n }\n return s;\n }\n\n readRemaining(): Uint8Array {\n const remaining = this.buffer.length - this.pointer;\n const idx = this.increasePointer(remaining);\n return this.buffer.subarray(idx, this.buffer.length);\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === BitWriter \u7C7B ===\nclass BitWriter {\n private buffer: number[] = [];\n private current = 0;\n private bitPos = 0;\n\n writeBits(value: number, length: number) {\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const shift = length - take;\n this.current |= ((value >>> shift) & ((1 << take) - 1)) << (remain - take);\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.buffer.push(this.current);\n this.current = 0;\n this.bitPos = 0;\n }\n }\n }\n\n finish(): Uint8Array {\n if (this.bitPos > 0) this.buffer.push(this.current);\n return new Uint8Array(this.buffer);\n }\n}\n\n// === BitReader \u7C7B ===\nclass BitReader {\n private index = 0;\n private bitPos = 0;\n\n constructor(private bytes: Uint8Array) {}\n\n readBits(length: number): number {\n let result = 0;\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const bits = (this.bytes[this.index] >>> (remain - take)) & ((1 << take) - 1);\n result = (result << take) | bits;\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.bitPos = 0;\n this.index++;\n }\n }\n return result;\n }\n}\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction countUnique(cards: number[]): number {\n let count = 0;\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n count++;\n while (i < cards.length && cards[i] === id) i++;\n }\n return count;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u7F16\u7801 ===\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const writer = new BitWriter();\n writer.writeBits(mNum, 8);\n writer.writeBits(eNum, 4);\n writer.writeBits(sNum, 4);\n\n const encodeSection = (cards: number[]) => {\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? 0b10 : count === 3 ? 0b11 : 0b01;\n writer.writeBits(prefix, 2);\n writer.writeBits(id, 27);\n i += count;\n }\n };\n\n encodeSection(main);\n encodeSection(extra);\n encodeSection(side);\n\n const encoded = toBase64Url(writer.finish());\n\n const searchParams = new URLSearchParams();\n for (const [k, v] of Object.entries(customParams)) {\n searchParams.set(k, v);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u89E3\u7801 ===\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Invalid deck URL');\n }\n\n const encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n const reader = new BitReader(bytes);\n\n const mNum = reader.readBits(8);\n const eNum = reader.readBits(4);\n const sNum = reader.readBits(4);\n const total = mNum + eNum + sNum;\n\n const result = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n };\n\n for (let i = 0; i < total; i++) {\n const prefix = reader.readBits(2);\n const count = prefix === 0b10 ? 2 : prefix === 0b11 ? 3 : 1;\n const id = reader.readBits(27);\n const target =\n i < mNum ? result.main : i < mNum + eNum ? result.extra : result.side;\n for (let j = 0; j < count; j++) {\n target.push(id);\n }\n }\n\n return {\n ...result,\n name: url.searchParams.get(QUERY_NAME) ?? undefined,\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferReader, BufferWriter, countConsecutiveItems, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength(noCompact = false) {\n const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);\n return counted.reduce((a, b) => a + b.length * 4, 0);\n }\n\n toUint8Array(noCompact = false) {\n const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.length * 4, 0),\n );\n const writeCards = (countMap: { item: number, count: number }[], type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const { item, count } of countMap) {\n if (count > 4) {\n throw new Error(`Too many cards: ${item}`);\n }\n const value = (item & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString(noCompact = false) {\n return toBase64Url(this.toUint8Array(noCompact));\n }\n\n toString(noCompact = false) {\n return this.toEncodedString(noCompact);\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number, i: number, mainc: number) => boolean = () => false) {\n const reader = new BufferReader(buf);\n const mainc = reader.readUint32LE();\n const sidec = reader.readUint32LE();\n this.main = [];\n this.extra = [];\n this.side = [];\n for(let i = 0; i < mainc; i++) {\n const id = reader.readUint32LE();\n if (isExtraDeckCard(id, i, mainc)) {\n this.extra.push(id);\n } else {\n this.main.push(id);\n }\n }\n for(let i = 0; i < sidec; i++) {\n const id = reader.readUint32LE();\n this.side.push(id);\n }\n return this;\n }\n\n static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number) => boolean = () => false) { \n return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n", "export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n const blocks: { item: T, count: number }[] = [];\n for (const [item, count] of map.entries()) {\n blocks.push({ item, count });\n }\n return blocks;\n}\n\nexport function countConsecutiveItems<T>(arr: T[]) {\n const result: { item: T; count: number }[] = [];\n\n if (arr.length === 0) return result;\n\n let currentItem = arr[0];\n let count = 1;\n\n for (let i = 1; i < arr.length; i++) {\n if (arr[i] === currentItem) {\n count++;\n } else {\n result.push({ item: currentItem, count });\n currentItem = arr[i];\n count = 1;\n }\n }\n\n // \u63A8\u5165\u6700\u540E\u4E00\u7EC4\n result.push({ item: currentItem, count });\n\n return result;\n}\n\nabstract class BufferCursor {\n buffer: Uint8Array;\n pointer = 0;\n\n constructor(bufOrLength: Uint8Array | number) {\n if (typeof bufOrLength === 'number') {\n this.buffer = new Uint8Array(bufOrLength);\n } else {\n this.buffer = bufOrLength;\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5C06 pointer \u5411\u524D\u79FB\u52A8\u6307\u5B9A\u5B57\u8282\u6570\u3002\n * @param bytes \u8981\u79FB\u52A8\u7684\u5B57\u8282\u6570\n * @returns \u539F\u6765 pointer \u7684\u503C\n * @throws RangeError \u5982\u679C\u8D8A\u754C\n */\n protected increasePointer(bytes: number): number {\n const old = this.pointer;\n const next = old + bytes;\n if (next > this.buffer.length) {\n throw new RangeError(\n `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`\n );\n }\n this.pointer = next;\n return old;\n }\n}\n\nexport class BufferWriter extends BufferCursor {\n constructor(length: number) {\n super(length);\n }\n\n writeUint32LE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n this.buffer[idx + 2] = (value >>> 16) & 0xff;\n this.buffer[idx + 3] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = (value >>> 24) & 0xff;\n this.buffer[idx + 1] = (value >>> 16) & 0xff;\n this.buffer[idx + 2] = (value >>> 8) & 0xff;\n this.buffer[idx + 3] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = (value >>> 8) & 0xff;\n this.buffer[idx + 1] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = str.charCodeAt(i);\n }\n return this;\n }\n}\n\nexport class BufferReader extends BufferCursor {\n constructor(buf: Uint8Array) {\n super(buf);\n }\n\n readUint32LE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n // >>>0 \u4FDD\u8BC1\u65E0\u7B26\u53F7\u8F93\u51FA\n return (\n (b[idx ] ) |\n (b[idx + 1] << 8) |\n (b[idx + 2] << 16) |\n (b[idx + 3] << 24)\n ) >>> 0;\n }\n\n readUint32BE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n return (\n (b[idx ] << 24) |\n (b[idx + 1] << 16) |\n (b[idx + 2] << 8) |\n (b[idx + 3] )\n ) >>> 0;\n }\n\n readUint16LE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return (b[idx] | (b[idx + 1] << 8));\n }\n\n readUint16BE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return ((b[idx] << 8) | b[idx + 1]);\n }\n\n readUint8(): number {\n const idx = this.increasePointer(1);\n return this.buffer[idx];\n }\n\n readString(length: number): string {\n let s = '';\n for (let i = 0; i < length; i++) {\n const idx = this.increasePointer(1);\n s += String.fromCharCode(this.buffer[idx]);\n }\n return s;\n }\n\n readRemaining(): Uint8Array {\n const remaining = this.buffer.length - this.pointer;\n const idx = this.increasePointer(remaining);\n return this.buffer.subarray(idx, this.buffer.length);\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === BitWriter \u7C7B ===\nclass BitWriter {\n private buffer: number[] = [];\n private current = 0;\n private bitPos = 0;\n\n writeBits(value: number, length: number) {\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const shift = length - take;\n this.current |= ((value >>> shift) & ((1 << take) - 1)) << (remain - take);\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.buffer.push(this.current);\n this.current = 0;\n this.bitPos = 0;\n }\n }\n }\n\n finish(): Uint8Array {\n if (this.bitPos > 0) this.buffer.push(this.current);\n return new Uint8Array(this.buffer);\n }\n}\n\n// === BitReader \u7C7B ===\nclass BitReader {\n private index = 0;\n private bitPos = 0;\n\n constructor(private bytes: Uint8Array) {}\n\n readBits(length: number): number {\n let result = 0;\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const bits = (this.bytes[this.index] >>> (remain - take)) & ((1 << take) - 1);\n result = (result << take) | bits;\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.bitPos = 0;\n this.index++;\n }\n }\n return result;\n }\n}\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction countUnique(cards: number[]): number {\n let count = 0;\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n count++;\n while (i < cards.length && cards[i] === id) i++;\n }\n return count;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u7F16\u7801 ===\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const writer = new BitWriter();\n writer.writeBits(mNum, 8);\n writer.writeBits(eNum, 4);\n writer.writeBits(sNum, 4);\n\n const encodeSection = (cards: number[]) => {\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? 0b10 : count === 3 ? 0b11 : 0b01;\n writer.writeBits(prefix, 2);\n writer.writeBits(id, 27);\n i += count;\n }\n };\n\n encodeSection(main);\n encodeSection(extra);\n encodeSection(side);\n\n const encoded = toBase64Url(writer.finish());\n\n const searchParams = new URLSearchParams();\n for (const [k, v] of Object.entries(customParams)) {\n searchParams.set(k, v);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u89E3\u7801 ===\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Invalid deck URL');\n }\n\n const encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n const reader = new BitReader(bytes);\n\n const mNum = reader.readBits(8);\n const eNum = reader.readBits(4);\n const sNum = reader.readBits(4);\n const total = mNum + eNum + sNum;\n\n const result = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n };\n\n for (let i = 0; i < total; i++) {\n const prefix = reader.readBits(2);\n const count = prefix === 0b10 ? 2 : prefix === 0b11 ? 3 : 1;\n const id = reader.readBits(27);\n const target =\n i < mNum ? result.main : i < mNum + eNum ? result.extra : result.side;\n for (let j = 0; j < count; j++) {\n target.push(id);\n }\n }\n\n return {\n ...result,\n name: url.searchParams.get(QUERY_NAME) ?? undefined,\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/index.d.ts CHANGED
@@ -3,10 +3,10 @@ export default class YGOProDeck {
3
3
  extra: number[];
4
4
  side: number[];
5
5
  name?: string;
6
- bufferLength(): number;
7
- toUint8Array(): Uint8Array;
8
- toEncodedString(): string;
9
- toString(): string;
6
+ bufferLength(noCompact?: boolean): number;
7
+ toUint8Array(noCompact?: boolean): Uint8Array;
8
+ toEncodedString(noCompact?: boolean): string;
9
+ toString(noCompact?: boolean): string;
10
10
  fromUint8Array(buf: Uint8Array): this;
11
11
  static fromUint8Array(buf: Uint8Array): YGOProDeck;
12
12
  fromEncodedString(str: string): this;
package/dist/index.mjs CHANGED
@@ -23,7 +23,29 @@ function countItems(arr) {
23
23
  for (const item of arr) {
24
24
  map.set(item, (map.get(item) || 0) + 1);
25
25
  }
26
- return map;
26
+ const blocks = [];
27
+ for (const [item, count] of map.entries()) {
28
+ blocks.push({ item, count });
29
+ }
30
+ return blocks;
31
+ }
32
+ function countConsecutiveItems(arr) {
33
+ const result = [];
34
+ if (arr.length === 0)
35
+ return result;
36
+ let currentItem = arr[0];
37
+ let count = 1;
38
+ for (let i = 1; i < arr.length; i++) {
39
+ if (arr[i] === currentItem) {
40
+ count++;
41
+ } else {
42
+ result.push({ item: currentItem, count });
43
+ currentItem = arr[i];
44
+ count = 1;
45
+ }
46
+ }
47
+ result.push({ item: currentItem, count });
48
+ return result;
27
49
  }
28
50
  var BufferCursor = class {
29
51
  buffer;
@@ -323,32 +345,32 @@ var YGOProDeck = class {
323
345
  extra = [];
324
346
  side = [];
325
347
  name;
326
- bufferLength() {
327
- const counted = [this.main, this.extra, this.side].map(countItems);
328
- return counted.reduce((a, b) => a + b.size * 4, 0);
348
+ bufferLength(noCompact = false) {
349
+ const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
350
+ return counted.reduce((a, b) => a + b.length * 4, 0);
329
351
  }
330
- toUint8Array() {
331
- const counted = [this.main, this.extra, this.side].map(countItems);
352
+ toUint8Array(noCompact = false) {
353
+ const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
332
354
  const writer = new BufferWriter(
333
- counted.reduce((a, b) => a + b.size * 4, 0)
355
+ counted.reduce((a, b) => a + b.length * 4, 0)
334
356
  );
335
357
  const writeCards = (countMap, type) => {
336
- for (const [id, count] of countMap.entries()) {
358
+ for (const { item, count } of countMap) {
337
359
  if (count > 4) {
338
- throw new Error(`Too many cards: ${id}`);
360
+ throw new Error(`Too many cards: ${item}`);
339
361
  }
340
- const value = id & 268435455 | type << 28 | count - 1 << 30;
362
+ const value = item & 268435455 | type << 28 | count - 1 << 30;
341
363
  writer.writeUint32LE(value);
342
364
  }
343
365
  };
344
366
  counted.forEach(writeCards);
345
367
  return writer.buffer;
346
368
  }
347
- toEncodedString() {
348
- return toBase64Url(this.toUint8Array());
369
+ toEncodedString(noCompact = false) {
370
+ return toBase64Url(this.toUint8Array(noCompact));
349
371
  }
350
- toString() {
351
- return this.toEncodedString();
372
+ toString(noCompact = false) {
373
+ return this.toEncodedString(noCompact);
352
374
  }
353
375
  fromUint8Array(buf) {
354
376
  for (let i = 0; i < buf.length - 3; i += 4) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/base64.ts", "../src/utils.ts", "../src/ydke.ts", "../src/ygom.ts", "../index.ts"],
4
- "sourcesContent": ["export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n return map;\n}\nabstract class BufferCursor {\n buffer: Uint8Array;\n pointer = 0;\n\n constructor(bufOrLength: Uint8Array | number) {\n if (typeof bufOrLength === 'number') {\n this.buffer = new Uint8Array(bufOrLength);\n } else {\n this.buffer = bufOrLength;\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5C06 pointer \u5411\u524D\u79FB\u52A8\u6307\u5B9A\u5B57\u8282\u6570\u3002\n * @param bytes \u8981\u79FB\u52A8\u7684\u5B57\u8282\u6570\n * @returns \u539F\u6765 pointer \u7684\u503C\n * @throws RangeError \u5982\u679C\u8D8A\u754C\n */\n protected increasePointer(bytes: number): number {\n const old = this.pointer;\n const next = old + bytes;\n if (next > this.buffer.length) {\n throw new RangeError(\n `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`\n );\n }\n this.pointer = next;\n return old;\n }\n}\n\nexport class BufferWriter extends BufferCursor {\n constructor(length: number) {\n super(length);\n }\n\n writeUint32LE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n this.buffer[idx + 2] = (value >>> 16) & 0xff;\n this.buffer[idx + 3] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = (value >>> 24) & 0xff;\n this.buffer[idx + 1] = (value >>> 16) & 0xff;\n this.buffer[idx + 2] = (value >>> 8) & 0xff;\n this.buffer[idx + 3] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = (value >>> 8) & 0xff;\n this.buffer[idx + 1] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = str.charCodeAt(i);\n }\n return this;\n }\n}\n\nexport class BufferReader extends BufferCursor {\n constructor(buf: Uint8Array) {\n super(buf);\n }\n\n readUint32LE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n // >>>0 \u4FDD\u8BC1\u65E0\u7B26\u53F7\u8F93\u51FA\n return (\n (b[idx ] ) |\n (b[idx + 1] << 8) |\n (b[idx + 2] << 16) |\n (b[idx + 3] << 24)\n ) >>> 0;\n }\n\n readUint32BE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n return (\n (b[idx ] << 24) |\n (b[idx + 1] << 16) |\n (b[idx + 2] << 8) |\n (b[idx + 3] )\n ) >>> 0;\n }\n\n readUint16LE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return (b[idx] | (b[idx + 1] << 8));\n }\n\n readUint16BE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return ((b[idx] << 8) | b[idx + 1]);\n }\n\n readUint8(): number {\n const idx = this.increasePointer(1);\n return this.buffer[idx];\n }\n\n readString(length: number): string {\n let s = '';\n for (let i = 0; i < length; i++) {\n const idx = this.increasePointer(1);\n s += String.fromCharCode(this.buffer[idx]);\n }\n return s;\n }\n\n readRemaining(): Uint8Array {\n const remaining = this.buffer.length - this.pointer;\n const idx = this.increasePointer(remaining);\n return this.buffer.subarray(idx, this.buffer.length);\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === BitWriter \u7C7B ===\nclass BitWriter {\n private buffer: number[] = [];\n private current = 0;\n private bitPos = 0;\n\n writeBits(value: number, length: number) {\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const shift = length - take;\n this.current |= ((value >>> shift) & ((1 << take) - 1)) << (remain - take);\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.buffer.push(this.current);\n this.current = 0;\n this.bitPos = 0;\n }\n }\n }\n\n finish(): Uint8Array {\n if (this.bitPos > 0) this.buffer.push(this.current);\n return new Uint8Array(this.buffer);\n }\n}\n\n// === BitReader \u7C7B ===\nclass BitReader {\n private index = 0;\n private bitPos = 0;\n\n constructor(private bytes: Uint8Array) {}\n\n readBits(length: number): number {\n let result = 0;\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const bits = (this.bytes[this.index] >>> (remain - take)) & ((1 << take) - 1);\n result = (result << take) | bits;\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.bitPos = 0;\n this.index++;\n }\n }\n return result;\n }\n}\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction countUnique(cards: number[]): number {\n let count = 0;\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n count++;\n while (i < cards.length && cards[i] === id) i++;\n }\n return count;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u7F16\u7801 ===\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const writer = new BitWriter();\n writer.writeBits(mNum, 8);\n writer.writeBits(eNum, 4);\n writer.writeBits(sNum, 4);\n\n const encodeSection = (cards: number[]) => {\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? 0b10 : count === 3 ? 0b11 : 0b01;\n writer.writeBits(prefix, 2);\n writer.writeBits(id, 27);\n i += count;\n }\n };\n\n encodeSection(main);\n encodeSection(extra);\n encodeSection(side);\n\n const encoded = toBase64Url(writer.finish());\n\n const searchParams = new URLSearchParams();\n for (const [k, v] of Object.entries(customParams)) {\n searchParams.set(k, v);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u89E3\u7801 ===\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Invalid deck URL');\n }\n\n const encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n const reader = new BitReader(bytes);\n\n const mNum = reader.readBits(8);\n const eNum = reader.readBits(4);\n const sNum = reader.readBits(4);\n const total = mNum + eNum + sNum;\n\n const result = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n };\n\n for (let i = 0; i < total; i++) {\n const prefix = reader.readBits(2);\n const count = prefix === 0b10 ? 2 : prefix === 0b11 ? 3 : 1;\n const id = reader.readBits(27);\n const target =\n i < mNum ? result.main : i < mNum + eNum ? result.extra : result.side;\n for (let j = 0; j < count; j++) {\n target.push(id);\n }\n }\n\n return {\n ...result,\n name: url.searchParams.get(QUERY_NAME) ?? undefined,\n };\n}\n", "import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferReader, BufferWriter, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n return counted.reduce((a, b) => a + b.size * 4, 0);\n }\n\n toUint8Array() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.size * 4, 0),\n );\n const writeCards = (countMap: Map<number, number>, type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const [id, count] of countMap.entries()) {\n if (count > 4) {\n throw new Error(`Too many cards: ${id}`);\n }\n const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString() {\n return toBase64Url(this.toUint8Array());\n }\n\n toString() {\n return this.toEncodedString();\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number, i: number, mainc: number) => boolean = () => false) {\n const reader = new BufferReader(buf);\n const mainc = reader.readUint32LE();\n const sidec = reader.readUint32LE();\n this.main = [];\n this.extra = [];\n this.side = [];\n for(let i = 0; i < mainc; i++) {\n const id = reader.readUint32LE();\n if (isExtraDeckCard(id, i, mainc)) {\n this.extra.push(id);\n } else {\n this.main.push(id);\n }\n }\n for(let i = 0; i < sidec; i++) {\n const id = reader.readUint32LE();\n this.side.push(id);\n }\n return this;\n }\n\n static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number) => boolean = () => false) { \n return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n const blocks: { item: T, count: number }[] = [];\n for (const [item, count] of map.entries()) {\n blocks.push({ item, count });\n }\n return blocks;\n}\n\nexport function countConsecutiveItems<T>(arr: T[]) {\n const result: { item: T; count: number }[] = [];\n\n if (arr.length === 0) return result;\n\n let currentItem = arr[0];\n let count = 1;\n\n for (let i = 1; i < arr.length; i++) {\n if (arr[i] === currentItem) {\n count++;\n } else {\n result.push({ item: currentItem, count });\n currentItem = arr[i];\n count = 1;\n }\n }\n\n // \u63A8\u5165\u6700\u540E\u4E00\u7EC4\n result.push({ item: currentItem, count });\n\n return result;\n}\n\nabstract class BufferCursor {\n buffer: Uint8Array;\n pointer = 0;\n\n constructor(bufOrLength: Uint8Array | number) {\n if (typeof bufOrLength === 'number') {\n this.buffer = new Uint8Array(bufOrLength);\n } else {\n this.buffer = bufOrLength;\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5C06 pointer \u5411\u524D\u79FB\u52A8\u6307\u5B9A\u5B57\u8282\u6570\u3002\n * @param bytes \u8981\u79FB\u52A8\u7684\u5B57\u8282\u6570\n * @returns \u539F\u6765 pointer \u7684\u503C\n * @throws RangeError \u5982\u679C\u8D8A\u754C\n */\n protected increasePointer(bytes: number): number {\n const old = this.pointer;\n const next = old + bytes;\n if (next > this.buffer.length) {\n throw new RangeError(\n `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`\n );\n }\n this.pointer = next;\n return old;\n }\n}\n\nexport class BufferWriter extends BufferCursor {\n constructor(length: number) {\n super(length);\n }\n\n writeUint32LE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n this.buffer[idx + 2] = (value >>> 16) & 0xff;\n this.buffer[idx + 3] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = (value >>> 24) & 0xff;\n this.buffer[idx + 1] = (value >>> 16) & 0xff;\n this.buffer[idx + 2] = (value >>> 8) & 0xff;\n this.buffer[idx + 3] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = (value >>> 8) & 0xff;\n this.buffer[idx + 1] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = str.charCodeAt(i);\n }\n return this;\n }\n}\n\nexport class BufferReader extends BufferCursor {\n constructor(buf: Uint8Array) {\n super(buf);\n }\n\n readUint32LE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n // >>>0 \u4FDD\u8BC1\u65E0\u7B26\u53F7\u8F93\u51FA\n return (\n (b[idx ] ) |\n (b[idx + 1] << 8) |\n (b[idx + 2] << 16) |\n (b[idx + 3] << 24)\n ) >>> 0;\n }\n\n readUint32BE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n return (\n (b[idx ] << 24) |\n (b[idx + 1] << 16) |\n (b[idx + 2] << 8) |\n (b[idx + 3] )\n ) >>> 0;\n }\n\n readUint16LE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return (b[idx] | (b[idx + 1] << 8));\n }\n\n readUint16BE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return ((b[idx] << 8) | b[idx + 1]);\n }\n\n readUint8(): number {\n const idx = this.increasePointer(1);\n return this.buffer[idx];\n }\n\n readString(length: number): string {\n let s = '';\n for (let i = 0; i < length; i++) {\n const idx = this.increasePointer(1);\n s += String.fromCharCode(this.buffer[idx]);\n }\n return s;\n }\n\n readRemaining(): Uint8Array {\n const remaining = this.buffer.length - this.pointer;\n const idx = this.increasePointer(remaining);\n return this.buffer.subarray(idx, this.buffer.length);\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === BitWriter \u7C7B ===\nclass BitWriter {\n private buffer: number[] = [];\n private current = 0;\n private bitPos = 0;\n\n writeBits(value: number, length: number) {\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const shift = length - take;\n this.current |= ((value >>> shift) & ((1 << take) - 1)) << (remain - take);\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.buffer.push(this.current);\n this.current = 0;\n this.bitPos = 0;\n }\n }\n }\n\n finish(): Uint8Array {\n if (this.bitPos > 0) this.buffer.push(this.current);\n return new Uint8Array(this.buffer);\n }\n}\n\n// === BitReader \u7C7B ===\nclass BitReader {\n private index = 0;\n private bitPos = 0;\n\n constructor(private bytes: Uint8Array) {}\n\n readBits(length: number): number {\n let result = 0;\n while (length > 0) {\n const remain = 8 - this.bitPos;\n const take = Math.min(remain, length);\n const bits = (this.bytes[this.index] >>> (remain - take)) & ((1 << take) - 1);\n result = (result << take) | bits;\n this.bitPos += take;\n length -= take;\n\n if (this.bitPos === 8) {\n this.bitPos = 0;\n this.index++;\n }\n }\n return result;\n }\n}\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction countUnique(cards: number[]): number {\n let count = 0;\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n count++;\n while (i < cards.length && cards[i] === id) i++;\n }\n return count;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u7F16\u7801 ===\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const writer = new BitWriter();\n writer.writeBits(mNum, 8);\n writer.writeBits(eNum, 4);\n writer.writeBits(sNum, 4);\n\n const encodeSection = (cards: number[]) => {\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? 0b10 : count === 3 ? 0b11 : 0b01;\n writer.writeBits(prefix, 2);\n writer.writeBits(id, 27);\n i += count;\n }\n };\n\n encodeSection(main);\n encodeSection(extra);\n encodeSection(side);\n\n const encoded = toBase64Url(writer.finish());\n\n const searchParams = new URLSearchParams();\n for (const [k, v] of Object.entries(customParams)) {\n searchParams.set(k, v);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n// === \u4E3B\u51FD\u6570\uFF1A\u89E3\u7801 ===\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Invalid deck URL');\n }\n\n const encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n const reader = new BitReader(bytes);\n\n const mNum = reader.readBits(8);\n const eNum = reader.readBits(4);\n const sNum = reader.readBits(4);\n const total = mNum + eNum + sNum;\n\n const result = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n };\n\n for (let i = 0; i < total; i++) {\n const prefix = reader.readBits(2);\n const count = prefix === 0b10 ? 2 : prefix === 0b11 ? 3 : 1;\n const id = reader.readBits(27);\n const target =\n i < mNum ? result.main : i < mNum + eNum ? result.extra : result.side;\n for (let j = 0; j < count; j++) {\n target.push(id);\n }\n }\n\n return {\n ...result,\n name: url.searchParams.get(QUERY_NAME) ?? undefined,\n };\n}\n", "import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferReader, BufferWriter, countConsecutiveItems, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength(noCompact = false) {\n const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);\n return counted.reduce((a, b) => a + b.length * 4, 0);\n }\n\n toUint8Array(noCompact = false) {\n const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.length * 4, 0),\n );\n const writeCards = (countMap: { item: number, count: number }[], type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const { item, count } of countMap) {\n if (count > 4) {\n throw new Error(`Too many cards: ${item}`);\n }\n const value = (item & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString(noCompact = false) {\n return toBase64Url(this.toUint8Array(noCompact));\n }\n\n toString(noCompact = false) {\n return this.toEncodedString(noCompact);\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number, i: number, mainc: number) => boolean = () => false) {\n const reader = new BufferReader(buf);\n const mainc = reader.readUint32LE();\n const sidec = reader.readUint32LE();\n this.main = [];\n this.extra = [];\n this.side = [];\n for(let i = 0; i < mainc; i++) {\n const id = reader.readUint32LE();\n if (isExtraDeckCard(id, i, mainc)) {\n this.extra.push(id);\n } else {\n this.main.push(id);\n }\n }\n for(let i = 0; i < sidec; i++) {\n const id = reader.readUint32LE();\n this.side.push(id);\n }\n return this;\n }\n\n static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number) => boolean = () => false) { \n return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n"],
5
+ "mappings": ";AAAO,SAAS,YAAY,OAA2B;AACrD,QAAM,SAAS,OAAO,WAAW,cAC7B,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ,IACpC,KAAK,OAAO,aAAa,GAAG,KAAK,CAAC;AAEtC,SAAO,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AACzE;AAEO,SAAS,cAAc,SAA6B;AACzD,QAAM,SAAS,QAAQ,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC3D,QAAM,SAAS,OAAO,OAAO,OAAO,UAAU,IAAI,OAAO,SAAS,KAAK,GAAG,GAAG;AAE7E,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,WAAW,KAAK,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAAA,EACtD;AAEA,QAAM,SAAS,KAAK,MAAM;AAC1B,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AACA,SAAO;AACT;;;ACtBO,SAAS,WAAc,KAAU;AACtC,QAAM,MAAM,oBAAI,IAAe;AAC/B,aAAW,QAAQ,KAAK;AACtB,QAAI,IAAI,OAAO,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EACxC;AACA,QAAM,SAAuC,CAAC;AAC9C,aAAW,CAAC,MAAM,KAAK,KAAK,IAAI,QAAQ,GAAG;AACzC,WAAO,KAAK,EAAE,MAAM,MAAM,CAAC;AAAA,EAC7B;AACA,SAAO;AACT;AAEO,SAAS,sBAAyB,KAAU;AACjD,QAAM,SAAuC,CAAC;AAE9C,MAAI,IAAI,WAAW;AAAG,WAAO;AAE7B,MAAI,cAAc,IAAI,CAAC;AACvB,MAAI,QAAQ;AAEZ,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,QAAI,IAAI,CAAC,MAAM,aAAa;AAC1B;AAAA,IACF,OAAO;AACL,aAAO,KAAK,EAAE,MAAM,aAAa,MAAM,CAAC;AACxC,oBAAc,IAAI,CAAC;AACnB,cAAQ;AAAA,IACV;AAAA,EACF;AAGA,SAAO,KAAK,EAAE,MAAM,aAAa,MAAM,CAAC;AAExC,SAAO;AACT;AAEA,IAAe,eAAf,MAA4B;AAAA,EAC1B;AAAA,EACA,UAAU;AAAA,EAEV,YAAY,aAAkC;AAC5C,QAAI,OAAO,gBAAgB,UAAU;AACnC,WAAK,SAAS,IAAI,WAAW,WAAW;AAAA,IAC1C,OAAO;AACL,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,gBAAgB,OAAuB;AAC/C,UAAM,MAAM,KAAK;AACjB,UAAM,OAAO,MAAM;AACnB,QAAI,OAAO,KAAK,OAAO,QAAQ;AAC7B,YAAM,IAAI;AAAA,QACR,sCAAsC,8BAA8B,KAAK,OAAO;AAAA,MAClF;AAAA,IACF;AACA,SAAK,UAAU;AACf,WAAO;AAAA,EACT;AACF;AAEO,IAAM,eAAN,cAA2B,aAAa;AAAA,EAC7C,YAAY,QAAgB;AAC1B,UAAM,MAAM;AAAA,EACd;AAAA,EAEA,cAAc,OAAe;AAC3B,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,SAAK,OAAO,GAAO,IAAK,QAAgB;AACxC,SAAK,OAAO,MAAM,CAAC,IAAK,UAAU,IAAM;AACxC,SAAK,OAAO,MAAM,CAAC,IAAK,UAAU,KAAM;AACxC,SAAK,OAAO,MAAM,CAAC,IAAK,UAAU,KAAM;AACxC,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,OAAe;AAC3B,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,SAAK,OAAO,GAAO,IAAK,UAAU,KAAM;AACxC,SAAK,OAAO,MAAM,CAAC,IAAK,UAAU,KAAM;AACxC,SAAK,OAAO,MAAM,CAAC,IAAK,UAAU,IAAM;AACxC,SAAK,OAAO,MAAM,CAAC,IAAK,QAAgB;AACxC,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,OAAe;AAC3B,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,SAAK,OAAO,GAAO,IAAK,QAAe;AACvC,SAAK,OAAO,MAAM,CAAC,IAAK,UAAU,IAAK;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,OAAe;AAC3B,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,SAAK,OAAO,GAAO,IAAK,UAAU,IAAK;AACvC,SAAK,OAAO,MAAM,CAAC,IAAK,QAAe;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,OAAe;AACxB,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,SAAK,OAAO,GAAG,IAAI,QAAQ;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,KAAa;AACvB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,WAAK,OAAO,GAAG,IAAI,IAAI,WAAW,CAAC;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AACF;AAEO,IAAM,eAAN,cAA2B,aAAa;AAAA,EAC7C,YAAY,KAAiB;AAC3B,UAAM,GAAG;AAAA,EACX;AAAA,EAEA,eAAuB;AACrB,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,UAAM,IAAI,KAAK;AAEf,YACG,EAAE,GAAO,IACT,EAAE,MAAM,CAAC,KAAM,IACf,EAAE,MAAM,CAAC,KAAK,KACd,EAAE,MAAM,CAAC,KAAK,QACX;AAAA,EACR;AAAA,EAEA,eAAuB;AACrB,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,UAAM,IAAI,KAAK;AACf,YACG,EAAE,GAAO,KAAK,KACd,EAAE,MAAM,CAAC,KAAK,KACd,EAAE,MAAM,CAAC,KAAM,IACf,EAAE,MAAM,CAAC,OACN;AAAA,EACR;AAAA,EAEA,eAAuB;AACrB,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,UAAM,IAAI,KAAK;AACf,WAAQ,EAAE,GAAG,IAAK,EAAE,MAAM,CAAC,KAAK;AAAA,EAClC;AAAA,EAEA,eAAuB;AACrB,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,UAAM,IAAI,KAAK;AACf,WAAS,EAAE,GAAG,KAAK,IAAK,EAAE,MAAM,CAAC;AAAA,EACnC;AAAA,EAEA,YAAoB;AAClB,UAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,WAAO,KAAK,OAAO,GAAG;AAAA,EACxB;AAAA,EAEA,WAAW,QAAwB;AACjC,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,YAAM,MAAM,KAAK,gBAAgB,CAAC;AAClC,WAAK,OAAO,aAAa,KAAK,OAAO,GAAG,CAAC;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,gBAA4B;AAC1B,UAAM,YAAY,KAAK,OAAO,SAAS,KAAK;AAC5C,UAAM,MAAM,KAAK,gBAAgB,SAAS;AAC1C,WAAO,KAAK,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM;AAAA,EACrD;AACF;;;AC1KA,SAAS,oBAAoB,QAA0B;AACrD,QAAM,SAAS,KAAK,MAAM;AAC1B,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AACA,QAAM,OAAO,IAAI,SAAS,MAAM,MAAM;AACtC,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,WAAO,KAAK,KAAK,UAAU,GAAG,IAAI,CAAC;AAAA,EACrC;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAwB;AACnD,QAAM,SAAS,IAAI,YAAY,KAAK,SAAS,CAAC;AAC9C,QAAM,OAAO,IAAI,SAAS,MAAM;AAChC,OAAK,QAAQ,CAAC,KAAK,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK,IAAI,CAAC;AACzD,QAAM,QAAQ,IAAI,WAAW,MAAM;AACnC,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACxC;AACA,SAAO,KAAK,MAAM;AACpB;AAEO,SAAS,UAAU,MAAyB;AACjD,SACE,YACA,oBAAoB,KAAK,IAAI,IAC7B,MACA,oBAAoB,KAAK,KAAK,IAC9B,MACA,oBAAoB,KAAK,IAAI,IAC7B;AAEJ;AAEO,SAAS,YAAY,MAAyB;AACnD,MAAI,CAAC,KAAK,WAAW,SAAS,GAAG;AAC/B,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AACA,QAAM,CAAC,SAAS,UAAU,OAAO,IAAI,KAAK,MAAM,CAAC,EAAE,MAAM,GAAG;AAC5D,MAAI,YAAY,UAAa,aAAa,UAAa,YAAY,QAAW;AAC5E,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACA,SAAO;AAAA,IACL,MAAM,oBAAoB,OAAO;AAAA,IACjC,OAAO,oBAAoB,QAAQ;AAAA,IACnC,MAAM,oBAAoB,OAAO;AAAA,EACnC;AACF;;;ACxDA,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AACtB,IAAM,WAAW;AACjB,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,kBAAkB;AACxB,IAAM,gBAAgB;AAGtB,IAAM,YAAN,MAAgB;AAAA,EACN,SAAmB,CAAC;AAAA,EACpB,UAAU;AAAA,EACV,SAAS;AAAA,EAEjB,UAAU,OAAe,QAAgB;AACvC,WAAO,SAAS,GAAG;AACjB,YAAM,SAAS,IAAI,KAAK;AACxB,YAAM,OAAO,KAAK,IAAI,QAAQ,MAAM;AACpC,YAAM,QAAQ,SAAS;AACvB,WAAK,YAAa,UAAU,SAAW,KAAK,QAAQ,MAAQ,SAAS;AACrE,WAAK,UAAU;AACf,gBAAU;AAEV,UAAI,KAAK,WAAW,GAAG;AACrB,aAAK,OAAO,KAAK,KAAK,OAAO;AAC7B,aAAK,UAAU;AACf,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAqB;AACnB,QAAI,KAAK,SAAS;AAAG,WAAK,OAAO,KAAK,KAAK,OAAO;AAClD,WAAO,IAAI,WAAW,KAAK,MAAM;AAAA,EACnC;AACF;AAGA,IAAM,YAAN,MAAgB;AAAA,EAId,YAAoB,OAAmB;AAAnB;AAAA,EAAoB;AAAA,EAHhC,QAAQ;AAAA,EACR,SAAS;AAAA,EAIjB,SAAS,QAAwB;AAC/B,QAAI,SAAS;AACb,WAAO,SAAS,GAAG;AACjB,YAAM,SAAS,IAAI,KAAK;AACxB,YAAM,OAAO,KAAK,IAAI,QAAQ,MAAM;AACpC,YAAM,OAAQ,KAAK,MAAM,KAAK,KAAK,MAAO,SAAS,QAAW,KAAK,QAAQ;AAC3E,eAAU,UAAU,OAAQ;AAC5B,WAAK,UAAU;AACf,gBAAU;AAEV,UAAI,KAAK,WAAW,GAAG;AACrB,aAAK,SAAS;AACd,aAAK;AAAA,MACP;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAGA,SAAS,YAAY,OAAyB;AAC5C,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,MAAM,UAAU;AAClC,UAAM,KAAK,MAAM,CAAC;AAClB;AACA,WAAO,IAAI,MAAM,UAAU,MAAM,CAAC,MAAM;AAAI;AAAA,EAC9C;AACA,SAAO;AACT;AAGO,SAAS,mBACd,MACA,OACA,MACA,eAAuC,CAAC,GAChC;AACR,QAAM,OAAO,YAAY,IAAI;AAC7B,QAAM,OAAO,YAAY,KAAK;AAC9B,QAAM,OAAO,YAAY,IAAI;AAE7B,QAAM,SAAS,IAAI,UAAU;AAC7B,SAAO,UAAU,MAAM,CAAC;AACxB,SAAO,UAAU,MAAM,CAAC;AACxB,SAAO,UAAU,MAAM,CAAC;AAExB,QAAM,gBAAgB,CAAC,UAAoB;AACzC,aAAS,IAAI,GAAG,IAAI,MAAM,UAAU;AAClC,YAAM,KAAK,MAAM,CAAC;AAClB,UAAI,QAAQ;AACZ,aAAO,IAAI,QAAQ,MAAM,UAAU,MAAM,IAAI,KAAK,MAAM,MAAM,QAAQ;AAAG;AACzE,YAAM,SAAS,UAAU,IAAI,IAAO,UAAU,IAAI,IAAO;AACzD,aAAO,UAAU,QAAQ,CAAC;AAC1B,aAAO,UAAU,IAAI,EAAE;AACvB,WAAK;AAAA,IACP;AAAA,EACF;AAEA,gBAAc,IAAI;AAClB,gBAAc,KAAK;AACnB,gBAAc,IAAI;AAElB,QAAM,UAAU,YAAY,OAAO,OAAO,CAAC;AAE3C,QAAM,eAAe,IAAI,gBAAgB;AACzC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,YAAY,GAAG;AACjD,iBAAa,IAAI,GAAG,CAAC;AAAA,EACvB;AACA,eAAa,IAAI,gBAAgB,QAAQ;AACzC,eAAa,IAAI,eAAe,GAAG;AACnC,eAAa,IAAI,YAAY,OAAO;AAEpC,SAAO,GAAG,qBAAqB,iBAAiB,aAAa,SAAS;AACxE;AAGO,SAAS,qBAAqB,KAKnC;AACA,QAAM,MAAM,IAAI,IAAI,GAAG;AACvB,MAAI,IAAI,aAAa,IAAI,cAAc,MAAM,UAAU;AACrD,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AAEA,QAAM,UAAU,IAAI,aAAa,IAAI,UAAU;AAC/C,MAAI,CAAC;AAAS,UAAM,IAAI,MAAM,mBAAmB;AAEjD,QAAM,QAAQ,cAAc,OAAO;AACnC,QAAM,SAAS,IAAI,UAAU,KAAK;AAElC,QAAM,OAAO,OAAO,SAAS,CAAC;AAC9B,QAAM,OAAO,OAAO,SAAS,CAAC;AAC9B,QAAM,OAAO,OAAO,SAAS,CAAC;AAC9B,QAAM,QAAQ,OAAO,OAAO;AAE5B,QAAM,SAAS;AAAA,IACb,MAAM,CAAC;AAAA,IACP,OAAO,CAAC;AAAA,IACR,MAAM,CAAC;AAAA,EACT;AAEA,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,SAAS,OAAO,SAAS,CAAC;AAChC,UAAM,QAAQ,WAAW,IAAO,IAAI,WAAW,IAAO,IAAI;AAC1D,UAAM,KAAK,OAAO,SAAS,EAAE;AAC7B,UAAM,SACJ,IAAI,OAAO,OAAO,OAAO,IAAI,OAAO,OAAO,OAAO,QAAQ,OAAO;AACnE,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,aAAO,KAAK,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,IAAI,aAAa,IAAI,UAAU,KAAK;AAAA,EAC5C;AACF;;;ACjKA,IAAqB,aAArB,MAAgC;AAAA,EAC9B,OAAiB,CAAC;AAAA,EAClB,QAAkB,CAAC;AAAA,EACnB,OAAiB,CAAC;AAAA,EAClB;AAAA,EAEA,aAAa,YAAY,OAAO;AAC9B,UAAM,UAAU,CAAC,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE,IAAI,YAAY,wBAAwB,UAAU;AACrG,WAAO,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,SAAS,GAAG,CAAC;AAAA,EACrD;AAAA,EAEA,aAAa,YAAY,OAAO;AAC9B,UAAM,UAAU,CAAC,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE,IAAI,YAAY,wBAAwB,UAAU;AACrG,UAAM,SAAS,IAAI;AAAA,MACjB,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,SAAS,GAAG,CAAC;AAAA,IAC9C;AACA,UAAM,aAAa,CAAC,UAA6C,SAAiB;AAEhF,iBAAW,EAAE,MAAM,MAAM,KAAK,UAAU;AACtC,YAAI,QAAQ,GAAG;AACb,gBAAM,IAAI,MAAM,mBAAmB,MAAM;AAAA,QAC3C;AACA,cAAM,QAAS,OAAO,YAAc,QAAQ,KAAQ,QAAQ,KAAM;AAClE,eAAO,cAAc,KAAK;AAAA,MAC5B;AAAA,IACF;AACA,YAAQ,QAAQ,UAAU;AAC1B,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,gBAAgB,YAAY,OAAO;AACjC,WAAO,YAAY,KAAK,aAAa,SAAS,CAAC;AAAA,EACjD;AAAA,EAEA,SAAS,YAAY,OAAO;AAC1B,WAAO,KAAK,gBAAgB,SAAS;AAAA,EACvC;AAAA,EAEA,eAAe,KAAiB;AAC9B,aAAS,IAAI,GAAG,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG;AAC1C,YAAM,QACJ,IAAI,CAAC,IAAK,IAAI,IAAI,CAAC,KAAK,IAAM,IAAI,IAAI,CAAC,KAAK,KAAO,IAAI,IAAI,CAAC,KAAK;AACnE,YAAM,KAAK,QAAQ;AACnB,YAAM,OAAQ,UAAU,KAAM;AAC9B,YAAM,SAAU,UAAU,KAAM,KAAO;AACvC,YAAM,QAAQ,CAAC,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE,IAAI;AACrD,eAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,eAAe,KAAiB;AACrC,WAAO,IAAI,WAAW,EAAE,eAAe,GAAG;AAAA,EAC5C;AAAA,EAEA,kBAAkB,KAAa;AAC7B,WAAO,KAAK,eAAe,cAAc,GAAG,CAAC;AAAA,EAC/C;AAAA,EAEA,OAAO,kBAAkB,KAAa;AACpC,WAAO,IAAI,WAAW,EAAE,kBAAkB,GAAG;AAAA,EAC/C;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAG,KAAK,KAAK,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;AAAA,MACtC;AAAA,MACA,GAAG,KAAK,MAAM,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;AAAA,MACvC;AAAA,MACA,GAAG,KAAK,KAAK,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;AAAA,IACxC,EAAE,KAAK,IAAI;AAAA,EACb;AAAA,EAEA,cAAc,KAAa;AACzB,UAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,QAAI,UAAU,KAAK;AACnB,eAAW,SAAS,OAAO;AACzB,YAAM,OAAO,MAAM,KAAK;AACxB,UAAI,SAAS,SAAS;AACpB,kBAAU,KAAK;AAAA,MACjB;AACA,UAAI,SAAS,UAAU;AACrB,kBAAU,KAAK;AAAA,MACjB;AACA,UAAI,SAAS,SAAS;AACpB,kBAAU,KAAK;AAAA,MACjB;AACA,UAAI,KAAK,MAAM,OAAO,GAAG;AACvB,gBAAQ,KAAK,SAAS,MAAM,EAAE,CAAC;AAAA,MACjC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,cAAc,KAAa;AAChC,WAAO,IAAI,WAAW,EAAE,cAAc,GAAG;AAAA,EAC3C;AAAA,EAEA,sBAAsB,KAAiB,kBAAuE,MAAM,OAAO;AACzH,UAAM,SAAS,IAAI,aAAa,GAAG;AACnC,UAAM,QAAQ,OAAO,aAAa;AAClC,UAAM,QAAQ,OAAO,aAAa;AAClC,SAAK,OAAO,CAAC;AACb,SAAK,QAAQ,CAAC;AACd,SAAK,OAAO,CAAC;AACb,aAAQ,IAAI,GAAG,IAAI,OAAO,KAAK;AAC7B,YAAM,KAAK,OAAO,aAAa;AAC/B,UAAI,gBAAgB,IAAI,GAAG,KAAK,GAAG;AACjC,aAAK,MAAM,KAAK,EAAE;AAAA,MACpB,OAAO;AACL,aAAK,KAAK,KAAK,EAAE;AAAA,MACnB;AAAA,IACF;AACA,aAAQ,IAAI,GAAG,IAAI,OAAO,KAAK;AAC7B,YAAM,KAAK,OAAO,aAAa;AAC/B,WAAK,KAAK,KAAK,EAAE;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,sBAAsB,KAAiB,kBAA6C,MAAM,OAAO;AACtG,WAAO,IAAI,WAAW,EAAE,sBAAsB,KAAK,eAAe;AAAA,EACpE;AAAA,EAEA,sBAAsB;AACpB,UAAM,QAAQ,CAAC,GAAG,KAAK,MAAM,GAAG,KAAK,OAAO,GAAG,KAAK,IAAI;AACxD,UAAM,SAAS,IAAI,aAAa,MAAM,SAAS,IAAI,CAAC,EACjD,cAAc,KAAK,KAAK,SAAS,KAAK,MAAM,MAAM,EAClD,cAAc,KAAK,KAAK,MAAM;AACjC,UAAM,QAAQ,CAAC,OAAO,OAAO,cAAc,EAAE,CAAC;AAC9C,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,qBAAqB,KAAyB;AAC5C,UAAM,SAAS,qBAAqB,GAAG;AACvC,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,OAAO;AACpB,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,OAAO;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,qBAAqB,KAAyB;AACnD,WAAO,IAAI,WAAW,EAAE,qBAAqB,GAAG;AAAA,EAClD;AAAA,EAEA,qBAA6B;AAC3B,WAAO,mBAAmB,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,KAAK,QAAQ;AAAA,MACvE,MAAM,KAAK;AAAA,IACb,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,KAAyB;AACnC,UAAM,SAAS,YAAY,GAAG;AAC9B,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,OAAO;AACpB,SAAK,OAAO,OAAO;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,YAAY,KAAyB;AAC1C,WAAO,IAAI,WAAW,EAAE,YAAY,GAAG;AAAA,EACzC;AAAA,EAEA,YAAoB;AAClB,WAAO,UAAU;AAAA,MACf,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,CAAC;AAAA,EACH;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,11 @@
1
- export declare function countItems<T>(arr: T[]): Map<T, number>;
1
+ export declare function countItems<T>(arr: T[]): {
2
+ item: T;
3
+ count: number;
4
+ }[];
5
+ export declare function countConsecutiveItems<T>(arr: T[]): {
6
+ item: T;
7
+ count: number;
8
+ }[];
2
9
  declare abstract class BufferCursor {
3
10
  buffer: Uint8Array;
4
11
  pointer: number;
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { fromBase64Url, toBase64Url } from './src/base64';
2
- import { BufferReader, BufferWriter, countItems } from './src/utils';
2
+ import { BufferReader, BufferWriter, countConsecutiveItems, countItems } from './src/utils';
3
3
  import { fromYdkeURL, toYdkeURL } from './src/ydke';
4
4
  import { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';
5
5
 
@@ -9,23 +9,23 @@ export default class YGOProDeck {
9
9
  side: number[] = [];
10
10
  name?: string;
11
11
 
12
- bufferLength() {
13
- const counted = [this.main, this.extra, this.side].map(countItems);
14
- return counted.reduce((a, b) => a + b.size * 4, 0);
12
+ bufferLength(noCompact = false) {
13
+ const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
14
+ return counted.reduce((a, b) => a + b.length * 4, 0);
15
15
  }
16
16
 
17
- toUint8Array() {
18
- const counted = [this.main, this.extra, this.side].map(countItems);
17
+ toUint8Array(noCompact = false) {
18
+ const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
19
19
  const writer = new BufferWriter(
20
- counted.reduce((a, b) => a + b.size * 4, 0),
20
+ counted.reduce((a, b) => a + b.length * 4, 0),
21
21
  );
22
- const writeCards = (countMap: Map<number, number>, type: number) => {
22
+ const writeCards = (countMap: { item: number, count: number }[], type: number) => {
23
23
  // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)
24
- for (const [id, count] of countMap.entries()) {
24
+ for (const { item, count } of countMap) {
25
25
  if (count > 4) {
26
- throw new Error(`Too many cards: ${id}`);
26
+ throw new Error(`Too many cards: ${item}`);
27
27
  }
28
- const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);
28
+ const value = (item & 0xfffffff) | (type << 28) | ((count - 1) << 30);
29
29
  writer.writeUint32LE(value);
30
30
  }
31
31
  };
@@ -33,12 +33,12 @@ export default class YGOProDeck {
33
33
  return writer.buffer;
34
34
  }
35
35
 
36
- toEncodedString() {
37
- return toBase64Url(this.toUint8Array());
36
+ toEncodedString(noCompact = false) {
37
+ return toBase64Url(this.toUint8Array(noCompact));
38
38
  }
39
39
 
40
- toString() {
41
- return this.toEncodedString();
40
+ toString(noCompact = false) {
41
+ return this.toEncodedString(noCompact);
42
42
  }
43
43
 
44
44
  fromUint8Array(buf: Uint8Array) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ygopro-deck-encode",
3
3
  "description": "YGOPro Deck encode and decode, with well-browser support.",
4
- "version": "1.0.9",
4
+ "version": "1.0.10",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",