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