textmode.js 0.0.5 → 0.0.7
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/textmode.esm.js +913 -732
- package/dist/textmode.umd.js +4 -4
- package/dist/types/ColorPalette.d.ts +2 -2
- package/dist/types/Textmode.d.ts +2 -2
- package/dist/types/index.d.ts +9 -2
- package/dist/types/rendering/core/AbstractFramebuffer.d.ts +1 -0
- package/dist/types/rendering/core/AbstractGeometry.d.ts +1 -0
- package/dist/types/rendering/core/AbstractShader.d.ts +1 -0
- package/dist/types/rendering/core/AbstractTexture.d.ts +1 -0
- package/dist/types/rendering/core/GraphicsContext.d.ts +1 -0
- package/dist/types/rendering/{Framebuffer.d.ts → webgl/Framebuffer.d.ts} +8 -8
- package/dist/types/rendering/{Renderer.d.ts → webgl/Renderer.d.ts} +0 -1
- package/dist/types/textmode/ConversionPipeline.d.ts +3 -3
- package/dist/types/textmode/Grid.d.ts +14 -33
- package/dist/types/textmode/Textmodifier.d.ts +2 -2
- package/dist/types/textmode/converters/BrightnessConverter.d.ts +13 -3
- package/dist/types/textmode/converters/Converter.d.ts +16 -4
- package/dist/types/textmode/converters/FeatureConverter.d.ts +54 -5
- package/dist/types/textmode/font/CharacterColorMapper.d.ts +33 -0
- package/dist/types/textmode/font/CharacterExtractor.d.ts +45 -0
- package/dist/types/textmode/font/MetricsCalculator.d.ts +22 -0
- package/dist/types/textmode/{Font.d.ts → font/TextmodeFont.d.ts} +24 -39
- package/dist/types/textmode/font/TextureAtlas.d.ts +53 -0
- package/dist/types/textmode/font/index.d.ts +6 -0
- package/dist/types/textmode/font/types.d.ts +42 -0
- package/package.json +1 -1
- /package/dist/types/rendering/{Shader.d.ts → webgl/Shader.d.ts} +0 -0
- /package/dist/types/rendering/{geometries → webgl/geometries}/Rectangle.d.ts +0 -0
package/dist/textmode.esm.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
var F = Object.defineProperty;
|
|
2
|
-
var y = (
|
|
3
|
-
var
|
|
4
|
-
class
|
|
5
|
-
constructor(
|
|
6
|
-
const B =
|
|
2
|
+
var y = (s, A, e) => A in s ? F(s, A, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[A] = e;
|
|
3
|
+
var Q = (s, A, e) => y(s, typeof A != "symbol" ? A + "" : A, e);
|
|
4
|
+
class D extends Error {
|
|
5
|
+
constructor(e, t, r = {}) {
|
|
6
|
+
const B = D.createFormattedMessage(e, r);
|
|
7
7
|
super(B);
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Q(this, "originalError");
|
|
9
|
+
Q(this, "context");
|
|
10
10
|
this.name = "TextmodeError", this.originalError = t, this.context = r;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Create a formatted error message that includes context
|
|
14
14
|
*/
|
|
15
|
-
static createFormattedMessage(
|
|
16
|
-
let r =
|
|
15
|
+
static createFormattedMessage(e, t) {
|
|
16
|
+
let r = e;
|
|
17
17
|
if (t && Object.keys(t).length > 0) {
|
|
18
18
|
r += `
|
|
19
19
|
|
|
20
20
|
📋 Context:`;
|
|
21
|
-
for (const [B,
|
|
22
|
-
const g =
|
|
21
|
+
for (const [B, E] of Object.entries(t)) {
|
|
22
|
+
const g = D.formatValue(E);
|
|
23
23
|
r += `
|
|
24
24
|
- ${B}: ${g}`;
|
|
25
25
|
}
|
|
@@ -32,36 +32,36 @@ class C extends Error {
|
|
|
32
32
|
/**
|
|
33
33
|
* Format values for better display in error messages
|
|
34
34
|
*/
|
|
35
|
-
static formatValue(
|
|
36
|
-
if (
|
|
37
|
-
if (
|
|
38
|
-
if (typeof
|
|
39
|
-
if (typeof
|
|
40
|
-
if (Array.isArray(
|
|
41
|
-
return
|
|
42
|
-
if (typeof
|
|
43
|
-
const t = Object.keys(
|
|
44
|
-
return t.length === 0 ? "{}" : t.length <= 3 ? `{ ${t.map((
|
|
35
|
+
static formatValue(e) {
|
|
36
|
+
if (e === null) return "null";
|
|
37
|
+
if (e === void 0) return "undefined";
|
|
38
|
+
if (typeof e == "string") return `"${e}"`;
|
|
39
|
+
if (typeof e == "number" || typeof e == "boolean") return String(e);
|
|
40
|
+
if (Array.isArray(e))
|
|
41
|
+
return e.length === 0 ? "[]" : e.length <= 5 ? `[${e.map((t) => D.formatValue(t)).join(", ")}]` : `[${e.slice(0, 3).map((t) => D.formatValue(t)).join(", ")}, ... +${e.length - 3} more]`;
|
|
42
|
+
if (typeof e == "object") {
|
|
43
|
+
const t = Object.keys(e);
|
|
44
|
+
return t.length === 0 ? "{}" : t.length <= 3 ? `{ ${t.map((E) => `${E}: ${D.formatValue(e[E])}`).join(", ")} }` : `{ ${t.slice(0, 2).map((B) => `${B}: ${D.formatValue(e[B])}`).join(", ")}, ... +${t.length - 2} more }`;
|
|
45
45
|
}
|
|
46
|
-
return String(
|
|
46
|
+
return String(e);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
var
|
|
50
|
-
const
|
|
49
|
+
var T = /* @__PURE__ */ ((s) => (s[s.SILENT = 0] = "SILENT", s[s.WARNING = 1] = "WARNING", s[s.ERROR = 2] = "ERROR", s[s.THROW = 3] = "THROW", s))(T || {});
|
|
50
|
+
const c = class c {
|
|
51
51
|
constructor() {
|
|
52
|
-
|
|
52
|
+
Q(this, "_options", {
|
|
53
53
|
globalLevel: 3
|
|
54
54
|
/* THROW */
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
static getInstance() {
|
|
58
|
-
return
|
|
58
|
+
return c._instance || (c._instance = new c()), c._instance;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
61
|
* Handle an error based on the configured settings
|
|
62
62
|
* @returns true if execution should continue, false if error was handled
|
|
63
63
|
*/
|
|
64
|
-
_handle(
|
|
64
|
+
_handle(A, e, t) {
|
|
65
65
|
const r = "[textmode.js]";
|
|
66
66
|
switch (this._options.globalLevel) {
|
|
67
67
|
case 0:
|
|
@@ -71,15 +71,15 @@ const l = class l {
|
|
|
71
71
|
return console.group(
|
|
72
72
|
`%c${r} Oops! (╯°□°)╯︵ Something went wrong in your code.`,
|
|
73
73
|
"color: #f44336; font-weight: bold; background: #ffebee; padding: 2px 6px; border-radius: 3px;"
|
|
74
|
-
), console.warn(
|
|
74
|
+
), console.warn(D.createFormattedMessage(A, e)), console.groupEnd(), !1;
|
|
75
75
|
case 2:
|
|
76
76
|
return console.group(
|
|
77
77
|
`%c${r} Oops! (╯°□°)╯︵ Something went wrong in your code.`,
|
|
78
78
|
"color: #f44336; font-weight: bold; background: #ffebee; padding: 2px 6px; border-radius: 3px;"
|
|
79
|
-
), console.error(
|
|
79
|
+
), console.error(D.createFormattedMessage(A, e)), console.groupEnd(), !1;
|
|
80
80
|
case 3:
|
|
81
81
|
default:
|
|
82
|
-
const B = new
|
|
82
|
+
const B = new D(A, t, e);
|
|
83
83
|
throw console.group(
|
|
84
84
|
`%c${r} Oops! (╯°□°)╯︵ Something went wrong in your code.`,
|
|
85
85
|
"color: #d32f2f; font-weight: bold; background: #ffcdd2; padding: 2px 6px; border-radius: 3px;"
|
|
@@ -93,117 +93,87 @@ const l = class l {
|
|
|
93
93
|
* @param context Additional context for debugging
|
|
94
94
|
* @returns true if validation passed, false if validation failed and was handled
|
|
95
95
|
*/
|
|
96
|
-
validate(
|
|
97
|
-
return
|
|
96
|
+
validate(A, e, t) {
|
|
97
|
+
return A ? !0 : (this._handle(e, t), !1);
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Set global error level
|
|
101
101
|
*/
|
|
102
|
-
setGlobalLevel(
|
|
103
|
-
this._options.globalLevel =
|
|
102
|
+
setGlobalLevel(A) {
|
|
103
|
+
this._options.globalLevel = A;
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
|
|
107
|
-
let I =
|
|
108
|
-
const
|
|
106
|
+
Q(c, "_instance", null);
|
|
107
|
+
let I = c;
|
|
108
|
+
const C = I.getInstance();
|
|
109
109
|
class M {
|
|
110
|
-
constructor(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.gl = e, this._width = A, this._height = t, this.options = {
|
|
110
|
+
constructor(A, e, t = e, r = {}) {
|
|
111
|
+
Q(this, "gl");
|
|
112
|
+
Q(this, "_framebuffer");
|
|
113
|
+
Q(this, "_texture");
|
|
114
|
+
Q(this, "_width");
|
|
115
|
+
Q(this, "_height");
|
|
116
|
+
Q(this, "options");
|
|
117
|
+
Q(this, "previousState", null);
|
|
118
|
+
this.gl = A, this._width = e, this._height = t, this.options = {
|
|
120
119
|
filter: "nearest",
|
|
121
120
|
wrap: "clamp",
|
|
122
121
|
format: "rgba",
|
|
123
122
|
type: "unsigned_byte",
|
|
124
123
|
...r
|
|
125
|
-
}, this._texture = this.createTexture(), this._framebuffer =
|
|
124
|
+
}, this._texture = this.createTexture(), this._framebuffer = A.createFramebuffer(), this.attachTexture();
|
|
126
125
|
}
|
|
127
126
|
createTexture() {
|
|
128
|
-
const e =
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
r,
|
|
137
|
-
this._width,
|
|
138
|
-
this._height,
|
|
139
|
-
0,
|
|
140
|
-
r,
|
|
141
|
-
B,
|
|
142
|
-
null
|
|
143
|
-
), this.gl.bindTexture(this.gl.TEXTURE_2D, null), e;
|
|
127
|
+
const { gl: A } = this, e = A.createTexture();
|
|
128
|
+
A.bindTexture(A.TEXTURE_2D, e);
|
|
129
|
+
const t = this.options.filter === "linear" ? A.LINEAR : A.NEAREST, r = this.options.wrap === "repeat" ? A.REPEAT : A.CLAMP_TO_EDGE;
|
|
130
|
+
return A.texParameteri(A.TEXTURE_2D, A.TEXTURE_MIN_FILTER, t), A.texParameteri(A.TEXTURE_2D, A.TEXTURE_MAG_FILTER, t), A.texParameteri(A.TEXTURE_2D, A.TEXTURE_WRAP_S, r), A.texParameteri(A.TEXTURE_2D, A.TEXTURE_WRAP_T, r), this.updateTextureSize(), e;
|
|
131
|
+
}
|
|
132
|
+
updateTextureSize() {
|
|
133
|
+
const { gl: A } = this, e = this.options.format === "rgb" ? A.RGB : A.RGBA, t = this.options.type === "float" ? A.FLOAT : A.UNSIGNED_BYTE;
|
|
134
|
+
A.texImage2D(A.TEXTURE_2D, 0, e, this._width, this._height, 0, e, t, null);
|
|
144
135
|
}
|
|
145
136
|
attachTexture() {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
this.gl.COLOR_ATTACHMENT0,
|
|
149
|
-
this.gl.TEXTURE_2D,
|
|
150
|
-
this._texture,
|
|
151
|
-
0
|
|
152
|
-
), this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
|
|
137
|
+
const { gl: A } = this;
|
|
138
|
+
A.bindFramebuffer(A.FRAMEBUFFER, this._framebuffer), A.framebufferTexture2D(A.FRAMEBUFFER, A.COLOR_ATTACHMENT0, A.TEXTURE_2D, this._texture, 0), A.bindFramebuffer(A.FRAMEBUFFER, null);
|
|
153
139
|
}
|
|
154
140
|
/**
|
|
155
141
|
* Update the framebuffer texture with canvas content
|
|
156
142
|
*/
|
|
157
|
-
update(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
0,
|
|
161
|
-
this.gl.RGBA,
|
|
162
|
-
this.gl.RGBA,
|
|
163
|
-
this.gl.UNSIGNED_BYTE,
|
|
164
|
-
e
|
|
165
|
-
), this.gl.bindTexture(this.gl.TEXTURE_2D, null);
|
|
143
|
+
update(A) {
|
|
144
|
+
const { gl: e } = this;
|
|
145
|
+
e.bindTexture(e.TEXTURE_2D, this._texture), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, A), e.bindTexture(e.TEXTURE_2D, null);
|
|
166
146
|
}
|
|
167
147
|
/**
|
|
168
|
-
*
|
|
148
|
+
* Update the framebuffer texture with pixel data
|
|
169
149
|
*/
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.gl.texImage2D(
|
|
174
|
-
this.gl.TEXTURE_2D,
|
|
175
|
-
0,
|
|
176
|
-
t,
|
|
177
|
-
this._width,
|
|
178
|
-
this._height,
|
|
179
|
-
0,
|
|
180
|
-
t,
|
|
181
|
-
r,
|
|
182
|
-
null
|
|
183
|
-
);
|
|
150
|
+
updatePixels(A, e, t) {
|
|
151
|
+
const { gl: r } = this;
|
|
152
|
+
r.bindTexture(r.TEXTURE_2D, this._texture), r.texImage2D(r.TEXTURE_2D, 0, r.RGBA, e, t, 0, r.RGBA, r.UNSIGNED_BYTE, A), r.bindTexture(r.TEXTURE_2D, null);
|
|
184
153
|
}
|
|
185
154
|
/**
|
|
186
|
-
*
|
|
155
|
+
* Resize the framebuffer
|
|
187
156
|
*/
|
|
188
|
-
|
|
189
|
-
this.
|
|
157
|
+
resize(A, e) {
|
|
158
|
+
this._width = A, this._height = e, this.gl.bindTexture(this.gl.TEXTURE_2D, this._texture), this.updateTextureSize(), this.gl.bindTexture(this.gl.TEXTURE_2D, null);
|
|
190
159
|
}
|
|
191
160
|
/**
|
|
192
|
-
*
|
|
161
|
+
* Begin rendering to this framebuffer
|
|
193
162
|
*/
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
);
|
|
163
|
+
begin() {
|
|
164
|
+
const { gl: A } = this;
|
|
165
|
+
this.previousState = {
|
|
166
|
+
framebuffer: A.getParameter(A.FRAMEBUFFER_BINDING),
|
|
167
|
+
viewport: A.getParameter(A.VIEWPORT)
|
|
168
|
+
}, A.bindFramebuffer(A.FRAMEBUFFER, this._framebuffer), A.viewport(0, 0, this._width, this._height);
|
|
201
169
|
}
|
|
202
170
|
/**
|
|
203
|
-
*
|
|
171
|
+
* End rendering to this framebuffer and restore previous state
|
|
204
172
|
*/
|
|
205
|
-
|
|
206
|
-
|
|
173
|
+
end() {
|
|
174
|
+
if (!this.previousState) return;
|
|
175
|
+
const { gl: A } = this;
|
|
176
|
+
A.bindFramebuffer(A.FRAMEBUFFER, this.previousState.framebuffer), A.viewport(...this.previousState.viewport), this.previousState = null;
|
|
207
177
|
}
|
|
208
178
|
// Getters
|
|
209
179
|
get framebuffer() {
|
|
@@ -219,22 +189,22 @@ class M {
|
|
|
219
189
|
return this._height;
|
|
220
190
|
}
|
|
221
191
|
}
|
|
222
|
-
class
|
|
223
|
-
constructor(
|
|
192
|
+
class G {
|
|
193
|
+
constructor(A, e, t, r, B) {
|
|
224
194
|
/** The WebGL rendering context */
|
|
225
|
-
|
|
195
|
+
Q(this, "gl");
|
|
226
196
|
/** The buffer containing the rectangle vertices */
|
|
227
|
-
|
|
197
|
+
Q(this, "buffer");
|
|
228
198
|
/** The number of vertices in the rectangle */
|
|
229
|
-
|
|
230
|
-
this.gl =
|
|
231
|
-
const
|
|
199
|
+
Q(this, "numVertices");
|
|
200
|
+
this.gl = A;
|
|
201
|
+
const E = A.getParameter(A.VIEWPORT), g = E[2], i = E[3];
|
|
232
202
|
if (g <= 0 || i <= 0)
|
|
233
203
|
throw new Error(`Invalid viewport dimensions: ${g}x${i}`);
|
|
234
|
-
const
|
|
235
|
-
(
|
|
236
|
-
const
|
|
237
|
-
|
|
204
|
+
const o = e / g * 2 - 1, n = 1 - t / i * 2, a = (e + r) / g * 2 - 1, h = 1 - (t + B) / i * 2;
|
|
205
|
+
(o < -1 || o > 1 || a < -1 || a > 1 || n < -1 || n > 1 || h < -1 || h > 1) && console.warn(`Rectangle coordinates outside NDC range: x1=${o}, y1=${n}, x2=${a}, y2=${h}`);
|
|
206
|
+
const u = A.getParameter(A.FRAMEBUFFER_BINDING) !== null ? new Float32Array([
|
|
207
|
+
o,
|
|
238
208
|
h,
|
|
239
209
|
0,
|
|
240
210
|
0,
|
|
@@ -244,13 +214,13 @@ class U {
|
|
|
244
214
|
1,
|
|
245
215
|
0,
|
|
246
216
|
// bottom-right
|
|
247
|
-
s,
|
|
248
217
|
o,
|
|
218
|
+
n,
|
|
249
219
|
0,
|
|
250
220
|
1,
|
|
251
221
|
// top-left
|
|
252
|
-
s,
|
|
253
222
|
o,
|
|
223
|
+
n,
|
|
254
224
|
0,
|
|
255
225
|
1,
|
|
256
226
|
// top-left
|
|
@@ -260,12 +230,12 @@ class U {
|
|
|
260
230
|
0,
|
|
261
231
|
// bottom-right
|
|
262
232
|
a,
|
|
263
|
-
|
|
233
|
+
n,
|
|
264
234
|
1,
|
|
265
235
|
1
|
|
266
236
|
// top-right
|
|
267
237
|
]) : new Float32Array([
|
|
268
|
-
|
|
238
|
+
o,
|
|
269
239
|
h,
|
|
270
240
|
0,
|
|
271
241
|
1,
|
|
@@ -275,13 +245,13 @@ class U {
|
|
|
275
245
|
1,
|
|
276
246
|
1,
|
|
277
247
|
// bottom-right
|
|
278
|
-
s,
|
|
279
248
|
o,
|
|
249
|
+
n,
|
|
280
250
|
0,
|
|
281
251
|
0,
|
|
282
252
|
// top-left
|
|
283
|
-
s,
|
|
284
253
|
o,
|
|
254
|
+
n,
|
|
285
255
|
0,
|
|
286
256
|
0,
|
|
287
257
|
// top-left
|
|
@@ -291,54 +261,54 @@ class U {
|
|
|
291
261
|
1,
|
|
292
262
|
// bottom-right
|
|
293
263
|
a,
|
|
294
|
-
|
|
264
|
+
n,
|
|
295
265
|
1,
|
|
296
266
|
0
|
|
297
267
|
// top-right
|
|
298
268
|
]);
|
|
299
|
-
this.numVertices = 6, this.buffer =
|
|
269
|
+
this.numVertices = 6, this.buffer = A.createBuffer(), A.bindBuffer(A.ARRAY_BUFFER, this.buffer), A.bufferData(A.ARRAY_BUFFER, u, A.STATIC_DRAW);
|
|
300
270
|
}
|
|
301
271
|
/**
|
|
302
272
|
* Draw the quad using attribute locations from the current shader
|
|
303
273
|
*/
|
|
304
274
|
draw() {
|
|
305
275
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
|
|
306
|
-
let
|
|
307
|
-
this.gl.enableVertexAttribArray(
|
|
276
|
+
let A = 0, e = 1;
|
|
277
|
+
this.gl.enableVertexAttribArray(A), this.gl.vertexAttribPointer(A, 2, this.gl.FLOAT, !1, 16, 0), this.gl.enableVertexAttribArray(e), this.gl.vertexAttribPointer(e, 2, this.gl.FLOAT, !1, 16, 8), this.gl.drawArrays(this.gl.TRIANGLES, 0, this.numVertices), this.gl.disableVertexAttribArray(A), this.gl.disableVertexAttribArray(e);
|
|
308
278
|
}
|
|
309
279
|
}
|
|
310
|
-
class
|
|
311
|
-
constructor(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
this.gl =
|
|
318
|
-
}
|
|
319
|
-
createProgram(
|
|
320
|
-
const t = this.createShader(this.gl.VERTEX_SHADER,
|
|
280
|
+
class l {
|
|
281
|
+
constructor(A, e, t) {
|
|
282
|
+
Q(this, "gl");
|
|
283
|
+
Q(this, "program");
|
|
284
|
+
Q(this, "uniformLocations", /* @__PURE__ */ new Map());
|
|
285
|
+
Q(this, "attributeLocations", /* @__PURE__ */ new Map());
|
|
286
|
+
Q(this, "textureUnitCounter", 0);
|
|
287
|
+
this.gl = A, this.program = this.createProgram(e, t), this.cacheLocations();
|
|
288
|
+
}
|
|
289
|
+
createProgram(A, e) {
|
|
290
|
+
const t = this.createShader(this.gl.VERTEX_SHADER, A), r = this.createShader(this.gl.FRAGMENT_SHADER, e), B = this.gl.createProgram();
|
|
321
291
|
if (this.gl.attachShader(B, t), this.gl.attachShader(B, r), this.gl.linkProgram(B), !this.gl.getProgramParameter(B, this.gl.LINK_STATUS)) {
|
|
322
|
-
const
|
|
323
|
-
throw new Error(`Shader program link error: ${
|
|
292
|
+
const E = this.gl.getProgramInfoLog(B);
|
|
293
|
+
throw new Error(`Shader program link error: ${E}`);
|
|
324
294
|
}
|
|
325
295
|
return this.gl.deleteShader(t), this.gl.deleteShader(r), B;
|
|
326
296
|
}
|
|
327
|
-
createShader(
|
|
328
|
-
const t = this.gl.createShader(
|
|
329
|
-
return this.gl.shaderSource(t,
|
|
297
|
+
createShader(A, e) {
|
|
298
|
+
const t = this.gl.createShader(A);
|
|
299
|
+
return this.gl.shaderSource(t, e), this.gl.compileShader(t), t;
|
|
330
300
|
}
|
|
331
301
|
cacheLocations() {
|
|
332
|
-
const
|
|
333
|
-
for (let t = 0; t <
|
|
302
|
+
const A = this.gl.getProgramParameter(this.program, this.gl.ACTIVE_UNIFORMS);
|
|
303
|
+
for (let t = 0; t < A; t++) {
|
|
334
304
|
const r = this.gl.getActiveUniform(this.program, t);
|
|
335
305
|
if (r) {
|
|
336
306
|
const B = this.gl.getUniformLocation(this.program, r.name);
|
|
337
307
|
B && this.uniformLocations.set(r.name, B);
|
|
338
308
|
}
|
|
339
309
|
}
|
|
340
|
-
const
|
|
341
|
-
for (let t = 0; t <
|
|
310
|
+
const e = this.gl.getProgramParameter(this.program, this.gl.ACTIVE_ATTRIBUTES);
|
|
311
|
+
for (let t = 0; t < e; t++) {
|
|
342
312
|
const r = this.gl.getActiveAttrib(this.program, t);
|
|
343
313
|
if (r) {
|
|
344
314
|
const B = this.gl.getAttribLocation(this.program, r.name);
|
|
@@ -355,34 +325,34 @@ class P {
|
|
|
355
325
|
/**
|
|
356
326
|
* Set a single uniform value with automatic texture unit management
|
|
357
327
|
*/
|
|
358
|
-
setUniform(
|
|
359
|
-
const t = this.uniformLocations.get(
|
|
360
|
-
if (typeof
|
|
361
|
-
this.gl.uniform1f(t,
|
|
362
|
-
else if (typeof
|
|
363
|
-
this.gl.uniform1i(t,
|
|
364
|
-
else if (Array.isArray(
|
|
365
|
-
switch (
|
|
328
|
+
setUniform(A, e) {
|
|
329
|
+
const t = this.uniformLocations.get(A);
|
|
330
|
+
if (typeof e == "number")
|
|
331
|
+
this.gl.uniform1f(t, e);
|
|
332
|
+
else if (typeof e == "boolean")
|
|
333
|
+
this.gl.uniform1i(t, e ? 1 : 0);
|
|
334
|
+
else if (Array.isArray(e))
|
|
335
|
+
switch (e.length) {
|
|
366
336
|
case 2:
|
|
367
|
-
this.gl.uniform2f(t,
|
|
337
|
+
this.gl.uniform2f(t, e[0], e[1]);
|
|
368
338
|
break;
|
|
369
339
|
case 3:
|
|
370
|
-
this.gl.uniform3f(t,
|
|
340
|
+
this.gl.uniform3f(t, e[0], e[1], e[2]);
|
|
371
341
|
break;
|
|
372
342
|
case 4:
|
|
373
|
-
this.gl.uniform4f(t,
|
|
343
|
+
this.gl.uniform4f(t, e[0], e[1], e[2], e[3]);
|
|
374
344
|
break;
|
|
375
345
|
default:
|
|
376
|
-
console.warn(`Unsupported array length ${
|
|
346
|
+
console.warn(`Unsupported array length ${e.length} for uniform '${A}'`);
|
|
377
347
|
}
|
|
378
|
-
else if (
|
|
348
|
+
else if (e instanceof WebGLTexture) {
|
|
379
349
|
const r = this.getNextTextureUnit();
|
|
380
|
-
this.gl.uniform1i(t, r), this.gl.activeTexture(this.gl.TEXTURE0 + r), this.gl.bindTexture(this.gl.TEXTURE_2D,
|
|
381
|
-
} else if (
|
|
350
|
+
this.gl.uniform1i(t, r), this.gl.activeTexture(this.gl.TEXTURE0 + r), this.gl.bindTexture(this.gl.TEXTURE_2D, e);
|
|
351
|
+
} else if (e && typeof e == "object" && "texture" in e) {
|
|
382
352
|
const r = this.getNextTextureUnit();
|
|
383
|
-
this.gl.uniform1i(t, r), this.gl.activeTexture(this.gl.TEXTURE0 + r), this.gl.bindTexture(this.gl.TEXTURE_2D,
|
|
353
|
+
this.gl.uniform1i(t, r), this.gl.activeTexture(this.gl.TEXTURE0 + r), this.gl.bindTexture(this.gl.TEXTURE_2D, e.texture);
|
|
384
354
|
} else
|
|
385
|
-
console.warn(`Unsupported uniform type for '${
|
|
355
|
+
console.warn(`Unsupported uniform type for '${A}':`, typeof e);
|
|
386
356
|
}
|
|
387
357
|
getNextTextureUnit() {
|
|
388
358
|
return this.textureUnitCounter++;
|
|
@@ -394,55 +364,52 @@ class P {
|
|
|
394
364
|
this.textureUnitCounter = 0;
|
|
395
365
|
}
|
|
396
366
|
}
|
|
397
|
-
var
|
|
367
|
+
var P = "attribute vec2 a_position;attribute vec2 a_texCoord;varying vec2 v_uv;void main(){v_uv=a_texCoord;gl_Position=vec4(a_position,0.0,1.0);}", U = "precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}";
|
|
398
368
|
class R {
|
|
399
|
-
constructor(
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
this.gl =
|
|
404
|
-
}
|
|
405
|
-
setupDefaultState() {
|
|
406
|
-
this.gl.enable(this.gl.BLEND), this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA), this.gl.disable(this.gl.DEPTH_TEST);
|
|
369
|
+
constructor(A) {
|
|
370
|
+
Q(this, "gl");
|
|
371
|
+
Q(this, "imageShader");
|
|
372
|
+
Q(this, "currentShader", null);
|
|
373
|
+
this.gl = A, this.imageShader = new l(this.gl, P, U), this.gl.enable(this.gl.BLEND), this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
|
|
407
374
|
}
|
|
408
375
|
/**
|
|
409
376
|
* Set the current shader (p5.js-like API)
|
|
410
377
|
*/
|
|
411
|
-
shader(
|
|
412
|
-
this.currentShader =
|
|
378
|
+
shader(A) {
|
|
379
|
+
this.currentShader = A, A.use();
|
|
413
380
|
}
|
|
414
|
-
createShader(
|
|
415
|
-
return new
|
|
381
|
+
createShader(A, e) {
|
|
382
|
+
return new l(this.gl, A, e);
|
|
416
383
|
}
|
|
417
384
|
/**
|
|
418
385
|
* Set a uniform value for the current shader (p5.js-like API)
|
|
419
386
|
*/
|
|
420
|
-
setUniform(
|
|
421
|
-
this.currentShader.setUniform(
|
|
387
|
+
setUniform(A, e) {
|
|
388
|
+
this.currentShader.setUniform(A, e);
|
|
422
389
|
}
|
|
423
390
|
/**
|
|
424
391
|
* Draw a rectangle with the current shader (p5.js-like API)
|
|
425
392
|
*/
|
|
426
|
-
rect(
|
|
427
|
-
new
|
|
393
|
+
rect(A, e, t, r) {
|
|
394
|
+
new G(this.gl, A, e, t, r).draw();
|
|
428
395
|
}
|
|
429
396
|
/**
|
|
430
397
|
* Create a new framebuffer
|
|
431
398
|
*/
|
|
432
|
-
createFramebuffer(
|
|
433
|
-
return new M(this.gl,
|
|
399
|
+
createFramebuffer(A, e, t = {}) {
|
|
400
|
+
return new M(this.gl, A, e, t);
|
|
434
401
|
}
|
|
435
402
|
/**
|
|
436
403
|
* Fill the current framebuffer with a solid color (p5.js-like API)
|
|
437
404
|
*/
|
|
438
|
-
background(
|
|
439
|
-
this.clear(
|
|
405
|
+
background(A, e = A, t = A, r = 1) {
|
|
406
|
+
this.clear(A / 255, e / 255, t / 255, r);
|
|
440
407
|
}
|
|
441
408
|
/**
|
|
442
409
|
* Clear the current framebuffer
|
|
443
410
|
*/
|
|
444
|
-
clear(
|
|
445
|
-
this.gl.clearColor(
|
|
411
|
+
clear(A = 0, e = 0, t = 0, r = 0) {
|
|
412
|
+
this.gl.clearColor(A, e, t, r), this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
446
413
|
}
|
|
447
414
|
/**
|
|
448
415
|
* Ensure viewport matches canvas dimensions
|
|
@@ -459,43 +426,43 @@ class R {
|
|
|
459
426
|
/**
|
|
460
427
|
* Render a framebuffer at a specific position with optional scaling
|
|
461
428
|
*/
|
|
462
|
-
image(
|
|
463
|
-
this.shader(this.imageShader), this.setUniform("u_texture",
|
|
429
|
+
image(A, e, t, r, B) {
|
|
430
|
+
this.shader(this.imageShader), this.setUniform("u_texture", A.texture), this.rect(e, t, r ?? A.width, B ?? A.height);
|
|
464
431
|
}
|
|
465
432
|
}
|
|
466
433
|
class Y {
|
|
467
434
|
constructor() {
|
|
468
|
-
|
|
435
|
+
Q(this, "bin");
|
|
469
436
|
this.bin = this.createBinaryReader();
|
|
470
437
|
}
|
|
471
438
|
/**
|
|
472
439
|
* Parse a font buffer and return font data
|
|
473
440
|
*/
|
|
474
|
-
parse(
|
|
475
|
-
const
|
|
441
|
+
parse(A) {
|
|
442
|
+
const e = new Uint8Array(A);
|
|
476
443
|
let t = 0;
|
|
477
|
-
if (this.bin.readASCII(
|
|
478
|
-
const B = this.bin.readUint(
|
|
444
|
+
if (this.bin.readASCII(e, t, 4) === "ttcf") {
|
|
445
|
+
const B = this.bin.readUint(e, t + 8);
|
|
479
446
|
t += 12;
|
|
480
|
-
const
|
|
447
|
+
const E = [];
|
|
481
448
|
for (let g = 0; g < B; g++) {
|
|
482
|
-
const i = this.bin.readUint(
|
|
483
|
-
t += 4,
|
|
449
|
+
const i = this.bin.readUint(e, t);
|
|
450
|
+
t += 4, E.push(this.readFont(e, g, i));
|
|
484
451
|
}
|
|
485
|
-
return
|
|
452
|
+
return E;
|
|
486
453
|
} else
|
|
487
|
-
return [this.readFont(
|
|
454
|
+
return [this.readFont(e, 0, 0)];
|
|
488
455
|
}
|
|
489
456
|
/**
|
|
490
457
|
* Find a table in the font data
|
|
491
458
|
*/
|
|
492
|
-
findTable(
|
|
493
|
-
const r = this.bin.readUshort(
|
|
459
|
+
findTable(A, e, t) {
|
|
460
|
+
const r = this.bin.readUshort(A, t + 4);
|
|
494
461
|
let B = t + 12;
|
|
495
|
-
for (let
|
|
496
|
-
const g = this.bin.readASCII(
|
|
497
|
-
if (g ===
|
|
498
|
-
return [i,
|
|
462
|
+
for (let E = 0; E < r; E++) {
|
|
463
|
+
const g = this.bin.readASCII(A, B, 4), i = this.bin.readUint(A, B + 8), o = this.bin.readUint(A, B + 12);
|
|
464
|
+
if (g === e)
|
|
465
|
+
return [i, o];
|
|
499
466
|
B += 16;
|
|
500
467
|
}
|
|
501
468
|
return null;
|
|
@@ -503,18 +470,18 @@ class Y {
|
|
|
503
470
|
/**
|
|
504
471
|
* Read font data from buffer
|
|
505
472
|
*/
|
|
506
|
-
readFont(
|
|
473
|
+
readFont(A, e, t) {
|
|
507
474
|
const r = {
|
|
508
|
-
_data:
|
|
509
|
-
_index:
|
|
475
|
+
_data: A,
|
|
476
|
+
_index: e,
|
|
510
477
|
_offset: t
|
|
511
|
-
}, B = /* @__PURE__ */ new Map(),
|
|
512
|
-
for (const g of
|
|
513
|
-
const i = this.findTable(
|
|
478
|
+
}, B = /* @__PURE__ */ new Map(), E = ["cmap", "head", "hhea", "maxp", "hmtx"];
|
|
479
|
+
for (const g of E) {
|
|
480
|
+
const i = this.findTable(A, g, t);
|
|
514
481
|
if (i) {
|
|
515
|
-
const [
|
|
516
|
-
let a = B.get(
|
|
517
|
-
a || (a = this.parseTable(g,
|
|
482
|
+
const [o, n] = i;
|
|
483
|
+
let a = B.get(o);
|
|
484
|
+
a || (a = this.parseTable(g, A, o, n, r), B.set(o, a)), r[g] = a;
|
|
518
485
|
}
|
|
519
486
|
}
|
|
520
487
|
return r;
|
|
@@ -522,66 +489,66 @@ class Y {
|
|
|
522
489
|
/**
|
|
523
490
|
* Parse a specific table
|
|
524
491
|
*/
|
|
525
|
-
parseTable(
|
|
526
|
-
switch (
|
|
492
|
+
parseTable(A, e, t, r, B) {
|
|
493
|
+
switch (A) {
|
|
527
494
|
case "cmap":
|
|
528
|
-
return this.parseCmapTable(
|
|
495
|
+
return this.parseCmapTable(e, t, r);
|
|
529
496
|
case "head":
|
|
530
|
-
return this.parseHeadTable(
|
|
497
|
+
return this.parseHeadTable(e, t, r);
|
|
531
498
|
case "hhea":
|
|
532
|
-
return this.parseHheaTable(
|
|
499
|
+
return this.parseHheaTable(e, t, r);
|
|
533
500
|
case "hmtx":
|
|
534
|
-
return this.parseHmtxTable(
|
|
501
|
+
return this.parseHmtxTable(e, t, r, B);
|
|
535
502
|
case "maxp":
|
|
536
|
-
return this.parseMaxpTable(
|
|
503
|
+
return this.parseMaxpTable(e, t, r);
|
|
537
504
|
default:
|
|
538
|
-
throw new Error(`Unknown table: ${
|
|
505
|
+
throw new Error(`Unknown table: ${A}`);
|
|
539
506
|
}
|
|
540
507
|
}
|
|
541
508
|
/**
|
|
542
509
|
* Parse cmap table
|
|
543
510
|
*/
|
|
544
|
-
parseCmapTable(
|
|
545
|
-
const r = new Uint8Array(
|
|
511
|
+
parseCmapTable(A, e, t) {
|
|
512
|
+
const r = new Uint8Array(A.buffer, e, t);
|
|
546
513
|
let B = 0;
|
|
547
514
|
B += 2;
|
|
548
|
-
const
|
|
515
|
+
const E = this.bin.readUshort(r, B);
|
|
549
516
|
B += 2;
|
|
550
517
|
const g = {
|
|
551
518
|
tables: [],
|
|
552
519
|
ids: {},
|
|
553
|
-
off:
|
|
520
|
+
off: e
|
|
554
521
|
}, i = /* @__PURE__ */ new Set();
|
|
555
|
-
for (let
|
|
556
|
-
const
|
|
522
|
+
for (let o = 0; o < E; o++) {
|
|
523
|
+
const n = this.bin.readUshort(r, B);
|
|
557
524
|
B += 2;
|
|
558
525
|
const a = this.bin.readUshort(r, B);
|
|
559
526
|
B += 2;
|
|
560
527
|
const h = this.bin.readUint(r, B);
|
|
561
528
|
B += 4;
|
|
562
|
-
const
|
|
529
|
+
const u = `p${n}e${a}`;
|
|
563
530
|
if (!i.has(h)) {
|
|
564
531
|
const x = this.bin.readUshort(r, h), v = this.parseCmapSubtable(r, h, x);
|
|
565
532
|
g.tables.push(v), i.add(h);
|
|
566
533
|
}
|
|
567
|
-
g.ids[
|
|
534
|
+
g.ids[u] = Array.from(i).indexOf(h);
|
|
568
535
|
}
|
|
569
536
|
return g;
|
|
570
537
|
}
|
|
571
538
|
/**
|
|
572
539
|
* Parse cmap subtable based on format
|
|
573
540
|
*/
|
|
574
|
-
parseCmapSubtable(
|
|
541
|
+
parseCmapSubtable(A, e, t) {
|
|
575
542
|
const r = { format: t };
|
|
576
543
|
switch (t) {
|
|
577
544
|
case 0:
|
|
578
|
-
return this.parseCmapFormat0(
|
|
545
|
+
return this.parseCmapFormat0(A, e, r);
|
|
579
546
|
case 4:
|
|
580
|
-
return this.parseCmapFormat4(
|
|
547
|
+
return this.parseCmapFormat4(A, e, r);
|
|
581
548
|
case 6:
|
|
582
|
-
return this.parseCmapFormat6(
|
|
549
|
+
return this.parseCmapFormat6(A, e, r);
|
|
583
550
|
case 12:
|
|
584
|
-
return this.parseCmapFormat12(
|
|
551
|
+
return this.parseCmapFormat12(A, e, r);
|
|
585
552
|
default:
|
|
586
553
|
return r;
|
|
587
554
|
}
|
|
@@ -589,81 +556,81 @@ class Y {
|
|
|
589
556
|
/**
|
|
590
557
|
* Parse cmap format 0
|
|
591
558
|
*/
|
|
592
|
-
parseCmapFormat0(
|
|
593
|
-
let r =
|
|
594
|
-
const B = this.bin.readUshort(
|
|
559
|
+
parseCmapFormat0(A, e, t) {
|
|
560
|
+
let r = e + 2;
|
|
561
|
+
const B = this.bin.readUshort(A, r);
|
|
595
562
|
r += 2, r += 2, t.map = [];
|
|
596
|
-
for (let
|
|
597
|
-
t.map.push(
|
|
563
|
+
for (let E = 0; E < B - 6; E++)
|
|
564
|
+
t.map.push(A[r + E]);
|
|
598
565
|
return t;
|
|
599
566
|
}
|
|
600
567
|
/**
|
|
601
568
|
* Parse cmap format 4
|
|
602
569
|
*/
|
|
603
|
-
parseCmapFormat4(
|
|
604
|
-
const r =
|
|
605
|
-
let B =
|
|
606
|
-
const
|
|
570
|
+
parseCmapFormat4(A, e, t) {
|
|
571
|
+
const r = e;
|
|
572
|
+
let B = e + 2;
|
|
573
|
+
const E = this.bin.readUshort(A, B);
|
|
607
574
|
B += 2, B += 2;
|
|
608
|
-
const g = this.bin.readUshort(
|
|
575
|
+
const g = this.bin.readUshort(A, B);
|
|
609
576
|
B += 2;
|
|
610
577
|
const i = g >>> 1;
|
|
611
|
-
t.searchRange = this.bin.readUshort(
|
|
612
|
-
for (let
|
|
613
|
-
t.idDelta.push(this.bin.readShort(
|
|
614
|
-
return t.idRangeOffset = this.bin.readUshorts(
|
|
578
|
+
t.searchRange = this.bin.readUshort(A, B), B += 2, t.entrySelector = this.bin.readUshort(A, B), B += 2, t.rangeShift = this.bin.readUshort(A, B), B += 2, t.endCount = this.bin.readUshorts(A, B, i), B += i * 2, B += 2, t.startCount = this.bin.readUshorts(A, B, i), B += i * 2, t.idDelta = [];
|
|
579
|
+
for (let o = 0; o < i; o++)
|
|
580
|
+
t.idDelta.push(this.bin.readShort(A, B)), B += 2;
|
|
581
|
+
return t.idRangeOffset = this.bin.readUshorts(A, B, i), B += i * 2, t.glyphIdArray = this.bin.readUshorts(A, B, r + E - B >> 1), t;
|
|
615
582
|
}
|
|
616
583
|
/**
|
|
617
584
|
* Parse cmap format 6
|
|
618
585
|
*/
|
|
619
|
-
parseCmapFormat6(
|
|
620
|
-
let r =
|
|
621
|
-
r += 2, r += 2, t.firstCode = this.bin.readUshort(
|
|
622
|
-
const B = this.bin.readUshort(
|
|
586
|
+
parseCmapFormat6(A, e, t) {
|
|
587
|
+
let r = e + 2;
|
|
588
|
+
r += 2, r += 2, t.firstCode = this.bin.readUshort(A, r), r += 2;
|
|
589
|
+
const B = this.bin.readUshort(A, r);
|
|
623
590
|
r += 2, t.glyphIdArray = [];
|
|
624
|
-
for (let
|
|
625
|
-
t.glyphIdArray.push(this.bin.readUshort(
|
|
591
|
+
for (let E = 0; E < B; E++)
|
|
592
|
+
t.glyphIdArray.push(this.bin.readUshort(A, r)), r += 2;
|
|
626
593
|
return t;
|
|
627
594
|
}
|
|
628
595
|
/**
|
|
629
596
|
* Parse cmap format 12
|
|
630
597
|
*/
|
|
631
|
-
parseCmapFormat12(
|
|
632
|
-
let r =
|
|
598
|
+
parseCmapFormat12(A, e, t) {
|
|
599
|
+
let r = e + 4;
|
|
633
600
|
r += 4, r += 4;
|
|
634
|
-
const B = this.bin.readUint(
|
|
601
|
+
const B = this.bin.readUint(A, r) * 3;
|
|
635
602
|
r += 4, t.groups = new Uint32Array(B);
|
|
636
|
-
for (let
|
|
637
|
-
t.groups[
|
|
603
|
+
for (let E = 0; E < B; E += 3)
|
|
604
|
+
t.groups[E] = this.bin.readUint(A, r + (E << 2)), t.groups[E + 1] = this.bin.readUint(A, r + (E << 2) + 4), t.groups[E + 2] = this.bin.readUint(A, r + (E << 2) + 8);
|
|
638
605
|
return t;
|
|
639
606
|
}
|
|
640
607
|
/**
|
|
641
608
|
* Parse head table
|
|
642
609
|
*/
|
|
643
|
-
parseHeadTable(
|
|
644
|
-
let r =
|
|
610
|
+
parseHeadTable(A, e, t) {
|
|
611
|
+
let r = e;
|
|
645
612
|
return r += 4, {
|
|
646
|
-
fontRevision: this.bin.readFixed(
|
|
647
|
-
flags: this.bin.readUshort(
|
|
648
|
-
unitsPerEm: this.bin.readUshort(
|
|
649
|
-
created: this.bin.readUint64(
|
|
650
|
-
modified: this.bin.readUint64(
|
|
651
|
-
xMin: this.bin.readShort(
|
|
652
|
-
yMin: this.bin.readShort(
|
|
653
|
-
xMax: this.bin.readShort(
|
|
654
|
-
yMax: this.bin.readShort(
|
|
655
|
-
macStyle: this.bin.readUshort(
|
|
656
|
-
lowestRecPPEM: this.bin.readUshort(
|
|
657
|
-
fontDirectionHint: this.bin.readShort(
|
|
658
|
-
indexToLocFormat: this.bin.readShort(
|
|
659
|
-
glyphDataFormat: this.bin.readShort(
|
|
613
|
+
fontRevision: this.bin.readFixed(A, r + 0),
|
|
614
|
+
flags: this.bin.readUshort(A, r + 8),
|
|
615
|
+
unitsPerEm: this.bin.readUshort(A, r + 10),
|
|
616
|
+
created: this.bin.readUint64(A, r + 12),
|
|
617
|
+
modified: this.bin.readUint64(A, r + 20),
|
|
618
|
+
xMin: this.bin.readShort(A, r + 28),
|
|
619
|
+
yMin: this.bin.readShort(A, r + 30),
|
|
620
|
+
xMax: this.bin.readShort(A, r + 32),
|
|
621
|
+
yMax: this.bin.readShort(A, r + 34),
|
|
622
|
+
macStyle: this.bin.readUshort(A, r + 36),
|
|
623
|
+
lowestRecPPEM: this.bin.readUshort(A, r + 38),
|
|
624
|
+
fontDirectionHint: this.bin.readShort(A, r + 40),
|
|
625
|
+
indexToLocFormat: this.bin.readShort(A, r + 42),
|
|
626
|
+
glyphDataFormat: this.bin.readShort(A, r + 44)
|
|
660
627
|
};
|
|
661
628
|
}
|
|
662
629
|
/**
|
|
663
630
|
* Parse hhea table
|
|
664
631
|
*/
|
|
665
|
-
parseHheaTable(
|
|
666
|
-
let r =
|
|
632
|
+
parseHheaTable(A, e, t) {
|
|
633
|
+
let r = e;
|
|
667
634
|
r += 4;
|
|
668
635
|
const B = [
|
|
669
636
|
"ascender",
|
|
@@ -682,203 +649,408 @@ class Y {
|
|
|
682
649
|
"res3",
|
|
683
650
|
"metricDataFormat",
|
|
684
651
|
"numberOfHMetrics"
|
|
685
|
-
],
|
|
652
|
+
], E = {};
|
|
686
653
|
for (let g = 0; g < B.length; g++) {
|
|
687
|
-
const i = B[g],
|
|
688
|
-
|
|
654
|
+
const i = B[g], n = i === "advanceWidthMax" || i === "numberOfHMetrics" ? this.bin.readUshort : this.bin.readShort;
|
|
655
|
+
E[i] = n(A, r + g * 2);
|
|
689
656
|
}
|
|
690
|
-
return
|
|
657
|
+
return E;
|
|
691
658
|
}
|
|
692
659
|
/**
|
|
693
660
|
* Parse hmtx table
|
|
694
661
|
*/
|
|
695
|
-
parseHmtxTable(
|
|
696
|
-
const B = r.maxp.numGlyphs,
|
|
697
|
-
let
|
|
698
|
-
for (let h = 0; h <
|
|
699
|
-
|
|
700
|
-
for (let h =
|
|
701
|
-
g.push(
|
|
662
|
+
parseHmtxTable(A, e, t, r) {
|
|
663
|
+
const B = r.maxp.numGlyphs, E = r.hhea.numberOfHMetrics, g = [], i = [];
|
|
664
|
+
let o = e, n = 0, a = 0;
|
|
665
|
+
for (let h = 0; h < E; h++)
|
|
666
|
+
n = this.bin.readUshort(A, o), a = this.bin.readShort(A, o + 2), g.push(n), i.push(a), o += 4;
|
|
667
|
+
for (let h = E; h < B; h++)
|
|
668
|
+
g.push(n), i.push(a);
|
|
702
669
|
return { aWidth: g, lsBearing: i };
|
|
703
670
|
}
|
|
704
671
|
/**
|
|
705
672
|
* Parse maxp table
|
|
706
673
|
*/
|
|
707
|
-
parseMaxpTable(
|
|
708
|
-
let r =
|
|
674
|
+
parseMaxpTable(A, e, t) {
|
|
675
|
+
let r = e;
|
|
709
676
|
r += 4;
|
|
710
|
-
const B = this.bin.readUshort(
|
|
677
|
+
const B = this.bin.readUshort(A, r);
|
|
711
678
|
return r += 2, { numGlyphs: B };
|
|
712
679
|
}
|
|
713
680
|
/**
|
|
714
681
|
* Create optimized binary reader
|
|
715
682
|
*/
|
|
716
683
|
createBinaryReader() {
|
|
717
|
-
const
|
|
718
|
-
buff:
|
|
719
|
-
int8: new Int8Array(
|
|
720
|
-
uint8: new Uint8Array(
|
|
721
|
-
int16: new Int16Array(
|
|
722
|
-
uint16: new Uint16Array(
|
|
723
|
-
int32: new Int32Array(
|
|
724
|
-
uint32: new Uint32Array(
|
|
684
|
+
const A = new ArrayBuffer(8), e = {
|
|
685
|
+
buff: A,
|
|
686
|
+
int8: new Int8Array(A),
|
|
687
|
+
uint8: new Uint8Array(A),
|
|
688
|
+
int16: new Int16Array(A),
|
|
689
|
+
uint16: new Uint16Array(A),
|
|
690
|
+
int32: new Int32Array(A),
|
|
691
|
+
uint32: new Uint32Array(A)
|
|
725
692
|
};
|
|
726
693
|
return {
|
|
727
694
|
readFixed: (t, r) => (t[r] << 8 | t[r + 1]) + (t[r + 2] << 8 | t[r + 3]) / (256 * 256 + 4),
|
|
728
|
-
readInt: (t, r) => (
|
|
729
|
-
readShort: (t, r) => (
|
|
695
|
+
readInt: (t, r) => (e.uint8[0] = t[r + 3], e.uint8[1] = t[r + 2], e.uint8[2] = t[r + 1], e.uint8[3] = t[r], e.int32[0]),
|
|
696
|
+
readShort: (t, r) => (e.uint16[0] = t[r] << 8 | t[r + 1], e.int16[0]),
|
|
730
697
|
readUshort: (t, r) => t[r] << 8 | t[r + 1],
|
|
731
698
|
readUshorts: (t, r, B) => {
|
|
732
|
-
const
|
|
699
|
+
const E = new Array(B);
|
|
733
700
|
for (let g = 0; g < B; g++)
|
|
734
|
-
|
|
735
|
-
return
|
|
701
|
+
E[g] = t[r + g * 2] << 8 | t[r + g * 2 + 1];
|
|
702
|
+
return E;
|
|
736
703
|
},
|
|
737
|
-
readUint: (t, r) => (
|
|
704
|
+
readUint: (t, r) => (e.uint8[3] = t[r], e.uint8[2] = t[r + 1], e.uint8[1] = t[r + 2], e.uint8[0] = t[r + 3], e.uint32[0]),
|
|
738
705
|
readUint64: (t, r) => {
|
|
739
|
-
const B =
|
|
740
|
-
return B * 4294967296 +
|
|
706
|
+
const B = e.uint32[0] = t[r] << 24 | t[r + 1] << 16 | t[r + 2] << 8 | t[r + 3], E = e.uint32[0] = t[r + 4] << 24 | t[r + 5] << 16 | t[r + 6] << 8 | t[r + 7];
|
|
707
|
+
return B * 4294967296 + E;
|
|
741
708
|
},
|
|
742
709
|
readASCII: (t, r, B) => {
|
|
743
|
-
let
|
|
710
|
+
let E = "";
|
|
744
711
|
for (let g = 0; g < B; g++)
|
|
745
|
-
|
|
746
|
-
return
|
|
712
|
+
E += String.fromCharCode(t[r + g]);
|
|
713
|
+
return E;
|
|
747
714
|
},
|
|
748
|
-
t:
|
|
715
|
+
t: e
|
|
749
716
|
};
|
|
750
717
|
}
|
|
751
718
|
}
|
|
752
|
-
const
|
|
753
|
-
parse: (
|
|
754
|
-
findTable: (
|
|
719
|
+
const w = new Y(), m = {
|
|
720
|
+
parse: (s) => w.parse(s),
|
|
721
|
+
findTable: (s, A, e) => w.findTable(s, A, e)
|
|
755
722
|
}, S = `data:font/truetype;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMs+QEyQAAAEoAAAAYGNtYXAg7yVJAAAFjAAACSBnbHlmuHLTdAAAErQAAGi0aGVhZFvXdUwAAACsAAAANmhoZWELAQUCAAAA5AAAACRobXR4BACDgAAAAYgAAAQEbG9jYQAy54AAAA6sAAAECG1heHABIgCCAAABCAAAACBuYW1lVs/OSgAAe2gAAAOicG9zdABpADQAAH8MAAAAIAABAAAAAQAAzOWHqV8PPPUAAAQAAAAAAHxiGCcAAAAAfGIYJwAAAAAEAAQAAAAACAACAAEAAAAAAAEAAAQAAAAAAAQAAAAAAAcAAAEAAAAAAAAAAAAAAAAAAAEBAAEAAAEBAIAAIAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAgQAAZAABQAEAgACAAAAAAACAAIAAAACAAAzAMwAAAAABAAAAAAAAACAAACLAABw4wAAAAAAAAAAWUFMLgBAACAmawQAAAAAAAQAAAAAAAFRAAAAAAMABAAAAAAgAAAEAAAABAAAAAQAAAAEAAGABAABAAQAAIAEAACABAAAgAQAAIAEAAGABAABAAQAAQAEAACABAABAAQAAIAEAACABAABAAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAABAAQAAIAEAAEABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAABAAQAAIAEAAEABAAAgAQAAIAEAAEABAAAgAQAAIAEAACABAAAgAQAAIAEAAEABAAAgAQAAIAEAAGABAAAgAQAAIAEAAGABAAAgAQAAIAEAACABAAAgAQAAIAEAAEABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAAAgAQAAIAEAACABAABgAQAAQAEAACABAAAAAQAAgAEAACABAAAgAQAAIAEAACABAACAAQAAAAEAAIABAABgAQAAgAEAACABAAAgAQAAAAEAACABAAAAAQAAAAEAAAABAAAAAQAAAAEAAIABAADAAQAAAAEAAAABAAAgAQAAYAEAAAABAAAAAQAAIAEAAAA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AIAAAACA/YAAgAAAAIAAAP8AAoABAAAA/4AAAP+A/4AAgAAAAIAAAP8AA4AAAP8AAAAAgAAAAIAAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAAAP+AAAD/gAAAAAAAAP8AAAAAgAAAAAAAAP+AAAD/gAAAAAAAAwCAAIAEAAQAABcAHQAjAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/4AAAACAAAAAgAAA/4AAAACAAAD9AAAA/4AAAACAAAD/gAAAAIAAgAAAAIAAAACAAAD/AAAAAQAAAP+AAAAEAAAA/4AAAP8AAAD/gAAAAIAAAP8AAAD/gAAA/4AAAACAAAABAAAAAIAAAAEAAAAAAP+AAAD/gAAAAQD+gP8AAAAAgAAAAIAAAAABAYACgAKABAAAAwAAAQEBAQGAAQAAAP8ABAAAAP6AAAAAAAABAQAAgAMABAAAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQECAAEAAAD/gAAA/4AAAACAAAAAgAAA/wAAAP+AAAD/gAAAAIAAAACABAAAAP+AAAD/gAAA/oAAAP+AAAD/gAAAAIAAAACAAAABgAAAAIAAAAAAAAEBAACAAwAEAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQAAAACAAAAAgAAA/4AAAP+AAAD/AAAAAIAAAACAAAD/gAAA/4AEAAAA/4AAAP+AAAD+gAAA/4AAAP+AAAAAgAAAAIAAAAGAAAAAgAAAAAAABQCAAYADgAQAAAMABwATABcAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAIAAAP+AAYAAgAAA/4D/AAEAAAABAAAA/wAAAP8AAAD/AAAAAQD/gACAAAD/gAGAAIAAAP+ABAAAAP+AAAAAgAAA/4AAAAAAAAD/gAAA/4AAAP+AAAAAgAAAAIAAAP8AAAD/gAAAAIAAAP+AAAAAAAABAQAAgAOAAwAACwAAAQEBAQEBAQEBAQEBAgAAgAAAAQAAAP8AAAD/gAAA/wAAAAEAAwAAAP8AAAD/gAAA/wAAAAEAAAAAgAAAAAAAAQCAAAACAAGAAAcAAAEBAQEBAQEBAQABAAAA/4AAAP8AAAAAgAGAAAD/AAAA/4AAAACAAAAAAAABAIABgAOAAgAAAwAAAQEBAQCAAwAAAP0AAgAAAP+AAAAAAAABAQAAgAIAAYAAAwAAAQEBAQEAAQAAAP8AAYAAAP8AAAAAAAABAIAAgAQAA4AAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwABAAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAIAAAACAA4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAAAwCAAIADgAQAAAsAEQAXAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/4AAAP4AAAD/gAAAAIAAgAAAAIAAAACAAAD/gAAA/4AAAAEAAAAEAAAA/4AAAP2AAAD/gAAAAIAAAAKAAAAAAP8AAAAAgAAAAID/AP+AAAD/AAAAAYAAAAABAIAAgAOABAAADQAAAQEBAQEBAQEBAQEBAQEBgAEAAAABAAAA/QAAAAEAAAD/AAAAAIAAAACABAAAAP0AAAD/gAAAAIAAAAGAAAAAgAAAAIAAAAABAIAAgAOABAAAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAgAAAACAAAD/gAAA/4AAAP+AAAABgAAA/QAAAACAAAAAgAAAAIAAAACAAAD/AAAA/wAAAACABAAAAP+AAAD/AAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAABAAAA/wAAAAEAAAAAAAABAIAAgAOABAAAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAgAAAACAAAD/gAAAAIAAAP+AAAD+AAAA/4AAAAEAAAABAAAA/wAAAAEAAAD/AAAA/wAAAACABAAAAP+AAAD/AAAA/4AAAP8AAAD/gAAAAIAAAACAAAD/gAAAAQAAAACAAAABAAAA/4AAAACAAAAAAAABAIAAgAOABAAAEQAAAQEBAQEBAQEBAQEBAQEBAQEBAYABAAAA/4AAAP+AAAABAAAAAQAAAP8AAAD+AAAAAIAAAACABAAAAP+AAAD/gAAA/wAAAAEAAAD9gAAAAQAAAAGAAAAAgAAAAAEAgACAA4AEAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQCAAwAAAP4AAAABgAAAAIAAAP+AAAD+AAAA/4AAAAEAAAABAAAA/gAEAAAA/4AAAP8AAAD/gAAA/wAAAP+AAAAAgAAAAIAAAP+AAAABAAAAAAAAAgCAAIADgAQAABMAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQACAAAAAIAAAP8AAAD/AAAAAYAAAACAAAD/gAAA/gAAAP+AAAAAgACAAAABAAAABAAAAP+AAAD/gAAAAIAAAP8AAAD/gAAA/wAAAP+AAAAAgAAAAoAAAP6A/wAAAAEAAAEAgACAA4AEAAAPAAABAQEBAQEBAQEBAQEBAQEBAIADAAAA/4AAAP+AAAD/AAAAAIAAAACAAAD+gAAA/4AEAAAA/oAAAP+AAAD+gAAAAYAAAACAAAABAAAA/4AAAAAAAAMAgACAA4AEAAATABcAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAgAAAACAAAD/gAAAAIAAAP+AAAD+AAAA/4AAAACAAAD/gAAAAIAAgAAAAQAAAP8AAAABAAAABAAAAP+AAAD/AAAA/4AAAP8AAAD/gAAAAIAAAAEAAAAAgAAAAQAAAAAA/wAAAAEA/oD/AAAAAQAAAAACAIAAgAOABAAACwAPAAABAQEBAQEBAQEBAQEBAQEBAQACAAAAAIAAAP8AAAD+gAAA/4AAAACAAIAAAAEAAAAEAAAA/4AAAP0AAAABAAAAAIAAAAGAAAAAAP6AAAABgAACAQABAAIAA4AAAwAHAAABAQEBAQEBAQEAAQAAAP8AAAABAAAA/wADgAAA/wAAAP+AAAD/AAAAAAIAgACAAgADgAADAAsAAAEBAQEBAQEBAQEBAQEAAQAAAP8AAAABAAAA/4AAAP8AAAAAgAOAAAD/AAAA/4AAAP8AAAD/gAAAAIAAAAABAQAAgAOABAAAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQKAAQAAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAP8AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACABAAAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAAAACAIABgAOAAwAAAwAHAAABAQEBAQEBAQCAAwAAAP0AAAADAAAA/QADAAAA/4AAAP+AAAD/gAAAAAEAgACAAwAEAAAbAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAIABAAAAAIAAAACAAAAAgAAA/4AAAP+AAAD/gAAA/wAAAACAAAAAgAAAAIAAAP+AAAD/gAAA/4AEAAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAAAAAAIAgACAA4AEAAATABcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAgAAAACAAAD/gAAA/4AAAP8AAAAAgAAAAIAAAP8AAAD/AAAAAIAAgAEAAAD/AAQAAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAAA/4AAAACAAAD+AAAA/wAAAAACAIAAgAOABAAAEQAVAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQACAAAAAIAAAP6AAAAAgAAA/wAAAAGAAAD+AAAA/4AAAACAAgAAgAAA/4AEAAAA/4AAAP6AAAABAAAAAIAAAP2AAAD/gAAAAIAAAAKAAAD+AAAA/4AAAAAAAAIAgACAA4AEAAAPABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAYABAAAAAIAAAACAAAD/AAAA/wAAAP8AAAAAgAAAAIAAAAAAAQAAAAQAAAD/gAAA/4AAAP2AAAABAAAA/wAAAAKAAAAAgAAA/4D/AAAAAQAAAwCAAIADgAQAAAsADwATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQCAAoAAAACAAAD/gAAAAIAAAP+AAAD9gAEAAAABAAAA/wAAAAEAAAAEAAAA/4AAAP8AAAD/gAAA/wAAAP+AAAADAP8AAAABAP6A/wAAAAEAAAAAAQCAAIADgAQAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQACAAAAAIAAAP8AAAD/AAAAAQAAAAEAAAD/gAAA/gAAAP+AAAAAgAQAAAD/gAAA/4AAAACAAAD9gAAAAIAAAP+AAAD/gAAAAIAAAAKAAAAAAAACAIAAgAOABAAACwATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQCAAgAAAACAAAAAgAAA/4AAAP+AAAD+AAEAAAAAgAAAAIAAAP+AAAAEAAAA/4AAAP+AAAD+gAAA/4AAAP+AAAADAP2AAAAAgAAAAYAAAACAAAEAgACAA4AEAAAXAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/wAAAP8AAAABAAAA/wAAAAEAAAABAAAA/4AAAP4AAAD/gAAAAIAEAAAA/4AAAP+AAAAAgAAA/wAAAP+AAAD/AAAAAIAAAP+AAAD/gAAAAIAAAAKAAAAAAAABAIAAgAOABAAACQAAAQEBAQEBAQEBAQCAAwAAAP4AAAABAAAA/wAAAP8ABAAAAP+AAAD/AAAA/4AAAP6AAAAAAQCAAIADgAQAABUAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/wAAAP8AAAABAAAA/4AAAAGAAAD/gAAA/gAAAP+AAAAAgAQAAAD/gAAA/4AAAACAAAD9gAAAAQAAAACAAAD+gAAA/4AAAACAAAACgAAAAAEAgACAA4AEAAALAAABAQEBAQEBAQEBAQEAgAEAAAABAAAAAQAAAP8AAAD/AAAA/wAEAAAA/gAAAAIAAAD8gAAAAQAAAP8AAAAAAAABAIAAgAOABAAACwAAAQEBAQEBAQEBAQEBAIADAAAA/wAAAAEAAAD9AAAAAQAAAP8ABAAAAP+AAAD9gAAA/4AAAACAAAACgAAAAAAAAQCAAIAEAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEBAAMAAAD/gAAA/4AAAP4AAAD/gAAAAQAAAAEAAAD+gAQAAAD/gAAA/YAAAP+AAAAAgAAAAQAAAP8AAAACgAAAAAAAAQCAAIADgAQAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAEAAAAAgAAAAIAAAAEAAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD/AAQAAAD/AAAAAIAAAACAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAD/AAAAAAAAAQCAAIADgAQAAAUAAAEBAQEBAQCAAQAAAAIAAAD9AAQAAAD9AAAA/4AAAAABAIAAgAQABAAAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAEAAAAAgAAAAIAAAACAAAABAAAA/wAAAP+AAAD/gAAA/4AAAP8ABAAAAP+AAAD/gAAAAIAAAACAAAD8gAAAAgAAAP+AAAAAgAAA/gAAAAAAAAEAgACABAAEAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQCAAQAAAACAAAAAgAAAAIAAAAEAAAD/AAAA/4AAAP+AAAD/gAAA/wAEAAAA/4AAAP+AAAD/gAAAAYAAAPyAAAABAAAAAIAAAACAAAD+AAAAAAAAAgCAAIADgAQAAAsADwAAAQEBAQEBAQEBAQEBAQEBAQEAAgAAAACAAAD/gAAA/gAAAP+AAAAAgACAAAABAAAABAAAAP+AAAD9gAAA/4AAAACAAAACgAAAAAD9gAAAAoAAAgCAAIADgAQAAAkADQAAAQEBAQEBAQEBAQEBAQEAgAKAAAAAgAAA/4AAAP6AAAD/AAEAAAABAAAABAAAAP+AAAD+gAAA/4AAAP8AAAADAP6AAAABgAAAAAIAgACABAAEAAAPABcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAgAAAACAAAAAgAAA/4AAAP+AAAD+AAAA/4AAAACAAIAAAAEAAAD/gAAAAIAAAAQAAAD/gAAA/gAAAP8AAAAAgAAA/4AAAACAAAACgAAAAAD9gAAAAIAAAACAAAABgAACAIAAgAOABAAAEwAXAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAKAAAAAgAAA/4AAAP+AAAAAgAAAAIAAAP8AAAD/gAAA/4AAAP8AAQAAAAEAAAAEAAAA/4AAAP8AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAD/AAAAAwD/AAAAAQAAAQCAAIADgAQAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/wAAAP8AAAABgAAAAIAAAP+AAAD+AAAA/4AAAAEAAAABAAAA/oAAAP+AAAAAgAQAAAD/gAAA/4AAAACAAAD/AAAA/4AAAP8AAAD/gAAAAIAAAACAAAD/gAAAAQAAAACAAAABAAAAAAAAAQCAAIADgAQAAAcAAAEBAQEBAQEBAIADAAAA/wAAAP8AAAD/AAQAAAD/gAAA/QAAAAMAAAAAAAABAIAAgAOABAAACwAAAQEBAQEBAQEBAQEBAIABAAAAAQAAAAEAAAD/gAAA/gAAAP+ABAAAAP0AAAADAAAA/QAAAP+AAAAAgAAAAAAAAQCAAIADgAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEAgAEAAAABAAAAAQAAAP+AAAD/gAAA/wAAAP+AAAD/gAQAAAD+AAAAAgAAAP4AAAD/AAAA/4AAAACAAAABAAAAAAAAAQCAAIAEAAQAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAIABAAAAAIAAAACAAAAAgAAAAQAAAP8AAAD/gAAA/4AAAP+AAAD/AAQAAAD+AAAAAIAAAP+AAAACAAAA/IAAAACAAAAAgAAA/4AAAP+AAAAAAAABAIAAgAOABAAAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQCAAQAAAAEAAAABAAAA/4AAAP+AAAAAgAAAAIAAAP8AAAD/AAAA/wAAAACAAAAAgAAA/4AAAP+ABAAAAP8AAAABAAAA/wAAAP+AAAD/gAAA/4AAAP8AAAABAAAA/wAAAAEAAAAAgAAAAIAAAACAAAAAAAABAIAAgAOABAAADwAAAQEBAQEBAQEBAQEBAQEBAQCAAQAAAAEAAAABAAAA/4AAAP+AAAD/AAAA/4AAAP+ABAAAAP6AAAABgAAA/oAAAP+AAAD+gAAAAYAAAACAAAAAAAABAIAAgAOABAAAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAIADAAAA/4AAAP+AAAD/gAAA/4AAAAIAAAD9AAAAAIAAAACAAAAAgAAAAIAAAP4ABAAAAP8AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAAEAAAAAgAAAAIAAAACAAAAAgAAAAAAAAQEAAIADAAQAAAcAAAEBAQEBAQEBAQACAAAA/wAAAAEAAAD+AAQAAAD/gAAA/YAAAP+AAAAAAAABAIAAgAQAA4AAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAIABAAAAAIAAAACAAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD/gAAA/4AAAP+AA4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAAAQEAAIADAAQAAAcAAAEBAQEBAQEBAQACAAAA/gAAAAEAAAD/AAQAAAD8gAAAAIAAAAKAAAAAAAABAIACAAQABAAAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAgAAgAAAAIAAAACAAAAAgAAA/wAAAP+AAAD/gAAA/4AAAP8AAAAAgAAAAIAAAACABAAAAP+AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAP+AAAD/gAAAAIAAAACAAAAAgAAAAAAAAQCAAIADgAEAAAMAAAEBAQEAgAMAAAD9AAEAAAD/gAAAAAAAAQEAAoACgAQAAAkAAAEBAQEBAQEBAQEBAAEAAAAAgAAA/4AAAP+AAAD/gAQAAAD/gAAA/wAAAACAAAAAgAAAAAEAgACAA4ADAAAPAAABAQEBAQEBAQEBAQEBAQEBAQACgAAA/4AAAP+AAAD/AAAAAQAAAP6AAAD/gAAAAIADAAAA/YAAAACAAAABgAAA/oAAAP+AAAAAgAAAAYAAAAAAAAIAgACAA4AEAAAJAA0AAAEBAQEBAQEBAQEBAQEBAIABAAAAAYAAAACAAAD/gAAA/YABAAAAAQAAAAQAAAD/AAAA/4AAAP6AAAD/gAAAAgD+gAAAAYAAAAABAIAAgAOAAwAAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/wAAAP8AAAABAAAAAQAAAP+AAAD+AAAA/4AAAACAAwAAAP+AAAD/gAAAAIAAAP6AAAAAgAAA/4AAAP+AAAAAgAAAAYAAAAAAAAIAgACAA4AEAAAJAA0AAAEBAQEBAQEBAQEBAQEBAoABAAAA/YAAAP+AAAAAgAAAAYD/AAAAAQAAAAQAAAD8gAAAAIAAAAGAAAAAgAAA/4D+gAAAAYAAAAACAIAAgAOAAwAADQARAAABAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/gAAAAGAAAD+AAAA/4AAAACAAIAAAAEAAAADAAAA/4AAAP8AAAD/gAAA/4AAAACAAAABgAAAAAD/gAAAAIAAAAABAQAAgAOAA4AACwAAAQEBAQEBAQEBAQEBAYACAAAA/oAAAAEAAAD/AAAA/wAAAACAA4AAAP+AAAD/AAAA/4AAAP8AAAACgAAAAAAAAgCAAIADgAOAAA8AEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/4AAAP4AAAABgAAA/oAAAP+AAAAAgACAAAABAAAAA4AAAP+AAAD+AAAA/4AAAACAAAAAgAAAAIAAAAEAAAAAAP8AAAABAAABAIAAgAOABAAACwAAAQEBAQEBAQEBAQEBAIABAAAAAYAAAACAAAD/AAAA/wAAAP8ABAAAAP8AAAD/gAAA/gAAAAIAAAD+AAAAAAAAAgGAAIACgAQAAAMABwAAAQEBAQEBAQEBgAEAAAD/AAAAAQAAAP8ABAAAAP+AAAD/gAAA/YAAAAACAIAAgAOABAAAAwAPAAABAQEBAQEBAQEBAQEBAQEBAoABAAAA/wAAAAEAAAD/gAAA/gAAAP+AAAABAAAAAQAEAAAA/4AAAP+AAAD+AAAA/4AAAACAAAABAAAA/wAAAAABAIAAgAOAA4AAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAEAAAAAgAAAAQAAAP+AAAAAgAAAAIAAAP8AAAD/gAAA/4AAAP8AA4AAAP8AAAAAgAAA/4AAAP8AAAD/gAAA/4AAAACAAAAAgAAA/wAAAAAAAAEBgACAAwAEAAAHAAABAQEBAQEBAQGAAQAAAACAAAD/AAAA/4AEAAAA/QAAAP+AAAAAgAAAAAAAAQCAAIAEAAMAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAAAAIAAAAEAAAAAgAAA/wAAAP+AAAD/gAAA/4AAAP8AAAAAgAMAAAD/gAAAAIAAAP+AAAD+AAAAAYAAAP+AAAAAgAAA/oAAAAIAAAAAAAABAIAAgAOAAwAADwAAAQEBAQEBAQEBAQEBAQEBAQCAAQAAAACAAAABAAAAAIAAAP8AAAD/gAAA/4AAAP8AAwAAAP+AAAAAgAAA/4AAAP4AAAABgAAA/4AAAP8AAAAAAAACAIAAgAOAAwAACwAPAAABAQEBAQEBAQEBAQEBAQEBAQACAAAAAIAAAP+AAAD+AAAA/4AAAACAAIAAAAEAAAADAAAA/4AAAP6AAAD/gAAAAIAAAAGAAAAAAP6AAAABgAACAIAAgAOAAwAACQANAAABAQEBAQEBAQEBAQEBAQCAAoAAAACAAAD/gAAA/oAAAP8AAQAAAAEAAAADAAAA/4AAAP+AAAD/gAAA/wAAAAIA/4AAAACAAAAAAgCAAIAEAAMAAA0AEQAAAQEBAQEBAQEBAQEBAQEBAQEBAQACgAAAAIAAAP+AAAD/AAAA/oAAAP+AAAAAgACAAAABAAAAAwAAAP6AAAD/gAAA/4AAAAEAAAAAgAAAAIAAAAAA/4AAAACAAAAAAQEAAIADgAMAAAkAAAEBAQEBAQEBAQEBAAIAAAAAgAAA/wAAAP+AAAD/AAMAAAD/gAAA/wAAAAEAAAD+AAAAAAEAgACABAADAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEAAoAAAP6AAAABgAAAAIAAAP+AAAD9AAAAAgAAAP6AAAD/gAAAAIADAAAA/4AAAP+AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAAAgAAAAAAAAQCAAIADgAOAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAAAAQAAAP8AAAAAgAAAAQAAAP+AAAD+gAAA/4AAAP+AAAAAgAOAAAD/gAAA/4AAAP6AAAAAgAAA/4AAAP+AAAAAgAAAAYAAAACAAAAAAAABAIAAgAOAAwAADwAAAQEBAQEBAQEBAQEBAQEBAQCAAQAAAACAAAAAgAAAAQAAAP+AAAD/gAAA/oAAAP+AAwAAAP4AAAAAgAAAAYAAAP2AAAAAgAAA/4AAAACAAAAAAAABAIAAgAOAAwAADwAAAQEBAQEBAQEBAQEBAQEBAQCAAQAAAAEAAAABAAAA/4AAAP+AAAD/AAAA/4AAAP+AAwAAAP6AAAABgAAA/oAAAP+AAAD/gAAAAIAAAACAAAAAAAABAIAAgAQAAwAAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAEAAAAAgAAAAIAAAACAAAABAAAA/4AAAP8AAAD/gAAA/wAAAP+AAwAAAP6AAAAAgAAA/4AAAAGAAAD+AAAA/4AAAACAAAD/gAAAAIAAAAAAAAEAgACAA4ADAAAbAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAIABAAAAAQAAAAEAAAD/gAAA/4AAAACAAAAAgAAA/wAAAP8AAAD/AAAAAIAAAACAAAD/gAAA/4ADAAAA/4AAAACAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAD/gAAAAIAAAACAAAAAgAAAAIAAAAAAAAEAgACAA4ADAAAPAAABAQEBAQEBAQEBAQEBAQEBAIABAAAAAQAAAAEAAAD/gAAA/gAAAAGAAAD+gAAA/4ADAAAA/wAAAAEAAAD+AAAA/4AAAACAAAAAgAAAAIAAAAAAAAEAgACAA4ADAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQCAAwAAAP+AAAD/gAAA/4AAAAGAAAD9AAAAAIAAAACAAAAAgAAA/oADAAAA/4AAAP+AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAAAgAAAAAAAAQCAAIADAAQAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAYABgAAA/wAAAP+AAAAAgAAAAQAAAP6AAAD/gAAA/4AAAACAAAAAgAQAAAD/gAAA/wAAAP+AAAD/AAAA/4AAAACAAAABAAAAAIAAAAEAAAAAAAABAYAAgAKABAAAAwAAAQEBAQGAAQAAAP8ABAAAAPyAAAAAAAABAQAAgAOABAAAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAGAAAAAgAAAAIAAAP+AAAD/gAAA/oAAAAEAAAAAgAAA/4AAAP8ABAAAAP+AAAD/AAAA/4AAAP8AAAD/gAAAAIAAAAEAAAAAgAAAAQAAAAAAAAEAgAGAA4ADAAAPAAABAQEBAQEBAQEBAQEBAQEBAQABAAAAAQAAAACAAAD/gAAA/wAAAP8AAAD/gAAAAIADAAAA/4AAAACAAAD/AAAA/4AAAACAAAD/gAAAAQAAAAAAAAEAAAAABAAEAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAYAAAAEAAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD/AAAA/wAEAAAA/4AAAP+AAAD/gAAA/wAAAP6AAAABAAAAAQAAAACAAAAAgAAAAAAAAQIAAAAEAAQAAAMAAAEBAQECAAIAAAD+AAQAAAD8AAAAAAAAAgCAAIADgAQAABcAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGAAYAAAP8AAAABAAAA/4AAAP+AAAABgAAA/QAAAACAAAAAgAAA/wAAAACAAAAAgAGAAIAAAP+ABAAAAP+AAAD/AAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAABAAAAAAAAAP+AAAAAAQCAAIADgAQAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAEAAAABAAAAAQAAAP+AAAAAgAAA/wAAAAEAAAD/AAAA/wAAAP8AAAABAAAA/wAAAACAAAD/gAQAAAD+gAAAAYAAAP8AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAABACAAIAEAAQAABcAGwAfACMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAoAAAP4AAAABgAAAAIAAAACAAAD/gAAA/YAAAAIAAAD+gAAA/4AAAP+AAAAAgAEAAAAAgAAAAQAAgAAA/4D9AACAAAD/gAQAAAD/gAAA/4AAAP+AAAD/gAAA/wAAAP+AAAAAgAAAAIAAAACAAAAAgAAAAQAAAP8A/4AAAACAAQAAAP+AAAD+gAAA/4AAAAAEAIAAgAQAA4AAAwAHAAsADwAAAQEBAQEBAQEBAQEBAQEBAQCAAIAAAP+AAQAAgAAA/4ABAACAAAD/gAEAAIAAAP+AA4AAAP0AAAADAAAA/QAAAAMAAAD9AAAAAwAAAP0AAAAAAQIAAAAEAAQAAAkAAAEBAQEBAQEBAQEDgACAAAD+AAAAAIAAAACAAAAAgAQAAAD8AAAAAQAAAAEAAAABAAAAAAgAAAAABAAEAAADAAcACwAPABMAFwAbAB8AAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAABAAAA/wACAAEAAAD/AP8AAQAAAP8AAgABAAAA/wD9AAEAAAD/AAIAAQAAAP8A/wABAAAA/wACAAEAAAD/AAQAAAD/AAAAAQAAAP8AAAAAAAAA/wAAAAEAAAD/AAAAAAAAAP8AAAABAAAA/wAAAAAAAAD/AAAAAQAAAP8AAAAAAQIAAAADAAQAAAMAAAEBAQECAAEAAAD/AAQAAAD8AAAAAAAAAgGAAIACgAQAAAMABwAAAQEBAQEBAQEBgAEAAAD/AAAAAQAAAP8ABAAAAP6AAAD/gAAA/oAAAAABAgAAAAQAAgAAAwAAAQEBAQIAAgAAAP4AAgAAAP4AAAAAAAAEAIAAAAQABAAAAwAHAAsADwAAAQEBAQEBAQEBAQEBAQEBAQCAAIAAAP+AAQAAgAAA/4ABAACAAAD/gAEAAIAAAP+ABAAAAPwAAAAEAAAA/AAAAAQAAAD8AAAABAAAAPwAAAAAAQCAAIADgAOAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAoABAAAA/oAAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAAEAAAD/gAOAAAD+AAAA/wAAAACAAAAAgAAAAIAAAACAAAAAgAAA/wAAAAEAAAAAAAABAAAAAAQABAAACwAAAQEBAQEBAQEBAQEBAAAEAAAA/gAAAP+AAAD/gAAA/4AAAP+ABAAAAPwAAAAAgAAAAIAAAACAAAAAgAAAAAAAAQCAAIAEAAOAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAOAAAD/gAAAAIAAAP8AAAABAAAA/oAAAAGAAAD9AAAAAIAAAP+AAAABAAAA/wAAAAGAAAD+gAAAAAAAAQAAAAACAAQAAAkAAAEBAQEBAQEBAQEAAACAAAAAgAAAAIAAAACAAAD+AAQAAAD/AAAA/wAAAP8AAAD/AAAAAAEAAAAABAAEAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQKAAYAAAP8AAAD/AAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAQAEAAAA/wAAAP+AAAD/gAAA/wAAAP8AAAABgAAAAQAAAACAAAAAgAAAAAAAAQAAAAAEAAIAAA8AAAEBAQEBAQEBAQEBAQEBAQEBgAEAAAAAgAAAAIAAAACAAAD8AAAAAIAAAACAAAAAgAIAAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAAAAAAAAgAAAAAEAAQAAAMABwAAAQEBAQEBAQEAAAIAAAD+AAIAAgAAAP4ABAAAAP4AAAAAAAAA/gAAAAAEAAACAAQABAAAAwAHAAsADwAAAQEBAQEBAQEBAQEBAQEBAQAAAQAAAP8AAgABAAAA/wD/AAEAAAD/AAIAAQAAAP8ABAAAAP8AAAABAAAA/wAAAAAAAAD/AAAAAQAAAP8AAAAABAIAAAAEAAQAAAMABwALAA8AAAEBAQEBAQEBAQEBAQEBAQECAAEAAAD/AAEAAQAAAP8A/wABAAAA/wABAAEAAAD/AAQAAAD/AAAAAAAAAP8AAAAAAAAA/wAAAAAAAAD/AAAAAAEDAAAABAAEAAADAAABAQEBAwABAAAA/wAEAAAA/AAAAAAAAAEAAAAABAAEAAAFAAABAQEBAQEAAAQAAAD9AAAA/wAEAAAA/wAAAP0AAAAAAQAAAAABAAQAAAMAAAEBAQEAAAEAAAD/AAQAAAD8AAAAAAAAAwCAAIADAAOAAAMABwALAAABAQEBAQEBAQEBAQEAgACAAAD/gAEAAIAAAP+AAQAAgAAA/4ADgAAA/QAAAAMAAAD9AAAAAwAAAP0AAAAAAAABAYABgAQABAAACwAAAQEBAQEBAQEBAQEBAYABAAAAAIAAAAEAAAD+gAAA/4AAAP+ABAAAAP8AAAD/gAAA/wAAAACAAAAAgAAAAAAAAQAAAYACgAQAAAsAAAEBAQEBAQEBAQEBAQGAAQAAAP+AAAD/gAAA/oAAAAEAAAAAgAQAAAD+gAAA/4AAAP+AAAABAAAAAIAAAAAAAAEAAAAABAAEAAAJAAABAQEBAQEBAQEBAwABAAAA/AAAAAEAAAABAAAAAQAEAAAA/AAAAAKAAAAAgAAAAIAAAAABAIAAgAMABAAACwAAAQEBAQEBAQEBAQEBAgABAAAA/4AAAP6AAAD/gAAAAIAAAAEABAAAAP0AAAD/gAAAAIAAAAEAAAAAgAAAAAAAAQAAAAAEAAQAAAUAAAEBAQEBAQAAAQAAAAMAAAD8AAQAAAD9AAAA/wAAAAACAIAAgAMAAoAACwAPAAABAQEBAQEBAQEBAQEBAQEBAQABgAAAAIAAAP+AAAD+gAAAAQAAAP8A/4AAgAAA/4ACgAAA/4AAAP8AAAD/gAAAAIAAAAEAAAAAAAAA/wAAAAACAIAAgAMABAAACwAPAAABAQEBAQEBAQEBAQEBAQEBAgABAAAA/4AAAP6AAAABAAAA/wAAAAEA/oAAgAAA/4AEAAAA/QAAAP+AAAAAgAAAAQAAAACAAAD/gAAA/wAAAAABAIAAgAQABAAADQAAAQEBAQEBAQEBAQEBAQECAAIAAAD/AAAA/4AAAP6AAAD/gAAAAIAAAAEABAAAAP+AAAD9gAAA/4AAAACAAAABAAAAAIAAAAACAAAAAAQABAAAAwAHAAABAQEBAQEBAQAABAAAAPwAAQAAAAIAAAAEAAAA/AAAAAMA/gAAAAIAAAEAgACABAAEAAARAAABAQEBAQEBAQEBAQEBAQEBAQECAAIAAAD/AAAAAQAAAP8AAAD/gAAA/oAAAP+AAAAAgAAAAQAEAAAA/4AAAP+AAAD/gAAA/oAAAP+AAAAAgAAAAQAAAACAAAAAAQAAAAACgAKAAAsAAAEBAQEBAQEBAQEBAQAAAYAAAACAAAAAgAAA/wAAAP+AAAD/AAKAAAD/gAAA/4AAAP6AAAABAAAAAIAAAAAAAAEAAAAABAAEAAAFAAABAQEBAQEAAAQAAAD/AAAA/QAEAAAA/AAAAAMAAAAAAQCAAIAEAAQAABUAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAAIAAAD/AAAAAQAAAP8AAAABAAAA/wAAAP+AAAD+gAAA/4AAAACAAAABAAQAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAAEAAAAAgAAAAAEBgAAABAACgAALAAABAQEBAQEBAQEBAQECgAGAAAD/AAAA/4AAAP8AAAAAgAAAAIACgAAA/wAAAP+AAAD/AAAAAYAAAACAAAAAAAABAAAAAAQABAAAEQAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAPwABAAAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAAEAAAAABAABAAADAAABAQEBAAAEAAAA/AABAAAA/wAAAAAAAAEAAAAABAAEAAARAAABAQEBAQEBAQEBAQEBAQEBAQEDgACAAAD8AAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAEAAAA/AAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAAQAAAgAEAAQAAAMAAAEBAQEAAAQAAAD8AAQAAAD+AAAAAAAAAgCAAIACAAOAAAMABwAAAQEBAQEBAQEAgACAAAD/gAEAAIAAAP+AA4AAAP0AAAADAAAA/QAAAAAEAIAAgAQABAAAAwAHAAsADwAAAQEBAQEBAQEBAQEBAQEBAQCAA4AAAPyAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAABAAAAPyAAAADAP+AAAAAgP8A/4AAAACA/wD/gAAAAIAAAQAAAAAEAAQAAAUAAAEBAQEBAQMAAQAAAPwAAAADAAQAAAD8AAAAAQAAAAACAIAAgAQABAAAAwAHAAABAQEBAQEBAQCAA4AAAPyAAYAAAACAAAAEAAAA/IAAAAIA/4AAAACAAAMAgACABAAEAAADAAcACwAAAQEBAQEBAQEBAQEBAIADgAAA/IAAgAAAAIAAAAGAAAAAgAAABAAAAPyAAAADAP+AAAAAgP4A/4AAAACAAAAABAAAAIAEAAQAAAMABwALAA8AAAEBAQEBAQEBAQEBAQEBAQEAAAQAAAD8AAAABAAAAPwAAAAEAAAA/AAAAAQAAAD8AAQAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAAYAgACABAAEAAADAAcACwAPABMAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAIADgAAA/IAAgAAAAIAAAAGAAAAAgAAA/oAAAACAAAD+gAAAAIAAAAGAAAAAgAAABAAAAPyAAAADAP+AAAAAgAAA/4AAAACA/wD/gAAAAID/AP+AAAAAgAAA/4AAAACAAAEAgACAAQADgAADAAABAQEBAIAAgAAA/4ADgAAA/QAAAAAAAAUAgACABAAEAAADAAcACwAPABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAIADgAAA/IAAgAAAAIAAAAGAAAAAgAAA/YAAAACAAAABgAAAAIAAAAQAAAD8gAAAAwD/gAAAAIAAAP+AAAAAgP4A/4AAAACAAAD/gAAAAIAAAAABAAADAAQABAAAAwAAAQEBAQAABAAAAPwABAAAAP8AAAAAAAAHAIAAgAQABAAAAwAHAAsADwATABcAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQCAA4AAAPyAAIAAAACAAAABgAAAAIAAAP2AAAAAgAAAAYAAAACAAAD9gAAAAIAAAAGAAAAAgAAABAAAAPyAAAADAP+AAAAAgAAA/4AAAACA/wD/gAAAAIAAAP+AAAAAgP8A/4AAAACAAAD/gAAAAIAAAAAEAAAAAAQAAgAAAwAHAAsADwAAAQEBAQEBAQEBAQEBAQEBAQAAAQAAAP8AAgABAAAA/wD/AAEAAAD/AAIAAQAAAP8AAgAAAP8AAAABAAAA/wAAAAAAAAD/AAAAAQAAAP8AAAAAAQAAAAAEAAQAAAkAAAEBAQEBAQEBAQEAAAEAAAABAAAAAQAAAAEAAAD8AAQAAAD/gAAA/4AAAP+AAAD9gAAAAAEBAAAAAgAEAAADAAABAQEBAQABAAAA/wAEAAAA/AAAAAAAAAEAAAAABAAEAAALAAABAQEBAQEBAQEBAQECgAGAAAD8AAAAAIAAAACAAAAAgAAAAQAEAAAA/AAAAAGAAAABAAAAAIAAAACAAAAAAAABAAABAAQAAgAAAwAAAQEBAQAABAAAAPwAAgAAAP8AAAAAAAABAAAAAAQABAAACwAAAQEBAQEBAQEBAQEBAgACAAAA/AAAAACAAAAAgAAAAIAAAACABAAAAPwAAAACAAAAAIAAAACAAAAAgAAAAAAAAQAAAAAEAAIAAAkAAAEBAQEBAQEBAQEDAAEAAAD8AAAAAQAAAAEAAAABAAIAAAD+AAAAAIAAAACAAAAAgAAAAAEAAAAABAAEAAALAAABAQEBAQEBAQEBAQEAAAIAAAAAgAAAAIAAAACAAAAAgAAA/AAEAAAA/4AAAP+AAAD/gAAA/4AAAP4AAAAAAAADAAAAAAQABAAAGwAnADMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAEAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAIAAYAAAACAAAD/gAAA/4AAAP+AAAD/gP4AAIAAAACAAAAAgAAAAIAAAP6AAAD/gAQAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAQAAAP+AAAD+gAAAAIAAAACAAAAAgAAA/oAAAP+AAAD/gAAA/4AAAP+AAAAAgAAAAAAAAQAAAAAEAAIAAAkAAAEBAQEBAQEBAQEAAAEAAAABAAAAAQAAAAEAAAD8AAIAAAD/gAAA/4AAAP+AAAD/gAAAAAEAAAAABAAEAAALAAABAQEBAQEBAQEBAQEAAAGAAAABAAAAAIAAAACAAAAAgAAA/AAEAAAA/4AAAP+AAAD/gAAA/wAAAP6AAAAAAAAEAAAAgAQABAAAAwAHAAsADwAAAQEBAQEBAQEBAQEBAQEBAQCAAYAAAP6AAgABgAAA/oD9gAGAAAD+gAIAAYAAAP6ABAAAAP6AAAABgAAA/oAAAP+AAAD+gAAAAYAAAP6AAAAAAQIAAgAEAAQAAAMAAAEBAQECAAIAAAD+AAQAAAD+AAAAAAAABACAAIAEAAQAAAMABwAjACcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAAD/AAGAAQAAAP8A/gAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4ABgACAAAD/gAQAAAD/gAAAAIAAAP+AAAAAAAAA/wAAAP+AAAD/gAAAAIAAAACAAAABAAAA/oAAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAAGAAAD/gAAAAAQAAAAABAAEAAADAAcACwAPAAABAQEBAQEBAQEBAQEBAQEBAAAAgAAA/4ADgACAAAD/gPyAAIAAAP+AA4AAgAAA/4AEAAAA/4AAAACAAAD/gAAA/QAAAP+AAAAAgAAA/4AAAAABAAAAAAIAAgAAAwAAAQEBAQAAAgAAAP4AAgAAAP4AAAAAAAAEAAAAAAIABAAAAwAHAAsADwAAAQEBAQEBAQEBAQEBAQEBAQAAAQAAAP8AAQABAAAA/wD/AAEAAAD/AAEAAQAAAP8ABAAAAP8AAAAAAAAA/wAAAAAAAAD/AAAAAAAAAP8AAAAAAQCAAQADgAOAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAYABAAAA/4AAAAGAAAD+gAAAAIAAAP8AAAD/gAAA/4AAAACAAAAAgAOAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAACAAAAAAAABAQABAAOABAAAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQECAACAAAAAgAAAAIAAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACABAAAAP+AAAD/gAAA/wAAAACAAAD+gAAAAYAAAP+AAAABAAAAAIAAAAAAAAEBAAEABAADgAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQIAAQAAAACAAAAAgAAA/4AAAP+AAAD/AAAAAIAAAP6AAAABgAAA/4ADgAAA/4AAAP+AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAAAgAAAAAAAAQEAAIADgAOAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAgAAgAAAAIAAAACAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAOAAAD+gAAAAIAAAP8AAAD/gAAA/4AAAACAAAAAgAAAAQAAAP+AAAAAAAABAQAAgAOABAAADwAAAQEBAQEBAQEBAQEBAQEBAQIAAIAAAACAAAAAgAAA/4AAAP6AAAD/gAAAAIAAAACABAAAAP8AAAD/AAAA/wAAAP+AAAAAgAAAAQAAAAEAAAAAAAACAIAAgAOAA4AAAwAJAAABAQEBAQEBAQEBAIADAAAA/QAAgAAAAgAAAP8AAAADgAAA/QAAAAKA/gAAAAEAAAABAAAAAAIAgACABAAEAAAbACcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAACAAAAAgAAAAIAAAACAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAAAAAD/gAAAAIAAAACAAAAAgAAA/4AAAAQAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAA/4D/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAEAAAIABAADAAADAAABAQEBAAAEAAAA/AADAAAA/wAAAAAAAAEAAAAABAAEAAALAAABAQEBAQEBAQEBAQEAAAQAAAD/gAAA/4AAAP+AAAD/gAAA/gAEAAAA/gAAAP+AAAD/gAAA/4AAAP+AAAAAAAABAAACAAIABAAAAwAAAQEBAQAAAgAAAP4ABAAAAP4AAAAAAAACAQAAgAOAA4AAFwAbAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAYABgAAAAIAAAP8AAAAAgAAAAIAAAP8AAAD/gAAA/wAAAACAAAAAgAAA/wAAAACAAIAAAACAAAADgAAA/wAAAP+AAAD/gAAA/4AAAP+AAAAAgAAA/4AAAACAAAAAgAAAAIAAAACAAAAAgP+AAAAAgAADAAAAAAQABAAACwAnADMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAGAAAD/gAAA/4AAAP+AAAD/gAAAAIACgAEAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgACAAIAAAP+AAAD+gAAAAIAAAACAAAAAgAQAAAD/gAAA/4AAAP+AAAD/gAAAAYAAAACAAAD/AAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAIAAAACAAAAAgAAA/oAAAP6AAAD/gAAAAIAAAACAAAAAgAAAAAAAAgCAAIADgAQAAA8AHwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAAABAAAAAIAAAP+AAAD/AAAA/wAAAP+AAAAAgAAAAQAAAAEAAAAAgAAA/4AAAP8AAAD/AAAA/4AAAACABAAAAP+AAAAAgAAA/wAAAP+AAAAAgAAA/4AAAAEAAAD+gAAA/4AAAACAAAD/AAAA/4AAAACAAAD/gAAAAQAAAAABAAAAAAQAA4AACwAAAQEBAQEBAQEBAQEBAQACAAAAAIAAAACAAAD8AAAAAIAAAACAA4AAAP+AAAD/gAAA/YAAAAKAAAAAgAAAAAAAAQAAAAACAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEAAACAAAAAgAAAAIAAAACAAAD/gAAA/4AAAP+AAAD/gAQAAAD/gAAA/4AAAP+AAAD/AAAA/4AAAP+AAAD/gAAAAAAAAQIAAAAEAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEDgACAAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAQAAAD8AAAAAIAAAACAAAAAgAAAAQAAAACAAAAAgAAAAAAAAQCAAIAEAAQAABcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQIAAIAAAACAAAAAgAAAAIAAAP+AAAD/AAAA/4AAAP8AAAD/gAAAAIAAAACAAAAAgAQAAAD/gAAA/4AAAP+AAAD/gAAA/oAAAAEAAAD/AAAAAYAAAACAAAAAgAAAAIAAAAAAACAAAAAABAAEAAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAOwA/AEMARwBLAE8AUwBXAFsAXwBjAGcAawBvAHMAdwB7AH8AAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAgAAA/4ABAACAAAD/gAEAAIAAAP+AAQAAgAAA/4D9gACAAAD/gAEAAIAAAP+AAQAAgAAA/4ABAACAAAD/gPyAAIAAAP+AAQAAgAAA/4ABAACAAAD/gAEAAIAAAP+A/YAAgAAA/4ABAACAAAD/gAEAAIAAAP+AAQAAgAAA/4D8gACAAAD/gAEAAIAAAP+AAQAAgAAA/4ABAACAAAD/gP2AAIAAAP+AAQAAgAAA/4ABAACAAAD/gAEAAIAAAP+A/IAAgAAA/4ABAACAAAD/gAEAAIAAAP+AAQAAgAAA/4D9gACAAAD/gAEAAIAAAP+AAQAAgAAA/4ABAACAAAD/gAQAAAD/gAAAAIAAAP+AAAAAgAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAACAAAD/gAAAAIAAAP+AAAAAAAAA/4AAAACAAAD/gAAAAIAAAP+AAAAAgAAA/4AAAAAAAAD/gAAAAIAAAP+AAAAAgAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAACAAAD/gAAAAIAAAP+AAAAAAAAA/4AAAACAAAD/gAAAAIAAAP+AAAAAgAAA/4AAAAAAAAD/gAAAAIAAAP+AAAAAgAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAACAAAD/gAAAAIAAAP+AAAAAAQAAAAAEAAQAAAsAAAEBAQEBAQEBAQEBAQAABAAAAP6AAAD/AAAA/4AAAP+AAAD/gAQAAAD8AAAAAIAAAACAAAAAgAAAAQAAAAAAAAEAAAAABAAEAAALAAABAQEBAQEBAQEBAQEAAAQAAAD/gAAA/4AAAP+AAAD/AAAA/oAEAAAA/oAAAP8AAAD/gAAA/4AAAP+AAAAAAAABAAABgAKABAAADwAAAQEBAQEBAQEBAQEBAQEBAQAAAQAAAACAAAAAgAAAAIAAAP8AAAD/gAAA/4AAAP+ABAAAAP+AAAD/gAAA/4AAAP8AAAAAgAAAAIAAAACAAAAAAAABAAAAAAKABAAADwAAAQEBAQEBAQEBAQEBAQEBAQAAAQAAAACAAAAAgAAAAIAAAP8AAAD/gAAA/4AAAP+ABAAAAP+AAAD/gAAA/4AAAP2AAAACAAAAAIAAAACAAAAAAAABAYAAAAQAAoAABQAAAQEBAQEBAYACgAAA/oAAAP8AAoAAAP8AAAD+gAAAAAEAAAAABAAEAAAJAAABAQEBAQEBAQEBAAACgAAAAIAAAACAAAAAgAAA/AAEAAAA/wAAAP8AAAD/AAAA/wAAAAACAAAAAAQABAAAGwAfAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGAAQAAAACAAAAAgAAAAIAAAP+AAAD/gAAA/4AAAP8AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAAAAAEAAAAEAAAA/4AAAP+AAAD/gAAA/wAAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAAEAAAAAgAAAAIAAAP8A/wAAAAEAAAEBgAGABAAEAAAFAAABAQEBAQEBgAEAAAABgAAA/YAEAAAA/oAAAP8AAAAAAQAAAAACgAKAAA8AAAEBAQEBAQEBAQEBAQEBAQEBgAEAAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAKAAAD/AAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAAAAAQGAAAAEAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEDAAEAAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAQAAAD/AAAA/4AAAP+AAAD+AAAAAoAAAACAAAAAgAAAAAAAAQGAAAAEAAKAAA8AAAEBAQEBAQEBAQEBAQEBAQEBgAEAAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD/gAKAAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAAAAAQGAAYAEAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEDAAEAAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAQAAAD/AAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAAAAAQAAAAAEAAQAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAEAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAQAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAAAQAAAAAEAAQAAB8AAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAABAAAAAIAAAAEAAAAAgAAAAQAAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP8AAAAAgAAAAIAAAP+AAAD/gAQAAAD/gAAA/4AAAACAAAAAgAAA/wAAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAAEAAAAAgAAAAQAAAACAAAAAAAABAAABgAQABAAADwAAAQEBAQEBAQEBAQEBAQEBAQAAAQAAAACAAAAAgAAAAgAAAP2AAAD/gAAA/4AAAP+ABAAAAP+AAAD/gAAA/4AAAP8AAAAAgAAAAIAAAACAAAAAAAABAAABgAQAAoAAAwAAAQEBAQAABAAAAPwAAoAAAP8AAAAAAAABAYAAAAKABAAAAwAAAQEBAQGAAQAAAP8ABAAAAPwAAAAAAAABAYAAAAQABAAAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwABAAAA/4AAAP+AAAAAgAAAAIAAAP8AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACABAAAAP8AAAD/gAAA/wAAAP+AAAD/AAAAAIAAAACAAAAAgAAAAQAAAACAAAAAgAAAAAAAAQAAAAAEAAKAAA8AAAEBAQEBAQEBAQEBAQEBAQEAAAKAAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD+AAKAAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAAAAAQAAAYAEAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEDAAEAAAD/gAAA/4AAAP+AAAD9gAAAAgAAAACAAAAAgAQAAAD/AAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAAAAAQAAAgAEAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEAAAQAAAD/gAAA/4AAAP+AAAD/AAAA/4AAAP+AAAD/gAQAAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAAAAAAAAQAAAYACgAKAAAMAAAEBAQEAAAKAAAD9gAKAAAD/AAAAAAAAAQGAAAACgAKAAAMAAAEBAQEBgAEAAAD/AAKAAAD9gAAAAAAAAQAAAYAEAAQAABcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAQAAAACAAAABAAAAAIAAAAEAAAD/gAAA/4AAAP+AAAD/AAAA/4AAAP+AAAD/gAQAAAD/gAAA/4AAAACAAAAAgAAA/wAAAP+AAAD/gAAA/4AAAACAAAAAgAAAAIAAAAAAAAEAAAAABAAEAAAJAAABAQEBAQEBAQEBAYACgAAA/AAAAACAAAAAgAAAAIAEAAAA/AAAAAEAAAABAAAAAQAAAAABAAAAAAQABAAAEwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEDAAEAAAD/gAAA/4AAAP+AAAD/AAAA/oAAAAEAAAABAAAAAIAAAACABAAAAP6AAAD/AAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAQAAAAAAAAEAAAAABAAEAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAQAAAACAAAAAgAAAAQAAAAEAAAD+gAAA/wAAAP+AAAD/gAAA/4AEAAAA/wAAAP8AAAD/gAAA/4AAAP8AAAAAgAAAAIAAAACAAAABAAAAAAAAAQAAAAAEAAQAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAAEAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAQAAAD/AAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAAAQAAAAACgAQAABcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAQAAAACAAAAAgAAAAIAAAP+AAAD/gAAA/4AAAP8AAAAAgAAAAIAAAP+AAAD/gAQAAAD/gAAA/4AAAP+AAAD/AAAA/4AAAP+AAAD/gAAAAQAAAACAAAABAAAAAIAAAAAAAAEAAAAABAAEAAAfAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAQAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAP8AAAD/gAAA/wAAAP+AAAD/AAAAAIAAAACAAAD/gAAA/4AEAAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/wAAAACAAAAAgAAA/4AAAP+AAAABAAAAAIAAAAEAAAAAgAAAAAAAAQAAAAACgAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEBgAEAAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAQAAAD9gAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAAAAAQGAAAAEAAQAAA8AAAEBAQEBAQEBAQEBAQEBAQEBgAEAAAAAgAAAAIAAAACAAAD/AAAA/4AAAP+AAAD/gAQAAAD+AAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAAAAAAAAQAAAAAEAAKAAA8AAAEBAQEBAQEBAQEBAQEBAQEBgAKAAAD+AAAA/4AAAP+AAAD/AAAAAIAAAACAAAAAgAKAAAD/AAAA/4AAAP+AAAD/gAAAAQAAAACAAAAAgAAAAAAAAQGAAYACgAQAAAMAAAEBAQEBgAEAAAD/AAQAAAD9gAAAAAAAAQGAAYAEAAKAAAMAAAEBAQEBgAKAAAD9gAKAAAD/AAAAAAAAAQAAAAAEAAQAAB8AAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwABAAAA/4AAAP+AAAAAgAAAAIAAAP8AAAD/gAAA/wAAAP+AAAD/AAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAQAAAD/AAAA/4AAAP8AAAD/gAAA/wAAAACAAAAAgAAA/4AAAP+AAAABAAAAAIAAAACAAAAAgAAAAIAAAACAAAAAAAABAAAAAAQABAAAIwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAABAAAAAIAAAAEAAAAAgAAAAQAAAP+AAAD/gAAAAIAAAACAAAD/AAAA/4AAAP8AAAD/gAAA/wAAAACAAAAAgAAA/4AAAP+ABAAAAP+AAAD/gAAAAIAAAACAAAD/AAAA/4AAAP8AAAD/gAAA/wAAAACAAAAAgAAA/4AAAP+AAAABAAAAAIAAAAEAAAAAgAAAAAAAAQGAAYACgAKAAAMAAAEBAQEBgAEAAAD/AAKAAAD/AAAAAAAAAQAAAAAEAAKAABcAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGAAQAAAACAAAAAgAAAAIAAAP8AAAD/gAAA/wAAAP+AAAD/AAAAAIAAAACAAAAAgAKAAAD/gAAA/4AAAP+AAAD/AAAAAIAAAACAAAD/gAAA/4AAAAEAAAAAgAAAAIAAAAAAAAEAAAGAAoAEAAAFAAABAQEBAQEBgAEAAAD9gAAAAYAEAAAA/YAAAAEAAAAAAQAAAAACgAKAAAUAAAEBAQEBAQAAAoAAAP8AAAD+gAKAAAD9gAAAAYAAAAABAAAAAAQABAAAHwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAEAAAAAgAAAAQAAAACAAAABAAAA/4AAAP+AAAAAgAAAAIAAAP8AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+ABAAAAP+AAAD/gAAAAIAAAACAAAD/AAAA/4AAAP8AAAD/gAAA/wAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAAAAAAEAAAAABAAEAAALAAABAQEBAQEBAQEBAQEBgAEAAAABgAAA/oAAAP8AAAD+gAAAAYAEAAAA/oAAAP8AAAD+gAAAAYAAAAEAAAAAAAABAAAAAAQAAoAABwAAAQEBAQEBAQEAAAQAAAD+gAAA/wAAAP6AAoAAAP8AAAD+gAAAAYAAAAAAAAEBgAAABAAEAAAHAAABAQEBAQEBAQGAAQAAAAGAAAD+gAAA/wAEAAAA/oAAAP8AAAD+gAAAAAAAAQAAAAACgAQAAAcAAAEBAQEBAQEBAYABAAAA/wAAAP6AAAABgAQAAAD8AAAAAYAAAAEAAAAAAAABAAABgAQABAAABwAAAQEBAQEBAQEBgAEAAAABgAAA/AAAAAGABAAAAP6AAAD/AAAAAQAAAAAAAAQBAAEAAwADAAADAAcACwAPAAABAQEBAQEBAQEBAQEBAQEBAYABAAAA/wD/gACAAAD/gAGAAIAAAP+A/wABAAAA/wADAAAA/4AAAAAAAAD/AAAAAQAAAP8AAAAAAAAA/4AAAAACAIAAgAOAA4AACwAPAAABAQEBAQEBAQEBAQEBAQEBAQACAAAAAIAAAP+AAAD+AAAA/4AAAACAAIAAAAEAAAADgAAA/4AAAP4AAAD/gAAAAIAAAAIAAAD/gP8AAAABAAACAAAAAAQABAAAEwAfAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAgAAAACAAAAAgAAA/4AAAP+AAAD+AAAA/4AAAP+AAAAAgAAAAIAAgAAA/4AAAACAAAABAAAAAIAAAP+AAAAEAAAA/4AAAP+AAAD+AAAA/4AAAP+AAAAAgAAAAIAAAAIAAAAAgAAA/4D/gAAA/wAAAP+AAAAAgAAAAQAAAACAABAAAAAABAAEAAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAOwA/AAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAYAAgAAA/4ACAACAAAD/gP2AAIAAAP+AAgAAgAAA/4D9gACAAAD/gAIAAIAAAP+A/YAAgAAA/4ACAACAAAD/gP+AAIAAAP+AAgAAgAAA/4D9gACAAAD/gAIAAIAAAP+A/YAAgAAA/4ACAACAAAD/gP2AAIAAAP+AAgAAgAAA/4AEAAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAAAAAAD/gAAAAIAAAP+AAAAAAAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAAAAAAD/gAAAAIAAAP+AAAAAAAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAAAQAAAAAAQABAAAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3ADsAPwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAIAAAP+AAgAAgAAA/4D+gACAAAD/gAIAAIAAAP+A/oAAgAAA/4ACAACAAAD/gP6AAIAAAP+AAgAAgAAA/4D8gACAAAD/gAIAAIAAAP+A/oAAgAAA/4ACAACAAAD/gP6AAIAAAP+AAgAAgAAA/4D+gACAAAD/gAIAAIAAAP+ABAAAAP+AAAAAgAAA/4AAAAAAAAD/gAAAAIAAAP+AAAAAAAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAAAAAAD/gAAAAIAAAP+AAAAAAAAA/4AAAACAAAD/gAAAAAAAAP+AAAAAgAAA/4AAAAAAAAD/gAAAAIAAAP+AAAAAAwCAAIADgAQAABcAGwAfAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQIAAIAAAAEAAAD/AAAAAIAAAP+AAAABAAAA/wAAAP+AAAD/AAAA/4AAAACAAAABAP+AAAAAgAAA/4AAAACAAAAEAAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACAAAAAgAAAAYAAAACAAAD/gP+AAAAAgP8A/4AAAACAAAAAAQCAAIADgAOAAA8AAAEBAQEBAQEBAQEBAQEBAQEBAAIAAAAAgAAA/4AAAP+AAAD/AAAA/4AAAP+AAAAAgAOAAAD/gAAA/wAAAP+AAAD/AAAAAQAAAACAAAABAAAAAAAAAgCAAIADgAOAAAMACQAAAQEBAQEBAQEBAQCAAwAAAP0AAYAAAP8AAAACAAAAA4AAAP0AAAACgP8AAAD/AAAAAgAAAAABAIAAgAOAA4AAAwAAAQEBAQCAAwAAAP0AA4AAAP0AAAAAAAACAIAAgAOAA4AAAwALAAABAQEBAQEBAQEBAQEAgAMAAAD9AACAAAACAAAA/4AAAP8AAAADgAAA/QAAAAKA/gAAAAIAAAD/AAAAAQAAAQAAAAAEAAQAABMAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQACAAAAAIAAAACAAAD/gAAA/4AAAP4AAAD/gAAA/4AAAACAAAAAgAQAAAD/gAAA/4AAAP4AAAD/gAAA/4AAAACAAAAAgAAAAgAAAACAAAAAAAABAQABAAMAAwAACwAAAQEBAQEBAQEBAQEBAYABAAAAAIAAAP+AAAD/AAAA/4AAAACAAwAAAP+AAAD/AAAA/4AAAACAAAABAAAAAAAAAQCAAQAEAAQAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAACAAAAAgAAAAQAAAP+AAAD/gAAAAIAAAP8AAAD/gAAA/wAAAACAAAD/gAAA/4AAAAEAAAAAgAQAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAAAgAAA/4AAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAABgCAAIAEAAQAAAMABwALAA8AEwAXAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAOAAAD8gAEAAAAAgAAAAIAAAACAAAD+AAAAAIAAAAGAAAAAgAAA/gAAAAGAAAAEAAAA/IAAAAMA/wAAAAEAAAD/AAAAAQD+gP+AAAAAgAAA/4AAAACA/4D/gAAAAIAABgCAAIAEAAQAAAMABwALAA8AEwAXAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgAOAAAD8gAEAAAAAgAAAAIAAAACAAAD+gAAAAYAAAP4AAAAAgAAAAYAAAACAAAAEAAAA/IAAAAMA/wAAAAEAAAD/AAAAAQD+gP+AAAAAgP+A/4AAAACAAAD/gAAAAIAABgCAAIAEAAQAABMAFwAbAB8AIwAnAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAgAAgAAAAIAAAAEAAAD/AAAA/4AAAP+AAAD/gAAA/wAAAAEAAAAAgAAAAAAAgAAA/oAAgAAA/4ACAACAAAD/gP4AAIAAAP+AAgAAgAAA/4AEAAAA/wAAAP+AAAD/gAAA/4AAAP8AAAABAAAAAIAAAACAAAAAgAAA/4D/gAAAAIABAAAA/4AAAACAAAD/gAAA/oAAAP+AAAAAgAAA/4AAAAACAQAAgAOABAAAFwAbAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAYABgAAAAIAAAP+AAAD/gAAAAIAAAP+AAAD/gAAA/4AAAACAAAD/gAAAAQAAAP8A/4AAgAAA/4AEAAAA/4AAAP8AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAAAAIAAAAEAAAAAAAAA/wAAAAACAIAAgAQABAAAFwAbAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAYACgAAA/4AAAP+AAAD/gAAAAIAAAP+AAAD+gAAAAQAAAP8AAAABAAAAAIAAAP8A/wAAgAAA/4AEAAAA/gAAAAEAAAD/gAAA/4AAAP8AAAD/gAAAAIAAAAEAAAAAgAAAAIAAAACAAAD+gAAA/wAAAAABAIAAgAQABAAAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQIAAIAAAACAAAAAgAAAAIAAAP8AAAD/gAAAAIAAAP6AAAAAgAAA/4AAAP8AAAAAgAAAAIAAAACABAAAAP+AAAD/gAAA/4AAAP8AAAAAgAAA/wAAAP+AAAAAgAAAAQAAAP+AAAABAAAAAIAAAACAAAAAAAABAIAAgAQABAAAGwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQGAAYAAAP+AAAAAgAAAAQAAAP8AAAD/gAAAAIAAAP6AAAAAgAAA/4AAAP8AAAABAAAAAIAAAP+ABAAAAP8AAAD/gAAAAIAAAP6AAAAAgAAA/wAAAP+AAAAAgAAAAQAAAP+AAAABgAAA/4AAAACAAAAAAAABAIAAgAQABAAAFwAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAAAAIAAAAEAAAAAgAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAACABAAAAP+AAAAAgAAA/4AAAP6AAAD/gAAA/4AAAP+AAAAAgAAAAIAAAACAAAABgAAAAAAAAQCAAIAEAAQAABsAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAACAAAAAgAAAAIAAAACAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAQAAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAAAAAQEAAIADgAQAAAsAAAEBAQEBAQEBAQEBAQIAAYAAAP8AAAD/gAAA/wAAAACAAAAAgAQAAAD/AAAA/gAAAP+AAAABAAAAAIAAAAAAAAEAgACABAAEAAATAAABAQEBAQEBAQEBAQEBAQEBAQEBAQGAAoAAAP+AAAD/AAAAAIAAAACAAAD+gAAA/4AAAP8AAAAAgAAAAIAEAAAA/QAAAP+AAAABAAAAAIAAAAEAAAD+AAAA/4AAAAEAAAAAgAAAAAAAAAAYASYAAQAAAAAAAAAIAAAAAQAAAAAAAQAIAAgAAQAAAAAAAgAHABAAAQAAAAAAAwAIABcAAQAAAAAABAAQAB8AAQAAAAAABQALAC8AAQAAAAAABgAIADoAAQAAAAAACQAJAEIAAQAAAAAACgA6AEsAAQAAAAAADQARAIUAAQAAAAAADgAyAJYAAQAAAAAAEwAMAMgAAwABBAkAAAAQANQAAwABBAkAAQAQAOQAAwABBAkAAgAOAPQAAwABBAkAAwAQAQIAAwABBAkABAAgARIAAwABBAkABQAWATIAAwABBAkABgAQAUgAAwABBAkACQASAVgAAwABBAkACgB0AWoAAwABBAkADQAiAd4AAwABBAkADgBkAgAAAwABBAkAEwAYAmQoYykgMjAyMlVyc2FGb250UmVndWxhclVyc2FGb250VXJzYUZvbnQgUmVndWxhclZlcnNpb24gMS4wVXJzYUZvbnRVcnNhRnJhbmtBbiBvcGVuIGxpY2VuY2UgZ2VuZXJhbCBwdXJwb3NlIHRleHRtb2RlIGZvbnQgYnkgVXJzYUZyYW5rQ0MwIDEuMCBVbml2ZXJzYWxodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvcHVibGljZG9tYWluL3plcm8vMS4wL0hlbGxvIFdvcmxkIQAoAGMAKQAgADIAMAAyADIAVQByAHMAYQBGAG8AbgB0AFIAZQBnAHUAbABhAHIAVQByAHMAYQBGAG8AbgB0AFUAcgBzAGEARgBvAG4AdAAgAFIAZQBnAHUAbABhAHIAVgBlAHIAcwBpAG8AbgAgADEALgAwAFUAcgBzAGEARgBvAG4AdABVAHIAcwBhAEYAcgBhAG4AawBBAG4AIABvAHAAZQBuACAAbABpAGMAZQBuAGMAZQAgAGcAZQBuAGUAcgBhAGwAIABwAHUAcgBwAG8AcwBlACAAdABlAHgAdABtAG8AZABlACAAZgBvAG4AdAAgAGIAeQAgAFUAcgBzAGEARgByAGEAbgBrAEMAQwAwACAAMQAuADAAIABVAG4AaQB2AGUAcgBzAGEAbABoAHQAdABwAHMAOgAvAC8AYwByAGUAYQB0AGkAdgBlAGMAbwBtAG0AbwBuAHMALgBvAHIAZwAvAHAAdQBiAGwAaQBjAGQAbwBtAGEAaQBuAC8AegBlAHIAbwAvADEALgAwAC8ASABlAGwAbABvACAAVwBvAHIAbABkACEAAAADAAAAAAAAAGYAMwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\r
|
|
756
723
|
`;
|
|
757
724
|
class O {
|
|
758
725
|
/**
|
|
759
|
-
*
|
|
726
|
+
* Extracts all available characters from a font's cmap tables.
|
|
727
|
+
* @param font The parsed font object from Typr
|
|
728
|
+
* @returns Array of unique character strings
|
|
729
|
+
*/
|
|
730
|
+
extractCharacters(A) {
|
|
731
|
+
var t;
|
|
732
|
+
const e = [];
|
|
733
|
+
return (t = A == null ? void 0 : A.cmap) != null && t.tables ? (A.cmap.tables.forEach((r) => {
|
|
734
|
+
if (r.format === 4) {
|
|
735
|
+
const B = this._extractCharactersFromFormat4Table(r);
|
|
736
|
+
e.push(...B);
|
|
737
|
+
} else if (r.format === 12) {
|
|
738
|
+
const B = this._extractCharactersFromFormat12Table(r);
|
|
739
|
+
e.push(...B);
|
|
740
|
+
}
|
|
741
|
+
}), [...new Set(e)]) : [];
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Extracts characters from a Format 4 cmap table (Basic Multilingual Plane).
|
|
745
|
+
* @param table The Format 4 cmap table
|
|
746
|
+
* @returns Array of character strings
|
|
747
|
+
*/
|
|
748
|
+
_extractCharactersFromFormat4Table(A) {
|
|
749
|
+
const e = [];
|
|
750
|
+
if (!A.startCount || !A.endCount || !A.idRangeOffset || !A.idDelta)
|
|
751
|
+
return e;
|
|
752
|
+
for (let t = 0; t < A.startCount.length; t++) {
|
|
753
|
+
const r = A.startCount[t], B = A.endCount[t];
|
|
754
|
+
if (!(r === 65535 && B === 65535)) {
|
|
755
|
+
for (let E = r; E <= B; E++)
|
|
756
|
+
if (this._calculateGlyphIndexFormat4(A, E, t) > 0) {
|
|
757
|
+
const i = String.fromCodePoint(E);
|
|
758
|
+
e.push(i);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return e;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Extracts characters from a Format 12 cmap table (Extended Unicode ranges).
|
|
766
|
+
* @param table The Format 12 cmap table
|
|
767
|
+
* @returns Array of character strings
|
|
768
|
+
*/
|
|
769
|
+
_extractCharactersFromFormat12Table(A) {
|
|
770
|
+
const e = [];
|
|
771
|
+
if (!A.groups)
|
|
772
|
+
return e;
|
|
773
|
+
for (let t = 0; t < A.groups.length; t += 3) {
|
|
774
|
+
const r = A.groups[t], B = A.groups[t + 1], E = A.groups[t + 2];
|
|
775
|
+
for (let g = r; g <= B; g++)
|
|
776
|
+
if (E + (g - r) > 0) {
|
|
777
|
+
const o = String.fromCodePoint(g);
|
|
778
|
+
e.push(o);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return e;
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Calculates the glyph index for a character in a Format 4 cmap table.
|
|
785
|
+
* @param table The Format 4 cmap table
|
|
786
|
+
* @param codePoint The Unicode code point
|
|
787
|
+
* @param rangeIndex The index of the character range
|
|
788
|
+
* @returns The glyph index, or 0 if not found
|
|
789
|
+
*/
|
|
790
|
+
_calculateGlyphIndexFormat4(A, e, t) {
|
|
791
|
+
if (A.idRangeOffset[t] === 0)
|
|
792
|
+
return e + A.idDelta[t] & 65535;
|
|
793
|
+
{
|
|
794
|
+
const r = A.idRangeOffset[t] / 2 + (e - A.startCount[t]) - (A.startCount.length - t);
|
|
795
|
+
if (r >= 0 && A.glyphIdArray && r < A.glyphIdArray.length) {
|
|
796
|
+
const B = A.glyphIdArray[r];
|
|
797
|
+
if (B !== 0)
|
|
798
|
+
return B + A.idDelta[t] & 65535;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
return 0;
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Filters out problematic characters that might cause rendering issues.
|
|
805
|
+
* @param characters Array of character strings to filter
|
|
806
|
+
* @returns Filtered array of character strings
|
|
807
|
+
*/
|
|
808
|
+
filterProblematicCharacters(A) {
|
|
809
|
+
return A.filter((e) => this._isValidCharacter(e));
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Checks if a character is valid for rendering.
|
|
813
|
+
* @param char The character to check
|
|
814
|
+
* @returns True if the character is valid, false otherwise
|
|
815
|
+
*/
|
|
816
|
+
_isValidCharacter(A) {
|
|
817
|
+
const e = A.codePointAt(0) || 0;
|
|
818
|
+
return !(e >= 0 && e <= 31 && e !== 9 && e !== 10 && e !== 13 || e >= 127 && e <= 159);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
class z {
|
|
822
|
+
/**
|
|
823
|
+
* Creates a new TextureAtlasCreation instance.
|
|
824
|
+
* @param renderer The WebGL renderer instance
|
|
825
|
+
*/
|
|
826
|
+
constructor(A) {
|
|
827
|
+
Q(this, "_textureCanvas");
|
|
828
|
+
Q(this, "_textureContext");
|
|
829
|
+
Q(this, "_renderer");
|
|
830
|
+
this._renderer = A, this._textureCanvas = document.createElement("canvas"), this._textureContext = this._textureCanvas.getContext("2d", { willReadFrequently: !0 });
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Creates a texture atlas from the given characters.
|
|
834
|
+
* @param characters Array of TextmodeCharacter objects
|
|
835
|
+
* @param maxGlyphDimensions Maximum dimensions of glyphs
|
|
836
|
+
* @param fontSize Font size for rendering
|
|
837
|
+
* @param fontFamilyName Font family name to use
|
|
838
|
+
* @returns Object containing framebuffer, columns, and rows
|
|
839
|
+
*/
|
|
840
|
+
async createTextureAtlas(A, e, t, r) {
|
|
841
|
+
const B = A.length, E = Math.ceil(Math.sqrt(B)), g = Math.ceil(B / E), i = e.width * E, o = e.height * g;
|
|
842
|
+
this._setupCanvas(i, o, t, r), this._renderCharactersToCanvas(A, e, E, t), this._applyBlackWhiteThreshold();
|
|
843
|
+
const n = this._renderer.createFramebuffer(i, o, { filter: "nearest" });
|
|
844
|
+
return n.update(this._textureCanvas), {
|
|
845
|
+
framebuffer: n,
|
|
846
|
+
columns: E,
|
|
847
|
+
rows: g
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Sets up the canvas for rendering.
|
|
852
|
+
* @param width Canvas width
|
|
853
|
+
* @param height Canvas height
|
|
854
|
+
* @param fontSize Font size
|
|
855
|
+
* @param fontFamilyName Font family name
|
|
856
|
+
*/
|
|
857
|
+
_setupCanvas(A, e, t, r) {
|
|
858
|
+
this._textureCanvas.width = A, this._textureCanvas.height = e, this._textureContext.imageSmoothingEnabled = !0, this._textureContext.imageSmoothingQuality = "high", this._textureContext.fillStyle = "black", this._textureContext.fillRect(0, 0, A, e), this._textureContext.font = `${t}px ${r}`, this._textureContext.textBaseline = "top", this._textureContext.textAlign = "left", this._textureContext.fillStyle = "white";
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Renders all characters to the canvas in a grid layout.
|
|
862
|
+
* @param characters Array of characters to render
|
|
863
|
+
* @param maxGlyphDimensions Maximum glyph dimensions
|
|
864
|
+
* @param textureColumns Number of columns in the texture
|
|
865
|
+
* @param fontSize Font size
|
|
866
|
+
*/
|
|
867
|
+
_renderCharactersToCanvas(A, e, t, r) {
|
|
868
|
+
for (let B = 0; B < A.length; B++) {
|
|
869
|
+
const E = B % t, g = Math.floor(B / t), i = E * e.width + e.width / 2, o = g * e.height + e.height / 2, n = i - e.width / 2, a = o - r / 2;
|
|
870
|
+
this._textureContext.fillText(A[B].character, n, a);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Applies a black and white threshold filter to the canvas.
|
|
875
|
+
* This converts antialiased grayscale pixels to pure black or white,
|
|
876
|
+
* ensuring crisp text rendering suitable for NEAREST texture filtering.
|
|
877
|
+
* @param threshold Threshold value (0-255) for black/white conversion
|
|
878
|
+
*/
|
|
879
|
+
_applyBlackWhiteThreshold(A = 128) {
|
|
880
|
+
const e = this._textureContext.getImageData(0, 0, this._textureCanvas.width, this._textureCanvas.height), t = e.data;
|
|
881
|
+
for (let r = 0; r < t.length; r += 4) {
|
|
882
|
+
const E = 0.299 * t[r] + 0.587 * t[r + 1] + 0.114 * t[r + 2] > A ? 255 : 0;
|
|
883
|
+
t[r] = E, t[r + 1] = E, t[r + 2] = E;
|
|
884
|
+
}
|
|
885
|
+
this._textureContext.putImageData(e, 0, 0);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
class H {
|
|
889
|
+
/**
|
|
890
|
+
* Creates a new MetricsCalculation instance.
|
|
891
|
+
*/
|
|
892
|
+
constructor() {
|
|
893
|
+
Q(this, "_tempCanvas");
|
|
894
|
+
Q(this, "_tempContext");
|
|
895
|
+
this._tempCanvas = document.createElement("canvas"), this._tempContext = this._tempCanvas.getContext("2d");
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Calculates the maximum glyph dimensions for a given set of characters.
|
|
899
|
+
* @param characters Array of character strings
|
|
900
|
+
* @param fontSize Font size to use for measurement
|
|
901
|
+
* @param fontFamilyName Font family name
|
|
902
|
+
* @param fontFace FontFace object (optional, for validation)
|
|
903
|
+
* @returns Object containing width and height dimensions
|
|
904
|
+
*/
|
|
905
|
+
calculateMaxGlyphDimensions(A, e, t) {
|
|
906
|
+
this._tempContext.font = `${e}px ${t}`;
|
|
907
|
+
let r = 0, B = 0;
|
|
908
|
+
for (const E of A) {
|
|
909
|
+
const g = this._tempContext.measureText(E), i = g.width, o = g.actualBoundingBoxAscent + g.actualBoundingBoxDescent;
|
|
910
|
+
i > 0 && (r = Math.max(r, i), B = Math.max(B, o));
|
|
911
|
+
}
|
|
912
|
+
return {
|
|
913
|
+
width: Math.ceil(r),
|
|
914
|
+
height: Math.ceil(B)
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
class L {
|
|
919
|
+
/**
|
|
920
|
+
* Creates TextmodeCharacter objects with unique color assignments.
|
|
921
|
+
* @param characters Array of character strings
|
|
922
|
+
* @returns Array of TextmodeCharacter objects with colors
|
|
923
|
+
*/
|
|
924
|
+
createCharacterObjects(A) {
|
|
925
|
+
return A.map((e, t) => {
|
|
926
|
+
const r = e.codePointAt(0) || 0, B = this._generateCharacterColor(t);
|
|
927
|
+
return {
|
|
928
|
+
character: e,
|
|
929
|
+
unicode: r,
|
|
930
|
+
color: B
|
|
931
|
+
};
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Generates a unique RGB color for a character based on its index.
|
|
936
|
+
* @param index The index of the character
|
|
937
|
+
* @returns RGB color as a tuple [r, g, b]
|
|
938
|
+
*/
|
|
939
|
+
_generateCharacterColor(A) {
|
|
940
|
+
const e = A % 256, t = Math.floor(A / 256) % 256, r = Math.floor(A / 65536) % 256;
|
|
941
|
+
return [e, t, r];
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Gets the color for a specific character.
|
|
945
|
+
* @param character The character to get the color for
|
|
946
|
+
* @param characters Array of TextmodeCharacter objects
|
|
947
|
+
* @returns RGB color as a tuple [r, g, b], or [0, 0, 0] if not found
|
|
948
|
+
*/
|
|
949
|
+
getCharacterColor(A, e) {
|
|
950
|
+
const t = e.find((r) => r.character === A);
|
|
951
|
+
return t ? t.color : [0, 0, 0];
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Gets colors for multiple characters.
|
|
955
|
+
* @param characterString String of characters to get colors for
|
|
956
|
+
* @param characters Array of TextmodeCharacter objects
|
|
957
|
+
* @returns Array of RGB colors for each character
|
|
958
|
+
*/
|
|
959
|
+
getCharacterColors(A, e) {
|
|
960
|
+
return A.split("").map((t) => this.getCharacterColor(t, e) || [0, 0, 0]);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
class k {
|
|
964
|
+
/**
|
|
965
|
+
* Creates a new TextmodeFont instance.
|
|
760
966
|
* @param renderer Renderer instance for texture creation
|
|
761
967
|
* @param fontSize Font size to use for the texture atlas
|
|
762
968
|
* @ignore
|
|
763
969
|
*/
|
|
764
|
-
constructor(
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
this
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
970
|
+
constructor(A, e = 16) {
|
|
971
|
+
Q(this, "_font");
|
|
972
|
+
Q(this, "_characters", []);
|
|
973
|
+
Q(this, "_fontFramebuffer");
|
|
974
|
+
Q(this, "_fontSize", 16);
|
|
975
|
+
Q(this, "_textureColumns", 0);
|
|
976
|
+
Q(this, "_textureRows", 0);
|
|
977
|
+
Q(this, "_maxGlyphDimensions", { width: 0, height: 0 });
|
|
978
|
+
Q(this, "_fontFace");
|
|
979
|
+
Q(this, "_fontFamilyName", "UrsaFont");
|
|
980
|
+
// Component classes
|
|
981
|
+
Q(this, "_characterExtractor");
|
|
982
|
+
Q(this, "_textureAtlas");
|
|
983
|
+
Q(this, "_metricsCalculator");
|
|
984
|
+
Q(this, "_characterColorMapper");
|
|
985
|
+
this._fontSize = e, this._characterExtractor = new O(), this._textureAtlas = new z(A), this._metricsCalculator = new H(), this._characterColorMapper = new L();
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Initializes the font manager by loading the font and creating the texture atlas.
|
|
781
989
|
* @returns Promise that resolves when initialization is complete
|
|
782
990
|
* @ignore
|
|
783
991
|
*/
|
|
784
992
|
async initialize() {
|
|
785
|
-
const
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
/**
|
|
789
|
-
* Initializes the characters array from the font's cmap table
|
|
790
|
-
*/
|
|
791
|
-
_initializeCharacters() {
|
|
792
|
-
const e = [], A = /* @__PURE__ */ new Map();
|
|
793
|
-
this._font && this._font.cmap && this._font.cmap.tables && this._font.cmap.tables.forEach((B) => {
|
|
794
|
-
if (B.format === 4 && B.startCount && B.endCount && B.idRangeOffset && B.idDelta)
|
|
795
|
-
for (let Q = 0; Q < B.startCount.length; Q++) {
|
|
796
|
-
const g = B.startCount[Q], i = B.endCount[Q];
|
|
797
|
-
if (!(g === 65535 && i === 65535))
|
|
798
|
-
for (let s = g; s <= i; s++) {
|
|
799
|
-
const o = String.fromCodePoint(s);
|
|
800
|
-
let a = 0;
|
|
801
|
-
if (B.idRangeOffset[Q] === 0)
|
|
802
|
-
a = s + B.idDelta[Q] & 65535;
|
|
803
|
-
else {
|
|
804
|
-
const h = B.idRangeOffset[Q] / 2 + (s - B.startCount[Q]) - (B.startCount.length - Q);
|
|
805
|
-
if (h >= 0 && B.glyphIdArray && h < B.glyphIdArray.length) {
|
|
806
|
-
const c = B.glyphIdArray[h];
|
|
807
|
-
c !== 0 && (a = c + B.idDelta[Q] & 65535);
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
a && a > 0 && (e.push(o), A.set(o, a));
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
else if (B.format === 12 && B.groups)
|
|
814
|
-
for (let Q = 0; Q < B.groups.length; Q += 3) {
|
|
815
|
-
const g = B.groups[Q], i = B.groups[Q + 1], s = B.groups[Q + 2];
|
|
816
|
-
for (let o = g; o <= i; o++) {
|
|
817
|
-
const a = String.fromCodePoint(o), h = s + (o - g);
|
|
818
|
-
h > 0 && (e.push(a), A.set(a, h));
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
});
|
|
822
|
-
const r = [...new Set(e)].filter((B) => {
|
|
823
|
-
const Q = B.codePointAt(0) || 0;
|
|
824
|
-
return !(Q >= 0 && Q <= 31 && Q !== 9 && Q !== 10 && Q !== 13 || Q >= 127 && Q <= 159);
|
|
825
|
-
});
|
|
826
|
-
this._characters = r.map((B, Q) => {
|
|
827
|
-
const g = B.codePointAt(0) || 0, i = Q % 256, s = Math.floor(Q / 256) % 256, o = Math.floor(Q / 65536) % 256;
|
|
828
|
-
return {
|
|
829
|
-
character: B,
|
|
830
|
-
unicode: g,
|
|
831
|
-
color: [i, s, o]
|
|
832
|
-
};
|
|
833
|
-
});
|
|
993
|
+
const e = await (await fetch(S)).arrayBuffer();
|
|
994
|
+
await this._loadFontFace(e), this._font = m.parse(e)[0], await this._initializeFont();
|
|
834
995
|
}
|
|
835
996
|
/**
|
|
836
|
-
*
|
|
997
|
+
* Loads a new font from a file path.
|
|
998
|
+
* @param fontPath Path to the .otf or .ttf font file
|
|
999
|
+
* @returns Promise that resolves when font loading is complete
|
|
1000
|
+
* @ignore
|
|
837
1001
|
*/
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1002
|
+
async loadFont(A) {
|
|
1003
|
+
try {
|
|
1004
|
+
const e = await fetch(A);
|
|
1005
|
+
if (!e.ok)
|
|
1006
|
+
throw new D(`Failed to load font file: ${e.status} ${e.statusText}`);
|
|
1007
|
+
const t = await e.arrayBuffer();
|
|
1008
|
+
await this._loadFontFace(t);
|
|
1009
|
+
const r = m.parse(t);
|
|
1010
|
+
if (!r || r.length === 0)
|
|
1011
|
+
throw new Error("Failed to parse font file");
|
|
1012
|
+
this._font = r[0], await this._initializeFont();
|
|
1013
|
+
} catch (e) {
|
|
1014
|
+
throw new D(`Failed to load font: ${e instanceof Error ? e.message : "Unknown error"}`, e);
|
|
848
1015
|
}
|
|
849
|
-
this._maxGlyphDimensions = {
|
|
850
|
-
width: Math.ceil(e),
|
|
851
|
-
height: Math.ceil(A)
|
|
852
|
-
};
|
|
853
1016
|
}
|
|
854
1017
|
/**
|
|
855
|
-
*
|
|
1018
|
+
* Loads a FontFace from a font buffer.
|
|
1019
|
+
* @param fontBuffer ArrayBuffer containing font data
|
|
856
1020
|
*/
|
|
857
|
-
async
|
|
858
|
-
const e =
|
|
859
|
-
this.
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
this.
|
|
1021
|
+
async _loadFontFace(A) {
|
|
1022
|
+
const e = Date.now();
|
|
1023
|
+
this._fontFamilyName = this._fontFamilyName === "UrsaFont" ? "UrsaFont" : `CustomFont_${e}`, this._fontFace = new FontFace(this._fontFamilyName, A), await this._fontFace.load(), document.fonts.add(this._fontFace);
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Initializes all font-dependent properties using the component classes.
|
|
1027
|
+
*/
|
|
1028
|
+
async _initializeFont() {
|
|
1029
|
+
const A = this._characterExtractor.extractCharacters(this._font), e = this._characterExtractor.filterProblematicCharacters(A);
|
|
1030
|
+
this._characters = this._characterColorMapper.createCharacterObjects(e), this._maxGlyphDimensions = this._metricsCalculator.calculateMaxGlyphDimensions(
|
|
1031
|
+
e,
|
|
1032
|
+
this._fontSize,
|
|
1033
|
+
this._fontFamilyName
|
|
1034
|
+
);
|
|
1035
|
+
const t = await this._textureAtlas.createTextureAtlas(
|
|
1036
|
+
this._characters,
|
|
1037
|
+
this._maxGlyphDimensions,
|
|
1038
|
+
this._fontSize,
|
|
1039
|
+
this._fontFamilyName
|
|
1040
|
+
);
|
|
1041
|
+
this._fontFramebuffer = t.framebuffer, this._textureColumns = t.columns, this._textureRows = t.rows;
|
|
867
1042
|
}
|
|
868
1043
|
/**
|
|
869
1044
|
* Get the color associated with a character.
|
|
870
1045
|
* @param character The character to get the color for.
|
|
871
1046
|
* @returns The RGB color as an array `[r, g, b]`.
|
|
872
1047
|
*/
|
|
873
|
-
getCharacterColor(
|
|
874
|
-
|
|
875
|
-
typeof
|
|
1048
|
+
getCharacterColor(A) {
|
|
1049
|
+
return C.validate(
|
|
1050
|
+
typeof A == "string" && A.length === 1,
|
|
876
1051
|
"Character must be a single character string.",
|
|
877
|
-
{ providedValue:
|
|
878
|
-
))
|
|
879
|
-
return [0, 0, 0];
|
|
880
|
-
const t = this._characters.find((r) => r.character === e);
|
|
881
|
-
return t ? t.color : [0, 0, 0];
|
|
1052
|
+
{ providedValue: A, method: "getCharacterColor" }
|
|
1053
|
+
) ? this._characterColorMapper.getCharacterColor(A, this._characters) : [0, 0, 0];
|
|
882
1054
|
}
|
|
883
1055
|
/**
|
|
884
1056
|
* Get the colors associated with a string of characters.
|
|
@@ -886,47 +1058,25 @@ class O {
|
|
|
886
1058
|
* @returns An array of RGB colors for each character in the string.
|
|
887
1059
|
* Each color is represented as an array `[r, g, b]`.
|
|
888
1060
|
*/
|
|
889
|
-
getCharacterColors(
|
|
890
|
-
return
|
|
891
|
-
typeof
|
|
1061
|
+
getCharacterColors(A) {
|
|
1062
|
+
return C.validate(
|
|
1063
|
+
typeof A == "string" && A.length > 0,
|
|
892
1064
|
"Characters must be a string with at least one character.",
|
|
893
|
-
{ providedValue:
|
|
894
|
-
) ?
|
|
1065
|
+
{ providedValue: A, method: "getCharacterColors" }
|
|
1066
|
+
) ? this._characterColorMapper.getCharacterColors(A, this._characters) : [[0, 0, 0]];
|
|
895
1067
|
}
|
|
896
1068
|
/**
|
|
897
1069
|
* Checks if all characters in the given string exist in the font.
|
|
898
1070
|
* @param str The string to check.
|
|
899
1071
|
* @returns `true` if all characters exist in the font, `false` otherwise.
|
|
900
1072
|
*/
|
|
901
|
-
hasAllCharacters(
|
|
902
|
-
if (typeof
|
|
903
|
-
const
|
|
904
|
-
for (const t of
|
|
905
|
-
if (!
|
|
1073
|
+
hasAllCharacters(A) {
|
|
1074
|
+
if (typeof A != "string" || A.length === 0) return !1;
|
|
1075
|
+
const e = new Set(this._characters.map((t) => t.character));
|
|
1076
|
+
for (const t of A)
|
|
1077
|
+
if (!e.has(t)) return !1;
|
|
906
1078
|
return !0;
|
|
907
1079
|
}
|
|
908
|
-
/**
|
|
909
|
-
* Updates the font by loading a new font file and regenerating all related properties
|
|
910
|
-
* @param fontPath Path to the .otf or .ttf font file
|
|
911
|
-
* @param fontSize Optional new font size (defaults to current fontSize)
|
|
912
|
-
* @returns Promise that resolves when font update is complete
|
|
913
|
-
* @ignore
|
|
914
|
-
*/
|
|
915
|
-
async loadFont(e) {
|
|
916
|
-
try {
|
|
917
|
-
const A = await fetch(e);
|
|
918
|
-
if (!A.ok)
|
|
919
|
-
throw new C(`Failed to load font file: ${A.status} ${A.statusText}`);
|
|
920
|
-
const t = await A.arrayBuffer(), r = Date.now();
|
|
921
|
-
this._fontFamilyName = `CustomFont_${r}`, this._fontFace = new FontFace(this._fontFamilyName, t), await this._fontFace.load(), document.fonts.add(this._fontFace);
|
|
922
|
-
const B = m.parse(t);
|
|
923
|
-
if (!B || B.length === 0)
|
|
924
|
-
throw new Error("Failed to parse font file");
|
|
925
|
-
this._font = B[0], this._initializeCharacters(), this._calculateMaxGlyphDimensions(), await this._createTextureAtlas();
|
|
926
|
-
} catch (A) {
|
|
927
|
-
throw new C(`Failed to load font: ${A instanceof Error ? A.message : "Unknown error"}`, A);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
1080
|
/**
|
|
931
1081
|
* Returns the WebGL framebuffer containing the font texture atlas.
|
|
932
1082
|
* @ignore
|
|
@@ -938,11 +1088,11 @@ class O {
|
|
|
938
1088
|
get characters() {
|
|
939
1089
|
return this._characters;
|
|
940
1090
|
}
|
|
941
|
-
/** Returns a string representation of all characters in the font
|
|
1091
|
+
/** Returns a string representation of all characters in the font. */
|
|
942
1092
|
get charactersString() {
|
|
943
|
-
return this._characters.map((
|
|
1093
|
+
return this._characters.map((A) => A.character).join("");
|
|
944
1094
|
}
|
|
945
|
-
/** Returns the number of columns in the texture atlas
|
|
1095
|
+
/** Returns the number of columns in the texture atlas. */
|
|
946
1096
|
get textureColumns() {
|
|
947
1097
|
return this._textureColumns;
|
|
948
1098
|
}
|
|
@@ -959,7 +1109,7 @@ class O {
|
|
|
959
1109
|
return this._fontSize;
|
|
960
1110
|
}
|
|
961
1111
|
}
|
|
962
|
-
class
|
|
1112
|
+
class N {
|
|
963
1113
|
/**
|
|
964
1114
|
* Create a new grid instance.
|
|
965
1115
|
* @param canvas The canvas element used to determine the grid dimensions.
|
|
@@ -967,28 +1117,28 @@ class z {
|
|
|
967
1117
|
* @param cellHeight The height of each cell in the grid.
|
|
968
1118
|
* @ignore
|
|
969
1119
|
*/
|
|
970
|
-
constructor(
|
|
1120
|
+
constructor(A, e, t) {
|
|
971
1121
|
/** The number of columns in the grid. */
|
|
972
|
-
|
|
1122
|
+
Q(this, "_cols");
|
|
973
1123
|
/** The number of rows in the grid. */
|
|
974
|
-
|
|
1124
|
+
Q(this, "_rows");
|
|
975
1125
|
/** The total width of the grid in pixels. */
|
|
976
|
-
|
|
1126
|
+
Q(this, "_width");
|
|
977
1127
|
/** The total height of the grid in pixels. */
|
|
978
|
-
|
|
1128
|
+
Q(this, "_height");
|
|
979
1129
|
/** The offset to the outer canvas on the x-axis when centering the grid. */
|
|
980
|
-
|
|
1130
|
+
Q(this, "_offsetX");
|
|
981
1131
|
/** The offset to the outer canvas on the y-axis when centering the grid. */
|
|
982
|
-
|
|
1132
|
+
Q(this, "_offsetY");
|
|
983
1133
|
/** Whether the grid dimensions are fixed, or responsive based on the canvas dimensions. */
|
|
984
|
-
|
|
1134
|
+
Q(this, "_fixedDimensions", !1);
|
|
985
1135
|
/** The canvas element used to determine the grid dimensions. */
|
|
986
|
-
|
|
1136
|
+
Q(this, "_canvas");
|
|
987
1137
|
/** The width of each cell in the grid. */
|
|
988
|
-
|
|
1138
|
+
Q(this, "_cellWidth");
|
|
989
1139
|
/** The height of each cell in the grid. */
|
|
990
|
-
|
|
991
|
-
this._canvas =
|
|
1140
|
+
Q(this, "_cellHeight");
|
|
1141
|
+
this._canvas = A, this._cellWidth = e, this._cellHeight = t, this.reset();
|
|
992
1142
|
}
|
|
993
1143
|
/**
|
|
994
1144
|
* Reset the grid to the default number of columns and rows based on the current canvas dimensions, and the grid cell dimensions.
|
|
@@ -1009,8 +1159,8 @@ class z {
|
|
|
1009
1159
|
* @param newCellHeight The new cell height.
|
|
1010
1160
|
* @ignore
|
|
1011
1161
|
*/
|
|
1012
|
-
resizeCellPixelDimensions(
|
|
1013
|
-
[this._cellWidth, this._cellHeight] = [
|
|
1162
|
+
resizeCellPixelDimensions(A, e) {
|
|
1163
|
+
[this._cellWidth, this._cellHeight] = [A, e], this.reset();
|
|
1014
1164
|
}
|
|
1015
1165
|
/**
|
|
1016
1166
|
* Re-assign the grid dimensions and resize the grid.
|
|
@@ -1020,8 +1170,8 @@ class z {
|
|
|
1020
1170
|
* @param newRows The new number of rows.
|
|
1021
1171
|
* @ignore
|
|
1022
1172
|
*/
|
|
1023
|
-
resizeGridDimensions(
|
|
1024
|
-
this._fixedDimensions = !0, [this._cols, this._rows] = [
|
|
1173
|
+
resizeGridDimensions(A, e) {
|
|
1174
|
+
this._fixedDimensions = !0, [this._cols, this._rows] = [A, e], this._resizeGrid();
|
|
1025
1175
|
}
|
|
1026
1176
|
/**
|
|
1027
1177
|
* Make the grid dimensions flexible again, and `reset()` the grid.
|
|
@@ -1035,116 +1185,105 @@ class z {
|
|
|
1035
1185
|
* @param canvas The new canvas element to use for the grid.
|
|
1036
1186
|
* @ignore
|
|
1037
1187
|
*/
|
|
1038
|
-
|
|
1039
|
-
this.
|
|
1188
|
+
resize() {
|
|
1189
|
+
this._fixedDimensions ? this._resizeGrid() : this.reset();
|
|
1040
1190
|
}
|
|
1041
1191
|
/**
|
|
1042
|
-
*
|
|
1192
|
+
* Gets or sets whether the grid dimensions *(columns and rows)* are fixed or responsive based on the canvas dimensions.
|
|
1193
|
+
* @param value Optional. `true` to make the grid dimensions fixed, or `false` to make them responsive. If not provided, returns the current state.
|
|
1194
|
+
* @returns If no parameter is provided, returns `true` if the grid dimensions are fixed, or `false` if they are responsive.
|
|
1195
|
+
* @ignore
|
|
1043
1196
|
*/
|
|
1197
|
+
fixedDimensions(A) {
|
|
1198
|
+
if (A === void 0)
|
|
1199
|
+
return this._fixedDimensions;
|
|
1200
|
+
this._fixedDimensions = A;
|
|
1201
|
+
}
|
|
1202
|
+
/** Returns the width of each cell in the grid. */
|
|
1044
1203
|
get cellWidth() {
|
|
1045
1204
|
return this._cellWidth;
|
|
1046
1205
|
}
|
|
1047
|
-
/**
|
|
1048
|
-
* Returns the height of each cell in the grid.
|
|
1049
|
-
*/
|
|
1206
|
+
/** Returns the height of each cell in the grid. */
|
|
1050
1207
|
get cellHeight() {
|
|
1051
1208
|
return this._cellHeight;
|
|
1052
1209
|
}
|
|
1053
|
-
/**
|
|
1054
|
-
* Returns the number of columns in the grid.
|
|
1055
|
-
*/
|
|
1210
|
+
/** Returns the number of columns in the grid. */
|
|
1056
1211
|
get cols() {
|
|
1057
1212
|
return this._cols;
|
|
1058
1213
|
}
|
|
1059
|
-
/**
|
|
1060
|
-
* Returns the number of rows in the grid.
|
|
1061
|
-
*/
|
|
1214
|
+
/** Returns the number of rows in the grid. */
|
|
1062
1215
|
get rows() {
|
|
1063
1216
|
return this._rows;
|
|
1064
1217
|
}
|
|
1065
|
-
/**
|
|
1066
|
-
* Returns the total width of the grid.
|
|
1067
|
-
*/
|
|
1218
|
+
/** Returns the total width of the grid. */
|
|
1068
1219
|
get width() {
|
|
1069
1220
|
return this._width;
|
|
1070
1221
|
}
|
|
1071
|
-
/**
|
|
1072
|
-
* Returns the total height of the grid.
|
|
1073
|
-
*/
|
|
1222
|
+
/** Returns the total height of the grid. */
|
|
1074
1223
|
get height() {
|
|
1075
1224
|
return this._height;
|
|
1076
1225
|
}
|
|
1077
|
-
/**
|
|
1078
|
-
* Returns the offset to the outer canvas borders on the x-axis when centering the grid.
|
|
1079
|
-
*/
|
|
1226
|
+
/** Returns the offset to the outer canvas borders on the x-axis when centering the grid. */
|
|
1080
1227
|
get offsetX() {
|
|
1081
1228
|
return this._offsetX;
|
|
1082
1229
|
}
|
|
1083
|
-
/**
|
|
1084
|
-
* Returns the offset to the outer canvas borders on the y-axis when centering the grid.
|
|
1085
|
-
*/
|
|
1230
|
+
/** Returns the offset to the outer canvas borders on the y-axis when centering the grid. */
|
|
1086
1231
|
get offsetY() {
|
|
1087
1232
|
return this._offsetY;
|
|
1088
1233
|
}
|
|
1089
|
-
/**
|
|
1090
|
-
* Returns `true` if the grid dimensions *(columns and rows)* are fixed, or `false` if they are responsive based on the canvas dimensions.
|
|
1091
|
-
*/
|
|
1092
|
-
get fixedDimensions() {
|
|
1093
|
-
return this._fixedDimensions;
|
|
1094
|
-
}
|
|
1095
|
-
/**
|
|
1096
|
-
* Sets whether the grid dimensions *(columns and rows)* are fixed or responsive based on the canvas dimensions.
|
|
1097
|
-
* @param value `true` to make the grid dimensions fixed, or `false` to make them responsive.
|
|
1098
|
-
* @ignore
|
|
1099
|
-
*/
|
|
1100
|
-
set fixedDimensions(e) {
|
|
1101
|
-
this._fixedDimensions = e;
|
|
1102
|
-
}
|
|
1103
1234
|
}
|
|
1104
|
-
class
|
|
1105
|
-
constructor(
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
this.captureCanvas =
|
|
1235
|
+
class V {
|
|
1236
|
+
constructor(A) {
|
|
1237
|
+
Q(this, "webglCanvas");
|
|
1238
|
+
Q(this, "captureCanvas");
|
|
1239
|
+
this.captureCanvas = A, this.webglCanvas = this.createOverlayCanvas();
|
|
1109
1240
|
}
|
|
1110
1241
|
generateUniqueCanvasId() {
|
|
1111
|
-
let
|
|
1112
|
-
for (; document.getElementById(
|
|
1113
|
-
|
|
1114
|
-
return
|
|
1242
|
+
let A = 0, e = `textmodeCanvas${A}`;
|
|
1243
|
+
for (; document.getElementById(e); )
|
|
1244
|
+
A++, e = `textmodeCanvas${A}`;
|
|
1245
|
+
return e;
|
|
1115
1246
|
}
|
|
1116
1247
|
createOverlayCanvas() {
|
|
1117
1248
|
var B;
|
|
1118
|
-
const
|
|
1119
|
-
|
|
1120
|
-
const
|
|
1121
|
-
let t = parseInt(
|
|
1122
|
-
isNaN(t) && (t = 0),
|
|
1249
|
+
const A = document.createElement("canvas");
|
|
1250
|
+
A.width = this.captureCanvas.width, A.height = this.captureCanvas.height, A.className = "textmodeCanvas", A.id = this.generateUniqueCanvasId(), A.style.position = "absolute", A.style.pointerEvents = "none";
|
|
1251
|
+
const e = window.getComputedStyle(this.captureCanvas);
|
|
1252
|
+
let t = parseInt(e.zIndex || "0", 10);
|
|
1253
|
+
isNaN(t) && (t = 0), A.style.zIndex = (t + 1).toString();
|
|
1123
1254
|
const r = this.captureCanvas.getBoundingClientRect();
|
|
1124
|
-
return
|
|
1255
|
+
return A.style.width = r.width + "px", A.style.height = r.height + "px", this.positionOverlayCanvas(A), (B = this.captureCanvas.parentNode) == null || B.insertBefore(A, this.captureCanvas.nextSibling), A;
|
|
1125
1256
|
}
|
|
1126
|
-
positionOverlayCanvas(
|
|
1127
|
-
const
|
|
1257
|
+
positionOverlayCanvas(A) {
|
|
1258
|
+
const e = this.captureCanvas.getBoundingClientRect();
|
|
1128
1259
|
let t = this.captureCanvas.offsetParent;
|
|
1129
1260
|
if (t && t !== document.body) {
|
|
1130
1261
|
const r = t.getBoundingClientRect();
|
|
1131
|
-
|
|
1262
|
+
A.style.top = e.top - r.top + "px", A.style.left = e.left - r.left + "px";
|
|
1132
1263
|
} else
|
|
1133
|
-
|
|
1264
|
+
A.style.top = e.top + window.scrollY + "px", A.style.left = e.left + window.scrollX + "px";
|
|
1134
1265
|
}
|
|
1135
1266
|
resize() {
|
|
1136
1267
|
this.webglCanvas.width = this.captureCanvas.width, this.webglCanvas.height = this.captureCanvas.height;
|
|
1137
|
-
const
|
|
1138
|
-
this.webglCanvas.style.width =
|
|
1268
|
+
const A = this.captureCanvas.getBoundingClientRect();
|
|
1269
|
+
this.webglCanvas.style.width = A.width + "px", this.webglCanvas.style.height = A.height + "px", this.positionOverlayCanvas(this.webglCanvas);
|
|
1139
1270
|
}
|
|
1140
1271
|
/**
|
|
1141
1272
|
* Get the WebGL context for the overlay canvas
|
|
1142
1273
|
*/
|
|
1143
1274
|
getWebGLContext() {
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1275
|
+
const A = {
|
|
1276
|
+
alpha: !0,
|
|
1277
|
+
premultipliedAlpha: !1,
|
|
1278
|
+
preserveDrawingBuffer: !0,
|
|
1279
|
+
antialias: !1,
|
|
1280
|
+
depth: !1,
|
|
1281
|
+
stencil: !1,
|
|
1282
|
+
powerPreference: "high-performance"
|
|
1283
|
+
}, e = this.webglCanvas.getContext("webgl2", A) || this.webglCanvas.getContext("webgl", A);
|
|
1284
|
+
if (!e)
|
|
1285
|
+
throw new D("WebGL context could not be created. Ensure your browser supports WebGL.");
|
|
1286
|
+
return e;
|
|
1148
1287
|
}
|
|
1149
1288
|
// Getters
|
|
1150
1289
|
get canvas() {
|
|
@@ -1158,18 +1297,22 @@ class H {
|
|
|
1158
1297
|
}
|
|
1159
1298
|
}
|
|
1160
1299
|
class p {
|
|
1161
|
-
constructor(
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
this.renderer =
|
|
1172
|
-
}
|
|
1300
|
+
constructor(A, e, t, r = {}) {
|
|
1301
|
+
Q(this, "renderer");
|
|
1302
|
+
Q(this, "fontManager");
|
|
1303
|
+
Q(this, "grid");
|
|
1304
|
+
Q(this, "_characterFramebuffer");
|
|
1305
|
+
Q(this, "_primaryColorFramebuffer");
|
|
1306
|
+
Q(this, "_secondaryColorFramebuffer");
|
|
1307
|
+
Q(this, "_rotationFramebuffer");
|
|
1308
|
+
Q(this, "_transformFramebuffer");
|
|
1309
|
+
Q(this, "options");
|
|
1310
|
+
this.renderer = A, this.fontManager = e, this.grid = t, this.options = r, this._characterFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._primaryColorFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._rotationFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._transformFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Resizes all internal framebuffers to match the grid dimensions.
|
|
1314
|
+
* @ignore
|
|
1315
|
+
*/
|
|
1173
1316
|
resize() {
|
|
1174
1317
|
this._characterFramebuffer.resize(this.grid.cols, this.grid.rows), this._primaryColorFramebuffer.resize(this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer.resize(this.grid.cols, this.grid.rows), this._rotationFramebuffer.resize(this.grid.cols, this.grid.rows), this._transformFramebuffer.resize(this.grid.cols, this.grid.rows);
|
|
1175
1318
|
}
|
|
@@ -1189,56 +1332,41 @@ class p {
|
|
|
1189
1332
|
return this._transformFramebuffer;
|
|
1190
1333
|
}
|
|
1191
1334
|
}
|
|
1192
|
-
class
|
|
1335
|
+
class J {
|
|
1193
1336
|
/**
|
|
1194
1337
|
* Create a new color palette instance.
|
|
1195
1338
|
* @param renderer The renderer instance.
|
|
1196
1339
|
* @param colors The RGB colors to store as [r, g, b] arrays where values are 0-255.
|
|
1197
1340
|
*/
|
|
1198
|
-
constructor(
|
|
1341
|
+
constructor(A, e) {
|
|
1199
1342
|
/** The framebuffer used to store the color palette. */
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
this._renderer =
|
|
1343
|
+
Q(this, "_framebuffer");
|
|
1344
|
+
Q(this, "_renderer");
|
|
1345
|
+
Q(this, "_colors");
|
|
1346
|
+
this._renderer = A, this._colors = e;
|
|
1204
1347
|
const t = Math.max(this._colors.length, 1);
|
|
1205
|
-
this._framebuffer = this._renderer.createFramebuffer(t, 1,
|
|
1206
|
-
filter: "nearest",
|
|
1207
|
-
wrap: "clamp",
|
|
1208
|
-
format: "rgba"
|
|
1209
|
-
}), this._updateFramebuffer();
|
|
1348
|
+
this._framebuffer = this._renderer.createFramebuffer(t, 1), this._updateFramebuffer();
|
|
1210
1349
|
}
|
|
1211
1350
|
/**
|
|
1212
1351
|
* Update the framebuffer with the currently selected colors.
|
|
1213
1352
|
*/
|
|
1214
1353
|
_updateFramebuffer() {
|
|
1215
|
-
if (!this._framebuffer
|
|
1216
|
-
const
|
|
1217
|
-
this._framebuffer.width !==
|
|
1218
|
-
const t = new Uint8Array(
|
|
1219
|
-
for (let
|
|
1220
|
-
const
|
|
1221
|
-
t[
|
|
1354
|
+
if (!this._framebuffer) return;
|
|
1355
|
+
const A = Math.max(this._colors.length, 1), e = 1;
|
|
1356
|
+
this._framebuffer.width !== A && this._framebuffer.resize(A, e);
|
|
1357
|
+
const t = new Uint8Array(A * e * 4);
|
|
1358
|
+
for (let r = 0; r < A; r++) {
|
|
1359
|
+
const B = r < this._colors.length ? this._colors[r] : [0, 0, 0], E = r * 4;
|
|
1360
|
+
t[E] = B[0], t[E + 1] = B[1], t[E + 2] = B[2], t[E + 3] = 255;
|
|
1222
1361
|
}
|
|
1223
|
-
|
|
1224
|
-
r.bindTexture(r.TEXTURE_2D, this._framebuffer.texture), r.texImage2D(
|
|
1225
|
-
r.TEXTURE_2D,
|
|
1226
|
-
0,
|
|
1227
|
-
r.RGBA,
|
|
1228
|
-
e,
|
|
1229
|
-
A,
|
|
1230
|
-
0,
|
|
1231
|
-
r.RGBA,
|
|
1232
|
-
r.UNSIGNED_BYTE,
|
|
1233
|
-
t
|
|
1234
|
-
), r.bindTexture(r.TEXTURE_2D, null);
|
|
1362
|
+
this._framebuffer.updatePixels(t, A, e);
|
|
1235
1363
|
}
|
|
1236
1364
|
/**
|
|
1237
1365
|
* Sets the colors of the palette and updates the framebuffer.
|
|
1238
1366
|
* @param newColors The new RGB colors to set as [r, g, b] arrays.
|
|
1239
1367
|
*/
|
|
1240
|
-
setColors(
|
|
1241
|
-
this._colors =
|
|
1368
|
+
setColors(A) {
|
|
1369
|
+
this._colors = A, this._updateFramebuffer();
|
|
1242
1370
|
}
|
|
1243
1371
|
/**
|
|
1244
1372
|
* Get the colors of the palette.
|
|
@@ -1259,78 +1387,124 @@ class L {
|
|
|
1259
1387
|
return this._framebuffer.texture;
|
|
1260
1388
|
}
|
|
1261
1389
|
}
|
|
1262
|
-
class
|
|
1263
|
-
constructor(
|
|
1264
|
-
super(
|
|
1265
|
-
|
|
1266
|
-
this.palette = new
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1390
|
+
class _ extends p {
|
|
1391
|
+
constructor(e, t, r, B = {}) {
|
|
1392
|
+
super(e, t, r, B);
|
|
1393
|
+
Q(this, "palette");
|
|
1394
|
+
this.palette = new J(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* Sets the characters used for brightness mapping.
|
|
1398
|
+
* @param characters The characters to use for brightness mapping, ordered from darkest to brightest.
|
|
1399
|
+
*/
|
|
1400
|
+
characters(e) {
|
|
1401
|
+
C.validate(
|
|
1402
|
+
this.fontManager.hasAllCharacters(e),
|
|
1271
1403
|
"One or more characters do not exist in the current font.",
|
|
1272
|
-
{ method: "characters", providedValue:
|
|
1273
|
-
) && (this.options.characters =
|
|
1404
|
+
{ method: "characters", providedValue: e }
|
|
1405
|
+
) && (this.options.characters = e, this.palette.setColors(this.fontManager.getCharacterColors(e)));
|
|
1274
1406
|
}
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1407
|
+
/**
|
|
1408
|
+
* Sets a fixed color for characters if `characterColorMode` is `fixed`.
|
|
1409
|
+
* @param r Red component (0-255).
|
|
1410
|
+
* @param g Green component (0-255).
|
|
1411
|
+
* @param b Blue component (0-255).
|
|
1412
|
+
* @param a Alpha component (0-255).
|
|
1413
|
+
*/
|
|
1414
|
+
characterColor(e, t = e, r = e, B = 255) {
|
|
1415
|
+
C.validate(
|
|
1416
|
+
[e, t, r, B].every((E) => E >= 0 && E <= 255),
|
|
1278
1417
|
"Character color values must be between 0 and 255",
|
|
1279
|
-
{ method: "characterColor", providedValues: { r:
|
|
1280
|
-
) && (this.options.characterColor = [
|
|
1418
|
+
{ method: "characterColor", providedValues: { r: e, g: t, b: r, a: B } }
|
|
1419
|
+
) && (this.options.characterColor = [e, t, r, B]);
|
|
1281
1420
|
}
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1421
|
+
/**
|
|
1422
|
+
* Sets the character color mode.
|
|
1423
|
+
* - `'sampled'`: Uses sampled colors from the source texture.
|
|
1424
|
+
* - `'fixed'`: Uses a fixed color set by `characterColor()`.
|
|
1425
|
+
* @param mode The color mode to use for characters.
|
|
1426
|
+
*/
|
|
1427
|
+
characterColorMode(e) {
|
|
1428
|
+
C.validate(
|
|
1429
|
+
["sampled", "fixed"].includes(e),
|
|
1285
1430
|
"Invalid character color mode. Must be 'sampled' or 'fixed'.",
|
|
1286
|
-
{ method: "characterColorMode", providedValue:
|
|
1287
|
-
) && (this.options.characterColorMode =
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
[
|
|
1299
|
-
"
|
|
1300
|
-
{ method: "
|
|
1301
|
-
) && (this.options.
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1431
|
+
{ method: "characterColorMode", providedValue: e }
|
|
1432
|
+
) && (this.options.characterColorMode = e);
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Sets the cell color if `backgroundColorMode` is `fixed`.
|
|
1436
|
+
* @param r Red component (0-255).
|
|
1437
|
+
* @param g Green component (0-255).
|
|
1438
|
+
* @param b Blue component (0-255).
|
|
1439
|
+
* @param a Alpha component (0-255).
|
|
1440
|
+
*/
|
|
1441
|
+
cellColor(e, t = e, r = e, B = 255) {
|
|
1442
|
+
C.validate(
|
|
1443
|
+
[e, t, r, B].every((E) => E >= 0 && E <= 255),
|
|
1444
|
+
"Cell color values must be between 0 and 255",
|
|
1445
|
+
{ method: "cellColor", providedValues: { r: e, g: t, b: r, a: B } }
|
|
1446
|
+
) && (this.options.backgroundColor = [e, t, r, B]);
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Sets the background color mode.
|
|
1450
|
+
* - `'sampled'`: Uses sampled colors from the source texture.
|
|
1451
|
+
* - `'fixed'`: Uses a fixed color set by `backgroundColor()`.
|
|
1452
|
+
* @param mode The color mode to use for background cells.
|
|
1453
|
+
*/
|
|
1454
|
+
cellColorMode(e) {
|
|
1455
|
+
C.validate(
|
|
1456
|
+
["sampled", "fixed"].includes(e),
|
|
1457
|
+
"Invalid cell color mode. Must be 'sampled' or 'fixed'.",
|
|
1458
|
+
{ method: "cellColorMode", providedValue: e }
|
|
1459
|
+
) && (this.options.backgroundColorMode = e);
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Swaps the character and cell color.
|
|
1463
|
+
* @param invert If `true`, the character color becomes the cell color and vice versa.
|
|
1464
|
+
*/
|
|
1465
|
+
invert(e) {
|
|
1466
|
+
C.validate(
|
|
1467
|
+
typeof e == "boolean" || typeof e == "number" && Number.isInteger(e),
|
|
1306
1468
|
"Invert must be a boolean value or an integer (0 for false, any other number for true).",
|
|
1307
|
-
{ method: "invert", providedValue:
|
|
1308
|
-
) && (this.options.invert = !!
|
|
1469
|
+
{ method: "invert", providedValue: e }
|
|
1470
|
+
) && (this.options.invert = !!e);
|
|
1309
1471
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1472
|
+
/**
|
|
1473
|
+
* Sets the rotation angle for the characters.
|
|
1474
|
+
* @param angle The rotation angle in degrees.
|
|
1475
|
+
*/
|
|
1476
|
+
rotation(e) {
|
|
1477
|
+
C.validate(
|
|
1478
|
+
typeof e == "number",
|
|
1313
1479
|
"Rotation angle must be a number.",
|
|
1314
|
-
{ method: "rotation", providedValue:
|
|
1315
|
-
) && (this.options.rotation =
|
|
1480
|
+
{ method: "rotation", providedValue: e }
|
|
1481
|
+
) && (this.options.rotation = e);
|
|
1316
1482
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1483
|
+
/**
|
|
1484
|
+
* Flips the characters horizontally.
|
|
1485
|
+
* @param flip If `true`, characters are flipped horizontally. If `false`, no flip is applied.
|
|
1486
|
+
*/
|
|
1487
|
+
flipHorizontally(e) {
|
|
1488
|
+
C.validate(
|
|
1489
|
+
typeof e == "boolean" || typeof e == "number" && Number.isInteger(e),
|
|
1320
1490
|
"Flip horizontally must be a boolean value or an integer (0 for false, any other number for true).",
|
|
1321
|
-
{ method: "flipHorizontally", providedValue:
|
|
1322
|
-
) && (this.options.flipHorizontally = !!
|
|
1491
|
+
{ method: "flipHorizontally", providedValue: e }
|
|
1492
|
+
) && (this.options.flipHorizontally = !!e);
|
|
1323
1493
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1494
|
+
/**
|
|
1495
|
+
* Flips the characters vertically.
|
|
1496
|
+
* @param flip If `true`, characters are flipped vertically. If `false`, no flip is applied.
|
|
1497
|
+
*/
|
|
1498
|
+
flipVertically(e) {
|
|
1499
|
+
C.validate(
|
|
1500
|
+
typeof e == "boolean" || typeof e == "number" && Number.isInteger(e),
|
|
1327
1501
|
"Flip vertically must be a boolean value or an integer (0 for false, any other number for true).",
|
|
1328
|
-
{ method: "flipVertically", providedValue:
|
|
1329
|
-
) && (this.options.flipVertically = !!
|
|
1502
|
+
{ method: "flipVertically", providedValue: e }
|
|
1503
|
+
) && (this.options.flipVertically = !!e);
|
|
1330
1504
|
}
|
|
1331
1505
|
}
|
|
1332
|
-
var
|
|
1333
|
-
const
|
|
1506
|
+
var W = "precision lowp float;uniform sampler2D u_sketchTexture;uniform vec2 u_gridCellDimensions;varying vec2 v_uv;void main(){vec2 cellCenter=(floor(v_uv*u_gridCellDimensions)+vec2(0.5))/u_gridCellDimensions;gl_FragColor=texture2D(u_sketchTexture,cellCenter);}", K = "precision lowp float;uniform sampler2D u_colorSampleFramebuffer;uniform sampler2D u_charPaletteTexture;uniform vec2 u_charPaletteSize;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec4 color=texture2D(u_colorSampleFramebuffer,v_uv);if(color.a==0.0){gl_FragColor=vec4(0.0);return;}float brightness=dot(color.rgb,vec3(0.299,0.587,0.114))*255.0;vec2 range=u_brightnessRange;if(brightness<range.x||brightness>range.y){gl_FragColor=vec4(0.0);return;}float t=(brightness-range.x)/(range.y-range.x);float idx=clamp(floor(t*u_charPaletteSize.x),0.0,u_charPaletteSize.x-1.0);vec3 charColor=texture2D(u_charPaletteTexture,vec2((idx+0.5)/u_charPaletteSize.x,0.0)).rgb;gl_FragColor=vec4(charColor,color.a);}";
|
|
1507
|
+
const X = {
|
|
1334
1508
|
/** Enable/disable the renderer */
|
|
1335
1509
|
enabled: !0,
|
|
1336
1510
|
/** Characters used for brightness mapping (from darkest to brightest) */
|
|
@@ -1354,16 +1528,16 @@ const N = {
|
|
|
1354
1528
|
/** Range of brightness values to map to ASCII characters */
|
|
1355
1529
|
brightnessRange: [0, 255]
|
|
1356
1530
|
};
|
|
1357
|
-
class
|
|
1358
|
-
constructor(
|
|
1359
|
-
super(
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
this.sampleShader = new
|
|
1364
|
-
}
|
|
1365
|
-
convert(
|
|
1366
|
-
this.sampleFramebuffer.begin(), this.renderer.clear(
|
|
1531
|
+
class b extends _ {
|
|
1532
|
+
constructor(e, t, r) {
|
|
1533
|
+
super(e, t, r, { ...X });
|
|
1534
|
+
Q(this, "sampleShader");
|
|
1535
|
+
Q(this, "charMappingShader");
|
|
1536
|
+
Q(this, "sampleFramebuffer");
|
|
1537
|
+
this.sampleShader = new l(e.context, P, W), this.charMappingShader = new l(e.context, P, K), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
1538
|
+
}
|
|
1539
|
+
convert(e) {
|
|
1540
|
+
this.sampleFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.sampleShader), this.renderer.setUniform("u_sketchTexture", e), this.renderer.setUniform("u_gridCellDimensions", [this.grid.cols, this.grid.rows]), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this.sampleFramebuffer.end(), this._primaryColorFramebuffer.begin(), this.options.characterColorMode === "fixed" ? this.renderer.background(this.options.characterColor[0], this.options.characterColor[1], this.options.characterColor[2], this.options.characterColor[3]) : (this.renderer.clear(), this.renderer.image(this.sampleFramebuffer, 0, 0, this.grid.cols, this.grid.rows)), this._primaryColorFramebuffer.end(), this._secondaryColorFramebuffer.begin(), this.options.backgroundColorMode === "fixed" ? this.renderer.background(this.options.backgroundColor[0], this.options.backgroundColor[1], this.options.backgroundColor[2], this.options.backgroundColor[3]) : (this.renderer.clear(), this.renderer.image(this.sampleFramebuffer, 0, 0, this.grid.cols, this.grid.rows)), this._secondaryColorFramebuffer.end(), this._transformFramebuffer.begin(), this.renderer.background(
|
|
1367
1541
|
this.options.invert ? 255 : 0,
|
|
1368
1542
|
this.options.flipHorizontally ? 255 : 0,
|
|
1369
1543
|
this.options.flipVertically ? 255 : 0
|
|
@@ -1372,75 +1546,82 @@ class _ extends b {
|
|
|
1372
1546
|
resize() {
|
|
1373
1547
|
super.resize(), this.sampleFramebuffer.resize(this.grid.cols, this.grid.rows);
|
|
1374
1548
|
}
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1549
|
+
/**
|
|
1550
|
+
* Sets the brightness range for ASCII character mapping.
|
|
1551
|
+
*
|
|
1552
|
+
* Cells that sample outside this range are rendered as transparent.
|
|
1553
|
+
*
|
|
1554
|
+
* @param range Array of two numbers `[min, max]`, where `min` is darkest and `max` is brightest.
|
|
1555
|
+
*/
|
|
1556
|
+
brightnessRange(e) {
|
|
1557
|
+
C.validate(
|
|
1558
|
+
Array.isArray(e) && e.length === 2 && e.every((t) => typeof t == "number" && t >= 0 && t <= 255),
|
|
1378
1559
|
"Brightness range must be an array of two numbers between 0 and 255.",
|
|
1379
|
-
{ method: "brightnessRange", providedValue:
|
|
1380
|
-
) && (this.options.brightnessRange =
|
|
1560
|
+
{ method: "brightnessRange", providedValue: e }
|
|
1561
|
+
) && (this.options.brightnessRange = e);
|
|
1381
1562
|
}
|
|
1382
1563
|
}
|
|
1383
|
-
const
|
|
1564
|
+
const q = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1384
1565
|
__proto__: null,
|
|
1385
|
-
TextmodeBrightnessConverter:
|
|
1566
|
+
TextmodeBrightnessConverter: b,
|
|
1386
1567
|
TextmodeConverter: p,
|
|
1387
|
-
TextmodeFeatureConverter:
|
|
1568
|
+
TextmodeFeatureConverter: _
|
|
1388
1569
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1389
|
-
var
|
|
1390
|
-
class
|
|
1391
|
-
constructor(
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
this.renderer =
|
|
1399
|
-
brightness: new
|
|
1570
|
+
var Z = "precision mediump float;uniform sampler2D u_characterTexture;uniform vec2 u_charsetDimensions;uniform sampler2D u_primaryColorTexture;uniform sampler2D u_secondaryColorTexture;uniform sampler2D u_transformTexture;uniform sampler2D u_asciiCharacterTexture;uniform sampler2D u_rotationTexture;uniform sampler2D u_captureTexture;uniform vec2 u_captureDimensions;uniform int u_backgroundMode;uniform vec2 u_gridCellDimensions;uniform vec2 u_gridPixelDimensions;uniform float u_pixelRatio;void main(){vec2 logicalPos=gl_FragCoord.xy/u_pixelRatio;vec2 gridCoord=(logicalPos/u_gridPixelDimensions)*u_gridCellDimensions;vec2 cellCoord=floor(gridCoord);vec2 texCoord=(cellCoord+0.5)/u_gridCellDimensions;vec4 primaryColor=texture2D(u_primaryColorTexture,texCoord);vec4 secondaryColor=texture2D(u_secondaryColorTexture,texCoord);vec4 transform=texture2D(u_transformTexture,texCoord);vec4 charData=texture2D(u_asciiCharacterTexture,texCoord);if(charData.a<0.01){gl_FragColor=u_backgroundMode==0 ? vec4(0.0):texture2D(u_captureTexture,logicalPos/u_captureDimensions);return;}int charIndex=int(charData.r*255.0+0.5)+int(charData.g*255.0+0.5)*256;vec2 charPos=vec2(mod(float(charIndex),u_charsetDimensions.x),floor(float(charIndex)/u_charsetDimensions.x))/u_charsetDimensions;vec4 rotation=texture2D(u_rotationTexture,texCoord);float angle=((rotation.r*255.0+rotation.g)*360.0/255.0)*0.017453293;vec2 frac=fract(gridCoord)-0.5;frac.x*=transform.g>0.5 ?-1.0 : 1.0;frac.y*=transform.b>0.5 ?-1.0 : 1.0;float s=sin(angle),c=cos(angle);frac=mat2(c,-s,s,c)*frac+0.5;vec2 cellSize=1.0/u_charsetDimensions;vec2 finalTexCoord=charPos+frac*cellSize;if(any(lessThan(frac,vec2(0.0)))||any(greaterThan(frac,vec2(1.0)))){gl_FragColor=transform.r>0.5 ? primaryColor : secondaryColor;}else{vec4 charTexel=texture2D(u_characterTexture,finalTexCoord);float inv=transform.r>0.5 ? 1.0 : 0.0;charTexel.rgb=mix(charTexel.rgb,1.0-charTexel.rgb,inv);gl_FragColor=mix(secondaryColor,primaryColor,charTexel);}}";
|
|
1571
|
+
class j {
|
|
1572
|
+
constructor(A, e, t) {
|
|
1573
|
+
Q(this, "renderer");
|
|
1574
|
+
Q(this, "font");
|
|
1575
|
+
Q(this, "grid");
|
|
1576
|
+
Q(this, "converters");
|
|
1577
|
+
Q(this, "_resultFramebuffer");
|
|
1578
|
+
Q(this, "_asciiShader");
|
|
1579
|
+
this.renderer = A, this.font = e, this.grid = t, this._asciiShader = this.renderer.createShader(P, Z), this.converters = {
|
|
1580
|
+
brightness: new b(A, e, t)
|
|
1400
1581
|
}, this._resultFramebuffer = this.renderer.createFramebuffer(this.grid.width, this.grid.height);
|
|
1401
1582
|
}
|
|
1402
|
-
render(
|
|
1403
|
-
for (const
|
|
1404
|
-
|
|
1405
|
-
this._resultFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this._asciiShader), this.renderer.setUniform("u_characterTexture", this.font.fontFramebuffer), this.renderer.setUniform("u_charsetDimensions", [this.font.textureColumns, this.font.textureRows]), this.renderer.setUniform("u_asciiCharacterTexture", this.converters.brightness.characterFramebuffer.texture), this.renderer.setUniform("u_primaryColorTexture", this.converters.brightness.primaryColorFramebuffer.texture), this.renderer.setUniform("u_secondaryColorTexture", this.converters.brightness.secondaryColorFramebuffer.texture), this.renderer.setUniform("u_transformTexture", this.converters.brightness.transformFramebuffer.texture), this.renderer.setUniform("u_rotationTexture", this.converters.brightness.rotationFramebuffer.texture), this.renderer.setUniform("u_captureTexture",
|
|
1583
|
+
render(A) {
|
|
1584
|
+
for (const e of Object.values(this.converters))
|
|
1585
|
+
e.convert(A);
|
|
1586
|
+
this._resultFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this._asciiShader), this.renderer.setUniform("u_characterTexture", this.font.fontFramebuffer), this.renderer.setUniform("u_charsetDimensions", [this.font.textureColumns, this.font.textureRows]), this.renderer.setUniform("u_asciiCharacterTexture", this.converters.brightness.characterFramebuffer.texture), this.renderer.setUniform("u_primaryColorTexture", this.converters.brightness.primaryColorFramebuffer.texture), this.renderer.setUniform("u_secondaryColorTexture", this.converters.brightness.secondaryColorFramebuffer.texture), this.renderer.setUniform("u_transformTexture", this.converters.brightness.transformFramebuffer.texture), this.renderer.setUniform("u_rotationTexture", this.converters.brightness.rotationFramebuffer.texture), this.renderer.setUniform("u_captureTexture", A.texture), this.renderer.setUniform("u_backgroundMode", !1), this.renderer.setUniform("u_captureDimensions", [A.width, A.height]), this.renderer.setUniform("u_gridCellDimensions", [this.grid.cols, this.grid.rows]), this.renderer.setUniform("u_gridPixelDimensions", [this.grid.width, this.grid.height]), this.renderer.setUniform("u_pixelRatio", 1), this.renderer.rect(0, 0, this._resultFramebuffer.width, this._resultFramebuffer.height), this._resultFramebuffer.end();
|
|
1406
1587
|
}
|
|
1407
|
-
get(
|
|
1408
|
-
const
|
|
1409
|
-
if (!
|
|
1410
|
-
throw new Error(`Converter "${
|
|
1411
|
-
return
|
|
1588
|
+
get(A) {
|
|
1589
|
+
const e = this.converters[A];
|
|
1590
|
+
if (!e)
|
|
1591
|
+
throw new Error(`Converter "${A}" not found in pipeline.`);
|
|
1592
|
+
return e;
|
|
1412
1593
|
}
|
|
1413
1594
|
get texture() {
|
|
1414
1595
|
return this._resultFramebuffer;
|
|
1415
1596
|
}
|
|
1416
1597
|
resize() {
|
|
1417
1598
|
this._resultFramebuffer.resize(this.grid.width, this.grid.height);
|
|
1418
|
-
for (const
|
|
1419
|
-
|
|
1599
|
+
for (const A of Object.values(this.converters))
|
|
1600
|
+
A.resize();
|
|
1420
1601
|
}
|
|
1421
1602
|
}
|
|
1422
1603
|
class f {
|
|
1423
|
-
constructor(
|
|
1604
|
+
constructor(A, e = {}) {
|
|
1424
1605
|
/** The canvas element to capture content from */
|
|
1425
|
-
|
|
1606
|
+
Q(this, "captureCanvas");
|
|
1426
1607
|
/** Our WebGL overlay canvas manager */
|
|
1427
|
-
|
|
1608
|
+
Q(this, "textmodeCanvas");
|
|
1428
1609
|
/** Core WebGL renderer */
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1610
|
+
Q(this, "renderer");
|
|
1611
|
+
Q(this, "canvasFramebuffer");
|
|
1612
|
+
Q(this, "_font");
|
|
1613
|
+
Q(this, "_grid");
|
|
1614
|
+
Q(this, "resizeObserver");
|
|
1434
1615
|
// Auto-rendering properties
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
this.captureCanvas =
|
|
1616
|
+
Q(this, "_mode");
|
|
1617
|
+
Q(this, "_frameRateLimit");
|
|
1618
|
+
Q(this, "animationFrameId", null);
|
|
1619
|
+
Q(this, "lastFrameTime", 0);
|
|
1620
|
+
Q(this, "frameInterval");
|
|
1621
|
+
Q(this, "_frameRate", 0);
|
|
1622
|
+
Q(this, "lastRenderTime", 0);
|
|
1623
|
+
Q(this, "_pipeline");
|
|
1624
|
+
this.captureCanvas = A, this.textmodeCanvas = new V(A), this._mode = e.renderMode ?? "auto", this._frameRateLimit = e.frameRate ?? 120, this.frameInterval = 1e3 / this._frameRateLimit, this.renderer = new R(this.textmodeCanvas.getWebGLContext()), this.canvasFramebuffer = this.renderer.createFramebuffer(A.width, A.height), this._font = new k(this.renderer, e.fontSize ?? 16);
|
|
1444
1625
|
}
|
|
1445
1626
|
/**
|
|
1446
1627
|
* Static factory method for creating and initializing a Textmodifier instance.
|
|
@@ -1448,11 +1629,11 @@ class f {
|
|
|
1448
1629
|
* @param opts Optional configuration options for the `Textmodifier` instance.
|
|
1449
1630
|
* @ignore
|
|
1450
1631
|
*/
|
|
1451
|
-
static async create(
|
|
1452
|
-
const t = new f(
|
|
1632
|
+
static async create(A, e = {}) {
|
|
1633
|
+
const t = new f(A, e);
|
|
1453
1634
|
await t._font.initialize();
|
|
1454
1635
|
const r = t._font.maxGlyphDimensions;
|
|
1455
|
-
return t._grid = new
|
|
1636
|
+
return t._grid = new N(t.captureCanvas, r.width, r.height), t._pipeline = new j(t.renderer, t._font, t._grid), t.setupEventListeners(), t.startAutoRendering(), t;
|
|
1456
1637
|
}
|
|
1457
1638
|
setupEventListeners() {
|
|
1458
1639
|
window.addEventListener("resize", this.resize.bind(this)), window.ResizeObserver && (this.resizeObserver = new ResizeObserver(() => {
|
|
@@ -1463,10 +1644,10 @@ class f {
|
|
|
1463
1644
|
* Update the font used for rendering.
|
|
1464
1645
|
* @param fontUrl The URL of the font to load.
|
|
1465
1646
|
*/
|
|
1466
|
-
async loadFont(
|
|
1467
|
-
return this._font.loadFont(
|
|
1468
|
-
const
|
|
1469
|
-
this._grid.resizeCellPixelDimensions(
|
|
1647
|
+
async loadFont(A) {
|
|
1648
|
+
return this._font.loadFont(A).then(() => {
|
|
1649
|
+
const e = this._font.maxGlyphDimensions;
|
|
1650
|
+
this._grid.resizeCellPixelDimensions(e.width, e.height), this._pipeline.resize();
|
|
1470
1651
|
});
|
|
1471
1652
|
}
|
|
1472
1653
|
/**
|
|
@@ -1476,31 +1657,31 @@ class f {
|
|
|
1476
1657
|
* In `'manual'` mode, you need to call this method when you want to update the rendering.
|
|
1477
1658
|
*/
|
|
1478
1659
|
render() {
|
|
1479
|
-
this.measureFrameRate(), this.canvasFramebuffer.update(this.captureCanvas), this._pipeline.render(this.canvasFramebuffer), this.renderer.
|
|
1660
|
+
this.measureFrameRate(), this.canvasFramebuffer.update(this.captureCanvas), this._pipeline.render(this.canvasFramebuffer), this.renderer.background(0), this.renderer.image(this._pipeline.texture, this._grid.offsetX, this._grid.offsetY, this._pipeline.texture.width, this._pipeline.texture.height);
|
|
1480
1661
|
}
|
|
1481
1662
|
resize() {
|
|
1482
|
-
this.textmodeCanvas.resize(), this.canvasFramebuffer.resize(this.textmodeCanvas.width, this.textmodeCanvas.height), this._grid.
|
|
1663
|
+
this.textmodeCanvas.resize(), this.canvasFramebuffer.resize(this.textmodeCanvas.width, this.textmodeCanvas.height), this._grid.resize(), this._pipeline.resize(), this.renderer.resetViewport(), this._mode !== "manual" && this.render();
|
|
1483
1664
|
}
|
|
1484
1665
|
/**
|
|
1485
1666
|
* Start automatic rendering
|
|
1486
1667
|
*/
|
|
1487
1668
|
startAutoRendering() {
|
|
1488
1669
|
if (this._mode !== "auto") return;
|
|
1489
|
-
const
|
|
1490
|
-
|
|
1670
|
+
const A = (e) => {
|
|
1671
|
+
e - this.lastFrameTime >= this.frameInterval && (this.render(), this.lastFrameTime = e), this.animationFrameId = requestAnimationFrame(A);
|
|
1491
1672
|
};
|
|
1492
|
-
this.animationFrameId = requestAnimationFrame(
|
|
1673
|
+
this.animationFrameId = requestAnimationFrame(A);
|
|
1493
1674
|
}
|
|
1494
1675
|
/**
|
|
1495
1676
|
* Update FPS measurement - works for both auto and manual modes
|
|
1496
1677
|
*/
|
|
1497
1678
|
measureFrameRate() {
|
|
1498
|
-
const
|
|
1679
|
+
const A = performance.now();
|
|
1499
1680
|
if (this.lastRenderTime > 0) {
|
|
1500
|
-
const
|
|
1501
|
-
this._frameRate = 1e3 /
|
|
1681
|
+
const e = A - this.lastRenderTime;
|
|
1682
|
+
this._frameRate = 1e3 / e;
|
|
1502
1683
|
}
|
|
1503
|
-
this.lastRenderTime =
|
|
1684
|
+
this.lastRenderTime = A;
|
|
1504
1685
|
}
|
|
1505
1686
|
/**
|
|
1506
1687
|
* Stop automatic rendering
|
|
@@ -1511,21 +1692,21 @@ class f {
|
|
|
1511
1692
|
/**
|
|
1512
1693
|
* Change the rendering mode.
|
|
1513
1694
|
*/
|
|
1514
|
-
renderMode(
|
|
1515
|
-
if (this._mode !==
|
|
1516
|
-
if (
|
|
1695
|
+
renderMode(A) {
|
|
1696
|
+
if (this._mode !== A) {
|
|
1697
|
+
if (A === void 0)
|
|
1517
1698
|
return this._mode;
|
|
1518
|
-
this.stopAutoRendering(), this._mode =
|
|
1699
|
+
this.stopAutoRendering(), this._mode = A, A === "auto" && this.startAutoRendering();
|
|
1519
1700
|
}
|
|
1520
1701
|
}
|
|
1521
1702
|
/**
|
|
1522
1703
|
* Set the maximum frame rate for auto rendering. If called without arguments, returns the current measured frame rate.
|
|
1523
1704
|
* @param fps The maximum frames per second for auto rendering.
|
|
1524
1705
|
*/
|
|
1525
|
-
frameRate(
|
|
1526
|
-
if (
|
|
1706
|
+
frameRate(A) {
|
|
1707
|
+
if (A === void 0)
|
|
1527
1708
|
return this._frameRate;
|
|
1528
|
-
this._frameRateLimit =
|
|
1709
|
+
this._frameRateLimit = A, this.frameInterval = 1e3 / A;
|
|
1529
1710
|
}
|
|
1530
1711
|
converter() {
|
|
1531
1712
|
return this._pipeline.get("brightness");
|
|
@@ -1547,43 +1728,43 @@ class f {
|
|
|
1547
1728
|
return this._pipeline;
|
|
1548
1729
|
}
|
|
1549
1730
|
}
|
|
1550
|
-
class
|
|
1731
|
+
class d {
|
|
1551
1732
|
/**
|
|
1552
1733
|
* Create a {@link Textmodifier} instance to apply textmode rendering to a given canvas.
|
|
1553
1734
|
* @param canvas The HTML canvas element to capture content from.
|
|
1554
1735
|
* @param opts Optional configuration options for the Textmodifier instance.
|
|
1555
1736
|
* @returns A Promise that resolves to a Textmodifier instance.
|
|
1556
1737
|
*/
|
|
1557
|
-
static async create(
|
|
1558
|
-
return f.create(
|
|
1738
|
+
static async create(A, e = {}) {
|
|
1739
|
+
return f.create(A, e);
|
|
1559
1740
|
}
|
|
1560
1741
|
/**
|
|
1561
1742
|
* Set the global error handling level for the library. This applies to all `Textmodifier` instances.
|
|
1562
1743
|
* @param level The error handling level to set.
|
|
1563
1744
|
*/
|
|
1564
|
-
static setErrorLevel(
|
|
1565
|
-
|
|
1745
|
+
static setErrorLevel(A) {
|
|
1746
|
+
C.setGlobalLevel(A);
|
|
1566
1747
|
}
|
|
1567
1748
|
/**
|
|
1568
1749
|
* The current version of the library.
|
|
1569
1750
|
*/
|
|
1570
1751
|
static get version() {
|
|
1571
|
-
return "0.0.
|
|
1752
|
+
return "0.0.6";
|
|
1572
1753
|
}
|
|
1573
1754
|
constructor() {
|
|
1574
1755
|
throw new Error("Textmode is a static class and cannot be instantiated.");
|
|
1575
1756
|
}
|
|
1576
1757
|
}
|
|
1577
|
-
const
|
|
1758
|
+
const AA = d.create, eA = d.setErrorLevel, tA = d.version;
|
|
1578
1759
|
export {
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1760
|
+
V as TextmodeCanvas,
|
|
1761
|
+
q as TextmodeConverters,
|
|
1762
|
+
T as TextmodeErrorLevel,
|
|
1763
|
+
k as TextmodeFont,
|
|
1764
|
+
N as TextmodeGrid,
|
|
1584
1765
|
f as Textmodifier,
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1766
|
+
AA as create,
|
|
1767
|
+
eA as setErrorLevel,
|
|
1768
|
+
d as textmode,
|
|
1769
|
+
tA as version
|
|
1589
1770
|
};
|