@tarsis/toolkit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3025 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const index = require('./index-CZ4lcB3k.cjs');
6
+
7
+ /*
8
+ object-assign
9
+ (c) Sindre Sorhus
10
+ @license MIT
11
+ */
12
+
13
+ var objectAssign;
14
+ var hasRequiredObjectAssign;
15
+
16
+ function requireObjectAssign () {
17
+ if (hasRequiredObjectAssign) return objectAssign;
18
+ hasRequiredObjectAssign = 1;
19
+ /* eslint-disable no-unused-vars */
20
+ var getOwnPropertySymbols = Object.getOwnPropertySymbols;
21
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
22
+ var propIsEnumerable = Object.prototype.propertyIsEnumerable;
23
+
24
+ function toObject(val) {
25
+ if (val === null || val === undefined) {
26
+ throw new TypeError('Object.assign cannot be called with null or undefined');
27
+ }
28
+
29
+ return Object(val);
30
+ }
31
+
32
+ function shouldUseNative() {
33
+ try {
34
+ if (!Object.assign) {
35
+ return false;
36
+ }
37
+
38
+ // Detect buggy property enumeration order in older V8 versions.
39
+
40
+ // https://bugs.chromium.org/p/v8/issues/detail?id=4118
41
+ var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
42
+ test1[5] = 'de';
43
+ if (Object.getOwnPropertyNames(test1)[0] === '5') {
44
+ return false;
45
+ }
46
+
47
+ // https://bugs.chromium.org/p/v8/issues/detail?id=3056
48
+ var test2 = {};
49
+ for (var i = 0; i < 10; i++) {
50
+ test2['_' + String.fromCharCode(i)] = i;
51
+ }
52
+ var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
53
+ return test2[n];
54
+ });
55
+ if (order2.join('') !== '0123456789') {
56
+ return false;
57
+ }
58
+
59
+ // https://bugs.chromium.org/p/v8/issues/detail?id=3056
60
+ var test3 = {};
61
+ 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
62
+ test3[letter] = letter;
63
+ });
64
+ if (Object.keys(Object.assign({}, test3)).join('') !==
65
+ 'abcdefghijklmnopqrst') {
66
+ return false;
67
+ }
68
+
69
+ return true;
70
+ } catch (err) {
71
+ // We don't expect any of the above to throw, but better to be safe.
72
+ return false;
73
+ }
74
+ }
75
+
76
+ objectAssign = shouldUseNative() ? Object.assign : function (target, source) {
77
+ var from;
78
+ var to = toObject(target);
79
+ var symbols;
80
+
81
+ for (var s = 1; s < arguments.length; s++) {
82
+ from = Object(arguments[s]);
83
+
84
+ for (var key in from) {
85
+ if (hasOwnProperty.call(from, key)) {
86
+ to[key] = from[key];
87
+ }
88
+ }
89
+
90
+ if (getOwnPropertySymbols) {
91
+ symbols = getOwnPropertySymbols(from);
92
+ for (var i = 0; i < symbols.length; i++) {
93
+ if (propIsEnumerable.call(from, symbols[i])) {
94
+ to[symbols[i]] = from[symbols[i]];
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ return to;
101
+ };
102
+ return objectAssign;
103
+ }
104
+
105
+ var threeOrbitControls = function( THREE ) {
106
+ /**
107
+ * @author qiao / https://github.com/qiao
108
+ * @author mrdoob / http://mrdoob.com
109
+ * @author alteredq / http://alteredqualia.com/
110
+ * @author WestLangley / http://github.com/WestLangley
111
+ * @author erich666 / http://erichaines.com
112
+ */
113
+
114
+ // This set of controls performs orbiting, dollying (zooming), and panning.
115
+ // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
116
+ //
117
+ // Orbit - left mouse / touch: one finger move
118
+ // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
119
+ // Pan - right mouse, or arrow keys / touch: three finter swipe
120
+
121
+ function OrbitControls( object, domElement ) {
122
+
123
+ this.object = object;
124
+
125
+ this.domElement = ( domElement !== undefined ) ? domElement : document;
126
+
127
+ // Set to false to disable this control
128
+ this.enabled = true;
129
+
130
+ // "target" sets the location of focus, where the object orbits around
131
+ this.target = new THREE.Vector3();
132
+
133
+ // How far you can dolly in and out ( PerspectiveCamera only )
134
+ this.minDistance = 0;
135
+ this.maxDistance = Infinity;
136
+
137
+ // How far you can zoom in and out ( OrthographicCamera only )
138
+ this.minZoom = 0;
139
+ this.maxZoom = Infinity;
140
+
141
+ // How far you can orbit vertically, upper and lower limits.
142
+ // Range is 0 to Math.PI radians.
143
+ this.minPolarAngle = 0; // radians
144
+ this.maxPolarAngle = Math.PI; // radians
145
+
146
+ // How far you can orbit horizontally, upper and lower limits.
147
+ // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
148
+ this.minAzimuthAngle = - Infinity; // radians
149
+ this.maxAzimuthAngle = Infinity; // radians
150
+
151
+ // Set to true to enable damping (inertia)
152
+ // If damping is enabled, you must call controls.update() in your animation loop
153
+ this.enableDamping = false;
154
+ this.dampingFactor = 0.25;
155
+
156
+ // This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
157
+ // Set to false to disable zooming
158
+ this.enableZoom = true;
159
+ this.zoomSpeed = 1.0;
160
+
161
+ // Set to false to disable rotating
162
+ this.enableRotate = true;
163
+ this.rotateSpeed = 1.0;
164
+
165
+ // Set to false to disable panning
166
+ this.enablePan = true;
167
+ this.keyPanSpeed = 7.0; // pixels moved per arrow key push
168
+
169
+ // Set to true to automatically rotate around the target
170
+ // If auto-rotate is enabled, you must call controls.update() in your animation loop
171
+ this.autoRotate = false;
172
+ this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
173
+
174
+ // Set to false to disable use of the keys
175
+ this.enableKeys = true;
176
+
177
+ // The four arrow keys
178
+ this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
179
+
180
+ // Mouse buttons
181
+ this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
182
+
183
+ // for reset
184
+ this.target0 = this.target.clone();
185
+ this.position0 = this.object.position.clone();
186
+ this.zoom0 = this.object.zoom;
187
+
188
+ //
189
+ // public methods
190
+ //
191
+
192
+ this.getPolarAngle = function () {
193
+
194
+ return spherical.phi;
195
+
196
+ };
197
+
198
+ this.getAzimuthalAngle = function () {
199
+
200
+ return spherical.theta;
201
+
202
+ };
203
+
204
+ this.reset = function () {
205
+
206
+ scope.target.copy( scope.target0 );
207
+ scope.object.position.copy( scope.position0 );
208
+ scope.object.zoom = scope.zoom0;
209
+
210
+ scope.object.updateProjectionMatrix();
211
+ scope.dispatchEvent( changeEvent );
212
+
213
+ scope.update();
214
+
215
+ state = STATE.NONE;
216
+
217
+ };
218
+
219
+ // this method is exposed, but perhaps it would be better if we can make it private...
220
+ this.update = function() {
221
+
222
+ var offset = new THREE.Vector3();
223
+
224
+ // so camera.up is the orbit axis
225
+ var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
226
+ var quatInverse = quat.clone().inverse();
227
+
228
+ var lastPosition = new THREE.Vector3();
229
+ var lastQuaternion = new THREE.Quaternion();
230
+
231
+ return function update () {
232
+
233
+ var position = scope.object.position;
234
+
235
+ offset.copy( position ).sub( scope.target );
236
+
237
+ // rotate offset to "y-axis-is-up" space
238
+ offset.applyQuaternion( quat );
239
+
240
+ // angle from z-axis around y-axis
241
+ spherical.setFromVector3( offset );
242
+
243
+ if ( scope.autoRotate && state === STATE.NONE ) {
244
+
245
+ rotateLeft( getAutoRotationAngle() );
246
+
247
+ }
248
+
249
+ spherical.theta += sphericalDelta.theta;
250
+ spherical.phi += sphericalDelta.phi;
251
+
252
+ // restrict theta to be between desired limits
253
+ spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
254
+
255
+ // restrict phi to be between desired limits
256
+ spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
257
+
258
+ spherical.makeSafe();
259
+
260
+
261
+ spherical.radius *= scale;
262
+
263
+ // restrict radius to be between desired limits
264
+ spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
265
+
266
+ // move target to panned location
267
+ scope.target.add( panOffset );
268
+
269
+ offset.setFromSpherical( spherical );
270
+
271
+ // rotate offset back to "camera-up-vector-is-up" space
272
+ offset.applyQuaternion( quatInverse );
273
+
274
+ position.copy( scope.target ).add( offset );
275
+
276
+ scope.object.lookAt( scope.target );
277
+
278
+ if ( scope.enableDamping === true ) {
279
+
280
+ sphericalDelta.theta *= ( 1 - scope.dampingFactor );
281
+ sphericalDelta.phi *= ( 1 - scope.dampingFactor );
282
+
283
+ } else {
284
+
285
+ sphericalDelta.set( 0, 0, 0 );
286
+
287
+ }
288
+
289
+ scale = 1;
290
+ panOffset.set( 0, 0, 0 );
291
+
292
+ // update condition is:
293
+ // min(camera displacement, camera rotation in radians)^2 > EPS
294
+ // using small-angle approximation cos(x/2) = 1 - x^2 / 8
295
+
296
+ if ( zoomChanged ||
297
+ lastPosition.distanceToSquared( scope.object.position ) > EPS ||
298
+ 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
299
+
300
+ scope.dispatchEvent( changeEvent );
301
+
302
+ lastPosition.copy( scope.object.position );
303
+ lastQuaternion.copy( scope.object.quaternion );
304
+ zoomChanged = false;
305
+
306
+ return true;
307
+
308
+ }
309
+
310
+ return false;
311
+
312
+ };
313
+
314
+ }();
315
+
316
+ this.dispose = function() {
317
+
318
+ scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );
319
+ scope.domElement.removeEventListener( 'mousedown', onMouseDown, false );
320
+ scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );
321
+
322
+ scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );
323
+ scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );
324
+ scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );
325
+
326
+ document.removeEventListener( 'mousemove', onMouseMove, false );
327
+ document.removeEventListener( 'mouseup', onMouseUp, false );
328
+
329
+ window.removeEventListener( 'keydown', onKeyDown, false );
330
+
331
+ //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
332
+
333
+ };
334
+
335
+ //
336
+ // internals
337
+ //
338
+
339
+ var scope = this;
340
+
341
+ var changeEvent = { type: 'change' };
342
+ var startEvent = { type: 'start' };
343
+ var endEvent = { type: 'end' };
344
+
345
+ var STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
346
+
347
+ var state = STATE.NONE;
348
+
349
+ var EPS = 0.000001;
350
+
351
+ // current position in spherical coordinates
352
+ var spherical = new THREE.Spherical();
353
+ var sphericalDelta = new THREE.Spherical();
354
+
355
+ var scale = 1;
356
+ var panOffset = new THREE.Vector3();
357
+ var zoomChanged = false;
358
+
359
+ var rotateStart = new THREE.Vector2();
360
+ var rotateEnd = new THREE.Vector2();
361
+ var rotateDelta = new THREE.Vector2();
362
+
363
+ var panStart = new THREE.Vector2();
364
+ var panEnd = new THREE.Vector2();
365
+ var panDelta = new THREE.Vector2();
366
+
367
+ var dollyStart = new THREE.Vector2();
368
+ var dollyEnd = new THREE.Vector2();
369
+ var dollyDelta = new THREE.Vector2();
370
+
371
+ function getAutoRotationAngle() {
372
+
373
+ return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
374
+
375
+ }
376
+
377
+ function getZoomScale() {
378
+
379
+ return Math.pow( 0.95, scope.zoomSpeed );
380
+
381
+ }
382
+
383
+ function rotateLeft( angle ) {
384
+
385
+ sphericalDelta.theta -= angle;
386
+
387
+ }
388
+
389
+ function rotateUp( angle ) {
390
+
391
+ sphericalDelta.phi -= angle;
392
+
393
+ }
394
+
395
+ var panLeft = function() {
396
+
397
+ var v = new THREE.Vector3();
398
+
399
+ return function panLeft( distance, objectMatrix ) {
400
+
401
+ v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
402
+ v.multiplyScalar( - distance );
403
+
404
+ panOffset.add( v );
405
+
406
+ };
407
+
408
+ }();
409
+
410
+ var panUp = function() {
411
+
412
+ var v = new THREE.Vector3();
413
+
414
+ return function panUp( distance, objectMatrix ) {
415
+
416
+ v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix
417
+ v.multiplyScalar( distance );
418
+
419
+ panOffset.add( v );
420
+
421
+ };
422
+
423
+ }();
424
+
425
+ // deltaX and deltaY are in pixels; right and down are positive
426
+ var pan = function() {
427
+
428
+ var offset = new THREE.Vector3();
429
+
430
+ return function pan ( deltaX, deltaY ) {
431
+
432
+ var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
433
+
434
+ if ( scope.object instanceof THREE.PerspectiveCamera ) {
435
+
436
+ // perspective
437
+ var position = scope.object.position;
438
+ offset.copy( position ).sub( scope.target );
439
+ var targetDistance = offset.length();
440
+
441
+ // half of the fov is center to top of screen
442
+ targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
443
+
444
+ // we actually don't use screenWidth, since perspective camera is fixed to screen height
445
+ panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
446
+ panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
447
+
448
+ } else if ( scope.object instanceof THREE.OrthographicCamera ) {
449
+
450
+ // orthographic
451
+ panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
452
+ panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
453
+
454
+ } else {
455
+
456
+ // camera neither orthographic nor perspective
457
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
458
+ scope.enablePan = false;
459
+
460
+ }
461
+
462
+ };
463
+
464
+ }();
465
+
466
+ function dollyIn( dollyScale ) {
467
+
468
+ if ( scope.object instanceof THREE.PerspectiveCamera ) {
469
+
470
+ scale /= dollyScale;
471
+
472
+ } else if ( scope.object instanceof THREE.OrthographicCamera ) {
473
+
474
+ scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
475
+ scope.object.updateProjectionMatrix();
476
+ zoomChanged = true;
477
+
478
+ } else {
479
+
480
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
481
+ scope.enableZoom = false;
482
+
483
+ }
484
+
485
+ }
486
+
487
+ function dollyOut( dollyScale ) {
488
+
489
+ if ( scope.object instanceof THREE.PerspectiveCamera ) {
490
+
491
+ scale *= dollyScale;
492
+
493
+ } else if ( scope.object instanceof THREE.OrthographicCamera ) {
494
+
495
+ scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
496
+ scope.object.updateProjectionMatrix();
497
+ zoomChanged = true;
498
+
499
+ } else {
500
+
501
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
502
+ scope.enableZoom = false;
503
+
504
+ }
505
+
506
+ }
507
+
508
+ //
509
+ // event callbacks - update the object state
510
+ //
511
+
512
+ function handleMouseDownRotate( event ) {
513
+
514
+ //console.log( 'handleMouseDownRotate' );
515
+
516
+ rotateStart.set( event.clientX, event.clientY );
517
+
518
+ }
519
+
520
+ function handleMouseDownDolly( event ) {
521
+
522
+ //console.log( 'handleMouseDownDolly' );
523
+
524
+ dollyStart.set( event.clientX, event.clientY );
525
+
526
+ }
527
+
528
+ function handleMouseDownPan( event ) {
529
+
530
+ //console.log( 'handleMouseDownPan' );
531
+
532
+ panStart.set( event.clientX, event.clientY );
533
+
534
+ }
535
+
536
+ function handleMouseMoveRotate( event ) {
537
+
538
+ //console.log( 'handleMouseMoveRotate' );
539
+
540
+ rotateEnd.set( event.clientX, event.clientY );
541
+ rotateDelta.subVectors( rotateEnd, rotateStart );
542
+
543
+ var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
544
+
545
+ // rotating across whole screen goes 360 degrees around
546
+ rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
547
+
548
+ // rotating up and down along whole screen attempts to go 360, but limited to 180
549
+ rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
550
+
551
+ rotateStart.copy( rotateEnd );
552
+
553
+ scope.update();
554
+
555
+ }
556
+
557
+ function handleMouseMoveDolly( event ) {
558
+
559
+ //console.log( 'handleMouseMoveDolly' );
560
+
561
+ dollyEnd.set( event.clientX, event.clientY );
562
+
563
+ dollyDelta.subVectors( dollyEnd, dollyStart );
564
+
565
+ if ( dollyDelta.y > 0 ) {
566
+
567
+ dollyIn( getZoomScale() );
568
+
569
+ } else if ( dollyDelta.y < 0 ) {
570
+
571
+ dollyOut( getZoomScale() );
572
+
573
+ }
574
+
575
+ dollyStart.copy( dollyEnd );
576
+
577
+ scope.update();
578
+
579
+ }
580
+
581
+ function handleMouseMovePan( event ) {
582
+
583
+ //console.log( 'handleMouseMovePan' );
584
+
585
+ panEnd.set( event.clientX, event.clientY );
586
+
587
+ panDelta.subVectors( panEnd, panStart );
588
+
589
+ pan( panDelta.x, panDelta.y );
590
+
591
+ panStart.copy( panEnd );
592
+
593
+ scope.update();
594
+
595
+ }
596
+
597
+ function handleMouseWheel( event ) {
598
+
599
+ //console.log( 'handleMouseWheel' );
600
+
601
+ if ( event.deltaY < 0 ) {
602
+
603
+ dollyOut( getZoomScale() );
604
+
605
+ } else if ( event.deltaY > 0 ) {
606
+
607
+ dollyIn( getZoomScale() );
608
+
609
+ }
610
+
611
+ scope.update();
612
+
613
+ }
614
+
615
+ function handleKeyDown( event ) {
616
+
617
+ //console.log( 'handleKeyDown' );
618
+
619
+ switch ( event.keyCode ) {
620
+
621
+ case scope.keys.UP:
622
+ pan( 0, scope.keyPanSpeed );
623
+ scope.update();
624
+ break;
625
+
626
+ case scope.keys.BOTTOM:
627
+ pan( 0, - scope.keyPanSpeed );
628
+ scope.update();
629
+ break;
630
+
631
+ case scope.keys.LEFT:
632
+ pan( scope.keyPanSpeed, 0 );
633
+ scope.update();
634
+ break;
635
+
636
+ case scope.keys.RIGHT:
637
+ pan( - scope.keyPanSpeed, 0 );
638
+ scope.update();
639
+ break;
640
+
641
+ }
642
+
643
+ }
644
+
645
+ function handleTouchStartRotate( event ) {
646
+
647
+ //console.log( 'handleTouchStartRotate' );
648
+
649
+ rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
650
+
651
+ }
652
+
653
+ function handleTouchStartDolly( event ) {
654
+
655
+ //console.log( 'handleTouchStartDolly' );
656
+
657
+ var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
658
+ var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
659
+
660
+ var distance = Math.sqrt( dx * dx + dy * dy );
661
+
662
+ dollyStart.set( 0, distance );
663
+
664
+ }
665
+
666
+ function handleTouchStartPan( event ) {
667
+
668
+ //console.log( 'handleTouchStartPan' );
669
+
670
+ panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
671
+
672
+ }
673
+
674
+ function handleTouchMoveRotate( event ) {
675
+
676
+ //console.log( 'handleTouchMoveRotate' );
677
+
678
+ rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
679
+ rotateDelta.subVectors( rotateEnd, rotateStart );
680
+
681
+ var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
682
+
683
+ // rotating across whole screen goes 360 degrees around
684
+ rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
685
+
686
+ // rotating up and down along whole screen attempts to go 360, but limited to 180
687
+ rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
688
+
689
+ rotateStart.copy( rotateEnd );
690
+
691
+ scope.update();
692
+
693
+ }
694
+
695
+ function handleTouchMoveDolly( event ) {
696
+
697
+ //console.log( 'handleTouchMoveDolly' );
698
+
699
+ var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
700
+ var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
701
+
702
+ var distance = Math.sqrt( dx * dx + dy * dy );
703
+
704
+ dollyEnd.set( 0, distance );
705
+
706
+ dollyDelta.subVectors( dollyEnd, dollyStart );
707
+
708
+ if ( dollyDelta.y > 0 ) {
709
+
710
+ dollyOut( getZoomScale() );
711
+
712
+ } else if ( dollyDelta.y < 0 ) {
713
+
714
+ dollyIn( getZoomScale() );
715
+
716
+ }
717
+
718
+ dollyStart.copy( dollyEnd );
719
+
720
+ scope.update();
721
+
722
+ }
723
+
724
+ function handleTouchMovePan( event ) {
725
+
726
+ //console.log( 'handleTouchMovePan' );
727
+
728
+ panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
729
+
730
+ panDelta.subVectors( panEnd, panStart );
731
+
732
+ pan( panDelta.x, panDelta.y );
733
+
734
+ panStart.copy( panEnd );
735
+
736
+ scope.update();
737
+
738
+ }
739
+
740
+ //
741
+ // event handlers - FSM: listen for events and reset state
742
+ //
743
+
744
+ function onMouseDown( event ) {
745
+
746
+ if ( scope.enabled === false ) return;
747
+
748
+ event.preventDefault();
749
+
750
+ if ( event.button === scope.mouseButtons.ORBIT ) {
751
+
752
+ if ( scope.enableRotate === false ) return;
753
+
754
+ handleMouseDownRotate( event );
755
+
756
+ state = STATE.ROTATE;
757
+
758
+ } else if ( event.button === scope.mouseButtons.ZOOM ) {
759
+
760
+ if ( scope.enableZoom === false ) return;
761
+
762
+ handleMouseDownDolly( event );
763
+
764
+ state = STATE.DOLLY;
765
+
766
+ } else if ( event.button === scope.mouseButtons.PAN ) {
767
+
768
+ if ( scope.enablePan === false ) return;
769
+
770
+ handleMouseDownPan( event );
771
+
772
+ state = STATE.PAN;
773
+
774
+ }
775
+
776
+ if ( state !== STATE.NONE ) {
777
+
778
+ document.addEventListener( 'mousemove', onMouseMove, false );
779
+ document.addEventListener( 'mouseup', onMouseUp, false );
780
+
781
+ scope.dispatchEvent( startEvent );
782
+
783
+ }
784
+
785
+ }
786
+
787
+ function onMouseMove( event ) {
788
+
789
+ if ( scope.enabled === false ) return;
790
+
791
+ event.preventDefault();
792
+
793
+ if ( state === STATE.ROTATE ) {
794
+
795
+ if ( scope.enableRotate === false ) return;
796
+
797
+ handleMouseMoveRotate( event );
798
+
799
+ } else if ( state === STATE.DOLLY ) {
800
+
801
+ if ( scope.enableZoom === false ) return;
802
+
803
+ handleMouseMoveDolly( event );
804
+
805
+ } else if ( state === STATE.PAN ) {
806
+
807
+ if ( scope.enablePan === false ) return;
808
+
809
+ handleMouseMovePan( event );
810
+
811
+ }
812
+
813
+ }
814
+
815
+ function onMouseUp( event ) {
816
+
817
+ if ( scope.enabled === false ) return;
818
+
819
+ document.removeEventListener( 'mousemove', onMouseMove, false );
820
+ document.removeEventListener( 'mouseup', onMouseUp, false );
821
+
822
+ scope.dispatchEvent( endEvent );
823
+
824
+ state = STATE.NONE;
825
+
826
+ }
827
+
828
+ function onMouseWheel( event ) {
829
+
830
+ if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;
831
+
832
+ event.preventDefault();
833
+ event.stopPropagation();
834
+
835
+ handleMouseWheel( event );
836
+
837
+ scope.dispatchEvent( startEvent ); // not sure why these are here...
838
+ scope.dispatchEvent( endEvent );
839
+
840
+ }
841
+
842
+ function onKeyDown( event ) {
843
+
844
+ if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;
845
+
846
+ handleKeyDown( event );
847
+
848
+ }
849
+
850
+ function onTouchStart( event ) {
851
+
852
+ if ( scope.enabled === false ) return;
853
+
854
+ switch ( event.touches.length ) {
855
+
856
+ case 1: // one-fingered touch: rotate
857
+
858
+ if ( scope.enableRotate === false ) return;
859
+
860
+ handleTouchStartRotate( event );
861
+
862
+ state = STATE.TOUCH_ROTATE;
863
+
864
+ break;
865
+
866
+ case 2: // two-fingered touch: dolly
867
+
868
+ if ( scope.enableZoom === false ) return;
869
+
870
+ handleTouchStartDolly( event );
871
+
872
+ state = STATE.TOUCH_DOLLY;
873
+
874
+ break;
875
+
876
+ case 3: // three-fingered touch: pan
877
+
878
+ if ( scope.enablePan === false ) return;
879
+
880
+ handleTouchStartPan( event );
881
+
882
+ state = STATE.TOUCH_PAN;
883
+
884
+ break;
885
+
886
+ default:
887
+
888
+ state = STATE.NONE;
889
+
890
+ }
891
+
892
+ if ( state !== STATE.NONE ) {
893
+
894
+ scope.dispatchEvent( startEvent );
895
+
896
+ }
897
+
898
+ }
899
+
900
+ function onTouchMove( event ) {
901
+
902
+ if ( scope.enabled === false ) return;
903
+
904
+ event.preventDefault();
905
+ event.stopPropagation();
906
+
907
+ switch ( event.touches.length ) {
908
+
909
+ case 1: // one-fingered touch: rotate
910
+
911
+ if ( scope.enableRotate === false ) return;
912
+ if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...
913
+
914
+ handleTouchMoveRotate( event );
915
+
916
+ break;
917
+
918
+ case 2: // two-fingered touch: dolly
919
+
920
+ if ( scope.enableZoom === false ) return;
921
+ if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...
922
+
923
+ handleTouchMoveDolly( event );
924
+
925
+ break;
926
+
927
+ case 3: // three-fingered touch: pan
928
+
929
+ if ( scope.enablePan === false ) return;
930
+ if ( state !== STATE.TOUCH_PAN ) return; // is this needed?...
931
+
932
+ handleTouchMovePan( event );
933
+
934
+ break;
935
+
936
+ default:
937
+
938
+ state = STATE.NONE;
939
+
940
+ }
941
+
942
+ }
943
+
944
+ function onTouchEnd( event ) {
945
+
946
+ if ( scope.enabled === false ) return;
947
+
948
+ scope.dispatchEvent( endEvent );
949
+
950
+ state = STATE.NONE;
951
+
952
+ }
953
+
954
+ function onContextMenu( event ) {
955
+
956
+ event.preventDefault();
957
+
958
+ }
959
+
960
+ //
961
+
962
+ scope.domElement.addEventListener( 'contextmenu', onContextMenu, false );
963
+
964
+ scope.domElement.addEventListener( 'mousedown', onMouseDown, false );
965
+ scope.domElement.addEventListener( 'wheel', onMouseWheel, false );
966
+
967
+ scope.domElement.addEventListener( 'touchstart', onTouchStart, false );
968
+ scope.domElement.addEventListener( 'touchend', onTouchEnd, false );
969
+ scope.domElement.addEventListener( 'touchmove', onTouchMove, false );
970
+
971
+ window.addEventListener( 'keydown', onKeyDown, false );
972
+
973
+ // force an update at start
974
+
975
+ this.update();
976
+
977
+ }
978
+ OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
979
+ OrbitControls.prototype.constructor = OrbitControls;
980
+
981
+ Object.defineProperties( OrbitControls.prototype, {
982
+
983
+ center: {
984
+
985
+ get: function () {
986
+
987
+ console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
988
+ return this.target;
989
+
990
+ }
991
+
992
+ },
993
+
994
+ // backward compatibility
995
+
996
+ noZoom: {
997
+
998
+ get: function () {
999
+
1000
+ console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
1001
+ return ! this.enableZoom;
1002
+
1003
+ },
1004
+
1005
+ set: function ( value ) {
1006
+
1007
+ console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
1008
+ this.enableZoom = ! value;
1009
+
1010
+ }
1011
+
1012
+ },
1013
+
1014
+ noRotate: {
1015
+
1016
+ get: function () {
1017
+
1018
+ console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
1019
+ return ! this.enableRotate;
1020
+
1021
+ },
1022
+
1023
+ set: function ( value ) {
1024
+
1025
+ console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
1026
+ this.enableRotate = ! value;
1027
+
1028
+ }
1029
+
1030
+ },
1031
+
1032
+ noPan: {
1033
+
1034
+ get: function () {
1035
+
1036
+ console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
1037
+ return ! this.enablePan;
1038
+
1039
+ },
1040
+
1041
+ set: function ( value ) {
1042
+
1043
+ console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
1044
+ this.enablePan = ! value;
1045
+
1046
+ }
1047
+
1048
+ },
1049
+
1050
+ noKeys: {
1051
+
1052
+ get: function () {
1053
+
1054
+ console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
1055
+ return ! this.enableKeys;
1056
+
1057
+ },
1058
+
1059
+ set: function ( value ) {
1060
+
1061
+ console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
1062
+ this.enableKeys = ! value;
1063
+
1064
+ }
1065
+
1066
+ },
1067
+
1068
+ staticMoving : {
1069
+
1070
+ get: function () {
1071
+
1072
+ console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
1073
+ return ! this.enableDamping;
1074
+
1075
+ },
1076
+
1077
+ set: function ( value ) {
1078
+
1079
+ console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
1080
+ this.enableDamping = ! value;
1081
+
1082
+ }
1083
+
1084
+ },
1085
+
1086
+ dynamicDampingFactor : {
1087
+
1088
+ get: function () {
1089
+
1090
+ console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1091
+ return this.dampingFactor;
1092
+
1093
+ },
1094
+
1095
+ set: function ( value ) {
1096
+
1097
+ console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1098
+ this.dampingFactor = value;
1099
+
1100
+ }
1101
+
1102
+ }
1103
+
1104
+ } );
1105
+
1106
+ return OrbitControls;
1107
+ };
1108
+
1109
+ const OrbitControls = /*@__PURE__*/index.getDefaultExportFromCjs(threeOrbitControls);
1110
+
1111
+ var xhr$1 = {exports: {}};
1112
+
1113
+ var win;
1114
+
1115
+ if (typeof window !== "undefined") {
1116
+ win = window;
1117
+ } else if (typeof index.commonjsGlobal !== "undefined") {
1118
+ win = index.commonjsGlobal;
1119
+ } else if (typeof self !== "undefined"){
1120
+ win = self;
1121
+ } else {
1122
+ win = {};
1123
+ }
1124
+
1125
+ var window_1 = win;
1126
+
1127
+ var isFunction_1 = isFunction$1;
1128
+
1129
+ var toString = Object.prototype.toString;
1130
+
1131
+ function isFunction$1 (fn) {
1132
+ if (!fn) {
1133
+ return false
1134
+ }
1135
+ var string = toString.call(fn);
1136
+ return string === '[object Function]' ||
1137
+ (typeof fn === 'function' && string !== '[object RegExp]') ||
1138
+ (typeof window !== 'undefined' &&
1139
+ // IE8 and below
1140
+ (fn === window.setTimeout ||
1141
+ fn === window.alert ||
1142
+ fn === window.confirm ||
1143
+ fn === window.prompt))
1144
+ }
1145
+
1146
+ var trim = function(string) {
1147
+ return string.replace(/^\s+|\s+$/g, '');
1148
+ }
1149
+ , isArray = function(arg) {
1150
+ return Object.prototype.toString.call(arg) === '[object Array]';
1151
+ };
1152
+
1153
+ var parseHeaders$1 = function (headers) {
1154
+ if (!headers)
1155
+ return {}
1156
+
1157
+ var result = {};
1158
+
1159
+ var headersArr = trim(headers).split('\n');
1160
+
1161
+ for (var i = 0; i < headersArr.length; i++) {
1162
+ var row = headersArr[i];
1163
+ var index = row.indexOf(':')
1164
+ , key = trim(row.slice(0, index)).toLowerCase()
1165
+ , value = trim(row.slice(index + 1));
1166
+
1167
+ if (typeof(result[key]) === 'undefined') {
1168
+ result[key] = value;
1169
+ } else if (isArray(result[key])) {
1170
+ result[key].push(value);
1171
+ } else {
1172
+ result[key] = [ result[key], value ];
1173
+ }
1174
+ }
1175
+
1176
+ return result
1177
+ };
1178
+
1179
+ var immutable = extend;
1180
+
1181
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
1182
+
1183
+ function extend() {
1184
+ var target = {};
1185
+
1186
+ for (var i = 0; i < arguments.length; i++) {
1187
+ var source = arguments[i];
1188
+
1189
+ for (var key in source) {
1190
+ if (hasOwnProperty.call(source, key)) {
1191
+ target[key] = source[key];
1192
+ }
1193
+ }
1194
+ }
1195
+
1196
+ return target
1197
+ }
1198
+
1199
+ var window$1 = window_1;
1200
+ var isFunction = isFunction_1;
1201
+ var parseHeaders = parseHeaders$1;
1202
+ var xtend$2 = immutable;
1203
+
1204
+ xhr$1.exports = createXHR;
1205
+ // Allow use of default import syntax in TypeScript
1206
+ xhr$1.exports.default = createXHR;
1207
+ createXHR.XMLHttpRequest = window$1.XMLHttpRequest || noop$1;
1208
+ createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window$1.XDomainRequest;
1209
+
1210
+ forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
1211
+ createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
1212
+ options = initParams(uri, options, callback);
1213
+ options.method = method.toUpperCase();
1214
+ return _createXHR(options)
1215
+ };
1216
+ });
1217
+
1218
+ function forEachArray(array, iterator) {
1219
+ for (var i = 0; i < array.length; i++) {
1220
+ iterator(array[i]);
1221
+ }
1222
+ }
1223
+
1224
+ function isEmpty(obj){
1225
+ for(var i in obj){
1226
+ if(obj.hasOwnProperty(i)) return false
1227
+ }
1228
+ return true
1229
+ }
1230
+
1231
+ function initParams(uri, options, callback) {
1232
+ var params = uri;
1233
+
1234
+ if (isFunction(options)) {
1235
+ callback = options;
1236
+ if (typeof uri === "string") {
1237
+ params = {uri:uri};
1238
+ }
1239
+ } else {
1240
+ params = xtend$2(options, {uri: uri});
1241
+ }
1242
+
1243
+ params.callback = callback;
1244
+ return params
1245
+ }
1246
+
1247
+ function createXHR(uri, options, callback) {
1248
+ options = initParams(uri, options, callback);
1249
+ return _createXHR(options)
1250
+ }
1251
+
1252
+ function _createXHR(options) {
1253
+ if(typeof options.callback === "undefined"){
1254
+ throw new Error("callback argument missing")
1255
+ }
1256
+
1257
+ var called = false;
1258
+ var callback = function cbOnce(err, response, body){
1259
+ if(!called){
1260
+ called = true;
1261
+ options.callback(err, response, body);
1262
+ }
1263
+ };
1264
+
1265
+ function readystatechange() {
1266
+ if (xhr.readyState === 4) {
1267
+ setTimeout(loadFunc, 0);
1268
+ }
1269
+ }
1270
+
1271
+ function getBody() {
1272
+ // Chrome with requestType=blob throws errors arround when even testing access to responseText
1273
+ var body = undefined;
1274
+
1275
+ if (xhr.response) {
1276
+ body = xhr.response;
1277
+ } else {
1278
+ body = xhr.responseText || getXml(xhr);
1279
+ }
1280
+
1281
+ if (isJson) {
1282
+ try {
1283
+ body = JSON.parse(body);
1284
+ } catch (e) {}
1285
+ }
1286
+
1287
+ return body
1288
+ }
1289
+
1290
+ function errorFunc(evt) {
1291
+ clearTimeout(timeoutTimer);
1292
+ if(!(evt instanceof Error)){
1293
+ evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") );
1294
+ }
1295
+ evt.statusCode = 0;
1296
+ return callback(evt, failureResponse)
1297
+ }
1298
+
1299
+ // will load the data & process the response in a special response object
1300
+ function loadFunc() {
1301
+ if (aborted) return
1302
+ var status;
1303
+ clearTimeout(timeoutTimer);
1304
+ if(options.useXDR && xhr.status===undefined) {
1305
+ //IE8 CORS GET successful response doesn't have a status field, but body is fine
1306
+ status = 200;
1307
+ } else {
1308
+ status = (xhr.status === 1223 ? 204 : xhr.status);
1309
+ }
1310
+ var response = failureResponse;
1311
+ var err = null;
1312
+
1313
+ if (status !== 0){
1314
+ response = {
1315
+ body: getBody(),
1316
+ statusCode: status,
1317
+ method: method,
1318
+ headers: {},
1319
+ url: uri,
1320
+ rawRequest: xhr
1321
+ };
1322
+ if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
1323
+ response.headers = parseHeaders(xhr.getAllResponseHeaders());
1324
+ }
1325
+ } else {
1326
+ err = new Error("Internal XMLHttpRequest Error");
1327
+ }
1328
+ return callback(err, response, response.body)
1329
+ }
1330
+
1331
+ var xhr = options.xhr || null;
1332
+
1333
+ if (!xhr) {
1334
+ if (options.cors || options.useXDR) {
1335
+ xhr = new createXHR.XDomainRequest();
1336
+ }else {
1337
+ xhr = new createXHR.XMLHttpRequest();
1338
+ }
1339
+ }
1340
+
1341
+ var key;
1342
+ var aborted;
1343
+ var uri = xhr.url = options.uri || options.url;
1344
+ var method = xhr.method = options.method || "GET";
1345
+ var body = options.body || options.data;
1346
+ var headers = xhr.headers = options.headers || {};
1347
+ var sync = !!options.sync;
1348
+ var isJson = false;
1349
+ var timeoutTimer;
1350
+ var failureResponse = {
1351
+ body: undefined,
1352
+ headers: {},
1353
+ statusCode: 0,
1354
+ method: method,
1355
+ url: uri,
1356
+ rawRequest: xhr
1357
+ };
1358
+
1359
+ if ("json" in options && options.json !== false) {
1360
+ isJson = true;
1361
+ headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json"); //Don't override existing accept header declared by user
1362
+ if (method !== "GET" && method !== "HEAD") {
1363
+ headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json"); //Don't override existing accept header declared by user
1364
+ body = JSON.stringify(options.json === true ? body : options.json);
1365
+ }
1366
+ }
1367
+
1368
+ xhr.onreadystatechange = readystatechange;
1369
+ xhr.onload = loadFunc;
1370
+ xhr.onerror = errorFunc;
1371
+ // IE9 must have onprogress be set to a unique function.
1372
+ xhr.onprogress = function () {
1373
+ // IE must die
1374
+ };
1375
+ xhr.onabort = function(){
1376
+ aborted = true;
1377
+ };
1378
+ xhr.ontimeout = errorFunc;
1379
+ xhr.open(method, uri, !sync, options.username, options.password);
1380
+ //has to be after open
1381
+ if(!sync) {
1382
+ xhr.withCredentials = !!options.withCredentials;
1383
+ }
1384
+ // Cannot set timeout with sync request
1385
+ // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
1386
+ // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
1387
+ if (!sync && options.timeout > 0 ) {
1388
+ timeoutTimer = setTimeout(function(){
1389
+ if (aborted) return
1390
+ aborted = true;//IE9 may still call readystatechange
1391
+ xhr.abort("timeout");
1392
+ var e = new Error("XMLHttpRequest timeout");
1393
+ e.code = "ETIMEDOUT";
1394
+ errorFunc(e);
1395
+ }, options.timeout );
1396
+ }
1397
+
1398
+ if (xhr.setRequestHeader) {
1399
+ for(key in headers){
1400
+ if(headers.hasOwnProperty(key)){
1401
+ xhr.setRequestHeader(key, headers[key]);
1402
+ }
1403
+ }
1404
+ } else if (options.headers && !isEmpty(options.headers)) {
1405
+ throw new Error("Headers cannot be set on an XDomainRequest object")
1406
+ }
1407
+
1408
+ if ("responseType" in options) {
1409
+ xhr.responseType = options.responseType;
1410
+ }
1411
+
1412
+ if ("beforeSend" in options &&
1413
+ typeof options.beforeSend === "function"
1414
+ ) {
1415
+ options.beforeSend(xhr);
1416
+ }
1417
+
1418
+ // Microsoft Edge browser sends "undefined" when send is called with undefined value.
1419
+ // XMLHttpRequest spec says to pass null as body to indicate no body
1420
+ // See https://github.com/naugtur/xhr/issues/100.
1421
+ xhr.send(body || null);
1422
+
1423
+ return xhr
1424
+
1425
+
1426
+ }
1427
+
1428
+ function getXml(xhr) {
1429
+ // xhr.responseXML will throw Exception "InvalidStateError" or "DOMException"
1430
+ // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML.
1431
+ try {
1432
+ if (xhr.responseType === "document") {
1433
+ return xhr.responseXML
1434
+ }
1435
+ var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror";
1436
+ if (xhr.responseType === "" && !firefoxBugTakenEffect) {
1437
+ return xhr.responseXML
1438
+ }
1439
+ } catch (e) {}
1440
+
1441
+ return null
1442
+ }
1443
+
1444
+ function noop$1() {}
1445
+
1446
+ var xhrExports = xhr$1.exports;
1447
+
1448
+ var parseBmfontAscii = function parseBMFontAscii(data) {
1449
+ if (!data)
1450
+ throw new Error('no data provided')
1451
+ data = data.toString().trim();
1452
+
1453
+ var output = {
1454
+ pages: [],
1455
+ chars: [],
1456
+ kernings: []
1457
+ };
1458
+
1459
+ var lines = data.split(/\r\n?|\n/g);
1460
+
1461
+ if (lines.length === 0)
1462
+ throw new Error('no data in BMFont file')
1463
+
1464
+ for (var i = 0; i < lines.length; i++) {
1465
+ var lineData = splitLine(lines[i], i);
1466
+ if (!lineData) //skip empty lines
1467
+ continue
1468
+
1469
+ if (lineData.key === 'page') {
1470
+ if (typeof lineData.data.id !== 'number')
1471
+ throw new Error('malformed file at line ' + i + ' -- needs page id=N')
1472
+ if (typeof lineData.data.file !== 'string')
1473
+ throw new Error('malformed file at line ' + i + ' -- needs page file="path"')
1474
+ output.pages[lineData.data.id] = lineData.data.file;
1475
+ } else if (lineData.key === 'chars' || lineData.key === 'kernings') ; else if (lineData.key === 'char') {
1476
+ output.chars.push(lineData.data);
1477
+ } else if (lineData.key === 'kerning') {
1478
+ output.kernings.push(lineData.data);
1479
+ } else {
1480
+ output[lineData.key] = lineData.data;
1481
+ }
1482
+ }
1483
+
1484
+ return output
1485
+ };
1486
+
1487
+ function splitLine(line, idx) {
1488
+ line = line.replace(/\t+/g, ' ').trim();
1489
+ if (!line)
1490
+ return null
1491
+
1492
+ var space = line.indexOf(' ');
1493
+ if (space === -1)
1494
+ throw new Error("no named row at line " + idx)
1495
+
1496
+ var key = line.substring(0, space);
1497
+
1498
+ line = line.substring(space + 1);
1499
+ //clear "letter" field as it is non-standard and
1500
+ //requires additional complexity to parse " / = symbols
1501
+ line = line.replace(/letter=[\'\"]\S+[\'\"]/gi, '');
1502
+ line = line.split("=");
1503
+ line = line.map(function(str) {
1504
+ return str.trim().match((/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g))
1505
+ });
1506
+
1507
+ var data = [];
1508
+ for (var i = 0; i < line.length; i++) {
1509
+ var dt = line[i];
1510
+ if (i === 0) {
1511
+ data.push({
1512
+ key: dt[0],
1513
+ data: ""
1514
+ });
1515
+ } else if (i === line.length - 1) {
1516
+ data[data.length - 1].data = parseData(dt[0]);
1517
+ } else {
1518
+ data[data.length - 1].data = parseData(dt[0]);
1519
+ data.push({
1520
+ key: dt[1],
1521
+ data: ""
1522
+ });
1523
+ }
1524
+ }
1525
+
1526
+ var out = {
1527
+ key: key,
1528
+ data: {}
1529
+ };
1530
+
1531
+ data.forEach(function(v) {
1532
+ out.data[v.key] = v.data;
1533
+ });
1534
+
1535
+ return out
1536
+ }
1537
+
1538
+ function parseData(data) {
1539
+ if (!data || data.length === 0)
1540
+ return ""
1541
+
1542
+ if (data.indexOf('"') === 0 || data.indexOf("'") === 0)
1543
+ return data.substring(1, data.length - 1)
1544
+ if (data.indexOf(',') !== -1)
1545
+ return parseIntList$1(data)
1546
+ return parseInt(data, 10)
1547
+ }
1548
+
1549
+ function parseIntList$1(data) {
1550
+ return data.split(',').map(function(val) {
1551
+ return parseInt(val, 10)
1552
+ })
1553
+ }
1554
+
1555
+ //Some versions of GlyphDesigner have a typo
1556
+ //that causes some bugs with parsing.
1557
+ //Need to confirm with recent version of the software
1558
+ //to see whether this is still an issue or not.
1559
+ var GLYPH_DESIGNER_ERROR = 'chasrset';
1560
+
1561
+ var parseAttribs = function parseAttributes(obj) {
1562
+ obj = Object.assign({}, obj);
1563
+ if (GLYPH_DESIGNER_ERROR in obj) {
1564
+ obj['charset'] = obj[GLYPH_DESIGNER_ERROR];
1565
+ delete obj[GLYPH_DESIGNER_ERROR];
1566
+ }
1567
+
1568
+ for (var k in obj) {
1569
+ if (k === 'face' || k === 'charset')
1570
+ continue
1571
+ else if (k === 'padding' || k === 'spacing')
1572
+ obj[k] = parseIntList(obj[k]);
1573
+ else
1574
+ obj[k] = parseInt(obj[k], 10);
1575
+ }
1576
+ return obj
1577
+ };
1578
+
1579
+ function parseIntList(data) {
1580
+ return data.split(',').map(function(val) {
1581
+ return parseInt(val, 10)
1582
+ })
1583
+ }
1584
+
1585
+ var xmlParseFromString = (function xmlparser() {
1586
+ //common browsers
1587
+ if (typeof self.DOMParser !== 'undefined') {
1588
+ return function(str) {
1589
+ var parser = new self.DOMParser();
1590
+ return parser.parseFromString(str, 'application/xml')
1591
+ }
1592
+ }
1593
+
1594
+ //IE8 fallback
1595
+ if (typeof self.ActiveXObject !== 'undefined'
1596
+ && new self.ActiveXObject('Microsoft.XMLDOM')) {
1597
+ return function(str) {
1598
+ var xmlDoc = new self.ActiveXObject("Microsoft.XMLDOM");
1599
+ xmlDoc.async = "false";
1600
+ xmlDoc.loadXML(str);
1601
+ return xmlDoc
1602
+ }
1603
+ }
1604
+
1605
+ //last resort fallback
1606
+ return function(str) {
1607
+ var div = document.createElement('div');
1608
+ div.innerHTML = str;
1609
+ return div
1610
+ }
1611
+ })();
1612
+
1613
+ var parseAttributes = parseAttribs;
1614
+ var parseFromString = xmlParseFromString;
1615
+
1616
+ //In some cases element.attribute.nodeName can return
1617
+ //all lowercase values.. so we need to map them to the correct
1618
+ //case
1619
+ var NAME_MAP = {
1620
+ scaleh: 'scaleH',
1621
+ scalew: 'scaleW',
1622
+ stretchh: 'stretchH',
1623
+ lineheight: 'lineHeight',
1624
+ alphachnl: 'alphaChnl',
1625
+ redchnl: 'redChnl',
1626
+ greenchnl: 'greenChnl',
1627
+ bluechnl: 'blueChnl'
1628
+ };
1629
+
1630
+ var browser$1 = function parse(data) {
1631
+ data = data.toString();
1632
+
1633
+ var xmlRoot = parseFromString(data);
1634
+ var output = {
1635
+ pages: [],
1636
+ chars: [],
1637
+ kernings: []
1638
+ }
1639
+
1640
+ //get config settings
1641
+ ;['info', 'common'].forEach(function(key) {
1642
+ var element = xmlRoot.getElementsByTagName(key)[0];
1643
+ if (element)
1644
+ output[key] = parseAttributes(getAttribs(element));
1645
+ });
1646
+
1647
+ //get page info
1648
+ var pageRoot = xmlRoot.getElementsByTagName('pages')[0];
1649
+ if (!pageRoot)
1650
+ throw new Error('malformed file -- no <pages> element')
1651
+ var pages = pageRoot.getElementsByTagName('page');
1652
+ for (var i=0; i<pages.length; i++) {
1653
+ var p = pages[i];
1654
+ var id = parseInt(p.getAttribute('id'), 10);
1655
+ var file = p.getAttribute('file');
1656
+ if (isNaN(id))
1657
+ throw new Error('malformed file -- page "id" attribute is NaN')
1658
+ if (!file)
1659
+ throw new Error('malformed file -- needs page "file" attribute')
1660
+ output.pages[parseInt(id, 10)] = file;
1661
+ }
1662
+ ['chars', 'kernings'].forEach(function(key) {
1663
+ var element = xmlRoot.getElementsByTagName(key)[0];
1664
+ if (!element)
1665
+ return
1666
+ var childTag = key.substring(0, key.length-1);
1667
+ var children = element.getElementsByTagName(childTag);
1668
+ for (var i=0; i<children.length; i++) {
1669
+ var child = children[i];
1670
+ output[key].push(parseAttributes(getAttribs(child)));
1671
+ }
1672
+ });
1673
+ return output
1674
+ };
1675
+
1676
+ function getAttribs(element) {
1677
+ var attribs = getAttribList(element);
1678
+ return attribs.reduce(function(dict, attrib) {
1679
+ var key = mapName(attrib.nodeName);
1680
+ dict[key] = attrib.nodeValue;
1681
+ return dict
1682
+ }, {})
1683
+ }
1684
+
1685
+ function getAttribList(element) {
1686
+ //IE8+ and modern browsers
1687
+ var attribs = [];
1688
+ for (var i=0; i<element.attributes.length; i++)
1689
+ attribs.push(element.attributes[i]);
1690
+ return attribs
1691
+ }
1692
+
1693
+ function mapName(nodeName) {
1694
+ return NAME_MAP[nodeName.toLowerCase()] || nodeName
1695
+ }
1696
+
1697
+ var HEADER$1 = [66, 77, 70];
1698
+
1699
+ var parseBmfontBinary = function readBMFontBinary(buf) {
1700
+ if (buf.length < 6)
1701
+ throw new Error('invalid buffer length for BMFont')
1702
+
1703
+ var header = HEADER$1.every(function(byte, i) {
1704
+ return buf.readUInt8(i) === byte
1705
+ });
1706
+
1707
+ if (!header)
1708
+ throw new Error('BMFont missing BMF byte header')
1709
+
1710
+ var i = 3;
1711
+ var vers = buf.readUInt8(i++);
1712
+ if (vers > 3)
1713
+ throw new Error('Only supports BMFont Binary v3 (BMFont App v1.10)')
1714
+
1715
+ var target = { kernings: [], chars: [] };
1716
+ for (var b=0; b<5; b++)
1717
+ i += readBlock(target, buf, i);
1718
+ return target
1719
+ };
1720
+
1721
+ function readBlock(target, buf, i) {
1722
+ if (i > buf.length-1)
1723
+ return 0
1724
+
1725
+ var blockID = buf.readUInt8(i++);
1726
+ var blockSize = buf.readInt32LE(i);
1727
+ i += 4;
1728
+
1729
+ switch(blockID) {
1730
+ case 1:
1731
+ target.info = readInfo(buf, i);
1732
+ break
1733
+ case 2:
1734
+ target.common = readCommon(buf, i);
1735
+ break
1736
+ case 3:
1737
+ target.pages = readPages(buf, i, blockSize);
1738
+ break
1739
+ case 4:
1740
+ target.chars = readChars(buf, i, blockSize);
1741
+ break
1742
+ case 5:
1743
+ target.kernings = readKernings(buf, i, blockSize);
1744
+ break
1745
+ }
1746
+ return 5 + blockSize
1747
+ }
1748
+
1749
+ function readInfo(buf, i) {
1750
+ var info = {};
1751
+ info.size = buf.readInt16LE(i);
1752
+
1753
+ var bitField = buf.readUInt8(i+2);
1754
+ info.smooth = (bitField >> 7) & 1;
1755
+ info.unicode = (bitField >> 6) & 1;
1756
+ info.italic = (bitField >> 5) & 1;
1757
+ info.bold = (bitField >> 4) & 1;
1758
+
1759
+ //fixedHeight is only mentioned in binary spec
1760
+ if ((bitField >> 3) & 1)
1761
+ info.fixedHeight = 1;
1762
+
1763
+ info.charset = buf.readUInt8(i+3) || '';
1764
+ info.stretchH = buf.readUInt16LE(i+4);
1765
+ info.aa = buf.readUInt8(i+6);
1766
+ info.padding = [
1767
+ buf.readInt8(i+7),
1768
+ buf.readInt8(i+8),
1769
+ buf.readInt8(i+9),
1770
+ buf.readInt8(i+10)
1771
+ ];
1772
+ info.spacing = [
1773
+ buf.readInt8(i+11),
1774
+ buf.readInt8(i+12)
1775
+ ];
1776
+ info.outline = buf.readUInt8(i+13);
1777
+ info.face = readStringNT(buf, i+14);
1778
+ return info
1779
+ }
1780
+
1781
+ function readCommon(buf, i) {
1782
+ var common = {};
1783
+ common.lineHeight = buf.readUInt16LE(i);
1784
+ common.base = buf.readUInt16LE(i+2);
1785
+ common.scaleW = buf.readUInt16LE(i+4);
1786
+ common.scaleH = buf.readUInt16LE(i+6);
1787
+ common.pages = buf.readUInt16LE(i+8);
1788
+ buf.readUInt8(i+10);
1789
+ common.packed = 0;
1790
+ common.alphaChnl = buf.readUInt8(i+11);
1791
+ common.redChnl = buf.readUInt8(i+12);
1792
+ common.greenChnl = buf.readUInt8(i+13);
1793
+ common.blueChnl = buf.readUInt8(i+14);
1794
+ return common
1795
+ }
1796
+
1797
+ function readPages(buf, i, size) {
1798
+ var pages = [];
1799
+ var text = readNameNT(buf, i);
1800
+ var len = text.length+1;
1801
+ var count = size / len;
1802
+ for (var c=0; c<count; c++) {
1803
+ pages[c] = buf.slice(i, i+text.length).toString('utf8');
1804
+ i += len;
1805
+ }
1806
+ return pages
1807
+ }
1808
+
1809
+ function readChars(buf, i, blockSize) {
1810
+ var chars = [];
1811
+
1812
+ var count = blockSize / 20;
1813
+ for (var c=0; c<count; c++) {
1814
+ var char = {};
1815
+ var off = c*20;
1816
+ char.id = buf.readUInt32LE(i + 0 + off);
1817
+ char.x = buf.readUInt16LE(i + 4 + off);
1818
+ char.y = buf.readUInt16LE(i + 6 + off);
1819
+ char.width = buf.readUInt16LE(i + 8 + off);
1820
+ char.height = buf.readUInt16LE(i + 10 + off);
1821
+ char.xoffset = buf.readInt16LE(i + 12 + off);
1822
+ char.yoffset = buf.readInt16LE(i + 14 + off);
1823
+ char.xadvance = buf.readInt16LE(i + 16 + off);
1824
+ char.page = buf.readUInt8(i + 18 + off);
1825
+ char.chnl = buf.readUInt8(i + 19 + off);
1826
+ chars[c] = char;
1827
+ }
1828
+ return chars
1829
+ }
1830
+
1831
+ function readKernings(buf, i, blockSize) {
1832
+ var kernings = [];
1833
+ var count = blockSize / 10;
1834
+ for (var c=0; c<count; c++) {
1835
+ var kern = {};
1836
+ var off = c*10;
1837
+ kern.first = buf.readUInt32LE(i + 0 + off);
1838
+ kern.second = buf.readUInt32LE(i + 4 + off);
1839
+ kern.amount = buf.readInt16LE(i + 8 + off);
1840
+ kernings[c] = kern;
1841
+ }
1842
+ return kernings
1843
+ }
1844
+
1845
+ function readNameNT(buf, offset) {
1846
+ var pos=offset;
1847
+ for (; pos<buf.length; pos++) {
1848
+ if (buf[pos] === 0x00)
1849
+ break
1850
+ }
1851
+ return buf.slice(offset, pos)
1852
+ }
1853
+
1854
+ function readStringNT(buf, offset) {
1855
+ return readNameNT(buf, offset).toString('utf8')
1856
+ }
1857
+
1858
+ const __viteBrowserExternal = {};
1859
+
1860
+ const __viteBrowserExternal$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1861
+ __proto__: null,
1862
+ default: __viteBrowserExternal
1863
+ }, Symbol.toStringTag, { value: 'Module' }));
1864
+
1865
+ const require$$0 = /*@__PURE__*/index.getAugmentedNamespace(__viteBrowserExternal$1);
1866
+
1867
+ var Buffer$1 = require$$0.Buffer; // for use with browserify
1868
+
1869
+ var bufferEqual = function (a, b) {
1870
+ if (!Buffer$1.isBuffer(a)) return undefined;
1871
+ if (!Buffer$1.isBuffer(b)) return undefined;
1872
+ if (typeof a.equals === 'function') return a.equals(b);
1873
+ if (a.length !== b.length) return false;
1874
+
1875
+ for (var i = 0; i < a.length; i++) {
1876
+ if (a[i] !== b[i]) return false;
1877
+ }
1878
+
1879
+ return true;
1880
+ };
1881
+
1882
+ var equal = bufferEqual;
1883
+ var HEADER = Buffer.from([66, 77, 70, 3]);
1884
+
1885
+ var isBinary = function(buf) {
1886
+ if (typeof buf === 'string')
1887
+ return buf.substring(0, 3) === 'BMF'
1888
+ return buf.length > 4 && equal(buf.slice(0, 4), HEADER)
1889
+ };
1890
+
1891
+ var xhr = xhrExports;
1892
+ var noop = function(){};
1893
+ var parseASCII = parseBmfontAscii;
1894
+ var parseXML = browser$1;
1895
+ var readBinary = parseBmfontBinary;
1896
+ var isBinaryFormat = isBinary;
1897
+ var xtend$1 = immutable;
1898
+
1899
+ var xml2 = (function hasXML2() {
1900
+ return self.XMLHttpRequest && "withCredentials" in new XMLHttpRequest
1901
+ })();
1902
+
1903
+ var browser = function(opt, cb) {
1904
+ cb = typeof cb === 'function' ? cb : noop;
1905
+
1906
+ if (typeof opt === 'string')
1907
+ opt = { uri: opt };
1908
+ else if (!opt)
1909
+ opt = {};
1910
+
1911
+ var expectBinary = opt.binary;
1912
+ if (expectBinary)
1913
+ opt = getBinaryOpts(opt);
1914
+
1915
+ xhr(opt, function(err, res, body) {
1916
+ if (err)
1917
+ return cb(err)
1918
+ if (!/^2/.test(res.statusCode))
1919
+ return cb(new Error('http status code: '+res.statusCode))
1920
+ if (!body)
1921
+ return cb(new Error('no body result'))
1922
+
1923
+ var binary = false;
1924
+
1925
+ //if the response type is an array buffer,
1926
+ //we need to convert it into a regular Buffer object
1927
+ if (isArrayBuffer(body)) {
1928
+ var array = new Uint8Array(body);
1929
+ body = Buffer.from(array, 'binary');
1930
+ }
1931
+
1932
+ //now check the string/Buffer response
1933
+ //and see if it has a binary BMF header
1934
+ if (isBinaryFormat(body)) {
1935
+ binary = true;
1936
+ //if we have a string, turn it into a Buffer
1937
+ if (typeof body === 'string')
1938
+ body = Buffer.from(body, 'binary');
1939
+ }
1940
+
1941
+ //we are not parsing a binary format, just ASCII/XML/etc
1942
+ if (!binary) {
1943
+ //might still be a buffer if responseType is 'arraybuffer'
1944
+ if (Buffer.isBuffer(body))
1945
+ body = body.toString(opt.encoding);
1946
+ body = body.trim();
1947
+ }
1948
+
1949
+ var result;
1950
+ try {
1951
+ var type = res.headers['content-type'];
1952
+ if (binary)
1953
+ result = readBinary(body);
1954
+ else if (/json/.test(type) || body.charAt(0) === '{')
1955
+ result = JSON.parse(body);
1956
+ else if (/xml/.test(type) || body.charAt(0) === '<')
1957
+ result = parseXML(body);
1958
+ else
1959
+ result = parseASCII(body);
1960
+ } catch (e) {
1961
+ cb(new Error('error parsing font '+e.message));
1962
+ cb = noop;
1963
+ }
1964
+ cb(null, result);
1965
+ });
1966
+ };
1967
+
1968
+ function isArrayBuffer(arr) {
1969
+ var str = Object.prototype.toString;
1970
+ return str.call(arr) === '[object ArrayBuffer]'
1971
+ }
1972
+
1973
+ function getBinaryOpts(opt) {
1974
+ //IE10+ and other modern browsers support array buffers
1975
+ if (xml2)
1976
+ return xtend$1(opt, { responseType: 'arraybuffer' })
1977
+
1978
+ if (typeof self.XMLHttpRequest === 'undefined')
1979
+ throw new Error('your browser does not support XHR loading')
1980
+
1981
+ //IE9 and XML1 browsers could still use an override
1982
+ var req = new self.XMLHttpRequest();
1983
+ req.overrideMimeType('text/plain; charset=x-user-defined');
1984
+ return xtend$1({
1985
+ xhr: req
1986
+ }, opt)
1987
+ }
1988
+
1989
+ const loadFont = /*@__PURE__*/index.getDefaultExportFromCjs(browser);
1990
+
1991
+ var wordWrapper = {exports: {}};
1992
+
1993
+ (function (module) {
1994
+ var newline = /\n/;
1995
+ var newlineChar = '\n';
1996
+ var whitespace = /\s/;
1997
+
1998
+ module.exports = function(text, opt) {
1999
+ var lines = module.exports.lines(text, opt);
2000
+ return lines.map(function(line) {
2001
+ return text.substring(line.start, line.end)
2002
+ }).join('\n')
2003
+ };
2004
+
2005
+ module.exports.lines = function wordwrap(text, opt) {
2006
+ opt = opt||{};
2007
+
2008
+ //zero width results in nothing visible
2009
+ if (opt.width === 0 && opt.mode !== 'nowrap')
2010
+ return []
2011
+
2012
+ text = text||'';
2013
+ var width = typeof opt.width === 'number' ? opt.width : Number.MAX_VALUE;
2014
+ var start = Math.max(0, opt.start||0);
2015
+ var end = typeof opt.end === 'number' ? opt.end : text.length;
2016
+ var mode = opt.mode;
2017
+
2018
+ var measure = opt.measure || monospace;
2019
+ if (mode === 'pre')
2020
+ return pre(measure, text, start, end, width)
2021
+ else
2022
+ return greedy(measure, text, start, end, width, mode)
2023
+ };
2024
+
2025
+ function idxOf(text, chr, start, end) {
2026
+ var idx = text.indexOf(chr, start);
2027
+ if (idx === -1 || idx > end)
2028
+ return end
2029
+ return idx
2030
+ }
2031
+
2032
+ function isWhitespace(chr) {
2033
+ return whitespace.test(chr)
2034
+ }
2035
+
2036
+ function pre(measure, text, start, end, width) {
2037
+ var lines = [];
2038
+ var lineStart = start;
2039
+ for (var i=start; i<end && i<text.length; i++) {
2040
+ var chr = text.charAt(i);
2041
+ var isNewline = newline.test(chr);
2042
+
2043
+ //If we've reached a newline, then step down a line
2044
+ //Or if we've reached the EOF
2045
+ if (isNewline || i===end-1) {
2046
+ var lineEnd = isNewline ? i : i+1;
2047
+ var measured = measure(text, lineStart, lineEnd, width);
2048
+ lines.push(measured);
2049
+
2050
+ lineStart = i+1;
2051
+ }
2052
+ }
2053
+ return lines
2054
+ }
2055
+
2056
+ function greedy(measure, text, start, end, width, mode) {
2057
+ //A greedy word wrapper based on LibGDX algorithm
2058
+ //https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/BitmapFontCache.java
2059
+ var lines = [];
2060
+
2061
+ var testWidth = width;
2062
+ //if 'nowrap' is specified, we only wrap on newline chars
2063
+ if (mode === 'nowrap')
2064
+ testWidth = Number.MAX_VALUE;
2065
+
2066
+ while (start < end && start < text.length) {
2067
+ //get next newline position
2068
+ var newLine = idxOf(text, newlineChar, start, end);
2069
+
2070
+ //eat whitespace at start of line
2071
+ while (start < newLine) {
2072
+ if (!isWhitespace( text.charAt(start) ))
2073
+ break
2074
+ start++;
2075
+ }
2076
+
2077
+ //determine visible # of glyphs for the available width
2078
+ var measured = measure(text, start, newLine, testWidth);
2079
+
2080
+ var lineEnd = start + (measured.end-measured.start);
2081
+ var nextStart = lineEnd + newlineChar.length;
2082
+
2083
+ //if we had to cut the line before the next newline...
2084
+ if (lineEnd < newLine) {
2085
+ //find char to break on
2086
+ while (lineEnd > start) {
2087
+ if (isWhitespace(text.charAt(lineEnd)))
2088
+ break
2089
+ lineEnd--;
2090
+ }
2091
+ if (lineEnd === start) {
2092
+ if (nextStart > start + newlineChar.length) nextStart--;
2093
+ lineEnd = nextStart; // If no characters to break, show all.
2094
+ } else {
2095
+ nextStart = lineEnd;
2096
+ //eat whitespace at end of line
2097
+ while (lineEnd > start) {
2098
+ if (!isWhitespace(text.charAt(lineEnd - newlineChar.length)))
2099
+ break
2100
+ lineEnd--;
2101
+ }
2102
+ }
2103
+ }
2104
+ if (lineEnd >= start) {
2105
+ var result = measure(text, start, lineEnd, testWidth);
2106
+ lines.push(result);
2107
+ }
2108
+ start = nextStart;
2109
+ }
2110
+ return lines
2111
+ }
2112
+
2113
+ //determines the visible number of glyphs within a given width
2114
+ function monospace(text, start, end, width) {
2115
+ var glyphs = Math.min(width, end-start);
2116
+ return {
2117
+ start: start,
2118
+ end: start+glyphs
2119
+ }
2120
+ }
2121
+ } (wordWrapper));
2122
+
2123
+ var wordWrapperExports = wordWrapper.exports;
2124
+
2125
+ var asNumber = function numtype(num, def) {
2126
+ return typeof num === 'number'
2127
+ ? num
2128
+ : (typeof def === 'number' ? def : 0)
2129
+ };
2130
+
2131
+ var wordWrap = wordWrapperExports;
2132
+ var xtend = immutable;
2133
+ var number = asNumber;
2134
+
2135
+ var X_HEIGHTS = ['x', 'e', 'a', 'o', 'n', 's', 'r', 'c', 'u', 'm', 'v', 'w', 'z'];
2136
+ var M_WIDTHS = ['m', 'w'];
2137
+ var CAP_HEIGHTS = ['H', 'I', 'N', 'E', 'F', 'K', 'L', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
2138
+
2139
+
2140
+ var TAB_ID = '\t'.charCodeAt(0);
2141
+ var SPACE_ID = ' '.charCodeAt(0);
2142
+ var ALIGN_LEFT = 0,
2143
+ ALIGN_CENTER = 1,
2144
+ ALIGN_RIGHT = 2;
2145
+
2146
+ var layoutBmfontText = function createLayout(opt) {
2147
+ return new TextLayout(opt)
2148
+ };
2149
+
2150
+ function TextLayout(opt) {
2151
+ this.glyphs = [];
2152
+ this._measure = this.computeMetrics.bind(this);
2153
+ this.update(opt);
2154
+ }
2155
+
2156
+ TextLayout.prototype.update = function(opt) {
2157
+ opt = xtend({
2158
+ measure: this._measure
2159
+ }, opt);
2160
+ this._opt = opt;
2161
+ this._opt.tabSize = number(this._opt.tabSize, 4);
2162
+
2163
+ if (!opt.font)
2164
+ throw new Error('must provide a valid bitmap font')
2165
+
2166
+ var glyphs = this.glyphs;
2167
+ var text = opt.text||'';
2168
+ var font = opt.font;
2169
+ this._setupSpaceGlyphs(font);
2170
+
2171
+ var lines = wordWrap.lines(text, opt);
2172
+ var minWidth = opt.width || 0;
2173
+
2174
+ //clear glyphs
2175
+ glyphs.length = 0;
2176
+
2177
+ //get max line width
2178
+ var maxLineWidth = lines.reduce(function(prev, line) {
2179
+ return Math.max(prev, line.width, minWidth)
2180
+ }, 0);
2181
+
2182
+ //the pen position
2183
+ var x = 0;
2184
+ var y = 0;
2185
+ var lineHeight = number(opt.lineHeight, font.common.lineHeight);
2186
+ var baseline = font.common.base;
2187
+ var descender = lineHeight-baseline;
2188
+ var letterSpacing = opt.letterSpacing || 0;
2189
+ var height = lineHeight * lines.length - descender;
2190
+ var align = getAlignType(this._opt.align);
2191
+
2192
+ //draw text along baseline
2193
+ y -= height;
2194
+
2195
+ //the metrics for this text layout
2196
+ this._width = maxLineWidth;
2197
+ this._height = height;
2198
+ this._descender = lineHeight - baseline;
2199
+ this._baseline = baseline;
2200
+ this._xHeight = getXHeight(font);
2201
+ this._capHeight = getCapHeight(font);
2202
+ this._lineHeight = lineHeight;
2203
+ this._ascender = lineHeight - descender - this._xHeight;
2204
+
2205
+ //layout each glyph
2206
+ var self = this;
2207
+ lines.forEach(function(line, lineIndex) {
2208
+ var start = line.start;
2209
+ var end = line.end;
2210
+ var lineWidth = line.width;
2211
+ var lastGlyph;
2212
+
2213
+ //for each glyph in that line...
2214
+ for (var i=start; i<end; i++) {
2215
+ var id = text.charCodeAt(i);
2216
+ var glyph = self.getGlyph(font, id);
2217
+ if (glyph) {
2218
+ if (lastGlyph)
2219
+ x += getKerning(font, lastGlyph.id, glyph.id);
2220
+
2221
+ var tx = x;
2222
+ if (align === ALIGN_CENTER)
2223
+ tx += (maxLineWidth-lineWidth)/2;
2224
+ else if (align === ALIGN_RIGHT)
2225
+ tx += (maxLineWidth-lineWidth);
2226
+
2227
+ glyphs.push({
2228
+ position: [tx, y],
2229
+ data: glyph,
2230
+ index: i,
2231
+ line: lineIndex
2232
+ });
2233
+
2234
+ //move pen forward
2235
+ x += glyph.xadvance + letterSpacing;
2236
+ lastGlyph = glyph;
2237
+ }
2238
+ }
2239
+
2240
+ //next line down
2241
+ y += lineHeight;
2242
+ x = 0;
2243
+ });
2244
+ this._linesTotal = lines.length;
2245
+ };
2246
+
2247
+ TextLayout.prototype._setupSpaceGlyphs = function(font) {
2248
+ //These are fallbacks, when the font doesn't include
2249
+ //' ' or '\t' glyphs
2250
+ this._fallbackSpaceGlyph = null;
2251
+ this._fallbackTabGlyph = null;
2252
+
2253
+ if (!font.chars || font.chars.length === 0)
2254
+ return
2255
+
2256
+ //try to get space glyph
2257
+ //then fall back to the 'm' or 'w' glyphs
2258
+ //then fall back to the first glyph available
2259
+ var space = getGlyphById(font, SPACE_ID)
2260
+ || getMGlyph(font)
2261
+ || font.chars[0];
2262
+
2263
+ //and create a fallback for tab
2264
+ var tabWidth = this._opt.tabSize * space.xadvance;
2265
+ this._fallbackSpaceGlyph = space;
2266
+ this._fallbackTabGlyph = xtend(space, {
2267
+ x: 0, y: 0, xadvance: tabWidth, id: TAB_ID,
2268
+ xoffset: 0, yoffset: 0, width: 0, height: 0
2269
+ });
2270
+ };
2271
+
2272
+ TextLayout.prototype.getGlyph = function(font, id) {
2273
+ var glyph = getGlyphById(font, id);
2274
+ if (glyph)
2275
+ return glyph
2276
+ else if (id === TAB_ID)
2277
+ return this._fallbackTabGlyph
2278
+ else if (id === SPACE_ID)
2279
+ return this._fallbackSpaceGlyph
2280
+ return null
2281
+ };
2282
+
2283
+ TextLayout.prototype.computeMetrics = function(text, start, end, width) {
2284
+ var letterSpacing = this._opt.letterSpacing || 0;
2285
+ var font = this._opt.font;
2286
+ var curPen = 0;
2287
+ var curWidth = 0;
2288
+ var count = 0;
2289
+ var glyph;
2290
+ var lastGlyph;
2291
+
2292
+ if (!font.chars || font.chars.length === 0) {
2293
+ return {
2294
+ start: start,
2295
+ end: start,
2296
+ width: 0
2297
+ }
2298
+ }
2299
+
2300
+ end = Math.min(text.length, end);
2301
+ for (var i=start; i < end; i++) {
2302
+ var id = text.charCodeAt(i);
2303
+ var glyph = this.getGlyph(font, id);
2304
+
2305
+ if (glyph) {
2306
+ //move pen forward
2307
+ glyph.xoffset;
2308
+ var kern = lastGlyph ? getKerning(font, lastGlyph.id, glyph.id) : 0;
2309
+ curPen += kern;
2310
+
2311
+ var nextPen = curPen + glyph.xadvance + letterSpacing;
2312
+ var nextWidth = curPen + glyph.width;
2313
+
2314
+ //we've hit our limit; we can't move onto the next glyph
2315
+ if (nextWidth >= width || nextPen >= width)
2316
+ break
2317
+
2318
+ //otherwise continue along our line
2319
+ curPen = nextPen;
2320
+ curWidth = nextWidth;
2321
+ lastGlyph = glyph;
2322
+ }
2323
+ count++;
2324
+ }
2325
+
2326
+ //make sure rightmost edge lines up with rendered glyphs
2327
+ if (lastGlyph)
2328
+ curWidth += lastGlyph.xoffset;
2329
+
2330
+ return {
2331
+ start: start,
2332
+ end: start + count,
2333
+ width: curWidth
2334
+ }
2335
+ }
2336
+
2337
+ //getters for the private vars
2338
+ ;['width', 'height',
2339
+ 'descender', 'ascender',
2340
+ 'xHeight', 'baseline',
2341
+ 'capHeight',
2342
+ 'lineHeight' ].forEach(addGetter);
2343
+
2344
+ function addGetter(name) {
2345
+ Object.defineProperty(TextLayout.prototype, name, {
2346
+ get: wrapper(name),
2347
+ configurable: true
2348
+ });
2349
+ }
2350
+
2351
+ //create lookups for private vars
2352
+ function wrapper(name) {
2353
+ return (new Function([
2354
+ 'return function '+name+'() {',
2355
+ ' return this._'+name,
2356
+ '}'
2357
+ ].join('\n')))()
2358
+ }
2359
+
2360
+ function getGlyphById(font, id) {
2361
+ if (!font.chars || font.chars.length === 0)
2362
+ return null
2363
+
2364
+ var glyphIdx = findChar(font.chars, id);
2365
+ if (glyphIdx >= 0)
2366
+ return font.chars[glyphIdx]
2367
+ return null
2368
+ }
2369
+
2370
+ function getXHeight(font) {
2371
+ for (var i=0; i<X_HEIGHTS.length; i++) {
2372
+ var id = X_HEIGHTS[i].charCodeAt(0);
2373
+ var idx = findChar(font.chars, id);
2374
+ if (idx >= 0)
2375
+ return font.chars[idx].height
2376
+ }
2377
+ return 0
2378
+ }
2379
+
2380
+ function getMGlyph(font) {
2381
+ for (var i=0; i<M_WIDTHS.length; i++) {
2382
+ var id = M_WIDTHS[i].charCodeAt(0);
2383
+ var idx = findChar(font.chars, id);
2384
+ if (idx >= 0)
2385
+ return font.chars[idx]
2386
+ }
2387
+ return 0
2388
+ }
2389
+
2390
+ function getCapHeight(font) {
2391
+ for (var i=0; i<CAP_HEIGHTS.length; i++) {
2392
+ var id = CAP_HEIGHTS[i].charCodeAt(0);
2393
+ var idx = findChar(font.chars, id);
2394
+ if (idx >= 0)
2395
+ return font.chars[idx].height
2396
+ }
2397
+ return 0
2398
+ }
2399
+
2400
+ function getKerning(font, left, right) {
2401
+ if (!font.kernings || font.kernings.length === 0)
2402
+ return 0
2403
+
2404
+ var table = font.kernings;
2405
+ for (var i=0; i<table.length; i++) {
2406
+ var kern = table[i];
2407
+ if (kern.first === left && kern.second === right)
2408
+ return kern.amount
2409
+ }
2410
+ return 0
2411
+ }
2412
+
2413
+ function getAlignType(align) {
2414
+ if (align === 'center')
2415
+ return ALIGN_CENTER
2416
+ else if (align === 'right')
2417
+ return ALIGN_RIGHT
2418
+ return ALIGN_LEFT
2419
+ }
2420
+
2421
+ function findChar (array, value, start) {
2422
+ start = start || 0;
2423
+ for (var i = start; i < array.length; i++) {
2424
+ if (array[i].id === value) {
2425
+ return i
2426
+ }
2427
+ }
2428
+ return -1
2429
+ }
2430
+
2431
+ var inherits_browser = {exports: {}};
2432
+
2433
+ if (typeof Object.create === 'function') {
2434
+ // implementation from standard node.js 'util' module
2435
+ inherits_browser.exports = function inherits(ctor, superCtor) {
2436
+ if (superCtor) {
2437
+ ctor.super_ = superCtor;
2438
+ ctor.prototype = Object.create(superCtor.prototype, {
2439
+ constructor: {
2440
+ value: ctor,
2441
+ enumerable: false,
2442
+ writable: true,
2443
+ configurable: true
2444
+ }
2445
+ });
2446
+ }
2447
+ };
2448
+ } else {
2449
+ // old school shim for old browsers
2450
+ inherits_browser.exports = function inherits(ctor, superCtor) {
2451
+ if (superCtor) {
2452
+ ctor.super_ = superCtor;
2453
+ var TempCtor = function () {};
2454
+ TempCtor.prototype = superCtor.prototype;
2455
+ ctor.prototype = new TempCtor();
2456
+ ctor.prototype.constructor = ctor;
2457
+ }
2458
+ };
2459
+ }
2460
+
2461
+ var inherits_browserExports = inherits_browser.exports;
2462
+
2463
+ var dtype$1 = function(dtype) {
2464
+ switch (dtype) {
2465
+ case 'int8':
2466
+ return Int8Array
2467
+ case 'int16':
2468
+ return Int16Array
2469
+ case 'int32':
2470
+ return Int32Array
2471
+ case 'uint8':
2472
+ return Uint8Array
2473
+ case 'uint16':
2474
+ return Uint16Array
2475
+ case 'uint32':
2476
+ return Uint32Array
2477
+ case 'float32':
2478
+ return Float32Array
2479
+ case 'float64':
2480
+ return Float64Array
2481
+ case 'array':
2482
+ return Array
2483
+ case 'uint8_clamped':
2484
+ return Uint8ClampedArray
2485
+ }
2486
+ };
2487
+
2488
+ var str = Object.prototype.toString;
2489
+
2490
+ var anArray_1 = anArray$1;
2491
+
2492
+ function anArray$1(arr) {
2493
+ return (
2494
+ arr.BYTES_PER_ELEMENT
2495
+ && str.call(arr.buffer) === '[object ArrayBuffer]'
2496
+ || Array.isArray(arr)
2497
+ )
2498
+ }
2499
+
2500
+ /*!
2501
+ * Determine if an object is a Buffer
2502
+ *
2503
+ * @author Feross Aboukhadijeh <https://feross.org>
2504
+ * @license MIT
2505
+ */
2506
+
2507
+ // The _isBuffer check is for Safari 5-7 support, because it's missing
2508
+ // Object.prototype.constructor. Remove this eventually
2509
+ var isBuffer_1 = function (obj) {
2510
+ return obj != null && (isBuffer$1(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
2511
+ };
2512
+
2513
+ function isBuffer$1 (obj) {
2514
+ return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
2515
+ }
2516
+
2517
+ // For Node v0.10 support. Remove this eventually.
2518
+ function isSlowBuffer (obj) {
2519
+ return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer$1(obj.slice(0, 0))
2520
+ }
2521
+
2522
+ var dtype = dtype$1;
2523
+ var anArray = anArray_1;
2524
+ var isBuffer = isBuffer_1;
2525
+
2526
+ var CW = [0, 2, 3];
2527
+ var CCW = [2, 1, 3];
2528
+
2529
+ var quadIndices = function createQuadElements(array, opt) {
2530
+ //if user didn't specify an output array
2531
+ if (!array || !(anArray(array) || isBuffer(array))) {
2532
+ opt = array || {};
2533
+ array = null;
2534
+ }
2535
+
2536
+ if (typeof opt === 'number') //backwards-compatible
2537
+ opt = { count: opt };
2538
+ else
2539
+ opt = opt || {};
2540
+
2541
+ var type = typeof opt.type === 'string' ? opt.type : 'uint16';
2542
+ var count = typeof opt.count === 'number' ? opt.count : 1;
2543
+ var start = (opt.start || 0);
2544
+
2545
+ var dir = opt.clockwise !== false ? CW : CCW,
2546
+ a = dir[0],
2547
+ b = dir[1],
2548
+ c = dir[2];
2549
+
2550
+ var numIndices = count * 6;
2551
+
2552
+ var indices = array || new (dtype(type))(numIndices);
2553
+ for (var i = 0, j = 0; i < numIndices; i += 6, j += 4) {
2554
+ var x = i + start;
2555
+ indices[x + 0] = j + 0;
2556
+ indices[x + 1] = j + 1;
2557
+ indices[x + 2] = j + 2;
2558
+ indices[x + 3] = j + a;
2559
+ indices[x + 4] = j + b;
2560
+ indices[x + 5] = j + c;
2561
+ }
2562
+ return indices
2563
+ };
2564
+
2565
+ var vertices$1 = {};
2566
+
2567
+ vertices$1.pages = function pages (glyphs) {
2568
+ var pages = new Float32Array(glyphs.length * 4 * 1);
2569
+ var i = 0;
2570
+ glyphs.forEach(function (glyph) {
2571
+ var id = glyph.data.page || 0;
2572
+ pages[i++] = id;
2573
+ pages[i++] = id;
2574
+ pages[i++] = id;
2575
+ pages[i++] = id;
2576
+ });
2577
+ return pages
2578
+ };
2579
+
2580
+ vertices$1.uvs = function uvs (glyphs, texWidth, texHeight, flipY) {
2581
+ var uvs = new Float32Array(glyphs.length * 4 * 2);
2582
+ var i = 0;
2583
+ glyphs.forEach(function (glyph) {
2584
+ var bitmap = glyph.data;
2585
+ var bw = (bitmap.x + bitmap.width);
2586
+ var bh = (bitmap.y + bitmap.height);
2587
+
2588
+ // top left position
2589
+ var u0 = bitmap.x / texWidth;
2590
+ var v1 = bitmap.y / texHeight;
2591
+ var u1 = bw / texWidth;
2592
+ var v0 = bh / texHeight;
2593
+
2594
+ if (flipY) {
2595
+ v1 = (texHeight - bitmap.y) / texHeight;
2596
+ v0 = (texHeight - bh) / texHeight;
2597
+ }
2598
+
2599
+ // BL
2600
+ uvs[i++] = u0;
2601
+ uvs[i++] = v1;
2602
+ // TL
2603
+ uvs[i++] = u0;
2604
+ uvs[i++] = v0;
2605
+ // TR
2606
+ uvs[i++] = u1;
2607
+ uvs[i++] = v0;
2608
+ // BR
2609
+ uvs[i++] = u1;
2610
+ uvs[i++] = v1;
2611
+ });
2612
+ return uvs
2613
+ };
2614
+
2615
+ vertices$1.positions = function positions (glyphs) {
2616
+ var positions = new Float32Array(glyphs.length * 4 * 2);
2617
+ var i = 0;
2618
+ glyphs.forEach(function (glyph) {
2619
+ var bitmap = glyph.data;
2620
+
2621
+ // bottom left position
2622
+ var x = glyph.position[0] + bitmap.xoffset;
2623
+ var y = glyph.position[1] + bitmap.yoffset;
2624
+
2625
+ // quad size
2626
+ var w = bitmap.width;
2627
+ var h = bitmap.height;
2628
+
2629
+ // BL
2630
+ positions[i++] = x;
2631
+ positions[i++] = y;
2632
+ // TL
2633
+ positions[i++] = x;
2634
+ positions[i++] = y + h;
2635
+ // TR
2636
+ positions[i++] = x + w;
2637
+ positions[i++] = y + h;
2638
+ // BR
2639
+ positions[i++] = x + w;
2640
+ positions[i++] = y;
2641
+ });
2642
+ return positions
2643
+ };
2644
+
2645
+ var utils$1 = {};
2646
+
2647
+ var itemSize = 2;
2648
+ var box = { min: [0, 0], max: [0, 0] };
2649
+
2650
+ function bounds (positions) {
2651
+ var count = positions.length / itemSize;
2652
+ box.min[0] = positions[0];
2653
+ box.min[1] = positions[1];
2654
+ box.max[0] = positions[0];
2655
+ box.max[1] = positions[1];
2656
+
2657
+ for (var i = 0; i < count; i++) {
2658
+ var x = positions[i * itemSize + 0];
2659
+ var y = positions[i * itemSize + 1];
2660
+ box.min[0] = Math.min(x, box.min[0]);
2661
+ box.min[1] = Math.min(y, box.min[1]);
2662
+ box.max[0] = Math.max(x, box.max[0]);
2663
+ box.max[1] = Math.max(y, box.max[1]);
2664
+ }
2665
+ }
2666
+
2667
+ utils$1.computeBox = function (positions, output) {
2668
+ bounds(positions);
2669
+ output.min.set(box.min[0], box.min[1], 0);
2670
+ output.max.set(box.max[0], box.max[1], 0);
2671
+ };
2672
+
2673
+ utils$1.computeSphere = function (positions, output) {
2674
+ bounds(positions);
2675
+ var minX = box.min[0];
2676
+ var minY = box.min[1];
2677
+ var maxX = box.max[0];
2678
+ var maxY = box.max[1];
2679
+ var width = maxX - minX;
2680
+ var height = maxY - minY;
2681
+ var length = Math.sqrt(width * width + height * height);
2682
+ output.center.set(minX + width / 2, minY + height / 2, 0);
2683
+ output.radius = length / 2;
2684
+ };
2685
+
2686
+ var createLayout = layoutBmfontText;
2687
+ var inherits = inherits_browserExports;
2688
+ var createIndices = quadIndices;
2689
+
2690
+ var vertices = vertices$1;
2691
+ var utils = utils$1;
2692
+
2693
+ var Base = THREE.BufferGeometry;
2694
+
2695
+ var threeBmfontText = function createTextGeometry (opt) {
2696
+ return new TextGeometry(opt)
2697
+ };
2698
+
2699
+ function TextGeometry (opt) {
2700
+ Base.call(this);
2701
+
2702
+ if (typeof opt === 'string') {
2703
+ opt = { text: opt };
2704
+ }
2705
+
2706
+ // use these as default values for any subsequent
2707
+ // calls to update()
2708
+ this._opt = Object.assign({}, opt);
2709
+
2710
+ // also do an initial setup...
2711
+ if (opt) this.update(opt);
2712
+ }
2713
+
2714
+ inherits(TextGeometry, Base);
2715
+
2716
+ TextGeometry.prototype.update = function (opt) {
2717
+ if (typeof opt === 'string') {
2718
+ opt = { text: opt };
2719
+ }
2720
+
2721
+ // use constructor defaults
2722
+ opt = Object.assign({}, this._opt, opt);
2723
+
2724
+ if (!opt.font) {
2725
+ throw new TypeError('must specify a { font } in options')
2726
+ }
2727
+
2728
+ this.layout = createLayout(opt);
2729
+
2730
+ // get vec2 texcoords
2731
+ var flipY = opt.flipY !== false;
2732
+
2733
+ // the desired BMFont data
2734
+ var font = opt.font;
2735
+
2736
+ // determine texture size from font file
2737
+ var texWidth = font.common.scaleW;
2738
+ var texHeight = font.common.scaleH;
2739
+
2740
+ // get visible glyphs
2741
+ var glyphs = this.layout.glyphs.filter(function (glyph) {
2742
+ var bitmap = glyph.data;
2743
+ return bitmap.width * bitmap.height > 0
2744
+ });
2745
+
2746
+ // provide visible glyphs for convenience
2747
+ this.visibleGlyphs = glyphs;
2748
+
2749
+ // get common vertex data
2750
+ var positions = vertices.positions(glyphs);
2751
+ var uvs = vertices.uvs(glyphs, texWidth, texHeight, flipY);
2752
+ var indices = createIndices([], {
2753
+ clockwise: true,
2754
+ type: 'uint16',
2755
+ count: glyphs.length
2756
+ });
2757
+
2758
+ // update vertex data
2759
+ this.setIndex(indices);
2760
+ this.setAttribute('position', new THREE.BufferAttribute(positions, 2));
2761
+ this.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));
2762
+
2763
+ // update multipage data
2764
+ if (!opt.multipage && 'page' in this.attributes) {
2765
+ // disable multipage rendering
2766
+ this.removeAttribute('page');
2767
+ } else if (opt.multipage) {
2768
+ // enable multipage rendering
2769
+ var pages = vertices.pages(glyphs);
2770
+ this.setAttribute('page', new THREE.BufferAttribute(pages, 1));
2771
+ }
2772
+ };
2773
+
2774
+ TextGeometry.prototype.computeBoundingSphere = function () {
2775
+ if (this.boundingSphere === null) {
2776
+ this.boundingSphere = new THREE.Sphere();
2777
+ }
2778
+
2779
+ var positions = this.attributes.position.array;
2780
+ var itemSize = this.attributes.position.itemSize;
2781
+ if (!positions || !itemSize || positions.length < 2) {
2782
+ this.boundingSphere.radius = 0;
2783
+ this.boundingSphere.center.set(0, 0, 0);
2784
+ return
2785
+ }
2786
+ utils.computeSphere(positions, this.boundingSphere);
2787
+ if (isNaN(this.boundingSphere.radius)) {
2788
+ console.error('THREE.BufferGeometry.computeBoundingSphere(): ' +
2789
+ 'Computed radius is NaN. The ' +
2790
+ '"position" attribute is likely to have NaN values.');
2791
+ }
2792
+ };
2793
+
2794
+ TextGeometry.prototype.computeBoundingBox = function () {
2795
+ if (this.boundingBox === null) {
2796
+ this.boundingBox = new THREE.Box3();
2797
+ }
2798
+
2799
+ var bbox = this.boundingBox;
2800
+ var positions = this.attributes.position.array;
2801
+ var itemSize = this.attributes.position.itemSize;
2802
+ if (!positions || !itemSize || positions.length < 2) {
2803
+ bbox.makeEmpty();
2804
+ return
2805
+ }
2806
+ utils.computeBox(positions, bbox);
2807
+ };
2808
+
2809
+ const createGeometry = /*@__PURE__*/index.getDefaultExportFromCjs(threeBmfontText);
2810
+
2811
+ var assign = requireObjectAssign();
2812
+
2813
+ var msdf = function createMSDFShader (opt) {
2814
+ opt = opt || {};
2815
+ var opacity = typeof opt.opacity === 'number' ? opt.opacity : 1;
2816
+ var alphaTest = typeof opt.alphaTest === 'number' ? opt.alphaTest : 0.0001;
2817
+ var precision = opt.precision || 'highp';
2818
+ var color = opt.color;
2819
+ var map = opt.map;
2820
+ var negate = typeof opt.negate === 'boolean' ? opt.negate : true;
2821
+
2822
+ // remove to satisfy r73
2823
+ delete opt.map;
2824
+ delete opt.color;
2825
+ delete opt.precision;
2826
+ delete opt.opacity;
2827
+ delete opt.negate;
2828
+
2829
+ return assign({
2830
+ uniforms: {
2831
+ opacity: { type: 'f', value: opacity },
2832
+ map: { type: 't', value: map || new THREE.Texture() },
2833
+ color: { type: 'c', value: new THREE.Color(color) }
2834
+ },
2835
+ vertexShader: [
2836
+ 'attribute vec2 uv;',
2837
+ 'attribute vec4 position;',
2838
+ 'uniform mat4 projectionMatrix;',
2839
+ 'uniform mat4 modelViewMatrix;',
2840
+ 'varying vec2 vUv;',
2841
+ 'void main() {',
2842
+ 'vUv = uv;',
2843
+ 'gl_Position = projectionMatrix * modelViewMatrix * position;',
2844
+ '}'
2845
+ ].join('\n'),
2846
+ fragmentShader: [
2847
+ '#ifdef GL_OES_standard_derivatives',
2848
+ '#extension GL_OES_standard_derivatives : enable',
2849
+ '#endif',
2850
+ 'precision ' + precision + ' float;',
2851
+ 'uniform float opacity;',
2852
+ 'uniform vec3 color;',
2853
+ 'uniform sampler2D map;',
2854
+ 'varying vec2 vUv;',
2855
+
2856
+ 'float median(float r, float g, float b) {',
2857
+ ' return max(min(r, g), min(max(r, g), b));',
2858
+ '}',
2859
+
2860
+ 'void main() {',
2861
+ ' vec3 sample = ' + (negate ? '1.0 - ' : '') + 'texture2D(map, vUv).rgb;',
2862
+ ' float sigDist = median(sample.r, sample.g, sample.b) - 0.5;',
2863
+ ' float alpha = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);',
2864
+ ' gl_FragColor = vec4(color.xyz, alpha * opacity);',
2865
+ alphaTest === 0
2866
+ ? ''
2867
+ : ' if (gl_FragColor.a < ' + alphaTest + ') discard;',
2868
+ '}'
2869
+ ].join('\n')
2870
+ }, opt);
2871
+ };
2872
+
2873
+ const MSDFShader = /*@__PURE__*/index.getDefaultExportFromCjs(msdf);
2874
+
2875
+ const vertexShader = `
2876
+ varying vec2 vUv;
2877
+ varying vec3 vPos;
2878
+
2879
+ void main() {
2880
+ vUv = uv;
2881
+ vPos = position;
2882
+
2883
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.);
2884
+ }
2885
+ `;
2886
+ const fragmentShader = `
2887
+ varying vec2 vUv;
2888
+ varying vec3 vPos;
2889
+
2890
+ uniform sampler2D uTexture;
2891
+ uniform float uTime;
2892
+
2893
+ void main() {
2894
+ float time = uTime * 0.5;
2895
+ vec2 repeat = -vec2(12., 3.);
2896
+ // To repeat the uvs we need to multiply them by a scalar
2897
+ // and then get the fractional part of it so they from 0 to 1
2898
+ // To move them continuously we have to add time
2899
+ // to the x or y component, to change the direction
2900
+ vec2 uv = fract(vUv * repeat - vec2(time, 0.)); // The sign of time change direction of movement
2901
+
2902
+ // Fake shadow
2903
+ float shadow = clamp(vPos.z / 5., 0., 1.);
2904
+
2905
+ vec3 texture = texture2D(uTexture, uv).rgb;
2906
+ // texture *= vec3(uv.x, uv.y, 1.); // To help visualize the repeated uvs
2907
+
2908
+ gl_FragColor = vec4(texture * shadow, 1.);
2909
+ }
2910
+ `;
2911
+
2912
+ class GL {
2913
+ renderer;
2914
+ camera;
2915
+ scene;
2916
+ controls;
2917
+ clock;
2918
+ rt;
2919
+ rtCamera;
2920
+ rtScene;
2921
+ text;
2922
+ mesh;
2923
+ geometry;
2924
+ material;
2925
+ fontGeometry;
2926
+ fontMaterial;
2927
+ loader;
2928
+ constructor() {
2929
+ this.renderer = new index.WebGLRenderer({
2930
+ alpha: true
2931
+ });
2932
+ this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5));
2933
+ this.renderer.setSize(window.innerWidth, window.innerHeight);
2934
+ this.renderer.setClearColor(0, 1);
2935
+ document.body.appendChild(this.renderer.domElement);
2936
+ this.camera = new index.PerspectiveCamera(
2937
+ 45,
2938
+ window.innerWidth / window.innerHeight,
2939
+ 1,
2940
+ 1e3
2941
+ );
2942
+ this.camera.position.z = 60;
2943
+ this.scene = new index.Scene();
2944
+ this.controls = new (OrbitControls(index.THREE))(
2945
+ this.camera,
2946
+ this.renderer.domElement
2947
+ );
2948
+ this.clock = new index.Clock();
2949
+ }
2950
+ init() {
2951
+ loadFont("/fonts/orbitron/orbitron-black.fnt", (_, font) => {
2952
+ this.fontGeometry = createGeometry({
2953
+ font,
2954
+ text: "ENDLESS"
2955
+ });
2956
+ this.loader = new index.TextureLoader();
2957
+ this.loader.load("/fonts/orbitron/orbitron-black.png", (texture) => {
2958
+ this.fontMaterial = new index.RawShaderMaterial(
2959
+ MSDFShader({
2960
+ map: texture,
2961
+ side: index.DoubleSide,
2962
+ transparent: true,
2963
+ negate: false,
2964
+ color: 16777215
2965
+ })
2966
+ );
2967
+ this.createRenderTarget();
2968
+ this.createMesh();
2969
+ this.animate();
2970
+ this.addEvents();
2971
+ });
2972
+ });
2973
+ }
2974
+ createRenderTarget() {
2975
+ this.rt = new index.WebGLRenderTarget(window.innerWidth, window.innerHeight);
2976
+ this.rtCamera = new index.PerspectiveCamera(45, 1, 0.1, 1e3);
2977
+ this.rtCamera.position.z = 2.5;
2978
+ this.rtScene = new index.Scene();
2979
+ this.rtScene.background = new index.Color("#000000");
2980
+ this.text = new index.Mesh(this.fontGeometry, this.fontMaterial);
2981
+ this.text.position.set(-0.965, -0.525, 0);
2982
+ this.text.rotation.set(Math.PI, 0, 0);
2983
+ this.text.scale.set(8e-3, 0.04, 1);
2984
+ this.rtScene.add(this.text);
2985
+ }
2986
+ createMesh() {
2987
+ if (!this.rt) return;
2988
+ this.geometry = new index.TorusKnotGeometry(9, 3, 768, 3, 4, 3);
2989
+ this.material = new index.ShaderMaterial({
2990
+ vertexShader,
2991
+ fragmentShader,
2992
+ uniforms: {
2993
+ uTime: { value: 0 },
2994
+ uTexture: { value: this.rt.texture }
2995
+ }
2996
+ });
2997
+ this.mesh = new index.Mesh(this.geometry, this.material);
2998
+ this.scene.add(this.mesh);
2999
+ }
3000
+ animate() {
3001
+ requestAnimationFrame(this.animate.bind(this));
3002
+ this.render();
3003
+ }
3004
+ render() {
3005
+ if (!this.material || !this.rt || !this.rtScene || !this.rtCamera) return;
3006
+ this.controls.update();
3007
+ this.material.uniforms.uTime.value = this.clock.getElapsedTime();
3008
+ this.renderer.setRenderTarget(this.rt);
3009
+ this.renderer.render(this.rtScene, this.rtCamera);
3010
+ this.renderer.setRenderTarget(null);
3011
+ this.renderer.render(this.scene, this.camera);
3012
+ }
3013
+ addEvents() {
3014
+ window.addEventListener("resize", this.resize.bind(this));
3015
+ }
3016
+ resize() {
3017
+ const width = window.innerWidth;
3018
+ const height = window.innerHeight;
3019
+ this.camera.aspect = width / height;
3020
+ this.camera.updateProjectionMatrix();
3021
+ this.renderer.setSize(width, height);
3022
+ }
3023
+ }
3024
+
3025
+ exports.GL = GL;