var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { ByteReader: () => ByteReader, Struct: () => Struct, TWKB: () => TWKB }); module.exports = __toCommonJS(src_exports); // src/ByteReader.ts var ByteReader = class _ByteReader { buffer; view; cursor; constructor(hex) { this.buffer = _ByteReader.HexToBuffer(hex); this.view = new DataView(this.buffer); this.cursor = 0; } /** * Unzigsags a zigzag-encoded byte. * @param value - the zigzag-encoded number to unzigzag. * @returns The unzigzagged number. */ unZigZag(value) { return !(value & 1) ? value >> 1 : -1 * (value + 1 >> 1); } /** * Decode zig-zag value (a little different with method above) * @param value - value to decode */ zigZagDecode(value) { return value >> 1 ^ -(value & 1); } /** * Read single byte from byte buffer * @returns byte data */ readByte() { if (this.cursor >= this.view.byteLength) throw "Reached end of byte buffer"; return this.view.getUint8(this.cursor++); } /** * Read varint from byte buffer * @returns varint data */ readVarInt() { let result = 0; let shift = 0; let byte; do { byte = this.readByte(); result |= (byte & 127) << shift; shift += 7; } while (byte >= 128); return result; } /** * Convert hex string to array buffer * @param hex - hex string to convert * @private */ static HexToBuffer(hex) { if (hex.length % 2 !== 0) throw "Odd number of characters in a hex string"; const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < bytes.length; i++) bytes[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16); return bytes.buffer; } }; // src/Struct.ts var Struct = class { description; actualByte; // [byte, bit-n] /** * Create the struct * @param description - structure schema */ constructor(description) { this.description = description; } /** * Parse bytes and convert it to structure */ parse(stream, def = this.description) { const result = {}; for (const key in def) { if (!Array.isArray(def[key])) result[key] = this.parse(stream, def[key]); else { if (def[key][1] < 1) { result[key] = def[key][0](0); continue; } let data = 0; const length = def[key][1]; for (let i = 0; i < length; i++) { if (!this.actualByte) this.actualByte = [stream.readByte(), 0]; const bit = this.actualByte[0] >> this.actualByte[1] & 1; data |= bit << i; this.actualByte[1]++; if (this.actualByte[1] === 8) this.actualByte = null; } const resValue = def[key][0](data); if (def[key][2] && typeof def[key][2] == "function") result[key] = def[key][2](resValue); else result[key] = resValue; } } return result; } }; // src/TWKB.ts var TWKB = class { reader; constructor(hex) { this.reader = new ByteReader(hex); } /** * Parse twkb hex string and convert it into array of points * @see {Point} */ parse() { const { geometryType, precision, metadata } = this.readHeadData(); const facXY = Math.pow(10, precision); if (metadata.hasBoundingBox || !metadata.hasExtendedDimensions) throw "Malformed track data: has bounding box or doesn't have extended dimensions"; const dims = this.reader.readVarInt(); const hasM = (dims & 2) >> 1; if (!hasM) throw "Malformed track data: M point not found"; const preM = (dims & 224) >> 5; const facM = Math.pow(10, preM); const pointsCount = this.reader.readVarInt(); const result = []; let lx = 0; let ly = 0; let lt = 0; for (let i = 0; i < pointsCount; i++) { const { dx, dy, dt } = this.readCoords(); const x = lx + dx; const y = ly + dy; const t = lt + dt; lx = x; ly = y; lt = t; const realX = x * Math.pow(10, -precision); const realY = y * Math.pow(10, -precision); const realM = t * Math.pow(10, -preM); result.push({ latitude: realY, longitude: realX, time: realM + 2147483647 }); } return result; } /** * Read header and metadata structures * @private */ readHeadData() { const struct = new Struct({ geometryType: [Number, 4], precision: [Number, 4, (v) => this.reader.unZigZag(v)], meta: { hasBoundingBox: [Boolean, 1], hasSize: [Boolean, 1], _: [Boolean, 1], hasExtendedDimensions: [Boolean, 1] } }); const { geometryType, precision, meta: { hasBoundingBox, hasSize, hasExtendedDimensions } } = struct.parse(this.reader); return { geometryType, precision, metadata: { hasBoundingBox, hasSize, hasExtendedDimensions } }; } /** * Read 3 varints for deltas of x, y, z * @private */ readCoords() { return { dx: this.reader.unZigZag(this.reader.readVarInt()), dy: this.reader.unZigZag(this.reader.readVarInt()), dt: this.reader.unZigZag(this.reader.readVarInt()) }; } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ByteReader, Struct, TWKB });