mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-07-12 15:36:32 +02:00
dc10a90851
- Implement tool registry system with individual tool modules - Reorganize transformers into categorized source modules - Remove emojiLibrary.js, consolidate into EmojiUtils and emojiData - Fix mobile close button and tooltip functionality - Add build system for transforms and emoji data - Migrate from Python backend to pure JavaScript - Add comprehensive documentation and testing - Improve code organization and maintainability - Ignore generated files (transforms-bundle.js, emojiData.js)
111 lines
4.0 KiB
JavaScript
111 lines
4.0 KiB
JavaScript
// ascii85 transform
|
|
import BaseTransformer from '../BaseTransformer.js';
|
|
|
|
export default new BaseTransformer({
|
|
name: 'ASCII85',
|
|
priority: 290,
|
|
// Detector: ASCII85 has distinctive <~ ~> wrapper
|
|
detector: function(text) {
|
|
return text.startsWith('<~') && text.endsWith('~>');
|
|
},
|
|
|
|
func: function(text) {
|
|
// Simple ASCII85 encoding implementation
|
|
// Use TextEncoder to properly handle multi-byte UTF-8 characters
|
|
const bytes = new TextEncoder().encode(text);
|
|
let result = '<~';
|
|
let buffer = 0;
|
|
let bufferLength = 0;
|
|
|
|
for (let i = 0; i < bytes.length; i++) {
|
|
buffer = (buffer << 8) | bytes[i];
|
|
bufferLength += 8;
|
|
|
|
if (bufferLength >= 32) {
|
|
let value = buffer >>> (bufferLength - 32);
|
|
buffer &= (1 << (bufferLength - 32)) - 1;
|
|
bufferLength -= 32;
|
|
|
|
if (value === 0) {
|
|
result += 'z';
|
|
} else {
|
|
for (let j = 4; j >= 0; j--) {
|
|
const digit = (value / Math.pow(85, j)) % 85;
|
|
result += String.fromCharCode(digit + 33);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle remaining bits
|
|
if (bufferLength > 0) {
|
|
buffer <<= (32 - bufferLength);
|
|
let value = buffer;
|
|
const bytes = Math.ceil(bufferLength / 8);
|
|
|
|
for (let j = 4; j >= (4 - bytes); j--) {
|
|
const digit = (value / Math.pow(85, j)) % 85;
|
|
result += String.fromCharCode(digit + 33);
|
|
}
|
|
}
|
|
|
|
return result + '~>';
|
|
},
|
|
preview: function(text) {
|
|
if (!text) return '[ascii85]';
|
|
const full = this.func(text);
|
|
return full.substring(0, 16) + (full.length > 16 ? '...' : '');
|
|
},
|
|
reverse: function(text) {
|
|
// Check if it's a valid ASCII85 string
|
|
if (!text.startsWith('<~') || !text.endsWith('~>')) {
|
|
return text;
|
|
}
|
|
|
|
// Remove delimiters and whitespace
|
|
text = text.substring(2, text.length - 2).replace(/\s+/g, '');
|
|
|
|
const bytes = [];
|
|
let i = 0;
|
|
|
|
while (i < text.length) {
|
|
// Handle 'z' special case (represents 4 zero bytes)
|
|
if (text[i] === 'z') {
|
|
bytes.push(0, 0, 0, 0);
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
// Process a group of 5 characters
|
|
if (i < text.length) {
|
|
let value = 0;
|
|
const groupSize = Math.min(5, text.length - i);
|
|
|
|
// Convert the group to a 32-bit value
|
|
for (let j = 0; j < groupSize; j++) {
|
|
value = value * 85 + (text.charCodeAt(i + j) - 33);
|
|
}
|
|
|
|
// Pad with 'u' (84) if needed for partial groups
|
|
for (let j = groupSize; j < 5; j++) {
|
|
value = value * 85 + 84;
|
|
}
|
|
|
|
// Extract bytes from the value
|
|
// groupSize chars encodes (groupSize - 1) bytes
|
|
const bytesToWrite = groupSize - 1;
|
|
for (let j = 0; j < bytesToWrite; j++) {
|
|
bytes.push((value >>> ((3 - j) * 8)) & 0xFF);
|
|
}
|
|
|
|
i += groupSize;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Use TextDecoder to properly handle UTF-8 multi-byte characters
|
|
return new TextDecoder().decode(new Uint8Array(bytes));
|
|
}
|
|
|
|
}); |