@esotericsoftware/spine-webgl 4.0.14 → 4.0.15
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/AssetManager.d.ts +33 -33
- package/dist/AssetManager.js +37 -37
- package/dist/Camera.d.ts +49 -49
- package/dist/Camera.js +80 -80
- package/dist/CameraController.d.ts +34 -34
- package/dist/CameraController.js +95 -95
- package/dist/GLTexture.d.ts +46 -46
- package/dist/GLTexture.js +102 -102
- package/dist/Input.d.ts +56 -56
- package/dist/Input.js +210 -210
- package/dist/LoadingScreen.d.ts +43 -43
- package/dist/LoadingScreen.js +114 -114
- package/dist/Matrix4.d.ts +68 -68
- package/dist/Matrix4.js +321 -321
- package/dist/Mesh.d.ts +88 -88
- package/dist/Mesh.js +193 -193
- package/dist/PolygonBatcher.d.ts +53 -53
- package/dist/PolygonBatcher.js +121 -119
- package/dist/SceneRenderer.d.ts +73 -73
- package/dist/SceneRenderer.js +476 -476
- package/dist/Shader.d.ts +75 -75
- package/dist/Shader.js +262 -262
- package/dist/ShapeRenderer.d.ts +69 -69
- package/dist/ShapeRenderer.js +338 -338
- package/dist/SkeletonDebugRenderer.d.ts +60 -60
- package/dist/SkeletonDebugRenderer.js +222 -222
- package/dist/SkeletonRenderer.d.ts +49 -49
- package/dist/SkeletonRenderer.js +295 -295
- package/dist/SpineCanvas.d.ts +73 -73
- package/dist/SpineCanvas.js +82 -82
- package/dist/Vector3.d.ts +47 -47
- package/dist/Vector3.js +103 -103
- package/dist/WebGL.d.ts +44 -44
- package/dist/WebGL.js +96 -96
- package/dist/iife/spine-webgl.js +2 -3
- package/dist/iife/spine-webgl.js.map +2 -2
- package/dist/iife/spine-webgl.min.js +3 -3
- package/dist/index.d.ts +18 -18
- package/dist/index.js +18 -18
- package/package.json +35 -35
package/dist/ShapeRenderer.js
CHANGED
|
@@ -1,339 +1,339 @@
|
|
|
1
|
-
/******************************************************************************
|
|
2
|
-
* Spine Runtimes License Agreement
|
|
3
|
-
* Last updated January 1, 2020. Replaces all prior versions.
|
|
4
|
-
*
|
|
5
|
-
* Copyright (c) 2013-2020, Esoteric Software LLC
|
|
6
|
-
*
|
|
7
|
-
* Integration of the Spine Runtimes into software or otherwise creating
|
|
8
|
-
* derivative works of the Spine Runtimes is permitted under the terms and
|
|
9
|
-
* conditions of Section 2 of the Spine Editor License Agreement:
|
|
10
|
-
* http://esotericsoftware.com/spine-editor-license
|
|
11
|
-
*
|
|
12
|
-
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
|
13
|
-
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
|
14
|
-
* "Products"), provided that each user of the Products must obtain their own
|
|
15
|
-
* Spine Editor license and redistribution of the Products in any form must
|
|
16
|
-
* include this license and copyright notice.
|
|
17
|
-
*
|
|
18
|
-
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
|
19
|
-
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
20
|
-
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
-
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
|
22
|
-
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
23
|
-
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
|
24
|
-
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
|
25
|
-
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
26
|
-
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
27
|
-
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
|
-
*****************************************************************************/
|
|
29
|
-
import { Color, Vector2, MathUtils } from "@esotericsoftware/spine-core";
|
|
30
|
-
import { Mesh, Position2Attribute, ColorAttribute } from "./Mesh";
|
|
31
|
-
import { ManagedWebGLRenderingContext } from "./WebGL";
|
|
32
|
-
export class ShapeRenderer {
|
|
33
|
-
constructor(context, maxVertices = 10920) {
|
|
34
|
-
this.isDrawing = false;
|
|
35
|
-
this.shapeType = ShapeType.Filled;
|
|
36
|
-
this.color = new Color(1, 1, 1, 1);
|
|
37
|
-
this.vertexIndex = 0;
|
|
38
|
-
this.tmp = new Vector2();
|
|
39
|
-
if (maxVertices > 10920)
|
|
40
|
-
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
|
41
|
-
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
|
|
42
|
-
this.mesh = new Mesh(context, [new Position2Attribute(), new ColorAttribute()], maxVertices, 0);
|
|
43
|
-
let gl = this.context.gl;
|
|
44
|
-
this.srcColorBlend = gl.SRC_ALPHA;
|
|
45
|
-
this.srcAlphaBlend = gl.ONE;
|
|
46
|
-
this.dstBlend = gl.ONE_MINUS_SRC_ALPHA;
|
|
47
|
-
}
|
|
48
|
-
begin(shader) {
|
|
49
|
-
if (this.isDrawing)
|
|
50
|
-
throw new Error("ShapeRenderer.begin() has already been called");
|
|
51
|
-
this.shader = shader;
|
|
52
|
-
this.vertexIndex = 0;
|
|
53
|
-
this.isDrawing = true;
|
|
54
|
-
let gl = this.context.gl;
|
|
55
|
-
gl.enable(gl.BLEND);
|
|
56
|
-
gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend);
|
|
57
|
-
}
|
|
58
|
-
setBlendMode(srcColorBlend, srcAlphaBlend, dstBlend) {
|
|
59
|
-
this.srcColorBlend = srcColorBlend;
|
|
60
|
-
this.srcAlphaBlend = srcAlphaBlend;
|
|
61
|
-
this.dstBlend = dstBlend;
|
|
62
|
-
if (this.isDrawing) {
|
|
63
|
-
this.flush();
|
|
64
|
-
let gl = this.context.gl;
|
|
65
|
-
gl.blendFuncSeparate(srcColorBlend, dstBlend, srcAlphaBlend, dstBlend);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
setColor(color) {
|
|
69
|
-
this.color.setFromColor(color);
|
|
70
|
-
}
|
|
71
|
-
setColorWith(r, g, b, a) {
|
|
72
|
-
this.color.set(r, g, b, a);
|
|
73
|
-
}
|
|
74
|
-
point(x, y, color = null) {
|
|
75
|
-
this.check(ShapeType.Point, 1);
|
|
76
|
-
if (color === null)
|
|
77
|
-
color = this.color;
|
|
78
|
-
this.vertex(x, y, color);
|
|
79
|
-
}
|
|
80
|
-
line(x, y, x2, y2, color = null) {
|
|
81
|
-
this.check(ShapeType.Line, 2);
|
|
82
|
-
let vertices = this.mesh.getVertices();
|
|
83
|
-
let idx = this.vertexIndex;
|
|
84
|
-
if (color === null)
|
|
85
|
-
color = this.color;
|
|
86
|
-
this.vertex(x, y, color);
|
|
87
|
-
this.vertex(x2, y2, color);
|
|
88
|
-
}
|
|
89
|
-
triangle(filled, x, y, x2, y2, x3, y3, color = null, color2 = null, color3 = null) {
|
|
90
|
-
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
|
|
91
|
-
let vertices = this.mesh.getVertices();
|
|
92
|
-
let idx = this.vertexIndex;
|
|
93
|
-
if (color === null)
|
|
94
|
-
color = this.color;
|
|
95
|
-
if (color2 === null)
|
|
96
|
-
color2 = this.color;
|
|
97
|
-
if (color3 === null)
|
|
98
|
-
color3 = this.color;
|
|
99
|
-
if (filled) {
|
|
100
|
-
this.vertex(x, y, color);
|
|
101
|
-
this.vertex(x2, y2, color2);
|
|
102
|
-
this.vertex(x3, y3, color3);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
this.vertex(x, y, color);
|
|
106
|
-
this.vertex(x2, y2, color2);
|
|
107
|
-
this.vertex(x2, y2, color);
|
|
108
|
-
this.vertex(x3, y3, color2);
|
|
109
|
-
this.vertex(x3, y3, color);
|
|
110
|
-
this.vertex(x, y, color2);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
quad(filled, x, y, x2, y2, x3, y3, x4, y4, color = null, color2 = null, color3 = null, color4 = null) {
|
|
114
|
-
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
|
|
115
|
-
let vertices = this.mesh.getVertices();
|
|
116
|
-
let idx = this.vertexIndex;
|
|
117
|
-
if (color === null)
|
|
118
|
-
color = this.color;
|
|
119
|
-
if (color2 === null)
|
|
120
|
-
color2 = this.color;
|
|
121
|
-
if (color3 === null)
|
|
122
|
-
color3 = this.color;
|
|
123
|
-
if (color4 === null)
|
|
124
|
-
color4 = this.color;
|
|
125
|
-
if (filled) {
|
|
126
|
-
this.vertex(x, y, color);
|
|
127
|
-
this.vertex(x2, y2, color2);
|
|
128
|
-
this.vertex(x3, y3, color3);
|
|
129
|
-
this.vertex(x3, y3, color3);
|
|
130
|
-
this.vertex(x4, y4, color4);
|
|
131
|
-
this.vertex(x, y, color);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
this.vertex(x, y, color);
|
|
135
|
-
this.vertex(x2, y2, color2);
|
|
136
|
-
this.vertex(x2, y2, color2);
|
|
137
|
-
this.vertex(x3, y3, color3);
|
|
138
|
-
this.vertex(x3, y3, color3);
|
|
139
|
-
this.vertex(x4, y4, color4);
|
|
140
|
-
this.vertex(x4, y4, color4);
|
|
141
|
-
this.vertex(x, y, color);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
rect(filled, x, y, width, height, color = null) {
|
|
145
|
-
this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color);
|
|
146
|
-
}
|
|
147
|
-
rectLine(filled, x1, y1, x2, y2, width, color = null) {
|
|
148
|
-
this.check(filled ? ShapeType.Filled : ShapeType.Line, 8);
|
|
149
|
-
if (color === null)
|
|
150
|
-
color = this.color;
|
|
151
|
-
let t = this.tmp.set(y2 - y1, x1 - x2);
|
|
152
|
-
t.normalize();
|
|
153
|
-
width *= 0.5;
|
|
154
|
-
let tx = t.x * width;
|
|
155
|
-
let ty = t.y * width;
|
|
156
|
-
if (!filled) {
|
|
157
|
-
this.vertex(x1 + tx, y1 + ty, color);
|
|
158
|
-
this.vertex(x1 - tx, y1 - ty, color);
|
|
159
|
-
this.vertex(x2 + tx, y2 + ty, color);
|
|
160
|
-
this.vertex(x2 - tx, y2 - ty, color);
|
|
161
|
-
this.vertex(x2 + tx, y2 + ty, color);
|
|
162
|
-
this.vertex(x1 + tx, y1 + ty, color);
|
|
163
|
-
this.vertex(x2 - tx, y2 - ty, color);
|
|
164
|
-
this.vertex(x1 - tx, y1 - ty, color);
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
this.vertex(x1 + tx, y1 + ty, color);
|
|
168
|
-
this.vertex(x1 - tx, y1 - ty, color);
|
|
169
|
-
this.vertex(x2 + tx, y2 + ty, color);
|
|
170
|
-
this.vertex(x2 - tx, y2 - ty, color);
|
|
171
|
-
this.vertex(x2 + tx, y2 + ty, color);
|
|
172
|
-
this.vertex(x1 - tx, y1 - ty, color);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
x(x, y, size) {
|
|
176
|
-
this.line(x - size, y - size, x + size, y + size);
|
|
177
|
-
this.line(x - size, y + size, x + size, y - size);
|
|
178
|
-
}
|
|
179
|
-
polygon(polygonVertices, offset, count, color = null) {
|
|
180
|
-
if (count < 3)
|
|
181
|
-
throw new Error("Polygon must contain at least 3 vertices");
|
|
182
|
-
this.check(ShapeType.Line, count * 2);
|
|
183
|
-
if (color === null)
|
|
184
|
-
color = this.color;
|
|
185
|
-
let vertices = this.mesh.getVertices();
|
|
186
|
-
let idx = this.vertexIndex;
|
|
187
|
-
offset <<= 1;
|
|
188
|
-
count <<= 1;
|
|
189
|
-
let firstX = polygonVertices[offset];
|
|
190
|
-
let firstY = polygonVertices[offset + 1];
|
|
191
|
-
let last = offset + count;
|
|
192
|
-
for (let i = offset, n = offset + count - 2; i < n; i += 2) {
|
|
193
|
-
let x1 = polygonVertices[i];
|
|
194
|
-
let y1 = polygonVertices[i + 1];
|
|
195
|
-
let x2 = 0;
|
|
196
|
-
let y2 = 0;
|
|
197
|
-
if (i + 2 >= last) {
|
|
198
|
-
x2 = firstX;
|
|
199
|
-
y2 = firstY;
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
x2 = polygonVertices[i + 2];
|
|
203
|
-
y2 = polygonVertices[i + 3];
|
|
204
|
-
}
|
|
205
|
-
this.vertex(x1, y1, color);
|
|
206
|
-
this.vertex(x2, y2, color);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
circle(filled, x, y, radius, color = null, segments = 0) {
|
|
210
|
-
if (segments === 0)
|
|
211
|
-
segments = Math.max(1, (6 * MathUtils.cbrt(radius)) | 0);
|
|
212
|
-
if (segments <= 0)
|
|
213
|
-
throw new Error("segments must be > 0.");
|
|
214
|
-
if (color === null)
|
|
215
|
-
color = this.color;
|
|
216
|
-
let angle = 2 * MathUtils.PI / segments;
|
|
217
|
-
let cos = Math.cos(angle);
|
|
218
|
-
let sin = Math.sin(angle);
|
|
219
|
-
let cx = radius, cy = 0;
|
|
220
|
-
if (!filled) {
|
|
221
|
-
this.check(ShapeType.Line, segments * 2 + 2);
|
|
222
|
-
for (let i = 0; i < segments; i++) {
|
|
223
|
-
this.vertex(x + cx, y + cy, color);
|
|
224
|
-
let temp = cx;
|
|
225
|
-
cx = cos * cx - sin * cy;
|
|
226
|
-
cy = sin * temp + cos * cy;
|
|
227
|
-
this.vertex(x + cx, y + cy, color);
|
|
228
|
-
}
|
|
229
|
-
// Ensure the last segment is identical to the first.
|
|
230
|
-
this.vertex(x + cx, y + cy, color);
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
this.check(ShapeType.Filled, segments * 3 + 3);
|
|
234
|
-
segments--;
|
|
235
|
-
for (let i = 0; i < segments; i++) {
|
|
236
|
-
this.vertex(x, y, color);
|
|
237
|
-
this.vertex(x + cx, y + cy, color);
|
|
238
|
-
let temp = cx;
|
|
239
|
-
cx = cos * cx - sin * cy;
|
|
240
|
-
cy = sin * temp + cos * cy;
|
|
241
|
-
this.vertex(x + cx, y + cy, color);
|
|
242
|
-
}
|
|
243
|
-
// Ensure the last segment is identical to the first.
|
|
244
|
-
this.vertex(x, y, color);
|
|
245
|
-
this.vertex(x + cx, y + cy, color);
|
|
246
|
-
}
|
|
247
|
-
let temp = cx;
|
|
248
|
-
cx = radius;
|
|
249
|
-
cy = 0;
|
|
250
|
-
this.vertex(x + cx, y + cy, color);
|
|
251
|
-
}
|
|
252
|
-
curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color = null) {
|
|
253
|
-
this.check(ShapeType.Line, segments * 2 + 2);
|
|
254
|
-
if (color === null)
|
|
255
|
-
color = this.color;
|
|
256
|
-
// Algorithm from: http://www.antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION
|
|
257
|
-
let subdiv_step = 1 / segments;
|
|
258
|
-
let subdiv_step2 = subdiv_step * subdiv_step;
|
|
259
|
-
let subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
|
|
260
|
-
let pre1 = 3 * subdiv_step;
|
|
261
|
-
let pre2 = 3 * subdiv_step2;
|
|
262
|
-
let pre4 = 6 * subdiv_step2;
|
|
263
|
-
let pre5 = 6 * subdiv_step3;
|
|
264
|
-
let tmp1x = x1 - cx1 * 2 + cx2;
|
|
265
|
-
let tmp1y = y1 - cy1 * 2 + cy2;
|
|
266
|
-
let tmp2x = (cx1 - cx2) * 3 - x1 + x2;
|
|
267
|
-
let tmp2y = (cy1 - cy2) * 3 - y1 + y2;
|
|
268
|
-
let fx = x1;
|
|
269
|
-
let fy = y1;
|
|
270
|
-
let dfx = (cx1 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
|
|
271
|
-
let dfy = (cy1 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
|
|
272
|
-
let ddfx = tmp1x * pre4 + tmp2x * pre5;
|
|
273
|
-
let ddfy = tmp1y * pre4 + tmp2y * pre5;
|
|
274
|
-
let dddfx = tmp2x * pre5;
|
|
275
|
-
let dddfy = tmp2y * pre5;
|
|
276
|
-
while (segments-- > 0) {
|
|
277
|
-
this.vertex(fx, fy, color);
|
|
278
|
-
fx += dfx;
|
|
279
|
-
fy += dfy;
|
|
280
|
-
dfx += ddfx;
|
|
281
|
-
dfy += ddfy;
|
|
282
|
-
ddfx += dddfx;
|
|
283
|
-
ddfy += dddfy;
|
|
284
|
-
this.vertex(fx, fy, color);
|
|
285
|
-
}
|
|
286
|
-
this.vertex(fx, fy, color);
|
|
287
|
-
this.vertex(x2, y2, color);
|
|
288
|
-
}
|
|
289
|
-
vertex(x, y, color) {
|
|
290
|
-
let idx = this.vertexIndex;
|
|
291
|
-
let vertices = this.mesh.getVertices();
|
|
292
|
-
vertices[idx++] = x;
|
|
293
|
-
vertices[idx++] = y;
|
|
294
|
-
vertices[idx++] = color.r;
|
|
295
|
-
vertices[idx++] = color.g;
|
|
296
|
-
vertices[idx++] = color.b;
|
|
297
|
-
vertices[idx++] = color.a;
|
|
298
|
-
this.vertexIndex = idx;
|
|
299
|
-
}
|
|
300
|
-
end() {
|
|
301
|
-
if (!this.isDrawing)
|
|
302
|
-
throw new Error("ShapeRenderer.begin() has not been called");
|
|
303
|
-
this.flush();
|
|
304
|
-
let gl = this.context.gl;
|
|
305
|
-
gl.disable(gl.BLEND);
|
|
306
|
-
this.isDrawing = false;
|
|
307
|
-
}
|
|
308
|
-
flush() {
|
|
309
|
-
if (this.vertexIndex == 0)
|
|
310
|
-
return;
|
|
311
|
-
this.mesh.setVerticesLength(this.vertexIndex);
|
|
312
|
-
this.mesh.draw(this.shader, this.shapeType);
|
|
313
|
-
this.vertexIndex = 0;
|
|
314
|
-
}
|
|
315
|
-
check(shapeType, numVertices) {
|
|
316
|
-
if (!this.isDrawing)
|
|
317
|
-
throw new Error("ShapeRenderer.begin() has not been called");
|
|
318
|
-
if (this.shapeType == shapeType) {
|
|
319
|
-
if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices)
|
|
320
|
-
this.flush();
|
|
321
|
-
else
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
this.flush();
|
|
326
|
-
this.shapeType = shapeType;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
dispose() {
|
|
330
|
-
this.mesh.dispose();
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
export var ShapeType;
|
|
334
|
-
(function (ShapeType) {
|
|
335
|
-
ShapeType[ShapeType["Point"] = 0] = "Point";
|
|
336
|
-
ShapeType[ShapeType["Line"] = 1] = "Line";
|
|
337
|
-
ShapeType[ShapeType["Filled"] = 4] = "Filled";
|
|
338
|
-
})(ShapeType || (ShapeType = {}));
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
* Spine Runtimes License Agreement
|
|
3
|
+
* Last updated January 1, 2020. Replaces all prior versions.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2013-2020, Esoteric Software LLC
|
|
6
|
+
*
|
|
7
|
+
* Integration of the Spine Runtimes into software or otherwise creating
|
|
8
|
+
* derivative works of the Spine Runtimes is permitted under the terms and
|
|
9
|
+
* conditions of Section 2 of the Spine Editor License Agreement:
|
|
10
|
+
* http://esotericsoftware.com/spine-editor-license
|
|
11
|
+
*
|
|
12
|
+
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
|
13
|
+
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
|
14
|
+
* "Products"), provided that each user of the Products must obtain their own
|
|
15
|
+
* Spine Editor license and redistribution of the Products in any form must
|
|
16
|
+
* include this license and copyright notice.
|
|
17
|
+
*
|
|
18
|
+
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
|
19
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
20
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
|
22
|
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
|
24
|
+
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
|
25
|
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
26
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
27
|
+
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
|
+
*****************************************************************************/
|
|
29
|
+
import { Color, Vector2, MathUtils } from "@esotericsoftware/spine-core";
|
|
30
|
+
import { Mesh, Position2Attribute, ColorAttribute } from "./Mesh";
|
|
31
|
+
import { ManagedWebGLRenderingContext } from "./WebGL";
|
|
32
|
+
export class ShapeRenderer {
|
|
33
|
+
constructor(context, maxVertices = 10920) {
|
|
34
|
+
this.isDrawing = false;
|
|
35
|
+
this.shapeType = ShapeType.Filled;
|
|
36
|
+
this.color = new Color(1, 1, 1, 1);
|
|
37
|
+
this.vertexIndex = 0;
|
|
38
|
+
this.tmp = new Vector2();
|
|
39
|
+
if (maxVertices > 10920)
|
|
40
|
+
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
|
41
|
+
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
|
|
42
|
+
this.mesh = new Mesh(context, [new Position2Attribute(), new ColorAttribute()], maxVertices, 0);
|
|
43
|
+
let gl = this.context.gl;
|
|
44
|
+
this.srcColorBlend = gl.SRC_ALPHA;
|
|
45
|
+
this.srcAlphaBlend = gl.ONE;
|
|
46
|
+
this.dstBlend = gl.ONE_MINUS_SRC_ALPHA;
|
|
47
|
+
}
|
|
48
|
+
begin(shader) {
|
|
49
|
+
if (this.isDrawing)
|
|
50
|
+
throw new Error("ShapeRenderer.begin() has already been called");
|
|
51
|
+
this.shader = shader;
|
|
52
|
+
this.vertexIndex = 0;
|
|
53
|
+
this.isDrawing = true;
|
|
54
|
+
let gl = this.context.gl;
|
|
55
|
+
gl.enable(gl.BLEND);
|
|
56
|
+
gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend);
|
|
57
|
+
}
|
|
58
|
+
setBlendMode(srcColorBlend, srcAlphaBlend, dstBlend) {
|
|
59
|
+
this.srcColorBlend = srcColorBlend;
|
|
60
|
+
this.srcAlphaBlend = srcAlphaBlend;
|
|
61
|
+
this.dstBlend = dstBlend;
|
|
62
|
+
if (this.isDrawing) {
|
|
63
|
+
this.flush();
|
|
64
|
+
let gl = this.context.gl;
|
|
65
|
+
gl.blendFuncSeparate(srcColorBlend, dstBlend, srcAlphaBlend, dstBlend);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
setColor(color) {
|
|
69
|
+
this.color.setFromColor(color);
|
|
70
|
+
}
|
|
71
|
+
setColorWith(r, g, b, a) {
|
|
72
|
+
this.color.set(r, g, b, a);
|
|
73
|
+
}
|
|
74
|
+
point(x, y, color = null) {
|
|
75
|
+
this.check(ShapeType.Point, 1);
|
|
76
|
+
if (color === null)
|
|
77
|
+
color = this.color;
|
|
78
|
+
this.vertex(x, y, color);
|
|
79
|
+
}
|
|
80
|
+
line(x, y, x2, y2, color = null) {
|
|
81
|
+
this.check(ShapeType.Line, 2);
|
|
82
|
+
let vertices = this.mesh.getVertices();
|
|
83
|
+
let idx = this.vertexIndex;
|
|
84
|
+
if (color === null)
|
|
85
|
+
color = this.color;
|
|
86
|
+
this.vertex(x, y, color);
|
|
87
|
+
this.vertex(x2, y2, color);
|
|
88
|
+
}
|
|
89
|
+
triangle(filled, x, y, x2, y2, x3, y3, color = null, color2 = null, color3 = null) {
|
|
90
|
+
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
|
|
91
|
+
let vertices = this.mesh.getVertices();
|
|
92
|
+
let idx = this.vertexIndex;
|
|
93
|
+
if (color === null)
|
|
94
|
+
color = this.color;
|
|
95
|
+
if (color2 === null)
|
|
96
|
+
color2 = this.color;
|
|
97
|
+
if (color3 === null)
|
|
98
|
+
color3 = this.color;
|
|
99
|
+
if (filled) {
|
|
100
|
+
this.vertex(x, y, color);
|
|
101
|
+
this.vertex(x2, y2, color2);
|
|
102
|
+
this.vertex(x3, y3, color3);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
this.vertex(x, y, color);
|
|
106
|
+
this.vertex(x2, y2, color2);
|
|
107
|
+
this.vertex(x2, y2, color);
|
|
108
|
+
this.vertex(x3, y3, color2);
|
|
109
|
+
this.vertex(x3, y3, color);
|
|
110
|
+
this.vertex(x, y, color2);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
quad(filled, x, y, x2, y2, x3, y3, x4, y4, color = null, color2 = null, color3 = null, color4 = null) {
|
|
114
|
+
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
|
|
115
|
+
let vertices = this.mesh.getVertices();
|
|
116
|
+
let idx = this.vertexIndex;
|
|
117
|
+
if (color === null)
|
|
118
|
+
color = this.color;
|
|
119
|
+
if (color2 === null)
|
|
120
|
+
color2 = this.color;
|
|
121
|
+
if (color3 === null)
|
|
122
|
+
color3 = this.color;
|
|
123
|
+
if (color4 === null)
|
|
124
|
+
color4 = this.color;
|
|
125
|
+
if (filled) {
|
|
126
|
+
this.vertex(x, y, color);
|
|
127
|
+
this.vertex(x2, y2, color2);
|
|
128
|
+
this.vertex(x3, y3, color3);
|
|
129
|
+
this.vertex(x3, y3, color3);
|
|
130
|
+
this.vertex(x4, y4, color4);
|
|
131
|
+
this.vertex(x, y, color);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
this.vertex(x, y, color);
|
|
135
|
+
this.vertex(x2, y2, color2);
|
|
136
|
+
this.vertex(x2, y2, color2);
|
|
137
|
+
this.vertex(x3, y3, color3);
|
|
138
|
+
this.vertex(x3, y3, color3);
|
|
139
|
+
this.vertex(x4, y4, color4);
|
|
140
|
+
this.vertex(x4, y4, color4);
|
|
141
|
+
this.vertex(x, y, color);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
rect(filled, x, y, width, height, color = null) {
|
|
145
|
+
this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color);
|
|
146
|
+
}
|
|
147
|
+
rectLine(filled, x1, y1, x2, y2, width, color = null) {
|
|
148
|
+
this.check(filled ? ShapeType.Filled : ShapeType.Line, 8);
|
|
149
|
+
if (color === null)
|
|
150
|
+
color = this.color;
|
|
151
|
+
let t = this.tmp.set(y2 - y1, x1 - x2);
|
|
152
|
+
t.normalize();
|
|
153
|
+
width *= 0.5;
|
|
154
|
+
let tx = t.x * width;
|
|
155
|
+
let ty = t.y * width;
|
|
156
|
+
if (!filled) {
|
|
157
|
+
this.vertex(x1 + tx, y1 + ty, color);
|
|
158
|
+
this.vertex(x1 - tx, y1 - ty, color);
|
|
159
|
+
this.vertex(x2 + tx, y2 + ty, color);
|
|
160
|
+
this.vertex(x2 - tx, y2 - ty, color);
|
|
161
|
+
this.vertex(x2 + tx, y2 + ty, color);
|
|
162
|
+
this.vertex(x1 + tx, y1 + ty, color);
|
|
163
|
+
this.vertex(x2 - tx, y2 - ty, color);
|
|
164
|
+
this.vertex(x1 - tx, y1 - ty, color);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this.vertex(x1 + tx, y1 + ty, color);
|
|
168
|
+
this.vertex(x1 - tx, y1 - ty, color);
|
|
169
|
+
this.vertex(x2 + tx, y2 + ty, color);
|
|
170
|
+
this.vertex(x2 - tx, y2 - ty, color);
|
|
171
|
+
this.vertex(x2 + tx, y2 + ty, color);
|
|
172
|
+
this.vertex(x1 - tx, y1 - ty, color);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
x(x, y, size) {
|
|
176
|
+
this.line(x - size, y - size, x + size, y + size);
|
|
177
|
+
this.line(x - size, y + size, x + size, y - size);
|
|
178
|
+
}
|
|
179
|
+
polygon(polygonVertices, offset, count, color = null) {
|
|
180
|
+
if (count < 3)
|
|
181
|
+
throw new Error("Polygon must contain at least 3 vertices");
|
|
182
|
+
this.check(ShapeType.Line, count * 2);
|
|
183
|
+
if (color === null)
|
|
184
|
+
color = this.color;
|
|
185
|
+
let vertices = this.mesh.getVertices();
|
|
186
|
+
let idx = this.vertexIndex;
|
|
187
|
+
offset <<= 1;
|
|
188
|
+
count <<= 1;
|
|
189
|
+
let firstX = polygonVertices[offset];
|
|
190
|
+
let firstY = polygonVertices[offset + 1];
|
|
191
|
+
let last = offset + count;
|
|
192
|
+
for (let i = offset, n = offset + count - 2; i < n; i += 2) {
|
|
193
|
+
let x1 = polygonVertices[i];
|
|
194
|
+
let y1 = polygonVertices[i + 1];
|
|
195
|
+
let x2 = 0;
|
|
196
|
+
let y2 = 0;
|
|
197
|
+
if (i + 2 >= last) {
|
|
198
|
+
x2 = firstX;
|
|
199
|
+
y2 = firstY;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
x2 = polygonVertices[i + 2];
|
|
203
|
+
y2 = polygonVertices[i + 3];
|
|
204
|
+
}
|
|
205
|
+
this.vertex(x1, y1, color);
|
|
206
|
+
this.vertex(x2, y2, color);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
circle(filled, x, y, radius, color = null, segments = 0) {
|
|
210
|
+
if (segments === 0)
|
|
211
|
+
segments = Math.max(1, (6 * MathUtils.cbrt(radius)) | 0);
|
|
212
|
+
if (segments <= 0)
|
|
213
|
+
throw new Error("segments must be > 0.");
|
|
214
|
+
if (color === null)
|
|
215
|
+
color = this.color;
|
|
216
|
+
let angle = 2 * MathUtils.PI / segments;
|
|
217
|
+
let cos = Math.cos(angle);
|
|
218
|
+
let sin = Math.sin(angle);
|
|
219
|
+
let cx = radius, cy = 0;
|
|
220
|
+
if (!filled) {
|
|
221
|
+
this.check(ShapeType.Line, segments * 2 + 2);
|
|
222
|
+
for (let i = 0; i < segments; i++) {
|
|
223
|
+
this.vertex(x + cx, y + cy, color);
|
|
224
|
+
let temp = cx;
|
|
225
|
+
cx = cos * cx - sin * cy;
|
|
226
|
+
cy = sin * temp + cos * cy;
|
|
227
|
+
this.vertex(x + cx, y + cy, color);
|
|
228
|
+
}
|
|
229
|
+
// Ensure the last segment is identical to the first.
|
|
230
|
+
this.vertex(x + cx, y + cy, color);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
this.check(ShapeType.Filled, segments * 3 + 3);
|
|
234
|
+
segments--;
|
|
235
|
+
for (let i = 0; i < segments; i++) {
|
|
236
|
+
this.vertex(x, y, color);
|
|
237
|
+
this.vertex(x + cx, y + cy, color);
|
|
238
|
+
let temp = cx;
|
|
239
|
+
cx = cos * cx - sin * cy;
|
|
240
|
+
cy = sin * temp + cos * cy;
|
|
241
|
+
this.vertex(x + cx, y + cy, color);
|
|
242
|
+
}
|
|
243
|
+
// Ensure the last segment is identical to the first.
|
|
244
|
+
this.vertex(x, y, color);
|
|
245
|
+
this.vertex(x + cx, y + cy, color);
|
|
246
|
+
}
|
|
247
|
+
let temp = cx;
|
|
248
|
+
cx = radius;
|
|
249
|
+
cy = 0;
|
|
250
|
+
this.vertex(x + cx, y + cy, color);
|
|
251
|
+
}
|
|
252
|
+
curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color = null) {
|
|
253
|
+
this.check(ShapeType.Line, segments * 2 + 2);
|
|
254
|
+
if (color === null)
|
|
255
|
+
color = this.color;
|
|
256
|
+
// Algorithm from: http://www.antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION
|
|
257
|
+
let subdiv_step = 1 / segments;
|
|
258
|
+
let subdiv_step2 = subdiv_step * subdiv_step;
|
|
259
|
+
let subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
|
|
260
|
+
let pre1 = 3 * subdiv_step;
|
|
261
|
+
let pre2 = 3 * subdiv_step2;
|
|
262
|
+
let pre4 = 6 * subdiv_step2;
|
|
263
|
+
let pre5 = 6 * subdiv_step3;
|
|
264
|
+
let tmp1x = x1 - cx1 * 2 + cx2;
|
|
265
|
+
let tmp1y = y1 - cy1 * 2 + cy2;
|
|
266
|
+
let tmp2x = (cx1 - cx2) * 3 - x1 + x2;
|
|
267
|
+
let tmp2y = (cy1 - cy2) * 3 - y1 + y2;
|
|
268
|
+
let fx = x1;
|
|
269
|
+
let fy = y1;
|
|
270
|
+
let dfx = (cx1 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
|
|
271
|
+
let dfy = (cy1 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
|
|
272
|
+
let ddfx = tmp1x * pre4 + tmp2x * pre5;
|
|
273
|
+
let ddfy = tmp1y * pre4 + tmp2y * pre5;
|
|
274
|
+
let dddfx = tmp2x * pre5;
|
|
275
|
+
let dddfy = tmp2y * pre5;
|
|
276
|
+
while (segments-- > 0) {
|
|
277
|
+
this.vertex(fx, fy, color);
|
|
278
|
+
fx += dfx;
|
|
279
|
+
fy += dfy;
|
|
280
|
+
dfx += ddfx;
|
|
281
|
+
dfy += ddfy;
|
|
282
|
+
ddfx += dddfx;
|
|
283
|
+
ddfy += dddfy;
|
|
284
|
+
this.vertex(fx, fy, color);
|
|
285
|
+
}
|
|
286
|
+
this.vertex(fx, fy, color);
|
|
287
|
+
this.vertex(x2, y2, color);
|
|
288
|
+
}
|
|
289
|
+
vertex(x, y, color) {
|
|
290
|
+
let idx = this.vertexIndex;
|
|
291
|
+
let vertices = this.mesh.getVertices();
|
|
292
|
+
vertices[idx++] = x;
|
|
293
|
+
vertices[idx++] = y;
|
|
294
|
+
vertices[idx++] = color.r;
|
|
295
|
+
vertices[idx++] = color.g;
|
|
296
|
+
vertices[idx++] = color.b;
|
|
297
|
+
vertices[idx++] = color.a;
|
|
298
|
+
this.vertexIndex = idx;
|
|
299
|
+
}
|
|
300
|
+
end() {
|
|
301
|
+
if (!this.isDrawing)
|
|
302
|
+
throw new Error("ShapeRenderer.begin() has not been called");
|
|
303
|
+
this.flush();
|
|
304
|
+
let gl = this.context.gl;
|
|
305
|
+
gl.disable(gl.BLEND);
|
|
306
|
+
this.isDrawing = false;
|
|
307
|
+
}
|
|
308
|
+
flush() {
|
|
309
|
+
if (this.vertexIndex == 0)
|
|
310
|
+
return;
|
|
311
|
+
this.mesh.setVerticesLength(this.vertexIndex);
|
|
312
|
+
this.mesh.draw(this.shader, this.shapeType);
|
|
313
|
+
this.vertexIndex = 0;
|
|
314
|
+
}
|
|
315
|
+
check(shapeType, numVertices) {
|
|
316
|
+
if (!this.isDrawing)
|
|
317
|
+
throw new Error("ShapeRenderer.begin() has not been called");
|
|
318
|
+
if (this.shapeType == shapeType) {
|
|
319
|
+
if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices)
|
|
320
|
+
this.flush();
|
|
321
|
+
else
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
this.flush();
|
|
326
|
+
this.shapeType = shapeType;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
dispose() {
|
|
330
|
+
this.mesh.dispose();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
export var ShapeType;
|
|
334
|
+
(function (ShapeType) {
|
|
335
|
+
ShapeType[ShapeType["Point"] = 0] = "Point";
|
|
336
|
+
ShapeType[ShapeType["Line"] = 1] = "Line";
|
|
337
|
+
ShapeType[ShapeType["Filled"] = 4] = "Filled";
|
|
338
|
+
})(ShapeType || (ShapeType = {}));
|
|
339
339
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2hhcGVSZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9TaGFwZVJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUUvRSxPQUFPLEVBQWMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNyRixPQUFPLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVsRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFdkQsTUFBTSxPQUFPLGFBQWE7SUFhekIsWUFBYSxPQUE2RCxFQUFFLGNBQXNCLEtBQUs7UUFYL0YsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUVsQixjQUFTLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUM3QixVQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFOUIsZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFDaEIsUUFBRyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFNM0IsSUFBSSxXQUFXLEdBQUcsS0FBSztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELEdBQUcsV0FBVyxDQUFDLENBQUM7UUFDM0csSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLFlBQVksNEJBQTRCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSw0QkFBNEIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNySCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksa0JBQWtCLEVBQUUsRUFBRSxJQUFJLGNBQWMsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hH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WUFDWCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDbkYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ25GO2FBQU07WUFDTixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDdEQ7SUFDRixDQUFDO0lBRUQsSUFBSSxDQUFFLE1BQWUsRUFBRSxDQUFTLEVBQUUsQ0FBUyxFQUFFLEtBQWEsRUFBRSxNQUFjLEVBQUUsUUFBZSxJQUFJO1FBQzlGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3pHLENBQUM7SUFFRCxRQUFRLENBQUUsTUFBZSxFQUFFLEVBQVUsRUFBRSxFQUFVLEVBQUUsRUFBVSxFQUFFLEVBQVUsRUFBRSxLQUFhLEVBQUUsUUFBZSxJQUFJO1FBQzVHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFELElBQUksS0FBSyxLQUFLLElBQUk7WUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUN2QyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDZCxLQUFLLElBQUksR0FBRyxDQUFDO1FBQ2IsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNaLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXJDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXJDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3JDO2FBQU07WUFDTixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUVyQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFD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RUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxLQUFLLENBQUUsRUFBVSxFQUFFLEVBQVUsRUFBRSxHQUFXLEVBQUUsR0FBVyxFQUFFLEdBQVcsRUFBRSxHQUFXLEVBQUUsRUFBVSxFQUFFLEVBQVUsRUFBRSxRQUFnQixFQUFFLFFBQWUsSUFBSTtRQUMvSSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM3QyxJQUFJLEtBQUssS0FBSyxJQUFJO1lBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFdkMsOEdBQThHO1FBQzlHLElBQUksV0FBVyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDL0IsSUFBSSxZQUFZLEdBQUcsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUM3QyxJQUFJLFlBQVksR0FBRyxXQUFXLEdBQUcsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUUzRCxJQUFJLElBQUksR0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFDO1FBQzNCLElBQUksSUFBSSxHQUFHLENBQUMsR0FBRyxZQUFZLENBQUM7UUFDNUIsSUFBSSxJQUFJLEdBQUcsQ0FBQyxHQUFHLFlBQVksQ0FBQztRQUM1QixJQUFJLElBQUksR0FBRyxDQUFDLEdBQUcsWUFBWSxDQUFDO1FBRTVCLElBQUksS0FBSyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUMvQixJQUFJLEtBQUssR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7UUFFL0IsSUFBSSxLQUFLLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDdEMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENB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
|