@pixagram/sanitizer 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +282 -0
- package/package.json +24 -0
- package/pixa_content.d.ts +108 -0
- package/pixa_content.js +568 -0
- package/pixa_content_bg.wasm +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# pixa-content
|
|
2
|
+
|
|
3
|
+
> Secure content processing engine for the PIXA blockchain platform.
|
|
4
|
+
> Rust → WebAssembly module for browser-side rendering of posts, comments, profiles, and metadata.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
| Feature | Description |
|
|
9
|
+
|---------|-------------|
|
|
10
|
+
| **Post Rendering** | Markdown/HTML → sanitized HTML with full formatting |
|
|
11
|
+
| **Comment Rendering** | Stricter subset — no headings, tables, iframes |
|
|
12
|
+
| **@Mentions** | `@username` → `<a href="/@username">` with validation |
|
|
13
|
+
| **#Hashtags** | `#tag` → `<a href="/trending/tag">` |
|
|
14
|
+
| **Image Extraction** | Returns image list; render with/without images |
|
|
15
|
+
| **Base64 Images** | Validates `data:image/*` URIs, blocks dangerous MIME types |
|
|
16
|
+
| **External Links** | Marks external links with `data-*` attrs for React dialog |
|
|
17
|
+
| **JSON Sanitizer** | `safeJson` — sanitizes any JSON tree (keys, strings, base64) |
|
|
18
|
+
| **Biography** | HTML → plain text sanitization |
|
|
19
|
+
| **Username** | HIVE-compatible validation (3-16 chars, a-z0-9.-) |
|
|
20
|
+
| **Metadata** | `parseMetadata` — safeJson + known-field extraction |
|
|
21
|
+
| **Plain Text** | Strip all formatting, return clean text |
|
|
22
|
+
| **Summarization** | TF-IDF extractive summarization |
|
|
23
|
+
| **XSS Protection** | Whitelist-based sanitization via ammonia |
|
|
24
|
+
|
|
25
|
+
## Security Model
|
|
26
|
+
|
|
27
|
+
- **Whitelist-based HTML sanitization** via `ammonia` — only approved tags and attributes pass through
|
|
28
|
+
- **No script execution** — `<script>`, event handlers (`onclick`, `onerror`, etc.), and `javascript:` URIs are all blocked
|
|
29
|
+
- **SVG safety** — Base64 SVGs are decoded and checked for embedded scripts
|
|
30
|
+
- **Link isolation** — External links get `rel="noopener noreferrer"` and `target="_blank"`
|
|
31
|
+
- **Input limits** — Maximum body length, image size, nesting depth, and URL length enforced
|
|
32
|
+
- **Username validation** — Strict HIVE-compatible rules prevent injection via mention links
|
|
33
|
+
- **JSON sanitization** — Every key validated, every string HTML-stripped, embedded JSON-in-strings rejected, dangerous URI schemes blocked, base64 images validated
|
|
34
|
+
|
|
35
|
+
## Build
|
|
36
|
+
|
|
37
|
+
### Prerequisites
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Rust toolchain
|
|
41
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
42
|
+
rustup target add wasm32-unknown-unknown
|
|
43
|
+
|
|
44
|
+
# wasm-pack
|
|
45
|
+
cargo install wasm-pack
|
|
46
|
+
|
|
47
|
+
# Optional: binaryen for extra ~20-30% size reduction
|
|
48
|
+
npm install -g binaryen
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Build Commands
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Standard release build (optimized for size)
|
|
55
|
+
./scripts/build.sh release
|
|
56
|
+
|
|
57
|
+
# Smaller build with wee_alloc (trades speed for ~20KB less)
|
|
58
|
+
./scripts/build.sh release-small
|
|
59
|
+
|
|
60
|
+
# Dev build (fast compile, no optimization)
|
|
61
|
+
./scripts/build.sh dev
|
|
62
|
+
|
|
63
|
+
# For bundlers (webpack, vite, rollup)
|
|
64
|
+
./scripts/build.sh bundler
|
|
65
|
+
|
|
66
|
+
# Run all tests
|
|
67
|
+
./scripts/build.sh test
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Expected Output Size
|
|
71
|
+
|
|
72
|
+
| Build | Raw WASM | + wasm-opt | Gzip |
|
|
73
|
+
|-------|----------|------------|------|
|
|
74
|
+
| `release` | ~800KB-1.2MB | ~600KB-900KB | ~250KB-350KB |
|
|
75
|
+
| `release-small` | ~750KB-1.1MB | ~550KB-850KB | ~220KB-320KB |
|
|
76
|
+
|
|
77
|
+
> **Why not smaller?** The bulk comes from `ammonia` (HTML sanitizer using `html5ever` parser) and `regex`. These are essential for security. The gzipped transfer size is what matters for users — and **250-350KB gzipped is reasonable** for a full content engine replacing multiple JavaScript libraries.
|
|
78
|
+
|
|
79
|
+
## Usage
|
|
80
|
+
|
|
81
|
+
### JavaScript / React
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
import { PixaContent } from './pixa-content.js';
|
|
85
|
+
|
|
86
|
+
// Initialize once
|
|
87
|
+
const pixa = await PixaContent.init('./pixa_content.js');
|
|
88
|
+
|
|
89
|
+
// ── Render a post ──────────────────────────────
|
|
90
|
+
const result = pixa.sanitizePost(postBody, {
|
|
91
|
+
max_image_count: 0, // 0 = unlimited
|
|
92
|
+
internal_domains: ['pixa.pics', 'custom-domain.com'],
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
console.log(result.html); // Sanitized HTML
|
|
96
|
+
console.log(result.images); // [{ src, alt, is_base64, index }]
|
|
97
|
+
console.log(result.links); // [{ href, text, domain, is_external }]
|
|
98
|
+
|
|
99
|
+
// ── Render a comment ───────────────────────────
|
|
100
|
+
const comment = pixa.sanitizeComment(commentBody);
|
|
101
|
+
|
|
102
|
+
// ── Render a memo ──────────────────────────────
|
|
103
|
+
const memo = pixa.sanitizeMemo(memoBody);
|
|
104
|
+
|
|
105
|
+
// ── Sanitize any JSON (the main entry point) ───
|
|
106
|
+
const safe = pixa.safeJson(rawJsonString);
|
|
107
|
+
// Every key validated, every string HTML-stripped,
|
|
108
|
+
// embedded JSON rejected, base64 images preserved.
|
|
109
|
+
|
|
110
|
+
// ── Sanitize a single string ───────────────────
|
|
111
|
+
const title = pixa.safeString(rawTitle); // '' if unsafe
|
|
112
|
+
const category = pixa.safeString(rawCategory);
|
|
113
|
+
|
|
114
|
+
// ── Parse metadata (convenience wrapper) ───────
|
|
115
|
+
const meta = pixa.parseMetadata(jsonMetadataString);
|
|
116
|
+
console.log(meta.profile); // Sanitized JSON object (whatever was in source)
|
|
117
|
+
console.log(meta.tags); // ['tag1', 'tag2']
|
|
118
|
+
console.log(meta.image); // ['https://...']
|
|
119
|
+
console.log(meta.app); // 'peakd/2024.10.11'
|
|
120
|
+
console.log(meta.extra); // Any unknown fields (already sanitized)
|
|
121
|
+
|
|
122
|
+
// ── Extract plain text ─────────────────────────
|
|
123
|
+
const text = pixa.extractPlainText(postBody);
|
|
124
|
+
|
|
125
|
+
// ── Summarize ──────────────────────────────────
|
|
126
|
+
const summary = pixa.summarizeContent(postBody, 3);
|
|
127
|
+
console.log(summary.summary); // Top 3 sentences joined
|
|
128
|
+
console.log(summary.keywords); // Top keywords with scores
|
|
129
|
+
console.log(summary.sentences); // Scored sentences with positions
|
|
130
|
+
|
|
131
|
+
// ── Sanitize profile data ──────────────────────
|
|
132
|
+
const bio = pixa.sanitizeBiography(rawBio, 256); // max 256 chars
|
|
133
|
+
const name = pixa.sanitizeUsername(rawUsername); // '' if invalid
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### External Link Dialog (React)
|
|
137
|
+
|
|
138
|
+
```jsx
|
|
139
|
+
import { ExternalLinkDialog } from './ExternalLinkDialog';
|
|
140
|
+
|
|
141
|
+
function PostContent({ html }) {
|
|
142
|
+
return (
|
|
143
|
+
<ExternalLinkDialog
|
|
144
|
+
onNavigate={(href, domain) => {
|
|
145
|
+
console.log('User navigated to:', domain);
|
|
146
|
+
}}
|
|
147
|
+
>
|
|
148
|
+
<div dangerouslySetInnerHTML={{ __html: html }} />
|
|
149
|
+
</ExternalLinkDialog>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Or with a custom dialog:
|
|
155
|
+
|
|
156
|
+
```jsx
|
|
157
|
+
<ExternalLinkDialog
|
|
158
|
+
renderDialog={({ href, domain, onConfirm, onCancel }) => (
|
|
159
|
+
<YourCustomModal
|
|
160
|
+
title={`Leave Pixa?`}
|
|
161
|
+
message={`Navigate to ${domain}?`}
|
|
162
|
+
onYes={onConfirm}
|
|
163
|
+
onNo={onCancel}
|
|
164
|
+
/>
|
|
165
|
+
)}
|
|
166
|
+
>
|
|
167
|
+
<div dangerouslySetInnerHTML={{ __html: html }} />
|
|
168
|
+
</ExternalLinkDialog>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Using from Rust (Non-WASM)
|
|
172
|
+
|
|
173
|
+
```rust
|
|
174
|
+
use pixa_content::{extract_plain_text, sanitize_biography, sanitize_username};
|
|
175
|
+
use pixa_content::sanitizer::{sanitize_post, safe_json, SanitizeOptions};
|
|
176
|
+
|
|
177
|
+
// Sanitize a post
|
|
178
|
+
let opts = SanitizeOptions::default();
|
|
179
|
+
let result = sanitize_post("# Hello @world\n\nCheck #pixelart!", &opts);
|
|
180
|
+
println!("HTML: {}", result.html);
|
|
181
|
+
println!("Images: {:?}", result.images);
|
|
182
|
+
println!("Links: {:?}", result.links);
|
|
183
|
+
|
|
184
|
+
// Sanitize any JSON metadata
|
|
185
|
+
let clean = safe_json(r#"{"tags":["art"],"profile":{"name":"Alice"}}"#).unwrap();
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Architecture
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
pixa-content/
|
|
192
|
+
├── Cargo.toml # Dependencies & WASM optimization config
|
|
193
|
+
├── src/
|
|
194
|
+
│ ├── lib.rs # Public API & WASM bindings
|
|
195
|
+
│ ├── types.rs # Shared types (ImageInfo, LinkInfo, ParsedMetadata, etc.)
|
|
196
|
+
│ ├── sanitizer.rs # ammonia-based HTML sanitization + safe_json/safe_string/safe_key
|
|
197
|
+
│ ├── mentions.rs # @mention and #hashtag processing
|
|
198
|
+
│ ├── images.rs # Image extraction, base64 validation
|
|
199
|
+
│ ├── links.rs # External link detection & wrapping
|
|
200
|
+
│ ├── text.rs # Plain text extraction, sentence splitting
|
|
201
|
+
│ ├── summarizer.rs # TF-IDF extractive summarization
|
|
202
|
+
│ └── metadata.rs # JSON metadata parsing (thin wrapper over safe_json)
|
|
203
|
+
├── tests/
|
|
204
|
+
│ └── integration.rs # Full pipeline integration tests
|
|
205
|
+
├── js/
|
|
206
|
+
│ ├── pixa-content.js # JS wrapper API
|
|
207
|
+
│ └── ExternalLinkDialog.jsx # React external link component
|
|
208
|
+
├── scripts/
|
|
209
|
+
│ └── build.sh # Build & optimization script
|
|
210
|
+
└── README.md
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Processing Pipeline
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
Input (Markdown or HTML)
|
|
217
|
+
│
|
|
218
|
+
├──► Detect format (is_predominantly_html)
|
|
219
|
+
│
|
|
220
|
+
├──► If Markdown: pulldown-cmark → HTML
|
|
221
|
+
│
|
|
222
|
+
├──► Extract images (before sanitization)
|
|
223
|
+
│
|
|
224
|
+
├──► Process @mentions and #hashtags
|
|
225
|
+
│ (text nodes only, not inside existing links)
|
|
226
|
+
│
|
|
227
|
+
├──► Sanitize HTML (ammonia whitelist)
|
|
228
|
+
│ ├── Post: full formatting
|
|
229
|
+
│ ├── Comment: restricted subset
|
|
230
|
+
│ └── Memo: inline only
|
|
231
|
+
│
|
|
232
|
+
├──► Process links (internal vs external)
|
|
233
|
+
│ └── External: add data-* attrs for React
|
|
234
|
+
│
|
|
235
|
+
├──► Optionally strip/limit images
|
|
236
|
+
│
|
|
237
|
+
└──► Return { html, images, links }
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## JSON Sanitization Pipeline
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
Input (raw JSON string)
|
|
244
|
+
│
|
|
245
|
+
├──► Parse JSON
|
|
246
|
+
│
|
|
247
|
+
├──► Walk tree recursively:
|
|
248
|
+
│ ├── Keys: safe_key → validate identifier format, drop bad keys
|
|
249
|
+
│ ├── Strings: safe_string →
|
|
250
|
+
│ │ ├── Reject embedded JSON-in-strings
|
|
251
|
+
│ │ ├── data:image/* → validate base64, pass through
|
|
252
|
+
│ │ ├── URLs → strip control chars (preserve & in query strings)
|
|
253
|
+
│ │ ├── Text → strip ALL HTML via ammonia, reject dangerous schemes
|
|
254
|
+
│ │ └── Enforce length limits
|
|
255
|
+
│ ├── Numbers: pass through (must be finite)
|
|
256
|
+
│ ├── Arrays: recurse (max 100 elements)
|
|
257
|
+
│ └── Objects: recurse (max 50 keys, max depth 5)
|
|
258
|
+
│
|
|
259
|
+
└──► Return sanitized JSON value
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Metadata Flexibility
|
|
263
|
+
|
|
264
|
+
`parseMetadata` calls `safeJson` first, then extracts known fields for convenience:
|
|
265
|
+
|
|
266
|
+
```json
|
|
267
|
+
{
|
|
268
|
+
"profile": { "name": "...", "about": "...", "profile_image": "..." },
|
|
269
|
+
"tags": ["tag1", "tag2"],
|
|
270
|
+
"app": "peakd/2024.10.11",
|
|
271
|
+
"format": "markdown",
|
|
272
|
+
"pixa_nft_id": "preserved-in-extra",
|
|
273
|
+
"custom_field": { "also": "preserved" }
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
All fields are sanitized by `safeJson` before extraction. Unknown fields land in `extra`.
|
|
278
|
+
For full control, use `safeJson` directly — it handles any JSON structure.
|
|
279
|
+
|
|
280
|
+
## License
|
|
281
|
+
|
|
282
|
+
Proprietary — Pixagram SA. All rights reserved.
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pixagram/sanitizer",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"collaborators": [
|
|
5
|
+
"Pixagram SA"
|
|
6
|
+
],
|
|
7
|
+
"description": "Secure content processing for PIXA blockchain — Markdown/HTML rendering, sanitization, metadata parsing, summarization",
|
|
8
|
+
"version": "0.2.0",
|
|
9
|
+
"license": "PROPRIETARY",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/nicmusic/pixa-content"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"pixa_content_bg.wasm",
|
|
16
|
+
"pixa_content.js",
|
|
17
|
+
"pixa_content.d.ts"
|
|
18
|
+
],
|
|
19
|
+
"main": "pixa_content.js",
|
|
20
|
+
"types": "pixa_content.d.ts",
|
|
21
|
+
"sideEffects": [
|
|
22
|
+
"./snippets/*"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Extract plain text from content.
|
|
6
|
+
*/
|
|
7
|
+
export function extractPlainText(body: string): string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Parse and sanitize JSON metadata.
|
|
11
|
+
* Internally calls safe_json then extracts known fields.
|
|
12
|
+
*/
|
|
13
|
+
export function parseMetadata(json_str: string): any;
|
|
14
|
+
|
|
15
|
+
export function pixaContentInit(): void;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Sanitize a JSON string. Every key validated, every string HTML-stripped,
|
|
19
|
+
* embedded JSON-in-strings rejected, base64 images allowed if valid.
|
|
20
|
+
*
|
|
21
|
+
* This is the single entry point for ALL metadata sanitization.
|
|
22
|
+
*/
|
|
23
|
+
export function safeJson(json_str: string): any;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sanitize a single string value. Strips HTML, rejects embedded JSON,
|
|
27
|
+
* rejects dangerous URI schemes, allows validated base64 images.
|
|
28
|
+
*
|
|
29
|
+
* Used by JS pipeline for title, category, and other text fields.
|
|
30
|
+
*/
|
|
31
|
+
export function safeString(s: string, max_len: number): string | undefined;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sanitize a user biography — returns plain text only (no HTML).
|
|
35
|
+
*/
|
|
36
|
+
export function sanitizeBiography(bio: string, max_length: number): string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Sanitize a comment body.
|
|
40
|
+
* Everything in memo + lists, blockquotes, code, links.
|
|
41
|
+
* No images, no headings, no tables.
|
|
42
|
+
*/
|
|
43
|
+
export function sanitizeComment(body: string, options_json: string): any;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Sanitize a transaction memo.
|
|
47
|
+
* Bold, italic, @mentions, #hashtags. No images, no lists, no blocks.
|
|
48
|
+
*/
|
|
49
|
+
export function sanitizeMemo(body: string, options_json: string): any;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Sanitize a post body. Full markdown → HTML.
|
|
53
|
+
* Returns sanitized HTML + extracted images (including base64) + links.
|
|
54
|
+
*/
|
|
55
|
+
export function sanitizePost(body: string, options_json: string): any;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Sanitize a username — alphanumeric, dots, hyphens only.
|
|
59
|
+
*/
|
|
60
|
+
export function sanitizeUsername(username: string): string;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* TF-IDF summarization.
|
|
64
|
+
*/
|
|
65
|
+
export function summarizeContent(body: string, sentence_count: number): any;
|
|
66
|
+
|
|
67
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
68
|
+
|
|
69
|
+
export interface InitOutput {
|
|
70
|
+
readonly memory: WebAssembly.Memory;
|
|
71
|
+
readonly pixaContentInit: () => void;
|
|
72
|
+
readonly sanitizeMemo: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
73
|
+
readonly sanitizeComment: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
74
|
+
readonly sanitizePost: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
75
|
+
readonly safeJson: (a: number, b: number, c: number) => void;
|
|
76
|
+
readonly safeString: (a: number, b: number, c: number, d: number) => void;
|
|
77
|
+
readonly sanitizeBiography: (a: number, b: number, c: number, d: number) => void;
|
|
78
|
+
readonly sanitizeUsername: (a: number, b: number, c: number) => void;
|
|
79
|
+
readonly extractPlainText: (a: number, b: number, c: number) => void;
|
|
80
|
+
readonly summarizeContent: (a: number, b: number, c: number, d: number) => void;
|
|
81
|
+
readonly parseMetadata: (a: number, b: number, c: number) => void;
|
|
82
|
+
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
83
|
+
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
84
|
+
readonly __wbindgen_export3: (a: number, b: number, c: number) => void;
|
|
85
|
+
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
92
|
+
* a precompiled `WebAssembly.Module`.
|
|
93
|
+
*
|
|
94
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
95
|
+
*
|
|
96
|
+
* @returns {InitOutput}
|
|
97
|
+
*/
|
|
98
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
102
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
103
|
+
*
|
|
104
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
105
|
+
*
|
|
106
|
+
* @returns {Promise<InitOutput>}
|
|
107
|
+
*/
|
|
108
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
package/pixa_content.js
ADDED
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
/* @ts-self-types="./pixa_content.d.ts" */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extract plain text from content.
|
|
5
|
+
* @param {string} body
|
|
6
|
+
* @returns {string}
|
|
7
|
+
*/
|
|
8
|
+
export function extractPlainText(body) {
|
|
9
|
+
let deferred2_0;
|
|
10
|
+
let deferred2_1;
|
|
11
|
+
try {
|
|
12
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
13
|
+
const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
14
|
+
const len0 = WASM_VECTOR_LEN;
|
|
15
|
+
wasm.extractPlainText(retptr, ptr0, len0);
|
|
16
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
17
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
18
|
+
deferred2_0 = r0;
|
|
19
|
+
deferred2_1 = r1;
|
|
20
|
+
return getStringFromWasm0(r0, r1);
|
|
21
|
+
} finally {
|
|
22
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
23
|
+
wasm.__wbindgen_export3(deferred2_0, deferred2_1, 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Parse and sanitize JSON metadata.
|
|
29
|
+
* Internally calls safe_json then extracts known fields.
|
|
30
|
+
* @param {string} json_str
|
|
31
|
+
* @returns {any}
|
|
32
|
+
*/
|
|
33
|
+
export function parseMetadata(json_str) {
|
|
34
|
+
try {
|
|
35
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
36
|
+
const ptr0 = passStringToWasm0(json_str, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
37
|
+
const len0 = WASM_VECTOR_LEN;
|
|
38
|
+
wasm.parseMetadata(retptr, ptr0, len0);
|
|
39
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
40
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
41
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
42
|
+
if (r2) {
|
|
43
|
+
throw takeObject(r1);
|
|
44
|
+
}
|
|
45
|
+
return takeObject(r0);
|
|
46
|
+
} finally {
|
|
47
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function pixaContentInit() {
|
|
52
|
+
wasm.pixaContentInit();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Sanitize a JSON string. Every key validated, every string HTML-stripped,
|
|
57
|
+
* embedded JSON-in-strings rejected, base64 images allowed if valid.
|
|
58
|
+
*
|
|
59
|
+
* This is the single entry point for ALL metadata sanitization.
|
|
60
|
+
* @param {string} json_str
|
|
61
|
+
* @returns {any}
|
|
62
|
+
*/
|
|
63
|
+
export function safeJson(json_str) {
|
|
64
|
+
try {
|
|
65
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
66
|
+
const ptr0 = passStringToWasm0(json_str, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
67
|
+
const len0 = WASM_VECTOR_LEN;
|
|
68
|
+
wasm.safeJson(retptr, ptr0, len0);
|
|
69
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
70
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
71
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
72
|
+
if (r2) {
|
|
73
|
+
throw takeObject(r1);
|
|
74
|
+
}
|
|
75
|
+
return takeObject(r0);
|
|
76
|
+
} finally {
|
|
77
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Sanitize a single string value. Strips HTML, rejects embedded JSON,
|
|
83
|
+
* rejects dangerous URI schemes, allows validated base64 images.
|
|
84
|
+
*
|
|
85
|
+
* Used by JS pipeline for title, category, and other text fields.
|
|
86
|
+
* @param {string} s
|
|
87
|
+
* @param {number} max_len
|
|
88
|
+
* @returns {string | undefined}
|
|
89
|
+
*/
|
|
90
|
+
export function safeString(s, max_len) {
|
|
91
|
+
try {
|
|
92
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
93
|
+
const ptr0 = passStringToWasm0(s, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
94
|
+
const len0 = WASM_VECTOR_LEN;
|
|
95
|
+
wasm.safeString(retptr, ptr0, len0, max_len);
|
|
96
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
97
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
98
|
+
let v2;
|
|
99
|
+
if (r0 !== 0) {
|
|
100
|
+
v2 = getStringFromWasm0(r0, r1).slice();
|
|
101
|
+
wasm.__wbindgen_export3(r0, r1 * 1, 1);
|
|
102
|
+
}
|
|
103
|
+
return v2;
|
|
104
|
+
} finally {
|
|
105
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Sanitize a user biography — returns plain text only (no HTML).
|
|
111
|
+
* @param {string} bio
|
|
112
|
+
* @param {number} max_length
|
|
113
|
+
* @returns {string}
|
|
114
|
+
*/
|
|
115
|
+
export function sanitizeBiography(bio, max_length) {
|
|
116
|
+
let deferred2_0;
|
|
117
|
+
let deferred2_1;
|
|
118
|
+
try {
|
|
119
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
120
|
+
const ptr0 = passStringToWasm0(bio, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
121
|
+
const len0 = WASM_VECTOR_LEN;
|
|
122
|
+
wasm.sanitizeBiography(retptr, ptr0, len0, max_length);
|
|
123
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
124
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
125
|
+
deferred2_0 = r0;
|
|
126
|
+
deferred2_1 = r1;
|
|
127
|
+
return getStringFromWasm0(r0, r1);
|
|
128
|
+
} finally {
|
|
129
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
130
|
+
wasm.__wbindgen_export3(deferred2_0, deferred2_1, 1);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Sanitize a comment body.
|
|
136
|
+
* Everything in memo + lists, blockquotes, code, links.
|
|
137
|
+
* No images, no headings, no tables.
|
|
138
|
+
* @param {string} body
|
|
139
|
+
* @param {string} options_json
|
|
140
|
+
* @returns {any}
|
|
141
|
+
*/
|
|
142
|
+
export function sanitizeComment(body, options_json) {
|
|
143
|
+
try {
|
|
144
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
145
|
+
const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
146
|
+
const len0 = WASM_VECTOR_LEN;
|
|
147
|
+
const ptr1 = passStringToWasm0(options_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
148
|
+
const len1 = WASM_VECTOR_LEN;
|
|
149
|
+
wasm.sanitizeComment(retptr, ptr0, len0, ptr1, len1);
|
|
150
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
151
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
152
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
153
|
+
if (r2) {
|
|
154
|
+
throw takeObject(r1);
|
|
155
|
+
}
|
|
156
|
+
return takeObject(r0);
|
|
157
|
+
} finally {
|
|
158
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Sanitize a transaction memo.
|
|
164
|
+
* Bold, italic, @mentions, #hashtags. No images, no lists, no blocks.
|
|
165
|
+
* @param {string} body
|
|
166
|
+
* @param {string} options_json
|
|
167
|
+
* @returns {any}
|
|
168
|
+
*/
|
|
169
|
+
export function sanitizeMemo(body, options_json) {
|
|
170
|
+
try {
|
|
171
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
172
|
+
const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
173
|
+
const len0 = WASM_VECTOR_LEN;
|
|
174
|
+
const ptr1 = passStringToWasm0(options_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
175
|
+
const len1 = WASM_VECTOR_LEN;
|
|
176
|
+
wasm.sanitizeMemo(retptr, ptr0, len0, ptr1, len1);
|
|
177
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
178
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
179
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
180
|
+
if (r2) {
|
|
181
|
+
throw takeObject(r1);
|
|
182
|
+
}
|
|
183
|
+
return takeObject(r0);
|
|
184
|
+
} finally {
|
|
185
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Sanitize a post body. Full markdown → HTML.
|
|
191
|
+
* Returns sanitized HTML + extracted images (including base64) + links.
|
|
192
|
+
* @param {string} body
|
|
193
|
+
* @param {string} options_json
|
|
194
|
+
* @returns {any}
|
|
195
|
+
*/
|
|
196
|
+
export function sanitizePost(body, options_json) {
|
|
197
|
+
try {
|
|
198
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
199
|
+
const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
200
|
+
const len0 = WASM_VECTOR_LEN;
|
|
201
|
+
const ptr1 = passStringToWasm0(options_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
202
|
+
const len1 = WASM_VECTOR_LEN;
|
|
203
|
+
wasm.sanitizePost(retptr, ptr0, len0, ptr1, len1);
|
|
204
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
205
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
206
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
207
|
+
if (r2) {
|
|
208
|
+
throw takeObject(r1);
|
|
209
|
+
}
|
|
210
|
+
return takeObject(r0);
|
|
211
|
+
} finally {
|
|
212
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Sanitize a username — alphanumeric, dots, hyphens only.
|
|
218
|
+
* @param {string} username
|
|
219
|
+
* @returns {string}
|
|
220
|
+
*/
|
|
221
|
+
export function sanitizeUsername(username) {
|
|
222
|
+
let deferred2_0;
|
|
223
|
+
let deferred2_1;
|
|
224
|
+
try {
|
|
225
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
226
|
+
const ptr0 = passStringToWasm0(username, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
227
|
+
const len0 = WASM_VECTOR_LEN;
|
|
228
|
+
wasm.sanitizeUsername(retptr, ptr0, len0);
|
|
229
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
230
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
231
|
+
deferred2_0 = r0;
|
|
232
|
+
deferred2_1 = r1;
|
|
233
|
+
return getStringFromWasm0(r0, r1);
|
|
234
|
+
} finally {
|
|
235
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
236
|
+
wasm.__wbindgen_export3(deferred2_0, deferred2_1, 1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* TF-IDF summarization.
|
|
242
|
+
* @param {string} body
|
|
243
|
+
* @param {number} sentence_count
|
|
244
|
+
* @returns {any}
|
|
245
|
+
*/
|
|
246
|
+
export function summarizeContent(body, sentence_count) {
|
|
247
|
+
try {
|
|
248
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
249
|
+
const ptr0 = passStringToWasm0(body, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
250
|
+
const len0 = WASM_VECTOR_LEN;
|
|
251
|
+
wasm.summarizeContent(retptr, ptr0, len0, sentence_count);
|
|
252
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
253
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
254
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
255
|
+
if (r2) {
|
|
256
|
+
throw takeObject(r1);
|
|
257
|
+
}
|
|
258
|
+
return takeObject(r0);
|
|
259
|
+
} finally {
|
|
260
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function __wbg_get_imports() {
|
|
265
|
+
const import0 = {
|
|
266
|
+
__proto__: null,
|
|
267
|
+
__wbg_Error_8c4e43fe74559d73: function(arg0, arg1) {
|
|
268
|
+
const ret = Error(getStringFromWasm0(arg0, arg1));
|
|
269
|
+
return addHeapObject(ret);
|
|
270
|
+
},
|
|
271
|
+
__wbg_String_8f0eb39a4a4c2f66: function(arg0, arg1) {
|
|
272
|
+
const ret = String(getObject(arg1));
|
|
273
|
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
274
|
+
const len1 = WASM_VECTOR_LEN;
|
|
275
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
276
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
277
|
+
},
|
|
278
|
+
__wbg___wbindgen_is_string_cd444516edc5b180: function(arg0) {
|
|
279
|
+
const ret = typeof(getObject(arg0)) === 'string';
|
|
280
|
+
return ret;
|
|
281
|
+
},
|
|
282
|
+
__wbg___wbindgen_throw_be289d5034ed271b: function(arg0, arg1) {
|
|
283
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
284
|
+
},
|
|
285
|
+
__wbg_error_7534b8e9a36f1ab4: function(arg0, arg1) {
|
|
286
|
+
let deferred0_0;
|
|
287
|
+
let deferred0_1;
|
|
288
|
+
try {
|
|
289
|
+
deferred0_0 = arg0;
|
|
290
|
+
deferred0_1 = arg1;
|
|
291
|
+
console.error(getStringFromWasm0(arg0, arg1));
|
|
292
|
+
} finally {
|
|
293
|
+
wasm.__wbindgen_export3(deferred0_0, deferred0_1, 1);
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
__wbg_new_361308b2356cecd0: function() {
|
|
297
|
+
const ret = new Object();
|
|
298
|
+
return addHeapObject(ret);
|
|
299
|
+
},
|
|
300
|
+
__wbg_new_3eb36ae241fe6f44: function() {
|
|
301
|
+
const ret = new Array();
|
|
302
|
+
return addHeapObject(ret);
|
|
303
|
+
},
|
|
304
|
+
__wbg_new_8a6f238a6ece86ea: function() {
|
|
305
|
+
const ret = new Error();
|
|
306
|
+
return addHeapObject(ret);
|
|
307
|
+
},
|
|
308
|
+
__wbg_new_dca287b076112a51: function() {
|
|
309
|
+
const ret = new Map();
|
|
310
|
+
return addHeapObject(ret);
|
|
311
|
+
},
|
|
312
|
+
__wbg_set_1eb0999cf5d27fc8: function(arg0, arg1, arg2) {
|
|
313
|
+
const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
|
|
314
|
+
return addHeapObject(ret);
|
|
315
|
+
},
|
|
316
|
+
__wbg_set_3f1d0b984ed272ed: function(arg0, arg1, arg2) {
|
|
317
|
+
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
|
|
318
|
+
},
|
|
319
|
+
__wbg_set_f43e577aea94465b: function(arg0, arg1, arg2) {
|
|
320
|
+
getObject(arg0)[arg1 >>> 0] = takeObject(arg2);
|
|
321
|
+
},
|
|
322
|
+
__wbg_stack_0ed75d68575b0f3c: function(arg0, arg1) {
|
|
323
|
+
const ret = getObject(arg1).stack;
|
|
324
|
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
325
|
+
const len1 = WASM_VECTOR_LEN;
|
|
326
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
327
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
328
|
+
},
|
|
329
|
+
__wbindgen_cast_0000000000000001: function(arg0) {
|
|
330
|
+
// Cast intrinsic for `F64 -> Externref`.
|
|
331
|
+
const ret = arg0;
|
|
332
|
+
return addHeapObject(ret);
|
|
333
|
+
},
|
|
334
|
+
__wbindgen_cast_0000000000000002: function(arg0) {
|
|
335
|
+
// Cast intrinsic for `I64 -> Externref`.
|
|
336
|
+
const ret = arg0;
|
|
337
|
+
return addHeapObject(ret);
|
|
338
|
+
},
|
|
339
|
+
__wbindgen_cast_0000000000000003: function(arg0, arg1) {
|
|
340
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
341
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
342
|
+
return addHeapObject(ret);
|
|
343
|
+
},
|
|
344
|
+
__wbindgen_cast_0000000000000004: function(arg0) {
|
|
345
|
+
// Cast intrinsic for `U64 -> Externref`.
|
|
346
|
+
const ret = BigInt.asUintN(64, arg0);
|
|
347
|
+
return addHeapObject(ret);
|
|
348
|
+
},
|
|
349
|
+
__wbindgen_object_clone_ref: function(arg0) {
|
|
350
|
+
const ret = getObject(arg0);
|
|
351
|
+
return addHeapObject(ret);
|
|
352
|
+
},
|
|
353
|
+
__wbindgen_object_drop_ref: function(arg0) {
|
|
354
|
+
takeObject(arg0);
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
return {
|
|
358
|
+
__proto__: null,
|
|
359
|
+
"./pixa_content_bg.js": import0,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function addHeapObject(obj) {
|
|
364
|
+
if (heap_next === heap.length) heap.push(heap.length + 1);
|
|
365
|
+
const idx = heap_next;
|
|
366
|
+
heap_next = heap[idx];
|
|
367
|
+
|
|
368
|
+
heap[idx] = obj;
|
|
369
|
+
return idx;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function dropObject(idx) {
|
|
373
|
+
if (idx < 132) return;
|
|
374
|
+
heap[idx] = heap_next;
|
|
375
|
+
heap_next = idx;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
let cachedDataViewMemory0 = null;
|
|
379
|
+
function getDataViewMemory0() {
|
|
380
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
381
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
382
|
+
}
|
|
383
|
+
return cachedDataViewMemory0;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function getStringFromWasm0(ptr, len) {
|
|
387
|
+
ptr = ptr >>> 0;
|
|
388
|
+
return decodeText(ptr, len);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
let cachedUint8ArrayMemory0 = null;
|
|
392
|
+
function getUint8ArrayMemory0() {
|
|
393
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
394
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
395
|
+
}
|
|
396
|
+
return cachedUint8ArrayMemory0;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function getObject(idx) { return heap[idx]; }
|
|
400
|
+
|
|
401
|
+
let heap = new Array(128).fill(undefined);
|
|
402
|
+
heap.push(undefined, null, true, false);
|
|
403
|
+
|
|
404
|
+
let heap_next = heap.length;
|
|
405
|
+
|
|
406
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
407
|
+
if (realloc === undefined) {
|
|
408
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
409
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
410
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
411
|
+
WASM_VECTOR_LEN = buf.length;
|
|
412
|
+
return ptr;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
let len = arg.length;
|
|
416
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
417
|
+
|
|
418
|
+
const mem = getUint8ArrayMemory0();
|
|
419
|
+
|
|
420
|
+
let offset = 0;
|
|
421
|
+
|
|
422
|
+
for (; offset < len; offset++) {
|
|
423
|
+
const code = arg.charCodeAt(offset);
|
|
424
|
+
if (code > 0x7F) break;
|
|
425
|
+
mem[ptr + offset] = code;
|
|
426
|
+
}
|
|
427
|
+
if (offset !== len) {
|
|
428
|
+
if (offset !== 0) {
|
|
429
|
+
arg = arg.slice(offset);
|
|
430
|
+
}
|
|
431
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
432
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
433
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
434
|
+
|
|
435
|
+
offset += ret.written;
|
|
436
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
WASM_VECTOR_LEN = offset;
|
|
440
|
+
return ptr;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function takeObject(idx) {
|
|
444
|
+
const ret = getObject(idx);
|
|
445
|
+
dropObject(idx);
|
|
446
|
+
return ret;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
450
|
+
cachedTextDecoder.decode();
|
|
451
|
+
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
|
452
|
+
let numBytesDecoded = 0;
|
|
453
|
+
function decodeText(ptr, len) {
|
|
454
|
+
numBytesDecoded += len;
|
|
455
|
+
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
|
456
|
+
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
457
|
+
cachedTextDecoder.decode();
|
|
458
|
+
numBytesDecoded = len;
|
|
459
|
+
}
|
|
460
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const cachedTextEncoder = new TextEncoder();
|
|
464
|
+
|
|
465
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
466
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
467
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
468
|
+
view.set(buf);
|
|
469
|
+
return {
|
|
470
|
+
read: arg.length,
|
|
471
|
+
written: buf.length
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
let WASM_VECTOR_LEN = 0;
|
|
477
|
+
|
|
478
|
+
let wasmModule, wasm;
|
|
479
|
+
function __wbg_finalize_init(instance, module) {
|
|
480
|
+
wasm = instance.exports;
|
|
481
|
+
wasmModule = module;
|
|
482
|
+
cachedDataViewMemory0 = null;
|
|
483
|
+
cachedUint8ArrayMemory0 = null;
|
|
484
|
+
return wasm;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
async function __wbg_load(module, imports) {
|
|
488
|
+
if (typeof Response === 'function' && module instanceof Response) {
|
|
489
|
+
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
|
490
|
+
try {
|
|
491
|
+
return await WebAssembly.instantiateStreaming(module, imports);
|
|
492
|
+
} catch (e) {
|
|
493
|
+
const validResponse = module.ok && expectedResponseType(module.type);
|
|
494
|
+
|
|
495
|
+
if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
|
|
496
|
+
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
|
497
|
+
|
|
498
|
+
} else { throw e; }
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const bytes = await module.arrayBuffer();
|
|
503
|
+
return await WebAssembly.instantiate(bytes, imports);
|
|
504
|
+
} else {
|
|
505
|
+
const instance = await WebAssembly.instantiate(module, imports);
|
|
506
|
+
|
|
507
|
+
if (instance instanceof WebAssembly.Instance) {
|
|
508
|
+
return { instance, module };
|
|
509
|
+
} else {
|
|
510
|
+
return instance;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function expectedResponseType(type) {
|
|
515
|
+
switch (type) {
|
|
516
|
+
case 'basic': case 'cors': case 'default': return true;
|
|
517
|
+
}
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function initSync(module) {
|
|
523
|
+
if (wasm !== undefined) return wasm;
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
if (module !== undefined) {
|
|
527
|
+
if (Object.getPrototypeOf(module) === Object.prototype) {
|
|
528
|
+
({module} = module)
|
|
529
|
+
} else {
|
|
530
|
+
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
const imports = __wbg_get_imports();
|
|
535
|
+
if (!(module instanceof WebAssembly.Module)) {
|
|
536
|
+
module = new WebAssembly.Module(module);
|
|
537
|
+
}
|
|
538
|
+
const instance = new WebAssembly.Instance(module, imports);
|
|
539
|
+
return __wbg_finalize_init(instance, module);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
async function __wbg_init(module_or_path) {
|
|
543
|
+
if (wasm !== undefined) return wasm;
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
if (module_or_path !== undefined) {
|
|
547
|
+
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
|
|
548
|
+
({module_or_path} = module_or_path)
|
|
549
|
+
} else {
|
|
550
|
+
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (module_or_path === undefined) {
|
|
555
|
+
module_or_path = new URL('pixa_content_bg.wasm', import.meta.url);
|
|
556
|
+
}
|
|
557
|
+
const imports = __wbg_get_imports();
|
|
558
|
+
|
|
559
|
+
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
|
|
560
|
+
module_or_path = fetch(module_or_path);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const { instance, module } = await __wbg_load(await module_or_path, imports);
|
|
564
|
+
|
|
565
|
+
return __wbg_finalize_init(instance, module);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export { initSync, __wbg_init as default };
|
|
Binary file
|