[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
This commit is contained in:
110
lib/textZip.ts
Normal file
110
lib/textZip.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
export interface TextZipFile {
|
||||
name: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
const ZIP_UTF8_FLAG = 0x0800;
|
||||
|
||||
const crcTable = Array.from({ length: 256 }, (_, index) => {
|
||||
let value = index;
|
||||
for (let bit = 0; bit < 8; bit += 1) {
|
||||
value = value & 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;
|
||||
}
|
||||
return value >>> 0;
|
||||
});
|
||||
|
||||
const crc32 = (bytes: Uint8Array): number => {
|
||||
let crc = 0xffffffff;
|
||||
bytes.forEach((byte) => {
|
||||
crc = crcTable[(crc ^ byte) & 0xff] ^ (crc >>> 8);
|
||||
});
|
||||
return (crc ^ 0xffffffff) >>> 0;
|
||||
};
|
||||
|
||||
const pushUint16 = (parts: number[], value: number) => {
|
||||
parts.push(value & 0xff, (value >>> 8) & 0xff);
|
||||
};
|
||||
|
||||
const pushUint32 = (parts: number[], value: number) => {
|
||||
parts.push(value & 0xff, (value >>> 8) & 0xff, (value >>> 16) & 0xff, (value >>> 24) & 0xff);
|
||||
};
|
||||
|
||||
const concatZipParts = (header: number[], ...parts: Uint8Array[]): Uint8Array => {
|
||||
const headerBytes = Uint8Array.from(header);
|
||||
const chunk = new Uint8Array(
|
||||
headerBytes.length + parts.reduce((total, part) => total + part.length, 0),
|
||||
);
|
||||
let offset = 0;
|
||||
chunk.set(headerBytes, offset);
|
||||
offset += headerBytes.length;
|
||||
parts.forEach((part) => {
|
||||
chunk.set(part, offset);
|
||||
offset += part.length;
|
||||
});
|
||||
return chunk;
|
||||
};
|
||||
|
||||
export const buildTextFilesZipBlob = (files: TextZipFile[]): Blob => {
|
||||
const encoder = new TextEncoder();
|
||||
const chunks: Uint8Array[] = [];
|
||||
const centralDirectory: Uint8Array[] = [];
|
||||
let offset = 0;
|
||||
|
||||
files.forEach((file) => {
|
||||
const nameBytes = encoder.encode(file.name);
|
||||
const contentBytes = encoder.encode(file.content);
|
||||
const checksum = crc32(contentBytes);
|
||||
|
||||
const localHeader: number[] = [];
|
||||
pushUint32(localHeader, 0x04034b50);
|
||||
pushUint16(localHeader, 20);
|
||||
pushUint16(localHeader, ZIP_UTF8_FLAG);
|
||||
pushUint16(localHeader, 0);
|
||||
pushUint16(localHeader, 0);
|
||||
pushUint16(localHeader, 0);
|
||||
pushUint32(localHeader, checksum);
|
||||
pushUint32(localHeader, contentBytes.length);
|
||||
pushUint32(localHeader, contentBytes.length);
|
||||
pushUint16(localHeader, nameBytes.length);
|
||||
pushUint16(localHeader, 0);
|
||||
const localChunk = concatZipParts(localHeader, nameBytes, contentBytes);
|
||||
chunks.push(localChunk);
|
||||
|
||||
const centralHeader: number[] = [];
|
||||
pushUint32(centralHeader, 0x02014b50);
|
||||
pushUint16(centralHeader, 20);
|
||||
pushUint16(centralHeader, 20);
|
||||
pushUint16(centralHeader, ZIP_UTF8_FLAG);
|
||||
pushUint16(centralHeader, 0);
|
||||
pushUint16(centralHeader, 0);
|
||||
pushUint16(centralHeader, 0);
|
||||
pushUint32(centralHeader, checksum);
|
||||
pushUint32(centralHeader, contentBytes.length);
|
||||
pushUint32(centralHeader, contentBytes.length);
|
||||
pushUint16(centralHeader, nameBytes.length);
|
||||
pushUint16(centralHeader, 0);
|
||||
pushUint16(centralHeader, 0);
|
||||
pushUint16(centralHeader, 0);
|
||||
pushUint16(centralHeader, 0);
|
||||
pushUint32(centralHeader, 0);
|
||||
pushUint32(centralHeader, offset);
|
||||
centralDirectory.push(concatZipParts(centralHeader, nameBytes));
|
||||
|
||||
offset += localChunk.length;
|
||||
});
|
||||
|
||||
const centralDirectorySize = centralDirectory.reduce((total, chunk) => total + chunk.length, 0);
|
||||
const endRecord: number[] = [];
|
||||
pushUint32(endRecord, 0x06054b50);
|
||||
pushUint16(endRecord, 0);
|
||||
pushUint16(endRecord, 0);
|
||||
pushUint16(endRecord, files.length);
|
||||
pushUint16(endRecord, files.length);
|
||||
pushUint32(endRecord, centralDirectorySize);
|
||||
pushUint32(endRecord, offset);
|
||||
pushUint16(endRecord, 0);
|
||||
|
||||
return new Blob([...chunks, ...centralDirectory, new Uint8Array(endRecord)], {
|
||||
type: "application/zip",
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user