ginipick commited on
Commit
fdc6c9c
·
verified ·
1 Parent(s): 7b29a2f

Upload 6 files

Browse files
Files changed (6) hide show
  1. libs/iscroll.js +2607 -0
  2. libs/mark.js +1464 -0
  3. libs/mod3d.js +2520 -0
  4. libs/pdf.js +0 -0
  5. libs/pdf.worker.js +0 -0
  6. libs/three.js +0 -0
libs/iscroll.js ADDED
@@ -0,0 +1,2607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Real3D FlipBook [https://real3dflipbook.com]
3
+ * @author creativeinteractivemedia [https://codecanyon.net/user/creativeinteractivemedia/portfolio]
4
+ * @version 4.10
5
+ * @date 2025-05-15
6
+ */
7
+ /*! iScroll v5.2.0-snapshot ~ (c) 2008-2017 Matteo Spinelli ~ http://cubiq.org/license */
8
+ (function (window, document, Math) {
9
+ var rAF =
10
+ window.requestAnimationFrame ||
11
+ window.webkitRequestAnimationFrame ||
12
+ window.mozRequestAnimationFrame ||
13
+ window.oRequestAnimationFrame ||
14
+ window.msRequestAnimationFrame ||
15
+ function (callback) {
16
+ window.setTimeout(callback, 1000 / 60);
17
+ };
18
+
19
+ var utils = (function () {
20
+ var me = {};
21
+
22
+ var _elementStyle = document.createElement('div').style;
23
+ var _vendor = (function () {
24
+ var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'];
25
+ var transform;
26
+ var i = 0;
27
+ var l = vendors.length;
28
+
29
+ for (; i < l; i++) {
30
+ transform = vendors[i] + 'ransform';
31
+ if (transform in _elementStyle) {
32
+ return vendors[i].substr(0, vendors[i].length - 1);
33
+ }
34
+ }
35
+
36
+ return false;
37
+ })();
38
+
39
+ function _prefixStyle(style) {
40
+ if (_vendor === false) {
41
+ return false;
42
+ }
43
+ if (_vendor === '') {
44
+ return style;
45
+ }
46
+ return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
47
+ }
48
+
49
+ me.getTime =
50
+ Date.now ||
51
+ function getTime() {
52
+ return new Date().getTime();
53
+ };
54
+
55
+ me.extend = function (target, obj) {
56
+ for (var i in obj) {
57
+ target[i] = obj[i];
58
+ }
59
+ };
60
+
61
+ me.addEvent = function (el, type, fn, capture) {
62
+ el.addEventListener(type, fn, !!capture);
63
+ };
64
+
65
+ me.removeEvent = function (el, type, fn, capture) {
66
+ el.removeEventListener(type, fn, !!capture);
67
+ };
68
+
69
+ me.prefixPointerEvent = function (pointerEvent) {
70
+ return window.MSPointerEvent
71
+ ? 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8)
72
+ : pointerEvent;
73
+ };
74
+
75
+ me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
76
+ var distance = current - start;
77
+ var speed = Math.abs(distance) / time;
78
+ var destination;
79
+ var duration;
80
+
81
+ deceleration = deceleration === undefined ? 0.0006 : deceleration;
82
+
83
+ destination = current + ((speed * speed) / (2 * deceleration)) * (distance < 0 ? -1 : 1);
84
+ duration = speed / deceleration;
85
+
86
+ if (destination < lowerMargin) {
87
+ destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5) * (speed / 8) : lowerMargin;
88
+ distance = Math.abs(destination - current);
89
+ duration = distance / speed;
90
+ } else if (destination > 0) {
91
+ destination = wrapperSize ? (wrapperSize / 2.5) * (speed / 8) : 0;
92
+ distance = Math.abs(current) + destination;
93
+ duration = distance / speed;
94
+ }
95
+
96
+ return {
97
+ destination: Math.round(destination),
98
+ duration: duration,
99
+ };
100
+ };
101
+
102
+ var _transform = _prefixStyle('transform');
103
+
104
+ me.extend(me, {
105
+ hasTransform: _transform !== false,
106
+ hasPerspective: _prefixStyle('perspective') in _elementStyle,
107
+ hasTouch: 'ontouchstart' in window,
108
+ hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
109
+ hasTransition: _prefixStyle('transition') in _elementStyle,
110
+ });
111
+
112
+ /*
113
+ This should find all Android browsers lower than build 535.19 (both stock browser and webview)
114
+ - galaxy S2 is ok
115
+ - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
116
+ - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
117
+ - galaxy S3 is badAndroid (stock brower, webview)
118
+ `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
119
+ - galaxy S4 is badAndroid (stock brower, webview)
120
+ `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
121
+ - galaxy S5 is OK
122
+ `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
123
+ - galaxy S6 is OK
124
+ `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
125
+ */
126
+ me.isBadAndroid = (function () {
127
+ var appVersion = window.navigator.appVersion;
128
+ // Android browser is not a chrome browser.
129
+ if (/Android/.test(appVersion) && !/Chrome\/\d/.test(appVersion)) {
130
+ var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
131
+ if (safariVersion && typeof safariVersion === 'object' && safariVersion.length >= 2) {
132
+ return parseFloat(safariVersion[1]) < 535.19;
133
+ } else {
134
+ return true;
135
+ }
136
+ } else {
137
+ return false;
138
+ }
139
+ })();
140
+
141
+ me.extend((me.style = {}), {
142
+ transform: _transform,
143
+ transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
144
+ transitionDuration: _prefixStyle('transitionDuration'),
145
+ transitionDelay: _prefixStyle('transitionDelay'),
146
+ transformOrigin: _prefixStyle('transformOrigin'),
147
+ touchAction: _prefixStyle('touchAction'),
148
+ });
149
+
150
+ me.hasClass = function (e, c) {
151
+ var re = new RegExp('(^|\\s)' + c + '(\\s|$)');
152
+ return re.test(e.className);
153
+ };
154
+
155
+ me.addClass = function (e, c) {
156
+ if (me.hasClass(e, c)) {
157
+ return;
158
+ }
159
+
160
+ var newclass = e.className.split(' ');
161
+ newclass.push(c);
162
+ e.className = newclass.join(' ');
163
+ };
164
+
165
+ me.removeClass = function (e, c) {
166
+ if (!me.hasClass(e, c)) {
167
+ return;
168
+ }
169
+
170
+ var re = new RegExp('(^|\\s)' + c + '(\\s|$)', 'g');
171
+ e.className = e.className.replace(re, ' ');
172
+ };
173
+
174
+ me.offset = function (el) {
175
+ var left = -el.offsetLeft;
176
+ var top = -el.offsetTop;
177
+
178
+ // jshint -W084
179
+ while ((el = el.offsetParent)) {
180
+ left -= el.offsetLeft;
181
+ top -= el.offsetTop;
182
+ }
183
+ // jshint +W084
184
+
185
+ /*custom*/
186
+ return { left: 0, top: 0 };
187
+ /*end*/
188
+
189
+ return {
190
+ left: left,
191
+ top: top,
192
+ };
193
+ };
194
+
195
+ me.preventDefaultException = function (el, exceptions) {
196
+ for (var i in exceptions) {
197
+ if (exceptions[i].test(el[i])) {
198
+ return true;
199
+ }
200
+ }
201
+
202
+ return false;
203
+ };
204
+
205
+ me.extend((me.eventType = {}), {
206
+ touchstart: 1,
207
+ touchmove: 1,
208
+ touchend: 1,
209
+
210
+ mousedown: 2,
211
+ mousemove: 2,
212
+ mouseup: 2,
213
+
214
+ pointerdown: 3,
215
+ pointermove: 3,
216
+ pointerup: 3,
217
+
218
+ MSPointerDown: 3,
219
+ MSPointerMove: 3,
220
+ MSPointerUp: 3,
221
+ });
222
+
223
+ me.extend((me.ease = {}), {
224
+ quadratic: {
225
+ style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
226
+ fn: function (k) {
227
+ return k * (2 - k);
228
+ },
229
+ },
230
+ circular: {
231
+ style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
232
+ fn: function (k) {
233
+ return Math.sqrt(1 - --k * k);
234
+ },
235
+ },
236
+ back: {
237
+ style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
238
+ fn: function (k) {
239
+ var b = 4;
240
+ return (k = k - 1) * k * ((b + 1) * k + b) + 1;
241
+ },
242
+ },
243
+ bounce: {
244
+ style: '',
245
+ fn: function (k) {
246
+ if ((k /= 1) < 1 / 2.75) {
247
+ return 7.5625 * k * k;
248
+ } else if (k < 2 / 2.75) {
249
+ return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
250
+ } else if (k < 2.5 / 2.75) {
251
+ return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
252
+ } else {
253
+ return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
254
+ }
255
+ },
256
+ },
257
+ elastic: {
258
+ style: '',
259
+ fn: function (k) {
260
+ var f = 0.22;
261
+ var e = 0.4;
262
+
263
+ if (k === 0) {
264
+ return 0;
265
+ }
266
+ if (k == 1) {
267
+ return 1;
268
+ }
269
+
270
+ return e * Math.pow(2, -10 * k) * Math.sin(((k - f / 4) * (2 * Math.PI)) / f) + 1;
271
+ },
272
+ },
273
+ });
274
+
275
+ me.tap = function (e, eventName) {
276
+ var ev = document.createEvent('Event');
277
+ ev.initEvent(eventName, true, true);
278
+ ev.pageX = e.pageX;
279
+ ev.pageY = e.pageY;
280
+ e.target.dispatchEvent(ev);
281
+ };
282
+
283
+ me.click = function (e) {
284
+ var target = e.target;
285
+ var ev;
286
+
287
+ if (!/(SELECT|INPUT|TEXTAREA)/i.test(target.tagName)) {
288
+ // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
289
+ // initMouseEvent is deprecated.
290
+ ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
291
+ ev.initEvent('click', true, true);
292
+ ev.view = e.view || window;
293
+ ev.detail = 1;
294
+ ev.screenX = target.screenX || 0;
295
+ ev.screenY = target.screenY || 0;
296
+ ev.clientX = target.clientX || 0;
297
+ ev.clientY = target.clientY || 0;
298
+ ev.ctrlKey = !!e.ctrlKey;
299
+ ev.altKey = !!e.altKey;
300
+ ev.shiftKey = !!e.shiftKey;
301
+ ev.metaKey = !!e.metaKey;
302
+ ev.button = 0;
303
+ ev.relatedTarget = null;
304
+ ev._constructed = true;
305
+ target.dispatchEvent(ev);
306
+ }
307
+ };
308
+
309
+ me.getTouchAction = function (eventPassthrough, addPinch) {
310
+ var touchAction = 'none';
311
+ if (eventPassthrough === 'vertical') {
312
+ touchAction = 'pan-y';
313
+ } else if (eventPassthrough === 'horizontal') {
314
+ touchAction = 'pan-x';
315
+ }
316
+ if (addPinch && touchAction != 'none') {
317
+ // add pinch-zoom support if the browser supports it, but if not (eg. Chrome <55) do nothing
318
+ touchAction += ' pinch-zoom';
319
+ }
320
+ return touchAction;
321
+ };
322
+
323
+ me.getRect = function (el) {
324
+ if (el instanceof SVGElement) {
325
+ var rect = el.getBoundingClientRect();
326
+ return {
327
+ top: rect.top,
328
+ left: rect.left,
329
+ width: rect.width,
330
+ height: rect.height,
331
+ };
332
+ } else {
333
+ return {
334
+ top: el.offsetTop,
335
+ left: el.offsetLeft,
336
+ width: el.offsetWidth,
337
+ height: el.offsetHeight,
338
+ };
339
+ }
340
+ };
341
+
342
+ return me;
343
+ })();
344
+ function IScroll(el, options) {
345
+ this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
346
+ this.scroller = this.wrapper.children[0];
347
+ this.scrollerStyle = this.scroller.style; // cache style for better performance
348
+
349
+ this.options = {
350
+ zoomMin: 1,
351
+ zoomMax: 4,
352
+ startZoom: 1,
353
+
354
+ resizeScrollbars: true,
355
+
356
+ mouseWheelSpeed: 20,
357
+ mouseWheelTimeout: 400,
358
+
359
+ snapThreshold: 0.334,
360
+
361
+ // INSERT POINT: OPTIONS
362
+ disablePointer: !utils.hasPointer,
363
+ disableTouch: utils.hasPointer || !utils.hasTouch,
364
+ disableMouse: utils.hasPointer || utils.hasTouch,
365
+ startX: 0,
366
+ startY: 0,
367
+ scrollY: true,
368
+ directionLockThreshold: 5,
369
+ momentum: true,
370
+
371
+ bounce: true,
372
+ bounceTime: 600,
373
+ bounceEasing: '',
374
+
375
+ preventDefault: true,
376
+ preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ },
377
+
378
+ HWCompositing: true,
379
+ useTransition: true,
380
+ useTransform: true,
381
+ bindToWrapper: typeof window.onmousedown === 'undefined',
382
+ };
383
+
384
+ for (var i in options) {
385
+ this.options[i] = options[i];
386
+ }
387
+
388
+ // Normalize options
389
+ this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
390
+
391
+ this.options.useTransition = utils.hasTransition && this.options.useTransition;
392
+ this.options.useTransform = utils.hasTransform && this.options.useTransform;
393
+
394
+ this.options.eventPassthrough =
395
+ this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
396
+ this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
397
+
398
+ // If you want eventPassthrough I have to lock one of the axes
399
+ this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
400
+ this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
401
+
402
+ // With eventPassthrough we also need lockDirection mechanism
403
+ this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
404
+ this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
405
+
406
+ this.options.bounceEasing =
407
+ typeof this.options.bounceEasing == 'string'
408
+ ? utils.ease[this.options.bounceEasing] || utils.ease.circular
409
+ : this.options.bounceEasing;
410
+
411
+ this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
412
+
413
+ if (this.options.tap === true) {
414
+ this.options.tap = 'tap';
415
+ }
416
+
417
+ // https://github.com/cubiq/iscroll/issues/1029
418
+ if (!this.options.useTransition && !this.options.useTransform) {
419
+ if (!/relative|absolute/i.test(this.scrollerStyle.position)) {
420
+ this.scrollerStyle.position = 'relative';
421
+ }
422
+ }
423
+
424
+ if (this.options.shrinkScrollbars == 'scale') {
425
+ this.options.useTransition = false;
426
+ }
427
+
428
+ this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
429
+
430
+ // INSERT POINT: NORMALIZATION
431
+
432
+ // Some defaults
433
+ this.x = 0;
434
+ this.y = 0;
435
+ this.directionX = 0;
436
+ this.directionY = 0;
437
+ this._events = {};
438
+
439
+ this.scale = Math.min(Math.max(this.options.startZoom, this.options.zoomMin), this.options.zoomMax);
440
+
441
+ // INSERT POINT: DEFAULTS
442
+
443
+ this._init();
444
+ this.refresh();
445
+
446
+ this.scrollTo(this.options.startX, this.options.startY);
447
+ this.enable();
448
+ }
449
+
450
+ IScroll.prototype = {
451
+ version: '5.2.0-snapshot',
452
+
453
+ _init: function () {
454
+ this._initEvents();
455
+
456
+ if (this.options.zoom) {
457
+ this._initZoom();
458
+ }
459
+
460
+ if (this.options.scrollbars || this.options.indicators) {
461
+ this._initIndicators();
462
+ }
463
+
464
+ if (this.options.mouseWheel) {
465
+ this._initWheel();
466
+ }
467
+
468
+ if (this.options.snap) {
469
+ this._initSnap();
470
+ }
471
+
472
+ if (this.options.keyBindings) {
473
+ this._initKeys();
474
+ }
475
+
476
+ // INSERT POINT: _init
477
+ },
478
+
479
+ destroy: function () {
480
+ this._initEvents(true);
481
+ clearTimeout(this.resizeTimeout);
482
+ this.resizeTimeout = null;
483
+ this._execEvent('destroy');
484
+ },
485
+
486
+ _transitionEnd: function (e) {
487
+ if (e.target != this.scroller || !this.isInTransition) {
488
+ return;
489
+ }
490
+
491
+ this._transitionTime();
492
+ if (!this.resetPosition(this.options.bounceTime)) {
493
+ this.isInTransition = false;
494
+ this._execEvent('scrollEnd');
495
+ }
496
+ },
497
+
498
+ _start: function (e) {
499
+ //ignore secondary touch
500
+ if (e.type == 'pointerdown' && !e.isPrimary) {
501
+ return;
502
+ }
503
+ // React to left mouse button only
504
+ if (utils.eventType[e.type] != 1) {
505
+ // for button property
506
+ // http://unixpapa.com/js/mouse.html
507
+ var button;
508
+ if (!e.which) {
509
+ /* IE case */
510
+ button = e.button < 2 ? 0 : e.button == 4 ? 1 : 2;
511
+ } else {
512
+ /* All others */
513
+ button = e.button;
514
+ }
515
+ if (button !== 0) {
516
+ return;
517
+ }
518
+ }
519
+
520
+ if (!this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated)) {
521
+ return;
522
+ }
523
+
524
+ if (
525
+ this.options.preventDefault &&
526
+ !utils.isBadAndroid &&
527
+ !utils.preventDefaultException(e.target, this.options.preventDefaultException)
528
+ ) {
529
+ e.preventDefault();
530
+ }
531
+
532
+ var point = e.touches ? e.touches[0] : e;
533
+ var pos;
534
+
535
+ this.initiated = utils.eventType[e.type];
536
+ this.moved = false;
537
+ this.distX = 0;
538
+ this.distY = 0;
539
+ this.directionX = 0;
540
+ this.directionY = 0;
541
+ this.directionLocked = 0;
542
+
543
+ this.startTime = utils.getTime();
544
+
545
+ if (this.options.useTransition && this.isInTransition) {
546
+ this._transitionTime();
547
+ this.isInTransition = false;
548
+ pos = this.getComputedPosition();
549
+ this._translate(Math.round(pos.x), Math.round(pos.y));
550
+ this._execEvent('scrollEnd');
551
+ } else if (!this.options.useTransition && this.isAnimating) {
552
+ this.isAnimating = false;
553
+ this._execEvent('scrollEnd');
554
+ }
555
+
556
+ this.startX = this.x;
557
+ this.startY = this.y;
558
+ this.absStartX = this.x;
559
+ this.absStartY = this.y;
560
+ this.pointX = point.pageX;
561
+ this.pointY = point.pageY;
562
+
563
+ this._execEvent('beforeScrollStart');
564
+ },
565
+
566
+ _move: function (e) {
567
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
568
+ return;
569
+ }
570
+
571
+ //ignore secondary touch
572
+ if (e.type == 'pointermove' && !e.isPrimary) {
573
+ return;
574
+ }
575
+
576
+ if (this.options.preventDefault) {
577
+ // increases performance on Android? TODO: check!
578
+ e.preventDefault();
579
+ }
580
+
581
+ var point = e.touches ? e.touches[0] : e;
582
+ var deltaX = point.pageX - this.pointX;
583
+ var deltaY = point.pageY - this.pointY;
584
+ var timestamp = utils.getTime();
585
+ var newX;
586
+ var newY;
587
+ var absDistX;
588
+ var absDistY;
589
+
590
+ this.pointX = point.pageX;
591
+ this.pointY = point.pageY;
592
+
593
+ this.distX += deltaX;
594
+ this.distY += deltaY;
595
+ absDistX = Math.abs(this.distX);
596
+ absDistY = Math.abs(this.distY);
597
+
598
+ // We need to move at least 10 pixels for the scrolling to initiate
599
+ if (timestamp - this.endTime > 300 && absDistX < 10 && absDistY < 10) {
600
+ return;
601
+ }
602
+
603
+ // If you are scrolling in one direction lock the other
604
+ if (!this.directionLocked && !this.options.freeScroll) {
605
+ if (absDistX > absDistY + this.options.directionLockThreshold) {
606
+ this.directionLocked = 'h'; // lock horizontally
607
+ } else if (absDistY >= absDistX + this.options.directionLockThreshold) {
608
+ this.directionLocked = 'v'; // lock vertically
609
+ } else {
610
+ this.directionLocked = 'n'; // no lock
611
+ }
612
+ }
613
+
614
+ if (this.directionLocked == 'h') {
615
+ if (this.options.eventPassthrough == 'vertical') {
616
+ e.preventDefault();
617
+ } else if (this.options.eventPassthrough == 'horizontal') {
618
+ this.initiated = false;
619
+ return;
620
+ }
621
+
622
+ deltaY = 0;
623
+ } else if (this.directionLocked == 'v') {
624
+ if (this.options.eventPassthrough == 'horizontal') {
625
+ e.preventDefault();
626
+ } else if (this.options.eventPassthrough == 'vertical') {
627
+ this.initiated = false;
628
+ return;
629
+ }
630
+
631
+ deltaX = 0;
632
+ }
633
+
634
+ deltaX = this.hasHorizontalScroll ? deltaX : 0;
635
+ deltaY = this.hasVerticalScroll ? deltaY : 0;
636
+
637
+ newX = this.x + deltaX;
638
+ newY = this.y + deltaY;
639
+
640
+ // Slow down if outside of the boundaries
641
+ if (newX > 0 || newX < this.maxScrollX) {
642
+ newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
643
+ }
644
+ if (newY > 0 || newY < this.maxScrollY) {
645
+ newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
646
+ }
647
+
648
+ this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
649
+ this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
650
+
651
+ if (!this.moved) {
652
+ this._execEvent('scrollStart');
653
+ }
654
+
655
+ this.moved = true;
656
+
657
+ this._translate(newX, newY);
658
+
659
+ /* REPLACE START: _move */
660
+
661
+ if (timestamp - this.startTime > 300) {
662
+ this.startTime = timestamp;
663
+ this.startX = this.x;
664
+ this.startY = this.y;
665
+ }
666
+
667
+ /* REPLACE END: _move */
668
+ },
669
+
670
+ _end: function (e) {
671
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
672
+ return;
673
+ }
674
+
675
+ //ignore secondary touch
676
+ if (e.type == 'pointerup' && !e.isPrimary) {
677
+ return;
678
+ }
679
+
680
+ if (
681
+ this.options.preventDefault &&
682
+ !utils.preventDefaultException(e.target, this.options.preventDefaultException)
683
+ ) {
684
+ e.preventDefault();
685
+ }
686
+
687
+ var point = e.changedTouches ? e.changedTouches[0] : e;
688
+ var momentumX;
689
+ var momentumY;
690
+ var duration = utils.getTime() - this.startTime;
691
+ var newX = Math.round(this.x);
692
+ var newY = Math.round(this.y);
693
+ var distanceX = Math.abs(newX - this.startX);
694
+ var distanceY = Math.abs(newY - this.startY);
695
+ var time = 0;
696
+ var easing = '';
697
+
698
+ this.isInTransition = 0;
699
+ this.initiated = 0;
700
+ this.endTime = utils.getTime();
701
+
702
+ // reset if we are outside of the boundaries
703
+ if (this.resetPosition(this.options.bounceTime)) {
704
+ return;
705
+ }
706
+
707
+ this.scrollTo(newX, newY); // ensures that the last position is rounded
708
+
709
+ // we scrolled less than 10 pixels
710
+ if (!this.moved) {
711
+ if (this.options.tap) {
712
+ utils.tap(e, this.options.tap);
713
+ }
714
+
715
+ if (this.options.click) {
716
+ utils.click(e);
717
+ }
718
+
719
+ this._execEvent('scrollCancel');
720
+ return;
721
+ }
722
+
723
+ if (this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100) {
724
+ this._execEvent('flick');
725
+ return;
726
+ }
727
+
728
+ // start momentum animation if needed
729
+ if (this.options.momentum && duration < 300) {
730
+ momentumX = this.hasHorizontalScroll
731
+ ? utils.momentum(
732
+ this.x,
733
+ this.startX,
734
+ duration,
735
+ this.maxScrollX,
736
+ this.options.bounce ? this.wrapperWidth : 0,
737
+ this.options.deceleration
738
+ )
739
+ : { destination: newX, duration: 0 };
740
+ momentumY = this.hasVerticalScroll
741
+ ? utils.momentum(
742
+ this.y,
743
+ this.startY,
744
+ duration,
745
+ this.maxScrollY,
746
+ this.options.bounce ? this.wrapperHeight : 0,
747
+ this.options.deceleration
748
+ )
749
+ : { destination: newY, duration: 0 };
750
+ newX = momentumX.destination;
751
+ newY = momentumY.destination;
752
+ time = Math.max(momentumX.duration, momentumY.duration);
753
+ this.isInTransition = 1;
754
+ }
755
+
756
+ if (this.options.snap) {
757
+ var snap = this._nearestSnap(newX, newY);
758
+ this.currentPage = snap;
759
+ time =
760
+ this.options.snapSpeed ||
761
+ Math.max(
762
+ Math.max(Math.min(Math.abs(newX - snap.x), 1000), Math.min(Math.abs(newY - snap.y), 1000)),
763
+ 300
764
+ );
765
+ newX = snap.x;
766
+ newY = snap.y;
767
+
768
+ this.directionX = 0;
769
+ this.directionY = 0;
770
+ easing = this.options.bounceEasing;
771
+ }
772
+
773
+ // INSERT POINT: _end
774
+
775
+ if (newX != this.x || newY != this.y) {
776
+ // change easing function when scroller goes out of the boundaries
777
+ if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) {
778
+ easing = utils.ease.quadratic;
779
+ }
780
+
781
+ this.scrollTo(newX, newY, time, easing);
782
+
783
+ //custom
784
+ this._execEvent('scrollToPage');
785
+ return;
786
+ }
787
+
788
+ this._execEvent('scrollEnd');
789
+ },
790
+
791
+ _resize: function () {
792
+ var that = this;
793
+
794
+ clearTimeout(this.resizeTimeout);
795
+
796
+ this.resizeTimeout = setTimeout(function () {
797
+ that.refresh();
798
+ }, this.options.resizePolling);
799
+ },
800
+
801
+ resetPosition: function (time) {
802
+ var x = this.x;
803
+ var y = this.y;
804
+
805
+ time = time || 0;
806
+
807
+ if (!this.hasHorizontalScroll || this.x > 0) {
808
+ x = 0;
809
+ // custom start
810
+ if (this.options.keepInCenterH && this.getScrollerWidth() * this.scale < this.wrapperWidth) {
811
+ x = this.wrapperWidth / 2 - (this.getScrollerWidth() * this.scale) / 2;
812
+ }
813
+ // custom end
814
+ } else if (this.x < this.maxScrollX) {
815
+ x = this.maxScrollX;
816
+ }
817
+
818
+ if (!this.hasVerticalScroll || this.y > 0) {
819
+ y = 0;
820
+ // custom start
821
+ if (this.options.keepInCenterV && this.getScrollerHeight() * this.scale < this.wrapperHeight) {
822
+ y = this.wrapperHeight / 2 - (this.getScrollerHeight() * this.scale) / 2;
823
+ }
824
+ // custom end
825
+ } else if (this.y < this.maxScrollY) {
826
+ y = this.maxScrollY;
827
+ }
828
+
829
+ if (x == this.x && y == this.y) {
830
+ return false;
831
+ }
832
+
833
+ this.scrollTo(x, y, time, this.options.bounceEasing);
834
+
835
+ return true;
836
+ },
837
+
838
+ disable: function () {
839
+ this.enabled = false;
840
+ },
841
+
842
+ enable: function () {
843
+ this.enabled = true;
844
+ },
845
+
846
+ //custom
847
+
848
+ setScrollerSize: function (w, h) {
849
+ this.scrollerW = w;
850
+ this.scrollerH = h;
851
+ },
852
+
853
+ setWrapperOffset: function (left, top) {
854
+ this.wrapperOffsetLeft = left;
855
+ this.wrapperOffsetTop = top;
856
+ },
857
+
858
+ //custom end
859
+
860
+ refresh: function () {
861
+ utils.getRect(this.wrapper); // Force reflow
862
+
863
+ this.wrapperWidth = this.wrapper.clientWidth;
864
+ this.wrapperHeight = this.wrapper.clientHeight;
865
+
866
+ var rect = utils.getRect(this.scroller);
867
+ if (this.scrollerW) {
868
+ rect.width = this.scrollerW;
869
+ }
870
+ if (this.scrollerH) {
871
+ rect.height = this.scrollerH;
872
+ }
873
+ /* REPLACE START: refresh */
874
+ this.scrollerWidth = Math.round(rect.width * this.scale);
875
+ this.scrollerHeight = Math.round(rect.height * this.scale);
876
+
877
+ this.maxScrollX = this.wrapperWidth - this.scrollerWidth;
878
+ this.maxScrollY = this.wrapperHeight - this.scrollerHeight;
879
+ /* REPLACE END: refresh */
880
+
881
+ this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
882
+ this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
883
+
884
+ if (!this.hasHorizontalScroll) {
885
+ this.maxScrollX = 0;
886
+ this.scrollerWidth = this.wrapperWidth;
887
+ }
888
+
889
+ if (!this.hasVerticalScroll) {
890
+ this.maxScrollY = 0;
891
+ this.scrollerHeight = this.wrapperHeight;
892
+ }
893
+
894
+ this.endTime = 0;
895
+ this.directionX = 0;
896
+ this.directionY = 0;
897
+
898
+ if (utils.hasPointer && !this.options.disablePointer) {
899
+ // The wrapper should have `touchAction` property for using pointerEvent.
900
+ this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, true);
901
+
902
+ // case. not support 'pinch-zoom'
903
+ // https://github.com/cubiq/iscroll/issues/1118#issuecomment-270057583
904
+ if (!this.wrapper.style[utils.style.touchAction]) {
905
+ this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(
906
+ this.options.eventPassthrough,
907
+ false
908
+ );
909
+ }
910
+ }
911
+ this.wrapperOffset = utils.offset(this.wrapper);
912
+ if (this.wrapperOffsetLeft) {
913
+ this.wrapperOffset.left = this.wrapperOffsetLeft;
914
+ }
915
+ if (this.wrapperOffsetTop) {
916
+ this.wrapperOffset.top = this.wrapperOffsetTop;
917
+ }
918
+
919
+ this._execEvent('refresh');
920
+
921
+ this.resetPosition();
922
+
923
+ // INSERT POINT: _refresh
924
+ },
925
+
926
+ on: function (type, fn) {
927
+ if (!this._events[type]) {
928
+ this._events[type] = [];
929
+ }
930
+
931
+ this._events[type].push(fn);
932
+ },
933
+
934
+ off: function (type, fn) {
935
+ if (!this._events[type]) {
936
+ return;
937
+ }
938
+
939
+ var index = this._events[type].indexOf(fn);
940
+
941
+ if (index > -1) {
942
+ this._events[type].splice(index, 1);
943
+ }
944
+ },
945
+
946
+ _execEvent: function (type) {
947
+ if (!this._events[type]) {
948
+ return;
949
+ }
950
+
951
+ var i = 0;
952
+ var l = this._events[type].length;
953
+
954
+ if (!l) {
955
+ return;
956
+ }
957
+
958
+ for (; i < l; i++) {
959
+ this._events[type][i].apply(this, [].slice.call(arguments, 1));
960
+ }
961
+ },
962
+
963
+ scrollBy: function (x, y, time, easing) {
964
+ x = this.x + x;
965
+ y = this.y + y;
966
+ time = time || 0;
967
+
968
+ this.scrollTo(x, y, time, easing);
969
+ },
970
+
971
+ //custom
972
+
973
+ getScrollerWidth: function () {
974
+ return this.scrollerW !== undefined ? this.scrollerW : this.scroller.offsetWidth;
975
+ },
976
+
977
+ getScrollerHeight: function () {
978
+ return this.scrollerH !== undefined ? this.scrollerH : this.scroller.offsetHeight;
979
+ },
980
+
981
+ //end custom
982
+
983
+ scrollTo: function (x, y, time, easing) {
984
+ /*custom*/
985
+
986
+ if (this.wrapperWidth == 0 || this.wrapperHeight == 0) {
987
+ return;
988
+ }
989
+
990
+ if (time) {
991
+ if (this.prevDisabled && x == 0) {
992
+ this.goToPage(1, 0, 0);
993
+ return;
994
+ }
995
+
996
+ if (this.nextDisabled && x == -(this.scrollerWidth - this.wrapperWidth)) {
997
+ this.goToPage(1, 0, 0);
998
+ return;
999
+ }
1000
+ }
1001
+
1002
+ if (this.options.keepInCenterH && this.getScrollerWidth() * this.scale < this.wrapperWidth) {
1003
+ x = this.wrapperWidth / 2 - (this.getScrollerWidth() * this.scale) / 2;
1004
+ }
1005
+
1006
+ if (this.options.keepInCenterV && this.getScrollerHeight() * this.scale < this.wrapperHeight) {
1007
+ y = this.wrapperHeight / 2 - (this.getScrollerHeight() * this.scale) / 2;
1008
+ }
1009
+ /*end custom*/
1010
+
1011
+ easing = easing || utils.ease.circular;
1012
+
1013
+ this.isInTransition = this.options.useTransition && time > 0;
1014
+ var transitionType = this.options.useTransition && easing.style;
1015
+ if (!time || transitionType) {
1016
+ if (transitionType) {
1017
+ this._transitionTimingFunction(easing.style);
1018
+ this._transitionTime(time);
1019
+ }
1020
+ this._translate(x, y);
1021
+ } else {
1022
+ this._animate(x, y, time, easing.fn);
1023
+ }
1024
+ },
1025
+
1026
+ scrollToElement: function (el, time, offsetX, offsetY, easing) {
1027
+ el = el.nodeType ? el : this.scroller.querySelector(el);
1028
+
1029
+ if (!el) {
1030
+ return;
1031
+ }
1032
+
1033
+ var pos = utils.offset(el);
1034
+
1035
+ pos.left -= this.wrapperOffset.left;
1036
+ pos.top -= this.wrapperOffset.top;
1037
+
1038
+ // if offsetX/Y are true we center the element to the screen
1039
+ var elRect = utils.getRect(el);
1040
+ var wrapperRect = utils.getRect(this.wrapper);
1041
+ if (offsetX === true) {
1042
+ offsetX = Math.round(elRect.width / 2 - wrapperRect.width / 2);
1043
+ }
1044
+ if (offsetY === true) {
1045
+ offsetY = Math.round(elRect.height / 2 - wrapperRect.height / 2);
1046
+ }
1047
+
1048
+ pos.left -= offsetX || 0;
1049
+ pos.top -= offsetY || 0;
1050
+
1051
+ pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
1052
+ pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top;
1053
+
1054
+ time =
1055
+ time === undefined || time === null || time === 'auto'
1056
+ ? Math.max(Math.abs(this.x - pos.left), Math.abs(this.y - pos.top))
1057
+ : time;
1058
+
1059
+ this.scrollTo(pos.left, pos.top, time, easing);
1060
+ },
1061
+
1062
+ _transitionTime: function (time) {
1063
+ if (!this.options.useTransition) {
1064
+ return;
1065
+ }
1066
+ time = time || 0;
1067
+ var durationProp = utils.style.transitionDuration;
1068
+ if (!durationProp) {
1069
+ return;
1070
+ }
1071
+
1072
+ this.scrollerStyle[durationProp] = time + 'ms';
1073
+
1074
+ if (!time && utils.isBadAndroid) {
1075
+ this.scrollerStyle[durationProp] = '0.0001ms';
1076
+ // remove 0.0001ms
1077
+ var self = this;
1078
+ rAF(function () {
1079
+ if (self.scrollerStyle[durationProp] === '0.0001ms') {
1080
+ self.scrollerStyle[durationProp] = '0s';
1081
+ }
1082
+ });
1083
+ }
1084
+
1085
+ if (this.indicators) {
1086
+ for (var i = this.indicators.length; i--; ) {
1087
+ this.indicators[i].transitionTime(time);
1088
+ }
1089
+ }
1090
+
1091
+ // INSERT POINT: _transitionTime
1092
+ },
1093
+
1094
+ _transitionTimingFunction: function (easing) {
1095
+ this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
1096
+
1097
+ if (this.indicators) {
1098
+ for (var i = this.indicators.length; i--; ) {
1099
+ this.indicators[i].transitionTimingFunction(easing);
1100
+ }
1101
+ }
1102
+
1103
+ // INSERT POINT: _transitionTimingFunction
1104
+ },
1105
+
1106
+ _translate: function (x, y) {
1107
+ if (this.options.useTransform) {
1108
+ /* REPLACE START: _translate */ this.scrollerStyle[utils.style.transform] =
1109
+ 'translate(' +
1110
+ x +
1111
+ 'px,' +
1112
+ y +
1113
+ 'px) scale(' +
1114
+ this.scale +
1115
+ ') ' +
1116
+ this.translateZ; /* REPLACE END: _translate */
1117
+ } else {
1118
+ x = Math.round(x);
1119
+ y = Math.round(y);
1120
+ this.scrollerStyle.left = x + 'px';
1121
+ this.scrollerStyle.top = y + 'px';
1122
+ }
1123
+
1124
+ this.x = x;
1125
+ this.y = y;
1126
+
1127
+ if (this.indicators) {
1128
+ for (var i = this.indicators.length; i--; ) {
1129
+ this.indicators[i].updatePosition();
1130
+ }
1131
+ }
1132
+
1133
+ // INSERT POINT: _translate
1134
+ },
1135
+
1136
+ _initEvents: function (remove) {
1137
+ var eventType = remove ? utils.removeEvent : utils.addEvent;
1138
+ var target = this.options.bindToWrapper ? this.wrapper : window;
1139
+
1140
+ eventType(window, 'orientationchange', this);
1141
+ eventType(window, 'resize', this);
1142
+
1143
+ if (this.options.click) {
1144
+ eventType(this.wrapper, 'click', this, true);
1145
+ }
1146
+
1147
+ if (!this.options.disableMouse) {
1148
+ eventType(this.wrapper, 'mousedown', this);
1149
+ eventType(target, 'mousemove', this);
1150
+ eventType(target, 'mousecancel', this);
1151
+ eventType(target, 'mouseup', this);
1152
+ }
1153
+
1154
+ if (utils.hasPointer && !this.options.disablePointer) {
1155
+ eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
1156
+ eventType(target, utils.prefixPointerEvent('pointermove'), this);
1157
+ eventType(target, utils.prefixPointerEvent('pointercancel'), this);
1158
+ eventType(target, utils.prefixPointerEvent('pointerup'), this);
1159
+ }
1160
+
1161
+ if (utils.hasTouch && !this.options.disableTouch) {
1162
+ eventType(this.wrapper, 'touchstart', this);
1163
+ eventType(target, 'touchmove', this);
1164
+ eventType(target, 'touchcancel', this);
1165
+ eventType(target, 'touchend', this);
1166
+ }
1167
+
1168
+ eventType(this.scroller, 'transitionend', this);
1169
+ eventType(this.scroller, 'webkitTransitionEnd', this);
1170
+ eventType(this.scroller, 'oTransitionEnd', this);
1171
+ eventType(this.scroller, 'MSTransitionEnd', this);
1172
+ },
1173
+
1174
+ getComputedPosition: function () {
1175
+ var matrix = window.getComputedStyle(this.scroller, null);
1176
+ var x;
1177
+ var y;
1178
+
1179
+ if (this.options.useTransform) {
1180
+ matrix = matrix[utils.style.transform].split(')')[0].split(', ');
1181
+ x = +(matrix[12] || matrix[4]);
1182
+ y = +(matrix[13] || matrix[5]);
1183
+ } else {
1184
+ x = +matrix.left.replace(/[^-\d.]/g, '');
1185
+ y = +matrix.top.replace(/[^-\d.]/g, '');
1186
+ }
1187
+
1188
+ return { x: x, y: y };
1189
+ },
1190
+ _initIndicators: function () {
1191
+ var interactive = this.options.interactiveScrollbars;
1192
+ var customStyle = typeof this.options.scrollbars != 'string';
1193
+ var indicators = [];
1194
+ var indicator;
1195
+
1196
+ var that = this;
1197
+
1198
+ this.indicators = [];
1199
+
1200
+ if (this.options.scrollbars) {
1201
+ // Vertical scrollbar
1202
+ if (this.options.scrollY) {
1203
+ indicator = {
1204
+ el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
1205
+ interactive: interactive,
1206
+ defaultScrollbars: true,
1207
+ customStyle: customStyle,
1208
+ resize: this.options.resizeScrollbars,
1209
+ shrink: this.options.shrinkScrollbars,
1210
+ fade: this.options.fadeScrollbars,
1211
+ listenX: false,
1212
+ };
1213
+
1214
+ this.wrapper.appendChild(indicator.el);
1215
+ indicators.push(indicator);
1216
+ }
1217
+
1218
+ // Horizontal scrollbar
1219
+ if (this.options.scrollX) {
1220
+ indicator = {
1221
+ el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
1222
+ interactive: interactive,
1223
+ defaultScrollbars: true,
1224
+ customStyle: customStyle,
1225
+ resize: this.options.resizeScrollbars,
1226
+ shrink: this.options.shrinkScrollbars,
1227
+ fade: this.options.fadeScrollbars,
1228
+ listenY: false,
1229
+ };
1230
+
1231
+ this.wrapper.appendChild(indicator.el);
1232
+ indicators.push(indicator);
1233
+ }
1234
+ }
1235
+
1236
+ if (this.options.indicators) {
1237
+ // TODO: check concat compatibility
1238
+ indicators = indicators.concat(this.options.indicators);
1239
+ }
1240
+
1241
+ for (var i = indicators.length; i--; ) {
1242
+ this.indicators.push(new Indicator(this, indicators[i]));
1243
+ }
1244
+
1245
+ // TODO: check if we can use array.map (wide compatibility and performance issues)
1246
+ function _indicatorsMap(fn) {
1247
+ if (that.indicators) {
1248
+ for (var i = that.indicators.length; i--; ) {
1249
+ fn.call(that.indicators[i]);
1250
+ }
1251
+ }
1252
+ }
1253
+
1254
+ if (this.options.fadeScrollbars) {
1255
+ this.on('scrollEnd', function () {
1256
+ _indicatorsMap(function () {
1257
+ this.fade();
1258
+ });
1259
+ });
1260
+
1261
+ this.on('scrollCancel', function () {
1262
+ _indicatorsMap(function () {
1263
+ this.fade();
1264
+ });
1265
+ });
1266
+
1267
+ this.on('scrollStart', function () {
1268
+ _indicatorsMap(function () {
1269
+ this.fade(1);
1270
+ });
1271
+ });
1272
+
1273
+ this.on('beforeScrollStart', function () {
1274
+ _indicatorsMap(function () {
1275
+ this.fade(1, true);
1276
+ });
1277
+ });
1278
+ }
1279
+
1280
+ this.on('refresh', function () {
1281
+ _indicatorsMap(function () {
1282
+ this.refresh();
1283
+ });
1284
+ });
1285
+
1286
+ this.on('destroy', function () {
1287
+ _indicatorsMap(function () {
1288
+ this.destroy();
1289
+ });
1290
+
1291
+ delete this.indicators;
1292
+ });
1293
+ },
1294
+
1295
+ _initZoom: function () {
1296
+ this.scrollerStyle[utils.style.transformOrigin] = '0 0';
1297
+ },
1298
+
1299
+ _zoomStart: function (e) {
1300
+ var c1 = Math.abs(e.touches[0].pageX - e.touches[1].pageX);
1301
+ var c2 = Math.abs(e.touches[0].pageY - e.touches[1].pageY);
1302
+
1303
+ this.touchesDistanceStart = Math.sqrt(c1 * c1 + c2 * c2);
1304
+ this.startScale = this.scale;
1305
+
1306
+ this.originX = Math.abs(e.touches[0].pageX + e.touches[1].pageX) / 2 + this.wrapperOffset.left - this.x;
1307
+ this.originY = Math.abs(e.touches[0].pageY + e.touches[1].pageY) / 2 + this.wrapperOffset.top - this.y;
1308
+
1309
+ this._execEvent('zoomStart');
1310
+ },
1311
+
1312
+ _zoom: function (e) {
1313
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
1314
+ return;
1315
+ }
1316
+
1317
+ if (this.options.preventDefault) {
1318
+ e.preventDefault();
1319
+ }
1320
+
1321
+ var c1 = Math.abs(e.touches[0].pageX - e.touches[1].pageX);
1322
+ var c2 = Math.abs(e.touches[0].pageY - e.touches[1].pageY);
1323
+ var distance = Math.sqrt(c1 * c1 + c2 * c2);
1324
+ var scale = (1 / this.touchesDistanceStart) * distance * this.startScale;
1325
+ var lastScale;
1326
+ var x;
1327
+ var y;
1328
+
1329
+ this.scaled = true;
1330
+
1331
+ if (scale < this.options.zoomMin) {
1332
+ scale = 0.5 * this.options.zoomMin * Math.pow(2.0, scale / this.options.zoomMin);
1333
+ } else if (scale > this.options.zoomMax) {
1334
+ scale = 2.0 * this.options.zoomMax * Math.pow(0.5, this.options.zoomMax / scale);
1335
+ }
1336
+
1337
+ lastScale = scale / this.startScale;
1338
+ x = this.originX - this.originX * lastScale + this.startX;
1339
+ y = this.originY - this.originY * lastScale + this.startY;
1340
+
1341
+ this.scale = scale;
1342
+
1343
+ this.scrollTo(x, y, 0);
1344
+ },
1345
+
1346
+ _zoomEnd: function (e) {
1347
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
1348
+ return;
1349
+ }
1350
+
1351
+ if (this.options.preventDefault) {
1352
+ e.preventDefault();
1353
+ }
1354
+
1355
+ var newX;
1356
+ var newY;
1357
+ var lastScale;
1358
+
1359
+ this.isInTransition = 0;
1360
+ this.initiated = 0;
1361
+
1362
+ if (this.scale > this.options.zoomMax) {
1363
+ this.scale = this.options.zoomMax;
1364
+ } else if (this.scale < this.options.zoomMin) {
1365
+ this.scale = this.options.zoomMin;
1366
+ }
1367
+
1368
+ // Update boundaries
1369
+ this.refresh();
1370
+
1371
+ lastScale = this.scale / this.startScale;
1372
+
1373
+ newX = this.originX - this.originX * lastScale + this.startX;
1374
+ newY = this.originY - this.originY * lastScale + this.startY;
1375
+
1376
+ if (newX > 0) {
1377
+ newX = 0;
1378
+ } else if (newX < this.maxScrollX) {
1379
+ newX = this.maxScrollX;
1380
+ }
1381
+
1382
+ if (newY > 0) {
1383
+ newY = 0;
1384
+ } else if (newY < this.maxScrollY) {
1385
+ newY = this.maxScrollY;
1386
+ }
1387
+
1388
+ if (this.x != newX || this.y != newY) {
1389
+ this.scrollTo(newX, newY, this.options.bounceTime);
1390
+ }
1391
+
1392
+ this.scaled = false;
1393
+
1394
+ this._execEvent('zoomEnd');
1395
+ },
1396
+
1397
+ zoom: function (scale, x, y, time) {
1398
+ /*custom*/
1399
+ if (this.wrapperWidth == 0 || this.wrapperHeight == 0) {
1400
+ return;
1401
+ }
1402
+ /* end custom*/
1403
+
1404
+ if (scale < this.options.zoomMin) {
1405
+ scale = this.options.zoomMin;
1406
+ } else if (scale > this.options.zoomMax) {
1407
+ scale = this.options.zoomMax;
1408
+ }
1409
+
1410
+ if (scale == this.scale) {
1411
+ return;
1412
+ }
1413
+
1414
+ var relScale = scale / this.scale;
1415
+
1416
+ /*custom*/
1417
+ var that = this;
1418
+ if (relScale != 1) {
1419
+ clearTimeout(this.zoomStartTimeout);
1420
+ this.zoomStartTimeout = setTimeout(function () {
1421
+ that._execEvent('zoomStart');
1422
+ }, 0);
1423
+
1424
+ // Execute the zoomEnd event after 400ms the wheel stopped scrolling
1425
+ clearTimeout(this.wheelTimeout);
1426
+ this.wheelTimeout = setTimeout(function () {
1427
+ that._execEvent('zoomEnd');
1428
+ }, Number(time + 100));
1429
+ }
1430
+
1431
+ /*custom end*/
1432
+
1433
+ x = x === undefined ? this.wrapperWidth / 2 : x;
1434
+ y = y === undefined ? this.wrapperHeight / 2 : y;
1435
+ time = time === undefined ? 300 : time;
1436
+
1437
+ x = x + this.wrapperOffset.left - this.x;
1438
+ y = y + this.wrapperOffset.top - this.y;
1439
+
1440
+ x = x - x * relScale + this.x;
1441
+ y = y - y * relScale + this.y;
1442
+
1443
+ this.scale = scale;
1444
+
1445
+ this.refresh(); // update boundaries
1446
+
1447
+ if (x > 0) {
1448
+ x = 0;
1449
+ } else if (x < this.maxScrollX) {
1450
+ x = this.maxScrollX;
1451
+ }
1452
+
1453
+ if (y > 0) {
1454
+ y = 0;
1455
+ } else if (y < this.maxScrollY) {
1456
+ y = this.maxScrollY;
1457
+ }
1458
+
1459
+ this.scrollTo(x, y, time);
1460
+ },
1461
+
1462
+ _wheelZoom: function (e) {
1463
+ var wheelDeltaY;
1464
+ var deltaScale;
1465
+ var that = this;
1466
+
1467
+ /*custom - moved to function zoom()
1468
+
1469
+ // Execute the zoomEnd event after 400ms the wheel stopped scrolling
1470
+ clearTimeout(this.wheelTimeout);
1471
+ this.wheelTimeout = setTimeout(function () {
1472
+ that._execEvent('zoomEnd');
1473
+ }, 400);
1474
+
1475
+ custom end*/
1476
+
1477
+ if ('deltaX' in e) {
1478
+ wheelDeltaY = -e.deltaY / Math.abs(e.deltaY);
1479
+ } else if ('wheelDeltaX' in e) {
1480
+ wheelDeltaY = e.wheelDeltaY / Math.abs(e.wheelDeltaY);
1481
+ } else if ('wheelDelta' in e) {
1482
+ wheelDeltaY = e.wheelDelta / Math.abs(e.wheelDelta);
1483
+ } else if ('detail' in e) {
1484
+ wheelDeltaY = -e.detail / Math.abs(e.wheelDelta);
1485
+ } else {
1486
+ return;
1487
+ }
1488
+
1489
+ deltaScale = this.scale + wheelDeltaY / 5;
1490
+
1491
+ this.zoom(deltaScale, e.pageX, e.pageY, 0);
1492
+ },
1493
+
1494
+ _initWheel: function () {
1495
+ utils.addEvent(this.wrapper, 'wheel', this);
1496
+ utils.addEvent(this.wrapper, 'mousewheel', this);
1497
+ utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
1498
+
1499
+ this.on('destroy', function () {
1500
+ clearTimeout(this.wheelTimeout);
1501
+ this.wheelTimeout = null;
1502
+ utils.removeEvent(this.wrapper, 'wheel', this);
1503
+ utils.removeEvent(this.wrapper, 'mousewheel', this);
1504
+ utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
1505
+ });
1506
+ },
1507
+
1508
+ _wheel: function (e) {
1509
+ if (!this.enabled) {
1510
+ return;
1511
+ }
1512
+ //custom - prevent default wheel behavior only if options.preventDefault
1513
+ if (this.options.preventDefault) {
1514
+ //custom end
1515
+ e.preventDefault();
1516
+ //custom
1517
+ }
1518
+ //custom end
1519
+ var wheelDeltaX;
1520
+ var wheelDeltaY;
1521
+ var newX;
1522
+ var newY;
1523
+ var that = this;
1524
+
1525
+ if (this.wheelTimeout === undefined) {
1526
+ that._execEvent('scrollStart');
1527
+ }
1528
+
1529
+ // Execute the scrollEnd event after 400ms the wheel stopped scrolling
1530
+ clearTimeout(this.wheelTimeout);
1531
+
1532
+ /* custom - fixed timet 400ms changed to this.options.mouseWheelTimeout, default is 400
1533
+ this.wheelTimeout = setTimeout(function () {
1534
+ if (!that.options.snap) {
1535
+ that._execEvent('scrollEnd');
1536
+ }
1537
+ that.wheelTimeout = undefined;
1538
+ }, 400);
1539
+
1540
+ */
1541
+
1542
+ this.wheelTimeout = setTimeout(function () {
1543
+ if (!that.options.snap) {
1544
+ that._execEvent('scrollEnd');
1545
+ }
1546
+ that.wheelTimeout = undefined;
1547
+ }, this.options.mouseWheelTimeout);
1548
+
1549
+ if ('deltaX' in e) {
1550
+ if (e.deltaMode === 1) {
1551
+ wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
1552
+ wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
1553
+ } else {
1554
+ wheelDeltaX = -e.deltaX;
1555
+ wheelDeltaY = -e.deltaY;
1556
+ }
1557
+ } else if ('wheelDeltaX' in e) {
1558
+ wheelDeltaX = (e.wheelDeltaX / 120) * this.options.mouseWheelSpeed;
1559
+ wheelDeltaY = (e.wheelDeltaY / 120) * this.options.mouseWheelSpeed;
1560
+ } else if ('wheelDelta' in e) {
1561
+ wheelDeltaX = wheelDeltaY = (e.wheelDelta / 120) * this.options.mouseWheelSpeed;
1562
+ } else if ('detail' in e) {
1563
+ wheelDeltaX = wheelDeltaY = (-e.detail / 3) * this.options.mouseWheelSpeed;
1564
+ } else {
1565
+ return;
1566
+ }
1567
+
1568
+ wheelDeltaX *= this.options.invertWheelDirection;
1569
+ wheelDeltaY *= this.options.invertWheelDirection;
1570
+
1571
+ if (!this.hasVerticalScroll) {
1572
+ wheelDeltaX = wheelDeltaY;
1573
+ wheelDeltaY = 0;
1574
+ }
1575
+
1576
+ if (this.options.snap) {
1577
+ newX = this.currentPage.pageX;
1578
+ newY = this.currentPage.pageY;
1579
+
1580
+ if (wheelDeltaX > 0) {
1581
+ newX--;
1582
+ } else if (wheelDeltaX < 0) {
1583
+ newX++;
1584
+ }
1585
+
1586
+ if (wheelDeltaY > 0) {
1587
+ newY--;
1588
+ } else if (wheelDeltaY < 0) {
1589
+ newY++;
1590
+ }
1591
+
1592
+ this.goToPage(newX, newY);
1593
+
1594
+ return;
1595
+ }
1596
+
1597
+ newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
1598
+ newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
1599
+
1600
+ this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
1601
+ this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
1602
+
1603
+ if (newX > 0) {
1604
+ newX = 0;
1605
+ } else if (newX < this.maxScrollX) {
1606
+ newX = this.maxScrollX;
1607
+ }
1608
+
1609
+ if (newY > 0) {
1610
+ newY = 0;
1611
+ } else if (newY < this.maxScrollY) {
1612
+ newY = this.maxScrollY;
1613
+ }
1614
+ //custom - prevent page scrolling if iscroll is scrolling
1615
+ else {
1616
+ e.preventDefault();
1617
+ }
1618
+ //end custom
1619
+
1620
+ this.scrollTo(newX, newY, 0);
1621
+
1622
+ // INSERT POINT: _wheel
1623
+ },
1624
+
1625
+ _initSnap: function () {
1626
+ this.currentPage = {};
1627
+
1628
+ if (typeof this.options.snap == 'string') {
1629
+ this.options.snap = this.scroller.querySelectorAll(this.options.snap);
1630
+ }
1631
+
1632
+ this.on('refresh', function () {
1633
+ var i = 0;
1634
+ var l;
1635
+ var m = 0;
1636
+ var n;
1637
+ var cx;
1638
+ var cy;
1639
+ var x = 0;
1640
+ var y;
1641
+ var stepX = this.options.snapStepX || this.wrapperWidth;
1642
+ var stepY = this.options.snapStepY || this.wrapperHeight;
1643
+ var el;
1644
+ var rect;
1645
+
1646
+ this.pages = [];
1647
+
1648
+ if (!this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight) {
1649
+ return;
1650
+ }
1651
+
1652
+ if (this.options.snap === true) {
1653
+ cx = Math.round(stepX / 2);
1654
+ cy = Math.round(stepY / 2);
1655
+
1656
+ while (x > -this.scrollerWidth) {
1657
+ this.pages[i] = [];
1658
+ l = 0;
1659
+ y = 0;
1660
+
1661
+ while (y > -this.scrollerHeight) {
1662
+ this.pages[i][l] = {
1663
+ x: Math.max(x, this.maxScrollX),
1664
+ y: Math.max(y, this.maxScrollY),
1665
+ width: stepX,
1666
+ height: stepY,
1667
+ cx: x - cx,
1668
+ cy: y - cy,
1669
+ };
1670
+
1671
+ y -= stepY;
1672
+ l++;
1673
+ }
1674
+
1675
+ x -= stepX;
1676
+ i++;
1677
+ }
1678
+ } else {
1679
+ el = this.options.snap;
1680
+ l = el.length;
1681
+ n = -1;
1682
+
1683
+ for (; i < l; i++) {
1684
+ rect = utils.getRect(el[i]);
1685
+ if (i === 0 || rect.left <= utils.getRect(el[i - 1]).left) {
1686
+ m = 0;
1687
+ n++;
1688
+ }
1689
+
1690
+ if (!this.pages[m]) {
1691
+ this.pages[m] = [];
1692
+ }
1693
+
1694
+ x = Math.max(-rect.left, this.maxScrollX);
1695
+ y = Math.max(-rect.top, this.maxScrollY);
1696
+ cx = x - Math.round(rect.width / 2);
1697
+ cy = y - Math.round(rect.height / 2);
1698
+
1699
+ this.pages[m][n] = {
1700
+ x: x,
1701
+ y: y,
1702
+ width: rect.width,
1703
+ height: rect.height,
1704
+ cx: cx,
1705
+ cy: cy,
1706
+ };
1707
+
1708
+ if (x > this.maxScrollX) {
1709
+ m++;
1710
+ }
1711
+ }
1712
+ }
1713
+
1714
+ this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
1715
+
1716
+ // Update snap threshold if needed
1717
+ if (this.options.snapThreshold % 1 === 0) {
1718
+ this.snapThresholdX = this.options.snapThreshold;
1719
+ this.snapThresholdY = this.options.snapThreshold;
1720
+ } else {
1721
+ this.snapThresholdX = Math.round(
1722
+ this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold
1723
+ );
1724
+ this.snapThresholdY = Math.round(
1725
+ this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold
1726
+ );
1727
+ }
1728
+ });
1729
+
1730
+ this.on('flick', function () {
1731
+ var time =
1732
+ this.options.snapSpeed ||
1733
+ Math.max(
1734
+ Math.max(
1735
+ Math.min(Math.abs(this.x - this.startX), 1000),
1736
+ Math.min(Math.abs(this.y - this.startY), 1000)
1737
+ ),
1738
+ 300
1739
+ );
1740
+
1741
+ this.goToPage(this.currentPage.pageX + this.directionX, this.currentPage.pageY + this.directionY, time);
1742
+ });
1743
+ },
1744
+
1745
+ _nearestSnap: function (x, y) {
1746
+ if (!this.pages.length) {
1747
+ return { x: 0, y: 0, pageX: 0, pageY: 0 };
1748
+ }
1749
+
1750
+ var i = 0;
1751
+ var l = this.pages.length;
1752
+ var m = 0;
1753
+
1754
+ // Check if we exceeded the snap threshold
1755
+ if (
1756
+ Math.abs(x - this.absStartX) < this.snapThresholdX &&
1757
+ Math.abs(y - this.absStartY) < this.snapThresholdY
1758
+ ) {
1759
+ return this.currentPage;
1760
+ }
1761
+
1762
+ if (x > 0) {
1763
+ x = 0;
1764
+ } else if (x < this.maxScrollX) {
1765
+ x = this.maxScrollX;
1766
+ }
1767
+
1768
+ if (y > 0) {
1769
+ y = 0;
1770
+ } else if (y < this.maxScrollY) {
1771
+ y = this.maxScrollY;
1772
+ }
1773
+
1774
+ for (; i < l; i++) {
1775
+ if (x >= this.pages[i][0].cx) {
1776
+ x = this.pages[i][0].x;
1777
+ break;
1778
+ }
1779
+ }
1780
+
1781
+ l = this.pages[i].length;
1782
+
1783
+ for (; m < l; m++) {
1784
+ if (y >= this.pages[0][m].cy) {
1785
+ y = this.pages[0][m].y;
1786
+ break;
1787
+ }
1788
+ }
1789
+
1790
+ if (i == this.currentPage.pageX) {
1791
+ i += this.directionX;
1792
+
1793
+ if (i < 0) {
1794
+ i = 0;
1795
+ } else if (i >= this.pages.length) {
1796
+ i = this.pages.length - 1;
1797
+ }
1798
+
1799
+ x = this.pages[i][0].x;
1800
+ }
1801
+
1802
+ if (m == this.currentPage.pageY) {
1803
+ m += this.directionY;
1804
+
1805
+ if (m < 0) {
1806
+ m = 0;
1807
+ } else if (m >= this.pages[0].length) {
1808
+ m = this.pages[0].length - 1;
1809
+ }
1810
+
1811
+ y = this.pages[0][m].y;
1812
+ }
1813
+
1814
+ return {
1815
+ x: x,
1816
+ y: y,
1817
+ pageX: i,
1818
+ pageY: m,
1819
+ };
1820
+ },
1821
+
1822
+ goToPage: function (x, y, time, easing) {
1823
+ easing = easing || this.options.bounceEasing;
1824
+
1825
+ if (x >= this.pages.length) {
1826
+ x = this.pages.length - 1;
1827
+ } else if (x < 0) {
1828
+ x = 0;
1829
+ }
1830
+
1831
+ if (y >= this.pages[x].length) {
1832
+ y = this.pages[x].length - 1;
1833
+ } else if (y < 0) {
1834
+ y = 0;
1835
+ }
1836
+
1837
+ var posX = this.pages[x][y].x;
1838
+ var posY = this.pages[x][y].y;
1839
+
1840
+ time =
1841
+ time === undefined
1842
+ ? this.options.snapSpeed ||
1843
+ Math.max(
1844
+ Math.max(Math.min(Math.abs(posX - this.x), 1000), Math.min(Math.abs(posY - this.y), 1000)),
1845
+ 300
1846
+ )
1847
+ : time;
1848
+
1849
+ this.currentPage = {
1850
+ x: posX,
1851
+ y: posY,
1852
+ pageX: x,
1853
+ pageY: y,
1854
+ };
1855
+
1856
+ this.scrollTo(posX, posY, time, easing);
1857
+ },
1858
+
1859
+ next: function (time, easing) {
1860
+ var x = this.currentPage.pageX;
1861
+ var y = this.currentPage.pageY;
1862
+
1863
+ x++;
1864
+
1865
+ if (x >= this.pages.length && this.hasVerticalScroll) {
1866
+ x = 0;
1867
+ y++;
1868
+ }
1869
+
1870
+ this.goToPage(x, y, time, easing);
1871
+ },
1872
+
1873
+ prev: function (time, easing) {
1874
+ var x = this.currentPage.pageX;
1875
+ var y = this.currentPage.pageY;
1876
+
1877
+ x--;
1878
+
1879
+ if (x < 0 && this.hasVerticalScroll) {
1880
+ x = 0;
1881
+ y--;
1882
+ }
1883
+
1884
+ this.goToPage(x, y, time, easing);
1885
+ },
1886
+
1887
+ _initKeys: function (e) {
1888
+ // default key bindings
1889
+ var keys = {
1890
+ pageUp: 33,
1891
+ pageDown: 34,
1892
+ end: 35,
1893
+ home: 36,
1894
+ left: 37,
1895
+ up: 38,
1896
+ right: 39,
1897
+ down: 40,
1898
+ };
1899
+ var i;
1900
+
1901
+ // if you give me characters I give you keycode
1902
+ if (typeof this.options.keyBindings == 'object') {
1903
+ for (i in this.options.keyBindings) {
1904
+ if (typeof this.options.keyBindings[i] == 'string') {
1905
+ this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0);
1906
+ }
1907
+ }
1908
+ } else {
1909
+ this.options.keyBindings = {};
1910
+ }
1911
+
1912
+ for (i in keys) {
1913
+ this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
1914
+ }
1915
+
1916
+ utils.addEvent(window, 'keydown', this);
1917
+
1918
+ this.on('destroy', function () {
1919
+ utils.removeEvent(window, 'keydown', this);
1920
+ });
1921
+ },
1922
+
1923
+ _key: function (e) {
1924
+ if (!this.enabled) {
1925
+ return;
1926
+ }
1927
+
1928
+ var snap = this.options.snap; // we are using this alot, better to cache it
1929
+ var newX = snap ? this.currentPage.pageX : this.x;
1930
+ var newY = snap ? this.currentPage.pageY : this.y;
1931
+ var now = utils.getTime();
1932
+ var prevTime = this.keyTime || 0;
1933
+ var acceleration = 0.25;
1934
+ var pos;
1935
+
1936
+ if (this.options.useTransition && this.isInTransition) {
1937
+ pos = this.getComputedPosition();
1938
+
1939
+ this._translate(Math.round(pos.x), Math.round(pos.y));
1940
+ this.isInTransition = false;
1941
+ }
1942
+
1943
+ this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
1944
+
1945
+ switch (e.keyCode) {
1946
+ case this.options.keyBindings.pageUp:
1947
+ if (this.hasHorizontalScroll && !this.hasVerticalScroll) {
1948
+ newX += snap ? 1 : this.wrapperWidth;
1949
+ } else {
1950
+ newY += snap ? 1 : this.wrapperHeight;
1951
+ }
1952
+ break;
1953
+ case this.options.keyBindings.pageDown:
1954
+ if (this.hasHorizontalScroll && !this.hasVerticalScroll) {
1955
+ newX -= snap ? 1 : this.wrapperWidth;
1956
+ } else {
1957
+ newY -= snap ? 1 : this.wrapperHeight;
1958
+ }
1959
+ break;
1960
+ case this.options.keyBindings.end:
1961
+ newX = snap ? this.pages.length - 1 : this.maxScrollX;
1962
+ newY = snap ? this.pages[0].length - 1 : this.maxScrollY;
1963
+ break;
1964
+ case this.options.keyBindings.home:
1965
+ newX = 0;
1966
+ newY = 0;
1967
+ break;
1968
+ case this.options.keyBindings.left:
1969
+ newX += snap ? -1 : (5 + this.keyAcceleration) >> 0;
1970
+ break;
1971
+ case this.options.keyBindings.up:
1972
+ newY += snap ? 1 : (5 + this.keyAcceleration) >> 0;
1973
+ break;
1974
+ case this.options.keyBindings.right:
1975
+ newX -= snap ? -1 : (5 + this.keyAcceleration) >> 0;
1976
+ break;
1977
+ case this.options.keyBindings.down:
1978
+ newY -= snap ? 1 : (5 + this.keyAcceleration) >> 0;
1979
+ break;
1980
+ default:
1981
+ return;
1982
+ }
1983
+
1984
+ if (snap) {
1985
+ this.goToPage(newX, newY);
1986
+ return;
1987
+ }
1988
+
1989
+ if (newX > 0) {
1990
+ newX = 0;
1991
+ this.keyAcceleration = 0;
1992
+ } else if (newX < this.maxScrollX) {
1993
+ newX = this.maxScrollX;
1994
+ this.keyAcceleration = 0;
1995
+ }
1996
+
1997
+ if (newY > 0) {
1998
+ newY = 0;
1999
+ this.keyAcceleration = 0;
2000
+ } else if (newY < this.maxScrollY) {
2001
+ newY = this.maxScrollY;
2002
+ this.keyAcceleration = 0;
2003
+ }
2004
+
2005
+ this.scrollTo(newX, newY, 0);
2006
+
2007
+ this.keyTime = now;
2008
+ },
2009
+
2010
+ _animate: function (destX, destY, duration, easingFn) {
2011
+ var that = this;
2012
+ var startX = this.x;
2013
+ var startY = this.y;
2014
+ var startTime = utils.getTime();
2015
+ var destTime = startTime + duration;
2016
+
2017
+ function step() {
2018
+ var now = utils.getTime();
2019
+ var newX;
2020
+ var newY;
2021
+ var easing;
2022
+
2023
+ if (now >= destTime) {
2024
+ that.isAnimating = false;
2025
+ that._translate(destX, destY);
2026
+
2027
+ if (!that.resetPosition(that.options.bounceTime)) {
2028
+ that._execEvent('scrollEnd');
2029
+ }
2030
+
2031
+ return;
2032
+ }
2033
+
2034
+ now = (now - startTime) / duration;
2035
+ easing = easingFn(now);
2036
+ newX = (destX - startX) * easing + startX;
2037
+ newY = (destY - startY) * easing + startY;
2038
+ that._translate(newX, newY);
2039
+
2040
+ if (that.isAnimating) {
2041
+ rAF(step);
2042
+ }
2043
+ }
2044
+
2045
+ this.isAnimating = true;
2046
+ step();
2047
+ },
2048
+ handleEvent: function (e) {
2049
+ switch (e.type) {
2050
+ case 'touchstart':
2051
+ case 'pointerdown':
2052
+ case 'MSPointerDown':
2053
+ case 'mousedown':
2054
+ this._start(e);
2055
+
2056
+ if (this.options.zoom && e.touches && e.touches.length > 1) {
2057
+ this._zoomStart(e);
2058
+ }
2059
+ break;
2060
+ case 'touchmove':
2061
+ case 'pointermove':
2062
+ case 'MSPointerMove':
2063
+ case 'mousemove':
2064
+ if (this.options.zoom && e.touches && e.touches[1]) {
2065
+ this._zoom(e);
2066
+ return;
2067
+ }
2068
+ this._move(e);
2069
+ break;
2070
+ case 'touchend':
2071
+ case 'pointerup':
2072
+ case 'MSPointerUp':
2073
+ case 'mouseup':
2074
+ case 'touchcancel':
2075
+ case 'pointercancel':
2076
+ case 'MSPointerCancel':
2077
+ case 'mousecancel':
2078
+ if (this.scaled) {
2079
+ this._zoomEnd(e);
2080
+ return;
2081
+ }
2082
+ this._end(e);
2083
+ break;
2084
+ case 'orientationchange':
2085
+ case 'resize':
2086
+ this._resize();
2087
+ break;
2088
+ case 'transitionend':
2089
+ case 'webkitTransitionEnd':
2090
+ case 'oTransitionEnd':
2091
+ case 'MSTransitionEnd':
2092
+ this._transitionEnd(e);
2093
+ break;
2094
+ case 'wheel':
2095
+ case 'DOMMouseScroll':
2096
+ case 'mousewheel':
2097
+ if (this.options.wheelAction == 'zoom') {
2098
+ this._wheelZoom(e);
2099
+ return;
2100
+ }
2101
+ this._wheel(e);
2102
+ break;
2103
+ case 'keydown':
2104
+ this._key(e);
2105
+ break;
2106
+ }
2107
+ },
2108
+ };
2109
+ function createDefaultScrollbar(direction, interactive, type) {
2110
+ var scrollbar = document.createElement('div');
2111
+ var indicator = document.createElement('div');
2112
+
2113
+ if (type === true) {
2114
+ scrollbar.style.cssText = 'position:absolute;z-index:9999';
2115
+ indicator.style.cssText =
2116
+ '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px';
2117
+ }
2118
+
2119
+ indicator.className = 'iScrollIndicator';
2120
+
2121
+ if (direction == 'h') {
2122
+ if (type === true) {
2123
+ scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
2124
+ indicator.style.height = '100%';
2125
+ }
2126
+ scrollbar.className = 'iScrollHorizontalScrollbar';
2127
+ } else {
2128
+ if (type === true) {
2129
+ scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
2130
+ indicator.style.width = '100%';
2131
+ }
2132
+ scrollbar.className = 'iScrollVerticalScrollbar';
2133
+ }
2134
+
2135
+ scrollbar.style.cssText += ';overflow:hidden';
2136
+
2137
+ if (!interactive) {
2138
+ scrollbar.style.pointerEvents = 'none';
2139
+ }
2140
+
2141
+ scrollbar.appendChild(indicator);
2142
+
2143
+ return scrollbar;
2144
+ }
2145
+
2146
+ function Indicator(scroller, options) {
2147
+ this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
2148
+ this.wrapperStyle = this.wrapper.style;
2149
+ this.indicator = this.wrapper.children[0];
2150
+ this.indicatorStyle = this.indicator.style;
2151
+ this.scroller = scroller;
2152
+
2153
+ this.options = {
2154
+ listenX: true,
2155
+ listenY: true,
2156
+ interactive: false,
2157
+ resize: true,
2158
+ defaultScrollbars: false,
2159
+ shrink: false,
2160
+ fade: false,
2161
+ speedRatioX: 0,
2162
+ speedRatioY: 0,
2163
+ };
2164
+
2165
+ for (var i in options) {
2166
+ this.options[i] = options[i];
2167
+ }
2168
+
2169
+ this.sizeRatioX = 1;
2170
+ this.sizeRatioY = 1;
2171
+ this.maxPosX = 0;
2172
+ this.maxPosY = 0;
2173
+
2174
+ if (this.options.interactive) {
2175
+ if (!this.options.disableTouch) {
2176
+ utils.addEvent(this.indicator, 'touchstart', this);
2177
+ utils.addEvent(window, 'touchend', this);
2178
+ }
2179
+ if (!this.options.disablePointer) {
2180
+ utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
2181
+ utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
2182
+ }
2183
+ if (!this.options.disableMouse) {
2184
+ utils.addEvent(this.indicator, 'mousedown', this);
2185
+ utils.addEvent(window, 'mouseup', this);
2186
+ }
2187
+ }
2188
+
2189
+ if (this.options.fade) {
2190
+ this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
2191
+ var durationProp = utils.style.transitionDuration;
2192
+ if (!durationProp) {
2193
+ return;
2194
+ }
2195
+ this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
2196
+ // remove 0.0001ms
2197
+ var self = this;
2198
+ if (utils.isBadAndroid) {
2199
+ rAF(function () {
2200
+ if (self.wrapperStyle[durationProp] === '0.0001ms') {
2201
+ self.wrapperStyle[durationProp] = '0s';
2202
+ }
2203
+ });
2204
+ }
2205
+ this.wrapperStyle.opacity = '0';
2206
+ }
2207
+ }
2208
+
2209
+ Indicator.prototype = {
2210
+ handleEvent: function (e) {
2211
+ switch (e.type) {
2212
+ case 'touchstart':
2213
+ case 'pointerdown':
2214
+ case 'MSPointerDown':
2215
+ case 'mousedown':
2216
+ this._start(e);
2217
+ break;
2218
+ case 'touchmove':
2219
+ case 'pointermove':
2220
+ case 'MSPointerMove':
2221
+ case 'mousemove':
2222
+ this._move(e);
2223
+ break;
2224
+ case 'touchend':
2225
+ case 'pointerup':
2226
+ case 'MSPointerUp':
2227
+ case 'mouseup':
2228
+ case 'touchcancel':
2229
+ case 'pointercancel':
2230
+ case 'MSPointerCancel':
2231
+ case 'mousecancel':
2232
+ this._end(e);
2233
+ break;
2234
+ }
2235
+ },
2236
+
2237
+ destroy: function () {
2238
+ if (this.options.fadeScrollbars) {
2239
+ clearTimeout(this.fadeTimeout);
2240
+ this.fadeTimeout = null;
2241
+ }
2242
+ if (this.options.interactive) {
2243
+ utils.removeEvent(this.indicator, 'touchstart', this);
2244
+ utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
2245
+ utils.removeEvent(this.indicator, 'mousedown', this);
2246
+
2247
+ utils.removeEvent(window, 'touchmove', this);
2248
+ utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
2249
+ utils.removeEvent(window, 'mousemove', this);
2250
+
2251
+ utils.removeEvent(window, 'touchend', this);
2252
+ utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
2253
+ utils.removeEvent(window, 'mouseup', this);
2254
+ }
2255
+
2256
+ if (this.options.defaultScrollbars && this.wrapper.parentNode) {
2257
+ this.wrapper.parentNode.removeChild(this.wrapper);
2258
+ }
2259
+ },
2260
+
2261
+ _start: function (e) {
2262
+ var point = e.touches ? e.touches[0] : e;
2263
+
2264
+ e.preventDefault();
2265
+ e.stopPropagation();
2266
+
2267
+ this.transitionTime();
2268
+
2269
+ this.initiated = true;
2270
+ this.moved = false;
2271
+ this.lastPointX = point.pageX;
2272
+ this.lastPointY = point.pageY;
2273
+
2274
+ this.startTime = utils.getTime();
2275
+
2276
+ if (!this.options.disableTouch) {
2277
+ utils.addEvent(window, 'touchmove', this);
2278
+ }
2279
+ if (!this.options.disablePointer) {
2280
+ utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
2281
+ }
2282
+ if (!this.options.disableMouse) {
2283
+ utils.addEvent(window, 'mousemove', this);
2284
+ }
2285
+
2286
+ this.scroller._execEvent('beforeScrollStart');
2287
+ },
2288
+
2289
+ _move: function (e) {
2290
+ var point = e.touches ? e.touches[0] : e;
2291
+ var deltaX;
2292
+ var deltaY;
2293
+ var newX;
2294
+ var newY;
2295
+ var timestamp = utils.getTime();
2296
+
2297
+ if (!this.moved) {
2298
+ this.scroller._execEvent('scrollStart');
2299
+ }
2300
+
2301
+ this.moved = true;
2302
+
2303
+ deltaX = point.pageX - this.lastPointX;
2304
+ this.lastPointX = point.pageX;
2305
+
2306
+ deltaY = point.pageY - this.lastPointY;
2307
+ this.lastPointY = point.pageY;
2308
+
2309
+ newX = this.x + deltaX;
2310
+ newY = this.y + deltaY;
2311
+
2312
+ this._pos(newX, newY);
2313
+
2314
+ // INSERT POINT: indicator._move
2315
+
2316
+ e.preventDefault();
2317
+ e.stopPropagation();
2318
+ },
2319
+
2320
+ _end: function (e) {
2321
+ if (!this.initiated) {
2322
+ return;
2323
+ }
2324
+
2325
+ this.initiated = false;
2326
+
2327
+ e.preventDefault();
2328
+ e.stopPropagation();
2329
+
2330
+ utils.removeEvent(window, 'touchmove', this);
2331
+ utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
2332
+ utils.removeEvent(window, 'mousemove', this);
2333
+
2334
+ if (this.scroller.options.snap) {
2335
+ var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
2336
+
2337
+ var time =
2338
+ this.options.snapSpeed ||
2339
+ Math.max(
2340
+ Math.max(
2341
+ Math.min(Math.abs(this.scroller.x - snap.x), 1000),
2342
+ Math.min(Math.abs(this.scroller.y - snap.y), 1000)
2343
+ ),
2344
+ 300
2345
+ );
2346
+
2347
+ if (this.scroller.x != snap.x || this.scroller.y != snap.y) {
2348
+ this.scroller.directionX = 0;
2349
+ this.scroller.directionY = 0;
2350
+ this.scroller.currentPage = snap;
2351
+ this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
2352
+ }
2353
+ }
2354
+
2355
+ if (this.moved) {
2356
+ this.scroller._execEvent('scrollEnd');
2357
+ }
2358
+ },
2359
+
2360
+ transitionTime: function (time) {
2361
+ time = time || 0;
2362
+ var durationProp = utils.style.transitionDuration;
2363
+ if (!durationProp) {
2364
+ return;
2365
+ }
2366
+
2367
+ this.indicatorStyle[durationProp] = time + 'ms';
2368
+
2369
+ if (!time && utils.isBadAndroid) {
2370
+ this.indicatorStyle[durationProp] = '0.0001ms';
2371
+ // remove 0.0001ms
2372
+ var self = this;
2373
+ rAF(function () {
2374
+ if (self.indicatorStyle[durationProp] === '0.0001ms') {
2375
+ self.indicatorStyle[durationProp] = '0s';
2376
+ }
2377
+ });
2378
+ }
2379
+ },
2380
+
2381
+ transitionTimingFunction: function (easing) {
2382
+ this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
2383
+ },
2384
+
2385
+ refresh: function () {
2386
+ this.transitionTime();
2387
+
2388
+ if (this.options.listenX && !this.options.listenY) {
2389
+ this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
2390
+ } else if (this.options.listenY && !this.options.listenX) {
2391
+ this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
2392
+ } else {
2393
+ this.indicatorStyle.display =
2394
+ this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
2395
+ }
2396
+
2397
+ if (this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll) {
2398
+ utils.addClass(this.wrapper, 'iScrollBothScrollbars');
2399
+ utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
2400
+
2401
+ if (this.options.defaultScrollbars && this.options.customStyle) {
2402
+ if (this.options.listenX) {
2403
+ this.wrapper.style.right = '8px';
2404
+ } else {
2405
+ this.wrapper.style.bottom = '8px';
2406
+ }
2407
+ }
2408
+ } else {
2409
+ utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
2410
+ utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
2411
+
2412
+ if (this.options.defaultScrollbars && this.options.customStyle) {
2413
+ if (this.options.listenX) {
2414
+ this.wrapper.style.right = '2px';
2415
+ } else {
2416
+ this.wrapper.style.bottom = '2px';
2417
+ }
2418
+ }
2419
+ }
2420
+
2421
+ utils.getRect(this.wrapper); // force refresh
2422
+
2423
+ if (this.options.listenX) {
2424
+ this.wrapperWidth = this.wrapper.clientWidth;
2425
+ if (this.options.resize) {
2426
+ this.indicatorWidth = Math.max(
2427
+ Math.round(
2428
+ (this.wrapperWidth * this.wrapperWidth) /
2429
+ (this.scroller.scrollerWidth || this.wrapperWidth || 1)
2430
+ ),
2431
+ 8
2432
+ );
2433
+ this.indicatorStyle.width = this.indicatorWidth + 'px';
2434
+ } else {
2435
+ this.indicatorWidth = this.indicator.clientWidth;
2436
+ }
2437
+
2438
+ this.maxPosX = this.wrapperWidth - this.indicatorWidth;
2439
+
2440
+ if (this.options.shrink == 'clip') {
2441
+ this.minBoundaryX = -this.indicatorWidth + 8;
2442
+ this.maxBoundaryX = this.wrapperWidth - 8;
2443
+ } else {
2444
+ this.minBoundaryX = 0;
2445
+ this.maxBoundaryX = this.maxPosX;
2446
+ }
2447
+
2448
+ this.sizeRatioX =
2449
+ this.options.speedRatioX || (this.scroller.maxScrollX && this.maxPosX / this.scroller.maxScrollX);
2450
+ }
2451
+
2452
+ if (this.options.listenY) {
2453
+ this.wrapperHeight = this.wrapper.clientHeight;
2454
+ if (this.options.resize) {
2455
+ this.indicatorHeight = Math.max(
2456
+ Math.round(
2457
+ (this.wrapperHeight * this.wrapperHeight) /
2458
+ (this.scroller.scrollerHeight || this.wrapperHeight || 1)
2459
+ ),
2460
+ 8
2461
+ );
2462
+ this.indicatorStyle.height = this.indicatorHeight + 'px';
2463
+ } else {
2464
+ this.indicatorHeight = this.indicator.clientHeight;
2465
+ }
2466
+
2467
+ this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2468
+
2469
+ if (this.options.shrink == 'clip') {
2470
+ this.minBoundaryY = -this.indicatorHeight + 8;
2471
+ this.maxBoundaryY = this.wrapperHeight - 8;
2472
+ } else {
2473
+ this.minBoundaryY = 0;
2474
+ this.maxBoundaryY = this.maxPosY;
2475
+ }
2476
+
2477
+ this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2478
+ this.sizeRatioY =
2479
+ this.options.speedRatioY || (this.scroller.maxScrollY && this.maxPosY / this.scroller.maxScrollY);
2480
+ }
2481
+
2482
+ this.updatePosition();
2483
+ },
2484
+
2485
+ updatePosition: function () {
2486
+ var x = (this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x)) || 0;
2487
+ var y = (this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y)) || 0;
2488
+
2489
+ if (!this.options.ignoreBoundaries) {
2490
+ if (x < this.minBoundaryX) {
2491
+ if (this.options.shrink == 'scale') {
2492
+ this.width = Math.max(this.indicatorWidth + x, 8);
2493
+ this.indicatorStyle.width = this.width + 'px';
2494
+ }
2495
+ x = this.minBoundaryX;
2496
+ } else if (x > this.maxBoundaryX) {
2497
+ if (this.options.shrink == 'scale') {
2498
+ this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
2499
+ this.indicatorStyle.width = this.width + 'px';
2500
+ x = this.maxPosX + this.indicatorWidth - this.width;
2501
+ } else {
2502
+ x = this.maxBoundaryX;
2503
+ }
2504
+ } else if (this.options.shrink == 'scale' && this.width != this.indicatorWidth) {
2505
+ this.width = this.indicatorWidth;
2506
+ this.indicatorStyle.width = this.width + 'px';
2507
+ }
2508
+
2509
+ if (y < this.minBoundaryY) {
2510
+ if (this.options.shrink == 'scale') {
2511
+ this.height = Math.max(this.indicatorHeight + y * 3, 8);
2512
+ this.indicatorStyle.height = this.height + 'px';
2513
+ }
2514
+ y = this.minBoundaryY;
2515
+ } else if (y > this.maxBoundaryY) {
2516
+ if (this.options.shrink == 'scale') {
2517
+ this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
2518
+ this.indicatorStyle.height = this.height + 'px';
2519
+ y = this.maxPosY + this.indicatorHeight - this.height;
2520
+ } else {
2521
+ y = this.maxBoundaryY;
2522
+ }
2523
+ } else if (this.options.shrink == 'scale' && this.height != this.indicatorHeight) {
2524
+ this.height = this.indicatorHeight;
2525
+ this.indicatorStyle.height = this.height + 'px';
2526
+ }
2527
+ }
2528
+
2529
+ this.x = x;
2530
+ this.y = y;
2531
+
2532
+ if (this.scroller.options.useTransform) {
2533
+ this.indicatorStyle[utils.style.transform] =
2534
+ 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
2535
+ } else {
2536
+ this.indicatorStyle.left = x + 'px';
2537
+ this.indicatorStyle.top = y + 'px';
2538
+ }
2539
+ },
2540
+
2541
+ _pos: function (x, y) {
2542
+ if (x < 0) {
2543
+ x = 0;
2544
+ } else if (x > this.maxPosX) {
2545
+ x = this.maxPosX;
2546
+ }
2547
+
2548
+ if (y < 0) {
2549
+ y = 0;
2550
+ } else if (y > this.maxPosY) {
2551
+ y = this.maxPosY;
2552
+ }
2553
+
2554
+ x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
2555
+ y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
2556
+
2557
+ this.scroller.scrollTo(x, y);
2558
+ },
2559
+
2560
+ fade: function (val, hold) {
2561
+ if (hold && !this.visible) {
2562
+ return;
2563
+ }
2564
+
2565
+ clearTimeout(this.fadeTimeout);
2566
+ this.fadeTimeout = null;
2567
+
2568
+ var time = val ? 250 : 500;
2569
+ var delay = val ? 0 : 300;
2570
+
2571
+ val = val ? '1' : '0';
2572
+
2573
+ this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
2574
+
2575
+ this.fadeTimeout = setTimeout(
2576
+ function (val) {
2577
+ this.wrapperStyle.opacity = val;
2578
+ this.visible = +val;
2579
+ }.bind(this, val),
2580
+ delay
2581
+ );
2582
+ },
2583
+ };
2584
+
2585
+ IScroll.utils = utils;
2586
+
2587
+ if (typeof module != 'undefined' && module.exports) {
2588
+ module.exports = IScroll;
2589
+ } else if (typeof define == 'function' && define.amd) {
2590
+ define(function () {
2591
+ return IScroll;
2592
+ });
2593
+ } else {
2594
+ window.IScroll = IScroll;
2595
+ }
2596
+
2597
+ window.FLIPBOOK = window.FLIPBOOK || {};
2598
+ window.FLIPBOOK.IScroll = IScroll;
2599
+
2600
+ window.PointerEvent = undefined;
2601
+
2602
+ // var oldEPD = Event.prototype.preventDefault;
2603
+ // Event.prototype.preventDefault = function() {
2604
+ // debugger;
2605
+ // oldEPD.call(this);
2606
+ // };
2607
+ })(window, document, Math);
libs/mark.js ADDED
@@ -0,0 +1,1464 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Real3D FlipBook [https://real3dflipbook.com]
3
+ * @author creativeinteractivemedia [https://codecanyon.net/user/creativeinteractivemedia/portfolio]
4
+ * @version 4.10
5
+ * @date 2025-05-15
6
+ */
7
+ /*!***************************************************
8
+ * mark.js v9.0.0
9
+ * https://markjs.io/
10
+ * Copyright (c) 2014–2018, Julian Kühnel
11
+ * Released under the MIT license https://git.io/vwTVl
12
+ *****************************************************/
13
+
14
+ (function (global, factory) {
15
+ typeof exports === 'object' && typeof module !== 'undefined'
16
+ ? (module.exports = factory())
17
+ : typeof define === 'function' && define.amd
18
+ ? define(factory)
19
+ : (global.Mark = factory());
20
+ })(this, function () {
21
+ 'use strict';
22
+
23
+ function _typeof(obj) {
24
+ if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
25
+ _typeof = function (obj) {
26
+ return typeof obj;
27
+ };
28
+ } else {
29
+ _typeof = function (obj) {
30
+ return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype
31
+ ? 'symbol'
32
+ : typeof obj;
33
+ };
34
+ }
35
+
36
+ return _typeof(obj);
37
+ }
38
+
39
+ function _classCallCheck(instance, Constructor) {
40
+ if (!(instance instanceof Constructor)) {
41
+ throw new TypeError('Cannot call a class as a function');
42
+ }
43
+ }
44
+
45
+ function _defineProperties(target, props) {
46
+ for (var i = 0; i < props.length; i++) {
47
+ var descriptor = props[i];
48
+ descriptor.enumerable = descriptor.enumerable || false;
49
+ descriptor.configurable = true;
50
+ if ('value' in descriptor) descriptor.writable = true;
51
+ Object.defineProperty(target, descriptor.key, descriptor);
52
+ }
53
+ }
54
+
55
+ function _createClass(Constructor, protoProps, staticProps) {
56
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
57
+ if (staticProps) _defineProperties(Constructor, staticProps);
58
+ return Constructor;
59
+ }
60
+
61
+ function _extends() {
62
+ _extends =
63
+ Object.assign ||
64
+ function (target) {
65
+ for (var i = 1; i < arguments.length; i++) {
66
+ var source = arguments[i];
67
+
68
+ for (var key in source) {
69
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
70
+ target[key] = source[key];
71
+ }
72
+ }
73
+ }
74
+
75
+ return target;
76
+ };
77
+
78
+ return _extends.apply(this, arguments);
79
+ }
80
+
81
+ var DOMIterator =
82
+ /*#__PURE__*/
83
+ (function () {
84
+ function DOMIterator(ctx) {
85
+ var iframes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
86
+ var exclude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
87
+ var iframesTimeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5000;
88
+
89
+ _classCallCheck(this, DOMIterator);
90
+
91
+ this.ctx = ctx;
92
+ this.iframes = iframes;
93
+ this.exclude = exclude;
94
+ this.iframesTimeout = iframesTimeout;
95
+ }
96
+
97
+ _createClass(
98
+ DOMIterator,
99
+ [
100
+ {
101
+ key: 'getContexts',
102
+ value: function getContexts() {
103
+ var ctx,
104
+ filteredCtx = [];
105
+
106
+ if (typeof this.ctx === 'undefined' || !this.ctx) {
107
+ ctx = [];
108
+ } else if (NodeList.prototype.isPrototypeOf(this.ctx)) {
109
+ ctx = Array.prototype.slice.call(this.ctx);
110
+ } else if (Array.isArray(this.ctx)) {
111
+ ctx = this.ctx;
112
+ } else if (typeof this.ctx === 'string') {
113
+ ctx = Array.prototype.slice.call(document.querySelectorAll(this.ctx));
114
+ } else {
115
+ ctx = [this.ctx];
116
+ }
117
+
118
+ ctx.forEach(function (ctx) {
119
+ var isDescendant =
120
+ filteredCtx.filter(function (contexts) {
121
+ return contexts.contains(ctx);
122
+ }).length > 0;
123
+
124
+ if (filteredCtx.indexOf(ctx) === -1 && !isDescendant) {
125
+ filteredCtx.push(ctx);
126
+ }
127
+ });
128
+ return filteredCtx;
129
+ },
130
+ },
131
+ {
132
+ key: 'getIframeContents',
133
+ value: function getIframeContents(ifr, successFn) {
134
+ var errorFn =
135
+ arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
136
+ var doc;
137
+
138
+ try {
139
+ var ifrWin = ifr.contentWindow;
140
+ doc = ifrWin.document;
141
+
142
+ if (!ifrWin || !doc) {
143
+ throw new Error('iframe inaccessible');
144
+ }
145
+ } catch (e) {
146
+ errorFn();
147
+ }
148
+
149
+ if (doc) {
150
+ successFn(doc);
151
+ }
152
+ },
153
+ },
154
+ {
155
+ key: 'isIframeBlank',
156
+ value: function isIframeBlank(ifr) {
157
+ var bl = 'about:blank',
158
+ src = ifr.getAttribute('src').trim(),
159
+ href = ifr.contentWindow.location.href;
160
+ return href === bl && src !== bl && src;
161
+ },
162
+ },
163
+ {
164
+ key: 'observeIframeLoad',
165
+ value: function observeIframeLoad(ifr, successFn, errorFn) {
166
+ var _this = this;
167
+
168
+ var called = false,
169
+ tout = null;
170
+
171
+ var listener = function listener() {
172
+ if (called) {
173
+ return;
174
+ }
175
+
176
+ called = true;
177
+ clearTimeout(tout);
178
+
179
+ try {
180
+ if (!_this.isIframeBlank(ifr)) {
181
+ ifr.removeEventListener('load', listener);
182
+
183
+ _this.getIframeContents(ifr, successFn, errorFn);
184
+ }
185
+ } catch (e) {
186
+ errorFn();
187
+ }
188
+ };
189
+
190
+ ifr.addEventListener('load', listener);
191
+ tout = setTimeout(listener, this.iframesTimeout);
192
+ },
193
+ },
194
+ {
195
+ key: 'onIframeReady',
196
+ value: function onIframeReady(ifr, successFn, errorFn) {
197
+ try {
198
+ if (ifr.contentWindow.document.readyState === 'complete') {
199
+ if (this.isIframeBlank(ifr)) {
200
+ this.observeIframeLoad(ifr, successFn, errorFn);
201
+ } else {
202
+ this.getIframeContents(ifr, successFn, errorFn);
203
+ }
204
+ } else {
205
+ this.observeIframeLoad(ifr, successFn, errorFn);
206
+ }
207
+ } catch (e) {
208
+ errorFn();
209
+ }
210
+ },
211
+ },
212
+ {
213
+ key: 'waitForIframes',
214
+ value: function waitForIframes(ctx, done) {
215
+ var _this2 = this;
216
+
217
+ var eachCalled = 0;
218
+ this.forEachIframe(
219
+ ctx,
220
+ function () {
221
+ return true;
222
+ },
223
+ function (ifr) {
224
+ eachCalled++;
225
+
226
+ _this2.waitForIframes(ifr.querySelector('html'), function () {
227
+ if (!--eachCalled) {
228
+ done();
229
+ }
230
+ });
231
+ },
232
+ function (handled) {
233
+ if (!handled) {
234
+ done();
235
+ }
236
+ }
237
+ );
238
+ },
239
+ },
240
+ {
241
+ key: 'forEachIframe',
242
+ value: function forEachIframe(ctx, filter, each) {
243
+ var _this3 = this;
244
+
245
+ var end =
246
+ arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {};
247
+ var ifr = ctx.querySelectorAll('iframe'),
248
+ open = ifr.length,
249
+ handled = 0;
250
+ ifr = Array.prototype.slice.call(ifr);
251
+
252
+ var checkEnd = function checkEnd() {
253
+ if (--open <= 0) {
254
+ end(handled);
255
+ }
256
+ };
257
+
258
+ if (!open) {
259
+ checkEnd();
260
+ }
261
+
262
+ ifr.forEach(function (ifr) {
263
+ if (DOMIterator.matches(ifr, _this3.exclude)) {
264
+ checkEnd();
265
+ } else {
266
+ _this3.onIframeReady(
267
+ ifr,
268
+ function (con) {
269
+ if (filter(ifr)) {
270
+ handled++;
271
+ each(con);
272
+ }
273
+
274
+ checkEnd();
275
+ },
276
+ checkEnd
277
+ );
278
+ }
279
+ });
280
+ },
281
+ },
282
+ {
283
+ key: 'createIterator',
284
+ value: function createIterator(ctx, whatToShow, filter) {
285
+ return document.createNodeIterator(ctx, whatToShow, filter, false);
286
+ },
287
+ },
288
+ {
289
+ key: 'createInstanceOnIframe',
290
+ value: function createInstanceOnIframe(contents) {
291
+ return new DOMIterator(contents.querySelector('html'), this.iframes);
292
+ },
293
+ },
294
+ {
295
+ key: 'compareNodeIframe',
296
+ value: function compareNodeIframe(node, prevNode, ifr) {
297
+ var compCurr = node.compareDocumentPosition(ifr),
298
+ prev = Node.DOCUMENT_POSITION_PRECEDING;
299
+
300
+ if (compCurr & prev) {
301
+ if (prevNode !== null) {
302
+ var compPrev = prevNode.compareDocumentPosition(ifr),
303
+ after = Node.DOCUMENT_POSITION_FOLLOWING;
304
+
305
+ if (compPrev & after) {
306
+ return true;
307
+ }
308
+ } else {
309
+ return true;
310
+ }
311
+ }
312
+
313
+ return false;
314
+ },
315
+ },
316
+ {
317
+ key: 'getIteratorNode',
318
+ value: function getIteratorNode(itr) {
319
+ var prevNode = itr.previousNode();
320
+ var node;
321
+
322
+ if (prevNode === null) {
323
+ node = itr.nextNode();
324
+ } else {
325
+ node = itr.nextNode() && itr.nextNode();
326
+ }
327
+
328
+ return {
329
+ prevNode: prevNode,
330
+ node: node,
331
+ };
332
+ },
333
+ },
334
+ {
335
+ key: 'checkIframeFilter',
336
+ value: function checkIframeFilter(node, prevNode, currIfr, ifr) {
337
+ var key = false,
338
+ handled = false;
339
+ ifr.forEach(function (ifrDict, i) {
340
+ if (ifrDict.val === currIfr) {
341
+ key = i;
342
+ handled = ifrDict.handled;
343
+ }
344
+ });
345
+
346
+ if (this.compareNodeIframe(node, prevNode, currIfr)) {
347
+ if (key === false && !handled) {
348
+ ifr.push({
349
+ val: currIfr,
350
+ handled: true,
351
+ });
352
+ } else if (key !== false && !handled) {
353
+ ifr[key].handled = true;
354
+ }
355
+
356
+ return true;
357
+ }
358
+
359
+ if (key === false) {
360
+ ifr.push({
361
+ val: currIfr,
362
+ handled: false,
363
+ });
364
+ }
365
+
366
+ return false;
367
+ },
368
+ },
369
+ {
370
+ key: 'handleOpenIframes',
371
+ value: function handleOpenIframes(ifr, whatToShow, eCb, fCb) {
372
+ var _this4 = this;
373
+
374
+ ifr.forEach(function (ifrDict) {
375
+ if (!ifrDict.handled) {
376
+ _this4.getIframeContents(ifrDict.val, function (con) {
377
+ _this4.createInstanceOnIframe(con).forEachNode(whatToShow, eCb, fCb);
378
+ });
379
+ }
380
+ });
381
+ },
382
+ },
383
+ {
384
+ key: 'iterateThroughNodes',
385
+ value: function iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) {
386
+ var _this5 = this;
387
+
388
+ var itr = this.createIterator(ctx, whatToShow, filterCb);
389
+
390
+ var ifr = [],
391
+ elements = [],
392
+ node,
393
+ prevNode,
394
+ retrieveNodes = function retrieveNodes() {
395
+ var _this5$getIteratorNod = _this5.getIteratorNode(itr);
396
+
397
+ prevNode = _this5$getIteratorNod.prevNode;
398
+ node = _this5$getIteratorNod.node;
399
+ return node;
400
+ };
401
+
402
+ while (retrieveNodes()) {
403
+ if (this.iframes) {
404
+ this.forEachIframe(
405
+ ctx,
406
+ function (currIfr) {
407
+ return _this5.checkIframeFilter(node, prevNode, currIfr, ifr);
408
+ },
409
+ function (con) {
410
+ _this5.createInstanceOnIframe(con).forEachNode(
411
+ whatToShow,
412
+ function (ifrNode) {
413
+ return elements.push(ifrNode);
414
+ },
415
+ filterCb
416
+ );
417
+ }
418
+ );
419
+ }
420
+
421
+ elements.push(node);
422
+ }
423
+
424
+ elements.forEach(function (node) {
425
+ eachCb(node);
426
+ });
427
+
428
+ if (this.iframes) {
429
+ this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb);
430
+ }
431
+
432
+ doneCb();
433
+ },
434
+ },
435
+ {
436
+ key: 'forEachNode',
437
+ value: function forEachNode(whatToShow, each, filter) {
438
+ var _this6 = this;
439
+
440
+ var done =
441
+ arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {};
442
+ var contexts = this.getContexts();
443
+ var open = contexts.length;
444
+
445
+ if (!open) {
446
+ done();
447
+ }
448
+
449
+ contexts.forEach(function (ctx) {
450
+ var ready = function ready() {
451
+ _this6.iterateThroughNodes(whatToShow, ctx, each, filter, function () {
452
+ if (--open <= 0) {
453
+ done();
454
+ }
455
+ });
456
+ };
457
+
458
+ if (_this6.iframes) {
459
+ _this6.waitForIframes(ctx, ready);
460
+ } else {
461
+ ready();
462
+ }
463
+ });
464
+ },
465
+ },
466
+ ],
467
+ [
468
+ {
469
+ key: 'matches',
470
+ value: function matches(element, selector) {
471
+ var selectors = typeof selector === 'string' ? [selector] : selector,
472
+ fn =
473
+ element.matches ||
474
+ element.matchesSelector ||
475
+ element.msMatchesSelector ||
476
+ element.mozMatchesSelector ||
477
+ element.oMatchesSelector ||
478
+ element.webkitMatchesSelector;
479
+
480
+ if (fn) {
481
+ var match = false;
482
+ selectors.every(function (sel) {
483
+ if (fn.call(element, sel)) {
484
+ match = true;
485
+ return false;
486
+ }
487
+
488
+ return true;
489
+ });
490
+ return match;
491
+ } else {
492
+ return false;
493
+ }
494
+ },
495
+ },
496
+ ]
497
+ );
498
+
499
+ return DOMIterator;
500
+ })();
501
+
502
+ var RegExpCreator =
503
+ /*#__PURE__*/
504
+ (function () {
505
+ function RegExpCreator(options) {
506
+ _classCallCheck(this, RegExpCreator);
507
+
508
+ this.opt = _extends(
509
+ {},
510
+ {
511
+ diacritics: true,
512
+ synonyms: {},
513
+ accuracy: 'partially',
514
+ caseSensitive: false,
515
+ ignoreJoiners: false,
516
+ ignorePunctuation: [],
517
+ wildcards: 'disabled',
518
+ },
519
+ options
520
+ );
521
+ }
522
+
523
+ _createClass(RegExpCreator, [
524
+ {
525
+ key: 'create',
526
+ value: function create(str) {
527
+ if (this.opt.wildcards !== 'disabled') {
528
+ str = this.setupWildcardsRegExp(str);
529
+ }
530
+
531
+ str = this.escapeStr(str);
532
+
533
+ if (Object.keys(this.opt.synonyms).length) {
534
+ str = this.createSynonymsRegExp(str);
535
+ }
536
+
537
+ if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
538
+ str = this.setupIgnoreJoinersRegExp(str);
539
+ }
540
+
541
+ if (this.opt.diacritics) {
542
+ str = this.createDiacriticsRegExp(str);
543
+ }
544
+
545
+ str = this.createMergedBlanksRegExp(str);
546
+
547
+ if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
548
+ str = this.createJoinersRegExp(str);
549
+ }
550
+
551
+ if (this.opt.wildcards !== 'disabled') {
552
+ str = this.createWildcardsRegExp(str);
553
+ }
554
+
555
+ str = this.createAccuracyRegExp(str);
556
+ return new RegExp(str, 'gm'.concat(this.opt.caseSensitive ? '' : 'i'));
557
+ },
558
+ },
559
+ {
560
+ key: 'sortByLength',
561
+ value: function sortByLength(arry) {
562
+ return arry.sort(function (a, b) {
563
+ return a.length === b.length ? (a > b ? 1 : -1) : b.length - a.length;
564
+ });
565
+ },
566
+ },
567
+ {
568
+ key: 'escapeStr',
569
+ value: function escapeStr(str) {
570
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
571
+ },
572
+ },
573
+ {
574
+ key: 'createSynonymsRegExp',
575
+ value: function createSynonymsRegExp(str) {
576
+ var _this = this;
577
+
578
+ var syn = this.opt.synonyms,
579
+ sens = this.opt.caseSensitive ? '' : 'i',
580
+ joinerPlaceholder = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? '\0' : '';
581
+
582
+ for (var index in syn) {
583
+ if (syn.hasOwnProperty(index)) {
584
+ var keys = Array.isArray(syn[index]) ? syn[index] : [syn[index]];
585
+ keys.unshift(index);
586
+ keys = this.sortByLength(keys)
587
+ .map(function (key) {
588
+ if (_this.opt.wildcards !== 'disabled') {
589
+ key = _this.setupWildcardsRegExp(key);
590
+ }
591
+
592
+ key = _this.escapeStr(key);
593
+ return key;
594
+ })
595
+ .filter(function (k) {
596
+ return k !== '';
597
+ });
598
+
599
+ if (keys.length > 1) {
600
+ str = str.replace(
601
+ new RegExp(
602
+ '('.concat(
603
+ keys
604
+ .map(function (k) {
605
+ return _this.escapeStr(k);
606
+ })
607
+ .join('|'),
608
+ ')'
609
+ ),
610
+ 'gm'.concat(sens)
611
+ ),
612
+ joinerPlaceholder +
613
+ '('.concat(
614
+ keys
615
+ .map(function (k) {
616
+ return _this.processSynonyms(k);
617
+ })
618
+ .join('|'),
619
+ ')'
620
+ ) +
621
+ joinerPlaceholder
622
+ );
623
+ }
624
+ }
625
+ }
626
+
627
+ return str;
628
+ },
629
+ },
630
+ {
631
+ key: 'processSynonyms',
632
+ value: function processSynonyms(str) {
633
+ if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
634
+ str = this.setupIgnoreJoinersRegExp(str);
635
+ }
636
+
637
+ return str;
638
+ },
639
+ },
640
+ {
641
+ key: 'setupWildcardsRegExp',
642
+ value: function setupWildcardsRegExp(str) {
643
+ str = str.replace(/(?:\\)*\?/g, function (val) {
644
+ return val.charAt(0) === '\\' ? '?' : '\x01';
645
+ });
646
+ return str.replace(/(?:\\)*\*/g, function (val) {
647
+ return val.charAt(0) === '\\' ? '*' : '\x02';
648
+ });
649
+ },
650
+ },
651
+ {
652
+ key: 'createWildcardsRegExp',
653
+ value: function createWildcardsRegExp(str) {
654
+ var spaces = this.opt.wildcards === 'withSpaces';
655
+ return str
656
+ .replace(/\u0001/g, spaces ? '[\\S\\s]?' : '\\S?')
657
+ .replace(/\u0002/g, spaces ? '[\\S\\s]*?' : '\\S*');
658
+ },
659
+ },
660
+ {
661
+ key: 'setupIgnoreJoinersRegExp',
662
+ value: function setupIgnoreJoinersRegExp(str) {
663
+ return str.replace(/[^(|)\\]/g, function (val, indx, original) {
664
+ var nextChar = original.charAt(indx + 1);
665
+
666
+ if (/[(|)\\]/.test(nextChar) || nextChar === '') {
667
+ return val;
668
+ } else {
669
+ return val + '\0';
670
+ }
671
+ });
672
+ },
673
+ },
674
+ {
675
+ key: 'createJoinersRegExp',
676
+ value: function createJoinersRegExp(str) {
677
+ var joiner = [];
678
+ var ignorePunctuation = this.opt.ignorePunctuation;
679
+
680
+ if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) {
681
+ joiner.push(this.escapeStr(ignorePunctuation.join('')));
682
+ }
683
+
684
+ if (this.opt.ignoreJoiners) {
685
+ joiner.push('\\u00ad\\u200b\\u200c\\u200d');
686
+ }
687
+
688
+ return joiner.length ? str.split(/\u0000+/).join('['.concat(joiner.join(''), ']*')) : str;
689
+ },
690
+ },
691
+ {
692
+ key: 'createDiacriticsRegExp',
693
+ value: function createDiacriticsRegExp(str) {
694
+ var sens = this.opt.caseSensitive ? '' : 'i',
695
+ dct = this.opt.caseSensitive
696
+ ? [
697
+ 'aàáảãạăằắẳẵặâầấẩẫậäåāą',
698
+ 'AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',
699
+ 'cçćč',
700
+ 'CÇĆČ',
701
+ 'dđď',
702
+ 'DĐĎ',
703
+ 'eèéẻẽẹêềếểễệëěēę',
704
+ 'EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',
705
+ 'iìíỉĩịîïī',
706
+ 'IÌÍỈĨỊÎÏĪ',
707
+ 'lł',
708
+ 'LŁ',
709
+ 'nñňń',
710
+ 'NÑŇŃ',
711
+ 'oòóỏõọôồốổỗộơởỡớờợöøō',
712
+ 'OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',
713
+ 'rř',
714
+ 'RŘ',
715
+ 'sšśșş',
716
+ 'SŠŚȘŞ',
717
+ 'tťțţ',
718
+ 'TŤȚŢ',
719
+ 'uùúủũụưừứửữựûüůū',
720
+ 'UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',
721
+ 'yýỳỷỹỵÿ',
722
+ 'YÝỲỶỸỴŸ',
723
+ 'zžżź',
724
+ 'ZŽŻŹ',
725
+ ]
726
+ : [
727
+ 'aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',
728
+ 'cçćčCÇĆČ',
729
+ 'dđďDĐĎ',
730
+ 'eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',
731
+ 'iìíỉĩịîïīIÌÍỈĨỊÎÏĪ',
732
+ 'lłLŁ',
733
+ 'nñňńNÑŇŃ',
734
+ 'oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',
735
+ 'rřRŘ',
736
+ 'sšśșşSŠŚȘŞ',
737
+ 'tťțţTŤȚŢ',
738
+ 'uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',
739
+ 'yýỳỷỹỵÿYÝỲỶỸỴŸ',
740
+ 'zžżźZŽŻŹ',
741
+ ];
742
+ var handled = [];
743
+ str.split('').forEach(function (ch) {
744
+ dct.every(function (dct) {
745
+ if (dct.indexOf(ch) !== -1) {
746
+ if (handled.indexOf(dct) > -1) {
747
+ return false;
748
+ }
749
+
750
+ str = str.replace(
751
+ new RegExp('['.concat(dct, ']'), 'gm'.concat(sens)),
752
+ '['.concat(dct, ']')
753
+ );
754
+ handled.push(dct);
755
+ }
756
+
757
+ return true;
758
+ });
759
+ });
760
+ return str;
761
+ },
762
+ },
763
+ {
764
+ key: 'createMergedBlanksRegExp',
765
+ value: function createMergedBlanksRegExp(str) {
766
+ return str.replace(/[\s]+/gim, '[\\s]+');
767
+ },
768
+ },
769
+ {
770
+ key: 'createAccuracyRegExp',
771
+ value: function createAccuracyRegExp(str) {
772
+ var _this2 = this;
773
+
774
+ var chars = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~¡¿';
775
+ var acc = this.opt.accuracy,
776
+ val = typeof acc === 'string' ? acc : acc.value,
777
+ ls = typeof acc === 'string' ? [] : acc.limiters,
778
+ lsJoin = '';
779
+ ls.forEach(function (limiter) {
780
+ lsJoin += '|'.concat(_this2.escapeStr(limiter));
781
+ });
782
+
783
+ switch (val) {
784
+ case 'partially':
785
+ default:
786
+ return '()('.concat(str, ')');
787
+
788
+ case 'complementary':
789
+ lsJoin = '\\s' + (lsJoin ? lsJoin : this.escapeStr(chars));
790
+ return '()([^'.concat(lsJoin, ']*').concat(str, '[^').concat(lsJoin, ']*)');
791
+
792
+ case 'exactly':
793
+ return '(^|\\s'.concat(lsJoin, ')(').concat(str, ')(?=$|\\s').concat(lsJoin, ')');
794
+ }
795
+ },
796
+ },
797
+ ]);
798
+
799
+ return RegExpCreator;
800
+ })();
801
+
802
+ var Mark =
803
+ /*#__PURE__*/
804
+ (function () {
805
+ function Mark(ctx) {
806
+ _classCallCheck(this, Mark);
807
+
808
+ this.ctx = ctx;
809
+ this.ie = false;
810
+ var ua = window.navigator.userAgent;
811
+
812
+ if (ua.indexOf('MSIE') > -1 || ua.indexOf('Trident') > -1) {
813
+ this.ie = true;
814
+ }
815
+ }
816
+
817
+ _createClass(Mark, [
818
+ {
819
+ key: 'log',
820
+ value: function log(msg) {
821
+ var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'debug';
822
+ var log = this.opt.log;
823
+
824
+ if (!this.opt.debug) {
825
+ return;
826
+ }
827
+
828
+ if (_typeof(log) === 'object' && typeof log[level] === 'function') {
829
+ log[level]('mark.js: '.concat(msg));
830
+ }
831
+ },
832
+ },
833
+ {
834
+ key: 'getSeparatedKeywords',
835
+ value: function getSeparatedKeywords(sv) {
836
+ var _this = this;
837
+
838
+ var stack = [];
839
+ sv.forEach(function (kw) {
840
+ if (!_this.opt.separateWordSearch) {
841
+ if (kw.trim() && stack.indexOf(kw) === -1) {
842
+ stack.push(kw);
843
+ }
844
+ } else {
845
+ kw.split(' ').forEach(function (kwSplitted) {
846
+ if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) {
847
+ stack.push(kwSplitted);
848
+ }
849
+ });
850
+ }
851
+ });
852
+ return {
853
+ keywords: stack.sort(function (a, b) {
854
+ return b.length - a.length;
855
+ }),
856
+ length: stack.length,
857
+ };
858
+ },
859
+ },
860
+ {
861
+ key: 'isNumeric',
862
+ value: function isNumeric(value) {
863
+ return Number(parseFloat(value)) == value;
864
+ },
865
+ },
866
+ {
867
+ key: 'checkRanges',
868
+ value: function checkRanges(array) {
869
+ var _this2 = this;
870
+
871
+ if (!Array.isArray(array) || Object.prototype.toString.call(array[0]) !== '[object Object]') {
872
+ this.log('markRanges() will only accept an array of objects');
873
+ this.opt.noMatch(array);
874
+ return [];
875
+ }
876
+
877
+ var stack = [];
878
+ var last = 0;
879
+ array
880
+ .sort(function (a, b) {
881
+ return a.start - b.start;
882
+ })
883
+ .forEach(function (item) {
884
+ var _this2$callNoMatchOnI = _this2.callNoMatchOnInvalidRanges(item, last),
885
+ start = _this2$callNoMatchOnI.start,
886
+ end = _this2$callNoMatchOnI.end,
887
+ valid = _this2$callNoMatchOnI.valid;
888
+
889
+ if (valid) {
890
+ item.start = start;
891
+ item.length = end - start;
892
+ stack.push(item);
893
+ last = end;
894
+ }
895
+ });
896
+ return stack;
897
+ },
898
+ },
899
+ {
900
+ key: 'callNoMatchOnInvalidRanges',
901
+ value: function callNoMatchOnInvalidRanges(range, last) {
902
+ var start,
903
+ end,
904
+ valid = false;
905
+
906
+ if (range && typeof range.start !== 'undefined') {
907
+ start = parseInt(range.start, 10);
908
+ end = start + parseInt(range.length, 10);
909
+
910
+ if (
911
+ this.isNumeric(range.start) &&
912
+ this.isNumeric(range.length) &&
913
+ end - last > 0 &&
914
+ end - start > 0
915
+ ) {
916
+ valid = true;
917
+ } else {
918
+ this.log('Ignoring invalid or overlapping range: ' + ''.concat(JSON.stringify(range)));
919
+ this.opt.noMatch(range);
920
+ }
921
+ } else {
922
+ this.log('Ignoring invalid range: '.concat(JSON.stringify(range)));
923
+ this.opt.noMatch(range);
924
+ }
925
+
926
+ return {
927
+ start: start,
928
+ end: end,
929
+ valid: valid,
930
+ };
931
+ },
932
+ },
933
+ {
934
+ key: 'checkWhitespaceRanges',
935
+ value: function checkWhitespaceRanges(range, originalLength, string) {
936
+ var end,
937
+ valid = true,
938
+ max = string.length,
939
+ offset = originalLength - max,
940
+ start = parseInt(range.start, 10) - offset;
941
+ start = start > max ? max : start;
942
+ end = start + parseInt(range.length, 10);
943
+
944
+ if (end > max) {
945
+ end = max;
946
+ this.log('End range automatically set to the max value of '.concat(max));
947
+ }
948
+
949
+ if (start < 0 || end - start < 0 || start > max || end > max) {
950
+ valid = false;
951
+ this.log('Invalid range: '.concat(JSON.stringify(range)));
952
+ this.opt.noMatch(range);
953
+ } else if (string.substring(start, end).replace(/\s+/g, '') === '') {
954
+ valid = false;
955
+ this.log('Skipping whitespace only range: ' + JSON.stringify(range));
956
+ this.opt.noMatch(range);
957
+ }
958
+
959
+ return {
960
+ start: start,
961
+ end: end,
962
+ valid: valid,
963
+ };
964
+ },
965
+ },
966
+ {
967
+ key: 'getTextNodes',
968
+ value: function getTextNodes(cb) {
969
+ var _this3 = this;
970
+
971
+ var val = '',
972
+ nodes = [];
973
+ this.iterator.forEachNode(
974
+ NodeFilter.SHOW_TEXT,
975
+ function (node) {
976
+ nodes.push({
977
+ start: val.length,
978
+ end: (val += node.textContent).length,
979
+ node: node,
980
+ });
981
+ },
982
+ function (node) {
983
+ if (_this3.matchesExclude(node.parentNode)) {
984
+ return NodeFilter.FILTER_REJECT;
985
+ } else {
986
+ return NodeFilter.FILTER_ACCEPT;
987
+ }
988
+ },
989
+ function () {
990
+ cb({
991
+ value: val,
992
+ nodes: nodes,
993
+ });
994
+ }
995
+ );
996
+ },
997
+ },
998
+ {
999
+ key: 'matchesExclude',
1000
+ value: function matchesExclude(el) {
1001
+ return DOMIterator.matches(
1002
+ el,
1003
+ this.opt.exclude.concat(['script', 'style', 'title', 'head', 'html'])
1004
+ );
1005
+ },
1006
+ },
1007
+ {
1008
+ key: 'wrapRangeInTextNode',
1009
+ value: function wrapRangeInTextNode(node, start, end) {
1010
+ var hEl = !this.opt.element ? 'mark' : this.opt.element,
1011
+ startNode = node.splitText(start),
1012
+ ret = startNode.splitText(end - start);
1013
+ var repl = document.createElement(hEl);
1014
+ repl.setAttribute('data-markjs', 'true');
1015
+
1016
+ if (this.opt.className) {
1017
+ repl.setAttribute('class', this.opt.className);
1018
+ }
1019
+
1020
+ repl.textContent = startNode.textContent;
1021
+ startNode.parentNode.replaceChild(repl, startNode);
1022
+ return ret;
1023
+ },
1024
+ },
1025
+ {
1026
+ key: 'wrapRangeInMappedTextNode',
1027
+ value: function wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) {
1028
+ var _this4 = this;
1029
+
1030
+ dict.nodes.every(function (n, i) {
1031
+ var sibl = dict.nodes[i + 1];
1032
+
1033
+ if (typeof sibl === 'undefined' || sibl.start > start) {
1034
+ if (!filterCb(n.node)) {
1035
+ return false;
1036
+ }
1037
+
1038
+ var s = start - n.start,
1039
+ e = (end > n.end ? n.end : end) - n.start,
1040
+ startStr = dict.value.substr(0, n.start),
1041
+ endStr = dict.value.substr(e + n.start);
1042
+ n.node = _this4.wrapRangeInTextNode(n.node, s, e);
1043
+ dict.value = startStr + endStr;
1044
+ dict.nodes.forEach(function (k, j) {
1045
+ if (j >= i) {
1046
+ if (dict.nodes[j].start > 0 && j !== i) {
1047
+ dict.nodes[j].start -= e;
1048
+ }
1049
+
1050
+ dict.nodes[j].end -= e;
1051
+ }
1052
+ });
1053
+ end -= e;
1054
+ eachCb(n.node.previousSibling, n.start);
1055
+
1056
+ if (end > n.end) {
1057
+ start = n.end;
1058
+ } else {
1059
+ return false;
1060
+ }
1061
+ }
1062
+
1063
+ return true;
1064
+ });
1065
+ },
1066
+ },
1067
+ {
1068
+ key: 'wrapGroups',
1069
+ value: function wrapGroups(node, pos, len, eachCb) {
1070
+ node = this.wrapRangeInTextNode(node, pos, pos + len);
1071
+ eachCb(node.previousSibling);
1072
+ return node;
1073
+ },
1074
+ },
1075
+ {
1076
+ key: 'separateGroups',
1077
+ value: function separateGroups(node, match, matchIdx, filterCb, eachCb) {
1078
+ var matchLen = match.length;
1079
+
1080
+ for (var i = 1; i < matchLen; i++) {
1081
+ var pos = node.textContent.indexOf(match[i]);
1082
+
1083
+ if (match[i] && pos > -1 && filterCb(match[i], node)) {
1084
+ node = this.wrapGroups(node, pos, match[i].length, eachCb);
1085
+ }
1086
+ }
1087
+
1088
+ return node;
1089
+ },
1090
+ },
1091
+ {
1092
+ key: 'wrapMatches',
1093
+ value: function wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) {
1094
+ var _this5 = this;
1095
+
1096
+ var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
1097
+ this.getTextNodes(function (dict) {
1098
+ dict.nodes.forEach(function (node) {
1099
+ node = node.node;
1100
+ var match;
1101
+
1102
+ while ((match = regex.exec(node.textContent)) !== null && match[matchIdx] !== '') {
1103
+ if (_this5.opt.separateGroups) {
1104
+ node = _this5.separateGroups(node, match, matchIdx, filterCb, eachCb);
1105
+ } else {
1106
+ if (!filterCb(match[matchIdx], node)) {
1107
+ continue;
1108
+ }
1109
+
1110
+ var pos = match.index;
1111
+
1112
+ if (matchIdx !== 0) {
1113
+ for (var i = 1; i < matchIdx; i++) {
1114
+ pos += match[i].length;
1115
+ }
1116
+ }
1117
+
1118
+ node = _this5.wrapGroups(node, pos, match[matchIdx].length, eachCb);
1119
+ }
1120
+
1121
+ regex.lastIndex = 0;
1122
+ }
1123
+ });
1124
+ endCb();
1125
+ });
1126
+ },
1127
+ },
1128
+ {
1129
+ key: 'wrapMatchesAcrossElements',
1130
+ value: function wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) {
1131
+ var _this6 = this;
1132
+
1133
+ var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
1134
+ this.getTextNodes(function (dict) {
1135
+ var match;
1136
+
1137
+ while ((match = regex.exec(dict.value)) !== null && match[matchIdx] !== '') {
1138
+ var start = match.index;
1139
+
1140
+ if (matchIdx !== 0) {
1141
+ for (var i = 1; i < matchIdx; i++) {
1142
+ start += match[i].length;
1143
+ }
1144
+ }
1145
+
1146
+ var end = start + match[matchIdx].length;
1147
+
1148
+ _this6.wrapRangeInMappedTextNode(
1149
+ dict,
1150
+ start,
1151
+ end,
1152
+ function (node) {
1153
+ return filterCb(match[matchIdx], node);
1154
+ },
1155
+ function (node, lastIndex) {
1156
+ regex.lastIndex = lastIndex;
1157
+ eachCb(node);
1158
+ }
1159
+ );
1160
+ }
1161
+
1162
+ endCb();
1163
+ });
1164
+ },
1165
+ },
1166
+ {
1167
+ key: 'wrapRangeFromIndex',
1168
+ value: function wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) {
1169
+ var _this7 = this;
1170
+
1171
+ this.getTextNodes(function (dict) {
1172
+ var originalLength = dict.value.length;
1173
+ ranges.forEach(function (range, counter) {
1174
+ var _this7$checkWhitespac = _this7.checkWhitespaceRanges(
1175
+ range,
1176
+ originalLength,
1177
+ dict.value
1178
+ ),
1179
+ start = _this7$checkWhitespac.start,
1180
+ end = _this7$checkWhitespac.end,
1181
+ valid = _this7$checkWhitespac.valid;
1182
+
1183
+ if (valid) {
1184
+ _this7.wrapRangeInMappedTextNode(
1185
+ dict,
1186
+ start,
1187
+ end,
1188
+ function (node) {
1189
+ return filterCb(node, range, dict.value.substring(start, end), counter);
1190
+ },
1191
+ function (node) {
1192
+ eachCb(node, range);
1193
+ }
1194
+ );
1195
+ }
1196
+ });
1197
+ endCb();
1198
+ });
1199
+ },
1200
+ },
1201
+ {
1202
+ key: 'unwrapMatches',
1203
+ value: function unwrapMatches(node) {
1204
+ var parent = node.parentNode;
1205
+ var docFrag = document.createDocumentFragment();
1206
+
1207
+ while (node.firstChild) {
1208
+ docFrag.appendChild(node.removeChild(node.firstChild));
1209
+ }
1210
+
1211
+ parent.replaceChild(docFrag, node);
1212
+
1213
+ if (!this.ie) {
1214
+ parent.normalize();
1215
+ } else {
1216
+ this.normalizeTextNode(parent);
1217
+ }
1218
+ },
1219
+ },
1220
+ {
1221
+ key: 'normalizeTextNode',
1222
+ value: function normalizeTextNode(node) {
1223
+ if (!node) {
1224
+ return;
1225
+ }
1226
+
1227
+ if (node.nodeType === 3) {
1228
+ while (node.nextSibling && node.nextSibling.nodeType === 3) {
1229
+ node.nodeValue += node.nextSibling.nodeValue;
1230
+ node.parentNode.removeChild(node.nextSibling);
1231
+ }
1232
+ } else {
1233
+ this.normalizeTextNode(node.firstChild);
1234
+ }
1235
+
1236
+ this.normalizeTextNode(node.nextSibling);
1237
+ },
1238
+ },
1239
+ {
1240
+ key: 'markRegExp',
1241
+ value: function markRegExp(regexp, opt) {
1242
+ var _this8 = this;
1243
+
1244
+ this.opt = opt;
1245
+ this.log('Searching with expression "'.concat(regexp, '"'));
1246
+ var totalMatches = 0,
1247
+ fn = 'wrapMatches';
1248
+
1249
+ var eachCb = function eachCb(element) {
1250
+ totalMatches++;
1251
+
1252
+ _this8.opt.each(element);
1253
+ };
1254
+
1255
+ if (this.opt.acrossElements) {
1256
+ fn = 'wrapMatchesAcrossElements';
1257
+ }
1258
+
1259
+ this[fn](
1260
+ regexp,
1261
+ this.opt.ignoreGroups,
1262
+ function (match, node) {
1263
+ return _this8.opt.filter(node, match, totalMatches);
1264
+ },
1265
+ eachCb,
1266
+ function () {
1267
+ if (totalMatches === 0) {
1268
+ _this8.opt.noMatch(regexp);
1269
+ }
1270
+
1271
+ _this8.opt.done(totalMatches);
1272
+ }
1273
+ );
1274
+ },
1275
+ },
1276
+ {
1277
+ key: 'mark',
1278
+ value: function mark(sv, opt) {
1279
+ var _this9 = this;
1280
+
1281
+ this.opt = opt;
1282
+ var totalMatches = 0,
1283
+ fn = 'wrapMatches';
1284
+
1285
+ var _this$getSeparatedKey = this.getSeparatedKeywords(typeof sv === 'string' ? [sv] : sv),
1286
+ kwArr = _this$getSeparatedKey.keywords,
1287
+ kwArrLen = _this$getSeparatedKey.length,
1288
+ handler = function handler(kw) {
1289
+ var regex = new RegExpCreator(_this9.opt).create(kw);
1290
+ var matches = 0;
1291
+
1292
+ _this9.log('Searching with expression "'.concat(regex, '"'));
1293
+
1294
+ _this9[fn](
1295
+ regex,
1296
+ 1,
1297
+ function (term, node) {
1298
+ return _this9.opt.filter(node, kw, totalMatches, matches);
1299
+ },
1300
+ function (element) {
1301
+ matches++;
1302
+ totalMatches++;
1303
+
1304
+ _this9.opt.each(element);
1305
+ },
1306
+ function () {
1307
+ if (matches === 0) {
1308
+ _this9.opt.noMatch(kw);
1309
+ }
1310
+
1311
+ if (kwArr[kwArrLen - 1] === kw) {
1312
+ _this9.opt.done(totalMatches);
1313
+ } else {
1314
+ handler(kwArr[kwArr.indexOf(kw) + 1]);
1315
+ }
1316
+ }
1317
+ );
1318
+ };
1319
+
1320
+ if (this.opt.acrossElements) {
1321
+ fn = 'wrapMatchesAcrossElements';
1322
+ }
1323
+
1324
+ if (kwArrLen === 0) {
1325
+ this.opt.done(totalMatches);
1326
+ } else {
1327
+ handler(kwArr[0]);
1328
+ }
1329
+ },
1330
+ },
1331
+ {
1332
+ key: 'markRanges',
1333
+ value: function markRanges(rawRanges, opt) {
1334
+ var _this10 = this;
1335
+
1336
+ this.opt = opt;
1337
+ var totalMatches = 0,
1338
+ ranges = this.checkRanges(rawRanges);
1339
+
1340
+ if (ranges && ranges.length) {
1341
+ this.log('Starting to mark with the following ranges: ' + JSON.stringify(ranges));
1342
+ this.wrapRangeFromIndex(
1343
+ ranges,
1344
+ function (node, range, match, counter) {
1345
+ return _this10.opt.filter(node, range, match, counter);
1346
+ },
1347
+ function (element, range) {
1348
+ totalMatches++;
1349
+
1350
+ _this10.opt.each(element, range);
1351
+ },
1352
+ function () {
1353
+ _this10.opt.done(totalMatches);
1354
+ }
1355
+ );
1356
+ } else {
1357
+ this.opt.done(totalMatches);
1358
+ }
1359
+ },
1360
+ },
1361
+ {
1362
+ key: 'unmark',
1363
+ value: function unmark(opt) {
1364
+ var _this11 = this;
1365
+
1366
+ this.opt = opt;
1367
+ var sel = this.opt.element ? this.opt.element : '*';
1368
+ sel += '[data-markjs]';
1369
+
1370
+ if (this.opt.className) {
1371
+ sel += '.'.concat(this.opt.className);
1372
+ }
1373
+
1374
+ this.log('Removal selector "'.concat(sel, '"'));
1375
+ this.iterator.forEachNode(
1376
+ NodeFilter.SHOW_ELEMENT,
1377
+ function (node) {
1378
+ _this11.unwrapMatches(node);
1379
+ },
1380
+ function (node) {
1381
+ var matchesSel = DOMIterator.matches(node, sel),
1382
+ matchesExclude = _this11.matchesExclude(node);
1383
+
1384
+ if (!matchesSel || matchesExclude) {
1385
+ return NodeFilter.FILTER_REJECT;
1386
+ } else {
1387
+ return NodeFilter.FILTER_ACCEPT;
1388
+ }
1389
+ },
1390
+ this.opt.done
1391
+ );
1392
+ },
1393
+ },
1394
+ {
1395
+ key: 'opt',
1396
+ set: function set(val) {
1397
+ this._opt = _extends(
1398
+ {},
1399
+ {
1400
+ element: '',
1401
+ className: '',
1402
+ exclude: [],
1403
+ iframes: false,
1404
+ iframesTimeout: 5000,
1405
+ separateWordSearch: true,
1406
+ acrossElements: false,
1407
+ ignoreGroups: 0,
1408
+ each: function each() {},
1409
+ noMatch: function noMatch() {},
1410
+ filter: function filter() {
1411
+ return true;
1412
+ },
1413
+ done: function done() {},
1414
+ debug: false,
1415
+ log: window.console,
1416
+ },
1417
+ val
1418
+ );
1419
+ },
1420
+ get: function get() {
1421
+ return this._opt;
1422
+ },
1423
+ },
1424
+ {
1425
+ key: 'iterator',
1426
+ get: function get() {
1427
+ return new DOMIterator(this.ctx, this.opt.iframes, this.opt.exclude, this.opt.iframesTimeout);
1428
+ },
1429
+ },
1430
+ ]);
1431
+
1432
+ return Mark;
1433
+ })();
1434
+
1435
+ function Mark$1(ctx) {
1436
+ var _this = this;
1437
+
1438
+ var instance = new Mark(ctx);
1439
+
1440
+ this.mark = function (sv, opt) {
1441
+ instance.mark(sv, opt);
1442
+ return _this;
1443
+ };
1444
+
1445
+ this.markRegExp = function (sv, opt) {
1446
+ instance.markRegExp(sv, opt);
1447
+ return _this;
1448
+ };
1449
+
1450
+ this.markRanges = function (sv, opt) {
1451
+ instance.markRanges(sv, opt);
1452
+ return _this;
1453
+ };
1454
+
1455
+ this.unmark = function (opt) {
1456
+ instance.unmark(opt);
1457
+ return _this;
1458
+ };
1459
+
1460
+ return this;
1461
+ }
1462
+
1463
+ return Mark$1;
1464
+ });
libs/mod3d.js ADDED
@@ -0,0 +1,2520 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Real3D FlipBook [https://real3dflipbook.com]
3
+ * @author creativeinteractivemedia [https://codecanyon.net/user/creativeinteractivemedia/portfolio]
4
+ * @version 4.10
5
+ * @date 2025-05-15
6
+ */
7
+ /**
8
+ * MOD3 3D Modifier Library for JavaScript
9
+ * port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/)
10
+ *
11
+ * @version 1.0.0 (2023-01-03 16:08:34)
12
+ * https://github.com/foo123/MOD3
13
+ *
14
+ **//**
15
+ * MOD3 3D Modifier Library for JavaScript
16
+ * port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/)
17
+ *
18
+ * @version 1.0.0 (2023-01-03 16:08:34)
19
+ * https://github.com/foo123/MOD3
20
+ *
21
+ **/
22
+ !function(root, name, factory) {
23
+ "use strict";
24
+ if (('object' === typeof module) && module.exports) /* CommonJS */
25
+ (module.$deps = module.$deps||{}) && (module.exports = module.$deps[name] = factory.call(root));
26
+ else if (('function' === typeof define) && define.amd && ('function' === typeof require) && ('function' === typeof require.specified) && require.specified(name) /*&& !require.defined(name)*/) /* AMD */
27
+ define(name, ['module'], function(module) {factory.moduleUri = module.uri; return factory.call(root);});
28
+ else if (!(name in root)) /* Browser/WebWorker/.. */
29
+ (root[name] = factory.call(root)||1) && ('function' === typeof(define)) && define.amd && define(function() {return root[name];});
30
+ }( /* current root */ 'undefined' !== typeof self ? self : this,
31
+ /* module name */ "MOD3",
32
+ /* module factory */ function ModuleFactory__MOD3(undef) {
33
+ "use strict";
34
+
35
+ var HAS = Object.prototype.hasOwnProperty,
36
+ toString = Object.prototype.toString,
37
+ def = Object.defineProperty,
38
+ stdMath = Math, PI = stdMath.PI,
39
+ TWO_PI = 2*PI, HALF_PI = PI/2, INV_PI = 1/PI,
40
+ EMPTY_ARR = [], EMPTY_OBJ = {}, NOP = function() {},
41
+ isNode = ("undefined" !== typeof global) && ("[object global]" === toString.call(global)),
42
+ isBrowser = ("undefined" !== typeof window) && ("[object Window]" === toString.call(window))
43
+ ;
44
+
45
+ // basic backwards-compatible "class" construction
46
+ function makeSuper(superklass)
47
+ {
48
+ var called = {};
49
+ return function $super(method, args) {
50
+ var self = this, m = ':'+method, ret;
51
+ if (1 === called[m]) return (superklass.prototype.$super || NOP).call(self, method, args);
52
+ called[m] = 1;
53
+ ret = ('constructor' === method ? superklass : (superklass.prototype[method] || NOP)).apply(self, args || []);
54
+ called[m] = 0;
55
+ return ret;
56
+ };
57
+ }
58
+ function makeClass(superklass, klass, statik)
59
+ {
60
+ if (arguments.length < 2)
61
+ {
62
+ klass = superklass;
63
+ superklass = null;
64
+ }
65
+ var C = HAS.call(klass, 'constructor') ? klass.constructor : function() {}, p;
66
+ if (superklass)
67
+ {
68
+ C.prototype = Object.create(superklass.prototype);
69
+ C.prototype.$super = makeSuper(superklass);
70
+ }
71
+ else
72
+ {
73
+ C.prototype.$super = NOP;
74
+ }
75
+ C.prototype.constructor = C;
76
+ for (p in klass)
77
+ {
78
+ if (HAS.call(klass, p) && ('constructor' !== p))
79
+ {
80
+ C.prototype[p] = klass[p];
81
+ }
82
+ }
83
+ if (statik)
84
+ {
85
+ for (p in statik)
86
+ {
87
+ if (HAS.call(statik, p))
88
+ {
89
+ C[p] = statik[p];
90
+ }
91
+ }
92
+ }
93
+ return C;
94
+ }
95
+ var MOD3 = {
96
+ VERSION: "1.0.0",
97
+ Class: makeClass
98
+ };
99
+ /**
100
+ * MOD3 Constants and Auxilliary methods
101
+ **/
102
+ MOD3.Constants = {
103
+ // cache math constants for reference and optimization
104
+ PI: PI,
105
+ invPI: INV_PI,
106
+ halfPI: HALF_PI,
107
+ doublePI: TWO_PI,
108
+ toRad: PI/180,
109
+ toDeg: 180/PI
110
+ };
111
+ MOD3.ModConstant = {
112
+ NONE: 0,
113
+ LEFT: -1,
114
+ RIGHT: 1,
115
+
116
+ X: 1,
117
+ Y: 2,
118
+ Z: 4,
119
+
120
+ Xi: 0,
121
+ Yi: 1,
122
+ Zi: 2
123
+ };
124
+ MOD3.XYZi = [
125
+ null,
126
+ 0,
127
+ 1,
128
+ null,
129
+ 2
130
+ ];
131
+ MOD3.iXYZ = [
132
+ 1,
133
+ 2,
134
+ 4
135
+ ];
136
+ MOD3.xyz = [
137
+ "x",
138
+ "y",
139
+ "z"
140
+ ];
141
+ MOD3.XYZ = [
142
+ "X",
143
+ "Y",
144
+ "Z"
145
+ ];
146
+
147
+ // Typed Arrays Substitutes
148
+ MOD3.Array32F = typeof Float32Array !== "undefined" ? Float32Array : Array;
149
+ MOD3.Array64F = typeof Float64Array !== "undefined" ? Float64Array : Array;
150
+ MOD3.Array8I = typeof Int8Array !== "undefined" ? Int8Array : Array;
151
+ MOD3.Array16I = typeof Int16Array !== "undefined" ? Int16Array : Array;
152
+ MOD3.Array32I = typeof Int32Array !== "undefined" ? Int32Array : Array;
153
+ MOD3.Array8U = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
154
+ MOD3.Array16U = typeof Uint16Array !== "undefined" ? Uint16Array : Array;
155
+ MOD3.Array32U = typeof Uint32Array !== "undefined" ? Uint32Array : Array;
156
+ // vector typed-array
157
+ MOD3.VecArray = MOD3.Array32F;
158
+ /**
159
+ * MOD3 Math Utilities Class
160
+ **/
161
+ MOD3.XMath = {
162
+ normalize: function(start, end, val) {
163
+ var range = end - start;
164
+ return 0 === range ? 1 : MOD3.XMath.trim(0, 1, (val - start)/end);
165
+ },
166
+
167
+ toRange: function(start, end, normalized) {
168
+ var range = end - start;
169
+ return 0 === range ? 0 : (start + range*normalized);
170
+ },
171
+
172
+ inRange: function(start, end, value, excluding) {
173
+ return false !== excluding ? (value >= start && value <= end) : (value > start && value < end);
174
+ },
175
+
176
+ sign: function(val, ifZero) {
177
+ return 0 === val ? (ifZero || 0) : (val > 0 ? 1 : -1);
178
+ },
179
+
180
+ trim: function(start, end, value) {
181
+ return value < start ? start : (value > end ? end : value);
182
+ },
183
+
184
+ wrap: function(start, end, value) {
185
+ var r = end - start;
186
+ return value < start ? (value + r) : (value >= end ? value - r : value);
187
+ },
188
+
189
+ degToRad: function(deg) {
190
+ return deg/180*PI;
191
+ },
192
+
193
+ radToDeg: function(rad) {
194
+ return rad/PI*180;
195
+ },
196
+
197
+ presicion: function(number, precision) {
198
+ var r = stdMath.pow(10, precision);
199
+ return stdMath.round(number*r)/r;
200
+ },
201
+
202
+ uceil: function(val) {
203
+ return val < 0 ? stdMath.floor(val) : stdMath.ceil(val);
204
+ }
205
+ };
206
+ // alias
207
+ MOD3.XMath.clamp = MOD3.XMath.trim;
208
+ /**
209
+ * MOD3 Range Auxilliary Class
210
+ **/
211
+ MOD3.Range = MOD3.Class({
212
+ constructor: function Range(s, e) {
213
+ var self = this;
214
+ if (!(self instanceof Range)) return new Range(s, e);
215
+ self.start = null != s ? s : 0;
216
+ self.end = null != e ? e : 1;
217
+ },
218
+
219
+ name: "Range",
220
+ start: 0,
221
+ end: 1,
222
+
223
+ dispose: function() {
224
+ var self = this;
225
+ self.start = null;
226
+ self.end = null;
227
+ return self;
228
+ },
229
+
230
+ getSize: function() {
231
+ return this.end - this.start;
232
+ },
233
+
234
+ move: function(amount) {
235
+ this.start += amount;
236
+ this.end += amount;
237
+ },
238
+
239
+ isIn: function(n) {
240
+ return (n >= this.start && n <= this.end);
241
+ },
242
+
243
+ normalize: function(n) {
244
+ return MOD3.XMath.normalize(this.start, this.end, n);
245
+ },
246
+
247
+ toRange: function(n) {
248
+ return MOD3.XMath.toRange(this.start, this.end, n);
249
+ },
250
+
251
+ trim: function(n) {
252
+ return MOD3.XMath.trim(this.start, this.end, n);
253
+ },
254
+
255
+ interpolate: function(n, r) {
256
+ return MOD3.XMath.toRange(this.start, this.end, r.normalize(n));
257
+ },
258
+
259
+ toString: function() {
260
+ return "[" + this.start + " - " + this.end + "]";
261
+ }
262
+ });
263
+ /**
264
+ * MOD3 Phase Auxilliary Class
265
+ **/
266
+ MOD3.Phase = MOD3.Class({
267
+ constructor: function Phase(v) {
268
+ var self = this;
269
+ if (!(self instanceof Phase)) return new Phase(v);
270
+ self.value = v || 0;
271
+ },
272
+
273
+ name: "Phase",
274
+ value: 0,
275
+
276
+ dispose: function() {
277
+ this.value = null;
278
+ return this;
279
+ },
280
+
281
+ getPhasedValue: function() {
282
+ return stdMath.sin(this.value);
283
+ },
284
+
285
+ getAbsPhasedValue: function() {
286
+ return stdMath.abs(stdMath.sin(this.value));
287
+ },
288
+
289
+ getNormValue: function() {
290
+ return (stdMath.sin(this.value) + 1)*0.5;
291
+ }
292
+ });
293
+ /**
294
+ * MOD3 2D Point Class
295
+ **/
296
+ MOD3.Point = MOD3.Class({
297
+ constructor: function Point(x, y) {
298
+ var self = this;
299
+ if (!(self instanceof Point)) return new Point(x, y);
300
+ self.x = x || 0;
301
+ self.y = y || 0;
302
+ },
303
+
304
+ name: "Point",
305
+ x: 0,
306
+ y: 0,
307
+
308
+ dispose: function() {
309
+ var self = this;
310
+ self.x = null;
311
+ self.y = null;
312
+ return self;
313
+ },
314
+
315
+ clone: function() {
316
+ return new MOD3.Point(this.x, this.y);
317
+ }
318
+ });
319
+ /**
320
+ * MOD3 2D Transform Matrix Class
321
+ **/
322
+ MOD3.Matrix = MOD3.Class(null, {
323
+ constructor: function Matrix(m11, m12,
324
+ m21, m22)
325
+ {
326
+ var self = this;
327
+ if (!(self instanceof Matrix)) return new Matrix(m11, m12,
328
+ m21, m22);
329
+ self.m = new MOD3.VecArray([
330
+ m11 == null ? 1 : m11,
331
+ m12 == null ? 0 : m12,
332
+ m21 == null ? 0 : m21,
333
+ m22 == null ? 1 : m22
334
+ ]);
335
+ },
336
+
337
+ name: "Matrix",
338
+ m: null,
339
+
340
+ dispose: function() {
341
+ this.m = null;
342
+ return this;
343
+ },
344
+
345
+ reset: function() {
346
+ var m = this.m;
347
+ m[0] = 1; m[1] = 0;
348
+ m[2] = 0; m[3] = 1;
349
+ return this;
350
+ },
351
+
352
+ rotate: function(angle) {
353
+ var m = this.m, c = stdMath.cos(angle), s = stdMath.sin(angle);
354
+ m[0] = c; m[1] = -s;
355
+ m[2] = s; m[3] = c;
356
+ return this;
357
+ },
358
+
359
+ scale: function(sx, sy) {
360
+ var m = this.m;
361
+ m[0] = 1; m[1] = 0;
362
+ m[2] = 0; m[3] = 1;
363
+ if (sx != null)
364
+ {
365
+ m[0] = sx;
366
+ m[3] = sx;
367
+ }
368
+ if (sy != null)
369
+ {
370
+ m[3] = sy;
371
+ }
372
+ return this;
373
+ },
374
+
375
+ multiply: function(b) {
376
+ return MOD3.Matrix.mult(this, b);
377
+ },
378
+
379
+ transformPoint: function(p) {
380
+ var xy = MOD3.Matrix.transform(this, [p.x, p.y]);
381
+ return new MOD3.Point(xy[0], xy[1]);
382
+ },
383
+
384
+ transformPointSelf: function(p) {
385
+ var xy = MOD3.Matrix.transform(this, [p.x, p.y]);
386
+ p.x = xy[0]; p.y = xy[1];
387
+ return p;
388
+ },
389
+
390
+ clone: function() {
391
+ var m = this.m;
392
+ return new MOD3.Matrix(m[0], m[1],
393
+ m[2], m[3]);
394
+ }
395
+ }, {
396
+ transform: function(m2, xy) {
397
+ var m = m2.m, x = xy[0], y = xy[1];
398
+ xy[0] = m[0]*x + m[1]*y;
399
+ xy[1] = m[2]*x + m[3]*y;
400
+ return xy;
401
+ },
402
+
403
+ mult: function(m1, m2) {
404
+ var a = m1.m, b = m2.m, a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
405
+ a[0] = a0*b[0] + a1*b[2];
406
+ a[1] = a0*b[1] + a1*b[3];
407
+ a[2] = a2*b[0] + a3*b[2];
408
+ a[3] = a2*b[1] + a3*b[3];
409
+ return m1;
410
+ }
411
+ });
412
+ /**
413
+ * MOD3 Vector3 Class
414
+ **/
415
+ MOD3.Vector3 = MOD3.Class(null, {
416
+ constructor: function Vector3(x, y, z) {
417
+ var self = this;
418
+ if (!(self instanceof Vector3)) return new Vector3(x, y, z);
419
+
420
+ // use an internal typed-array for speed
421
+ var v = new MOD3.VecArray(3);
422
+ if (x && (3 === x.length))
423
+ {
424
+ // array passed
425
+ v[0] = x[0] || 0;
426
+ v[1] = x[1] || 0;
427
+ v[2] = x[2] || 0;
428
+ }
429
+ else
430
+ {
431
+ // numbers passed
432
+ v[0] = x || 0;
433
+ v[1] = y || 0;
434
+ v[2] = z || 0;
435
+ }
436
+ self.xyz = v;
437
+ },
438
+
439
+ name: "Vector3",
440
+ xyz: null,
441
+
442
+ dispose: function() {
443
+ this.xyz = null;
444
+ return this;
445
+ },
446
+
447
+ getXYZ: function() {
448
+ // copy it
449
+ return new MOD3.VecArray(this.xyz);
450
+ },
451
+
452
+ getXYZRef: function() {
453
+ return this.xyz;
454
+ },
455
+
456
+ setXYZ: function(w) {
457
+ var v = this.xyz;
458
+ v[0] = w[0];
459
+ v[1] = w[1];
460
+ v[2] = w[2];
461
+ return this;
462
+ },
463
+
464
+ setXYZRef: function(xyz) {
465
+ this.xyz = xyz;
466
+ return this;
467
+ },
468
+
469
+ clone: function() {
470
+ return new MOD3.Vector3(this.xyz);
471
+ },
472
+
473
+ equalsSelf: function(b) {
474
+ var v = this.xyz, w = b.xyz;
475
+ return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]);
476
+ },
477
+
478
+ zeroSelf: function() {
479
+ var v = this.xyz;
480
+ v[0] = 0; v[1] = 0; v[2] = 0;
481
+ return this;
482
+ },
483
+
484
+ negate: function() {
485
+ var v = this.xyz;
486
+ return new MOD3.Vector3(-v[0], -v[1], -v[2]);
487
+ },
488
+
489
+ negateSelf: function() {
490
+ var v = this.xyz;
491
+ v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2];
492
+ return this;
493
+ },
494
+
495
+ add: function(b) {
496
+ var v = this.xyz, w = b.xyz;
497
+ return new MOD3.Vector3(v[0] + w[0], v[1] + w[1], v[2] + w[2]);
498
+ },
499
+
500
+ addSelf: function(b) {
501
+ var v = this.xyz, w = b.xyz;
502
+ v[0] += w[0]; v[1] += w[1]; v[2] += w[2];
503
+ return this;
504
+ },
505
+
506
+ subtract: function(b) {
507
+ var v = this.xyz, w = b.xyz;
508
+ return new MOD3.Vector3(v[0] - w[0], v[1] - w[1], v[2] - w[2]);
509
+ },
510
+
511
+ subtractSelf: function(b) {
512
+ var v = this.xyz, w = b.xyz;
513
+ v[0] -= w[0]; v[1] -= w[1]; v[2] -= w[2];
514
+ return this;
515
+ },
516
+
517
+ multiplyScalar: function(s) {
518
+ var v = this.xyz;
519
+ return new MOD3.Vector3(v[0]*s, v[1]*s, v[2]*s);
520
+ },
521
+
522
+ multiplyScalarSelf: function(s) {
523
+ var v = this.xyz;
524
+ v[0] *= s; v[1] *= s; v[2] *= s;
525
+ return this;
526
+ },
527
+
528
+ multiply: function(b) {
529
+ var v = this.xyz, w = b.xyz;
530
+ return new MOD3.Vector3(v[0] * w[0], v[1] * w[1], v[2] * w[2]);
531
+ },
532
+
533
+ multiplySelf: function(b) {
534
+ var v = this.xyz, w = b.xyz;
535
+ v[0] *= w[0]; v[1] *= w[1]; v[2] *= w[2];
536
+ return this;
537
+ },
538
+
539
+ divide: function(s) {
540
+ var v = this.xyz;
541
+ return new MOD3.Vector3(v[0] / s, v[1] / s, v[2] / s);
542
+ },
543
+
544
+ divideSelf: function(s) {
545
+ var v = this.xyz;
546
+ v[0] /= s; v[1] /= s; v[2] /= s;
547
+ return this;
548
+ },
549
+
550
+ normalize: function() {
551
+ var v = this.xyz,
552
+ x = v[0], y = v[1], z = v[2],
553
+ m = x * x + y * y + z * z, n;
554
+ if (0 < m)
555
+ {
556
+ n = stdMath.sqrt(m);
557
+ x /= n;
558
+ y /= n;
559
+ z /= n;
560
+ }
561
+ return new MOD3.Vector3(x, y, z);
562
+ },
563
+
564
+ normalizeSelf: function() {
565
+ var v = this.xyz,
566
+ x = v[0], y = v[1], z = v[2],
567
+ m = x * x + y * y + z * z, n;
568
+ if (0 < m)
569
+ {
570
+ n = stdMath.sqrt(m);
571
+ x /= n;
572
+ y /= n;
573
+ z /= n;
574
+ }
575
+ v[0] = x; v[1] = y; v[2] = z;
576
+ return this;
577
+ },
578
+
579
+ getMagnitude: function() {
580
+ var v = this.xyz, x = v[0], y = v[1], z = v[2];
581
+ return stdMath.sqrt(x*x + y*y + z*z);
582
+ },
583
+
584
+ setMagnitude: function(m) {
585
+ this.normalizeSelf();
586
+ var v = this.xyz;
587
+ v[0] *= m; v[1] *= m; v[2] *= m;
588
+ return this;
589
+ },
590
+
591
+ dot: function(b) {
592
+ var v = this.xyz, w = b.xyz;
593
+ return v[0]*w[0] + v[1]*w[1] + v[2]*w[2];
594
+ },
595
+
596
+ cross: function(b) {
597
+ var v = this.xyz, w = b.xyz,
598
+ x1 = v[0], y1 = v[1], z1 = v[2],
599
+ x2 = w[0], y2 = w[1], z2 = w[2];
600
+ return new MOD3.Vector3(y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2);
601
+ },
602
+
603
+ crossSelf: function(v) {
604
+ var v = this.xyz, w = b.xyz,
605
+ x1 = v[0], y1 = v[1], z1 = v[2],
606
+ x2 = w[0], y2 = w[1], z2 = w[2];
607
+ v[0] = y1 * z2 - z1 * y2;
608
+ v[1] = z1 * x2 - x1 * z2;
609
+ v[2] = x1 * y2 - y1 * x2;
610
+ return this;
611
+ },
612
+
613
+ distance: function(b) {
614
+ var v = this.xyz, w = b.xyz,
615
+ dx = v[0] - w[0],
616
+ dy = v[1] - w[1],
617
+ dz = v[2] - w[2];
618
+ return stdMath.sqrt(dx*dx + dy*dy + dz*dz);
619
+ },
620
+
621
+ toString: function() {
622
+ var v = this.xyz;
623
+ return "[" + v[0] + " , " + v[1] + " , " + v[2] + "]";
624
+ }
625
+ }, {
626
+ ZERO: function() {
627
+ return new MOD3.Vector3(0, 0, 0);
628
+ },
629
+
630
+ X: function(direct_or_complement) {
631
+ return false === direct_or_complement ? new MOD3.Vector3(0, 1, 1) : new MOD3.Vector3(1, 0, 0);
632
+ },
633
+
634
+ Y: function(direct_or_complement) {
635
+ return false === direct_or_complement ? new MOD3.Vector3(1, 0, 1) : new MOD3.Vector3(0, 1, 0);
636
+ },
637
+
638
+ Z: function(direct_or_complement) {
639
+ return false === direct_or_complement ? new MOD3.Vector3(1, 1, 0) : new MOD3.Vector3(0, 0, 1);
640
+ },
641
+
642
+ dot: function(v, w) {
643
+ return v[0]*w[0] + v[1]*w[1] + v[2]*w[2];
644
+ },
645
+
646
+ equals: function(v, w) {
647
+ return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]);
648
+ },
649
+
650
+ cross: function(v, w) {
651
+ var vw = new MOD3.VecArray(3);
652
+ vw[0] = v[1] * w[2] - v[2] * w[1];
653
+ vw[1] = v[2] * w[0] - v[0] * w[2];
654
+ vw[2] = v[0] * w[1] - v[1] * w[0];
655
+ return vw;
656
+ },
657
+
658
+ mod: function(v) {
659
+ var x = v[0], y = v[1], z = v[2];
660
+ return stdMath.sqrt(x*x + y*y + z*z);
661
+ },
662
+
663
+ dist: function(v, w) {
664
+ var dx = v[0] - w[0],
665
+ dy = v[1] - w[1],
666
+ dz = v[2] - w[2];
667
+ return stdMath.sqrt(dx*dx + dy*dy + dz*dz);
668
+ },
669
+
670
+ add: function(v, w) {
671
+ v[0] += w[0];
672
+ v[1] += w[1];
673
+ v[2] += w[2];
674
+ return v;
675
+ },
676
+
677
+ sub: function(v, w) {
678
+ v[0] -= w[0];
679
+ v[1] -= w[1];
680
+ v[2] -= w[2];
681
+ return v;
682
+ },
683
+
684
+ mul: function(v, w) {
685
+ v[0] *= w[0];
686
+ v[1] *= w[1];
687
+ v[2] *= w[2];
688
+ return v;
689
+ },
690
+
691
+ muls: function(v, m) {
692
+ v[0] *= m;
693
+ v[1] *= m;
694
+ v[2] *= m;
695
+ return v;
696
+ },
697
+
698
+ norm: function(v) {
699
+ var x = v[0], y = v[1], z = v[2],
700
+ m = x*x + y*y + z*z, n;
701
+ if (0 < m)
702
+ {
703
+ n = stdMath.sqrt(m);
704
+ x /= n;
705
+ y /= n;
706
+ z /= n;
707
+ }
708
+ v[0] = x; v[1] = y; v[2] = z;
709
+ return v;
710
+ }
711
+ });
712
+ // alaises
713
+ MOD3.Vector3.modulo = MOD3.Vector3.mod;
714
+ MOD3.Vector3.distance = MOD3.Vector3.dist;
715
+ MOD3.Vector3.prototype.dotSelf = MOD3.Vector3.prototype.dot;
716
+ MOD3.Vector3.prototype.distanceSelf = MOD3.Vector3.prototype.distance;
717
+ /**
718
+ * MOD3 3D Transform Matrix Class
719
+ **/
720
+ MOD3.Matrix4 = MOD3.Class(null, {
721
+ constructor: function Matrix4(n11, n12, n13, n14,
722
+ n21, n22, n23, n24,
723
+ n31, n32, n33, n34,
724
+ n41, n42, n43, n44)
725
+ {
726
+ var self = this;
727
+ if (!(self instanceof Matrix4)) return new Matrix4(n11, n12, n13, n14,
728
+ n21, n22, n23, n24,
729
+ n31, n32, n33, n34,
730
+ n41, n42, n43, n44);
731
+ self.m = new MOD3.VecArray([
732
+ n11 == null ? 1 : n11,
733
+ n12 == null ? 0 : n12,
734
+ n13 == null ? 0 : n13,
735
+ n14 == null ? 0 : n14,
736
+
737
+ n21 == null ? 0 : n21,
738
+ n22 == null ? 1 : n22,
739
+ n23 == null ? 0 : n23,
740
+ n24 == null ? 0 : n24,
741
+
742
+ n31 == null ? 0 : n31,
743
+ n32 == null ? 0 : n32,
744
+ n33 == null ? 1 : n33,
745
+ n34 == null ? 0 : n34,
746
+
747
+ n41 == null ? 0 : n41,
748
+ n42 == null ? 0 : n42,
749
+ n43 == null ? 0 : n43,
750
+ n44 == null ? 1 : n44
751
+ ]);
752
+ },
753
+
754
+ name: "Matrix4",
755
+ m: null,
756
+
757
+ dispose: function() {
758
+ this.m = null;
759
+ return this;
760
+ },
761
+
762
+ reset: function() {
763
+ var m = this.m;
764
+ m[0 ] = 1; m[1 ] = 0; m[2 ] = 0; m[3 ] = 0;
765
+ m[4 ] = 0; m[5 ] = 1; m[6 ] = 0; m[7 ] = 0;
766
+ m[8 ] = 0; m[9 ] = 0; m[10] = 1; m[11] = 0;
767
+ m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
768
+ return this;
769
+ },
770
+
771
+ translate: function(tx, ty, tz, reset) {
772
+ var m = this.m;
773
+ if (true === reset) this.reset();
774
+ m[3 ] = tx;
775
+ m[7 ] = ty;
776
+ m[11] = tz;
777
+ return this;
778
+ },
779
+
780
+ scale: function(sx, sy, sz, reset) {
781
+ var m = this.m;
782
+ if (true === reset) this.reset();
783
+ m[0 ] = sx;
784
+ m[5 ] = sy;
785
+ m[10] = sz;
786
+ return this;
787
+ },
788
+
789
+ rotate: function(rx, ry, rz, theta, reset) {
790
+ var m = this.m,
791
+ nCos = stdMath.cos(theta), nSin = stdMath.sin(theta), scos = 1 - nCos,
792
+ sxy = rx*ry*scos, syz = ry*rz*scos, sxz = rx*rz*scos,
793
+ sz = nSin*rz, sy = nSin*ry, sx = nSin*rx
794
+ ;
795
+ if (true === reset) this.reset();
796
+ m[0 ] = nCos + rx*rx*scos;
797
+ m[1 ] = -sz + sxy;
798
+ m[2 ] = sy + sxz;
799
+ m[3 ] = 0;
800
+
801
+ m[4 ] = sz + sxy;
802
+ m[5 ] = nCos + ry*ry*scos;
803
+ m[6 ] = -sx + syz;
804
+ m[7 ] = 0;
805
+
806
+ m[8 ] = -sy + sxz;
807
+ m[9 ] = sx + syz;
808
+ m[10] = nCos + rz*rz*scos;
809
+ m[11] = 0;
810
+ return this;
811
+ },
812
+
813
+ translateFromVector: function(v, reset) {
814
+ return this.translate(v.xyz[0], v.xyz[1], v.xyz[2], reset);
815
+ },
816
+
817
+ scaleFromVector: function(v, reset) {
818
+ return this.scale(v.xyz[0], v.xyz[1], v.xyz[2], reset);
819
+ },
820
+
821
+ rotateFromVector: function(v, theta, reset) {
822
+ return this.rotate(v.xyz[0], v.xyz[1], v.xyz[2], theta, reset);
823
+ },
824
+
825
+ multiply: function(b) {
826
+ return MOD3.Matrix4.mult(this, b);
827
+ },
828
+
829
+ multiplyVector: function(v) {
830
+ MOD3.Matrix4.multXYZ(this, v.xyz);
831
+ return v;
832
+ }
833
+ }, {
834
+ multXYZ: function(m4, v) {
835
+ var m = m4.m, x = v[0], y = v[1], z = v[2];
836
+ v[0] = x*m[0 ] + y*m[1 ] + z*m[2 ] + m[3 ];
837
+ v[1] = x*m[4 ] + y*m[5 ] + z*m[6 ] + m[7 ];
838
+ v[2] = x*m[8 ] + y*m[9 ] + z*m[10] + m[11];
839
+ return v;
840
+ },
841
+
842
+ mult: function(m1, m2) {
843
+ var a = m1.m, b = m2.m,
844
+ a11 = a[0 ], b11 = b[0 ],
845
+ a21 = a[4 ], b21 = b[4 ],
846
+ a31 = a[8 ], b31 = b[8 ],
847
+ a12 = a[1 ], b12 = b[1 ],
848
+ a22 = a[5 ], b22 = b[5 ],
849
+ a32 = a[9 ], b32 = b[9 ],
850
+ a13 = a[2 ], b13 = b[2 ],
851
+ a23 = a[6 ], b23 = b[6 ],
852
+ a33 = a[10], b33 = b[10],
853
+ a14 = a[3 ], b14 = b[3 ],
854
+ a24 = a[7 ], b24 = b[7 ],
855
+ a34 = a[11], b34 = b[11];
856
+
857
+ a[0 ] = a11*b11 + a12*b21 + a13*b31;
858
+ a[1 ] = a11*b12 + a12*b22 + a13*b32;
859
+ a[2 ] = a11*b13 + a12*b23 + a13*b33;
860
+ a[3 ] = a11*b14 + a12*b24 + a13*b34 + a14;
861
+
862
+ a[4 ] = a21*b11 + a22*b21 + a23*b31;
863
+ a[5 ] = a21*b12 + a22*b22 + a23*b32;
864
+ a[6 ] = a21*b13 + a22*b23 + a23*b33;
865
+ a[7 ] = a21*b14 + a22*b24 + a23*b34 + a24;
866
+
867
+ a[8 ] = a31*b11 + a32*b21 + a33*b31;
868
+ a[9 ] = a31*b12 + a32*b22 + a33*b32;
869
+ a[10] = a31*b13 + a32*b23 + a33*b33;
870
+ a[11] = a31*b14 + a32*b24 + a33*b34 + a34;
871
+ return m1;
872
+ }
873
+ });
874
+ // aliases
875
+ MOD3.Matrix4.prototype.translationMatrix = MOD3.Matrix4.prototype.translate;
876
+ MOD3.Matrix4.prototype.scaleMatrix = MOD3.Matrix4.prototype.scale;
877
+ MOD3.Matrix4.prototype.rotationMatrix = MOD3.Matrix4.prototype.rotate;
878
+ MOD3.Matrix4.prototype.translationMatrixFromVector = MOD3.Matrix4.prototype.translateFromVector;
879
+ MOD3.Matrix4.prototype.scaleMatrixFromVector = MOD3.Matrix4.prototype.scaleFromVector;
880
+ MOD3.Matrix4.prototype.rotationMatrixFromVector = MOD3.Matrix4.prototype.rotateFromVector;
881
+ // fast list utilities
882
+ MOD3.List = {
883
+ operate: function operate(x, F, F0, i0, i1, reverse) {
884
+ var len = x.length;
885
+ if (arguments.length < 5) i1 = len-1;
886
+ if (0 > i1) i1 += len;
887
+ if (arguments.length < 4) i0 = 0;
888
+ if (i0 > i1) return F0;
889
+ if (true === reverse)
890
+ {
891
+ var i, k, l=i1-i0+1, l1=l-1, r=l&15, q=r&1, lr=l1-r, Fv=q?F(F0,x[i1],i1):F0;
892
+ for (i=l1-q; i>lr; i-=2) { k = i0+i; Fv = F(F(Fv,x[k],k),x[k-1],k-1); }
893
+ for (i=lr; i>=0; i-=16) { k = i0+i; Fv = F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(Fv,x[k],k),x[k-1],k-1),x[k-2],k-2),x[k-3],k-3),x[k-4],k-4),x[k-5],k-5),x[k-6],k-6),x[k-7],k-7),x[k-8],k-8),x[k-9],k-9),x[k-10],k-10),x[k-11],k-11),x[k-12],k-12),x[k-13],k-13),x[k-14],k-14),x[k-15],k-15); }
894
+ }
895
+ else
896
+ {
897
+ var i, k, l=i1-i0+1, r=l&15, q=r&1, Fv=q?F(F0,x[i0],i0):F0;
898
+ for (i=q; i<r; i+=2) { k = i0+i; Fv = F(F(Fv,x[k],k),x[k+1],k+1); }
899
+ for (i=r; i<l; i+=16) { k = i0+i; Fv = F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(Fv,x[k],k),x[k+1],k+1),x[k+2],k+2),x[k+3],k+3),x[k+4],k+4),x[k+5],k+5),x[k+6],k+6),x[k+7],k+7),x[k+8],k+8),x[k+9],k+9),x[k+10],k+10),x[k+11],k+11),x[k+12],k+12),x[k+13],k+13),x[k+14],k+14),x[k+15],k+15); }
900
+ }
901
+ return Fv;
902
+ }
903
+
904
+ ,each: function each(x, F, i0, i1, reverse) {
905
+ if (null == x || !x.length) return x;
906
+ var len = x.length;
907
+ if (arguments.length < 4) i1 = len-1;
908
+ if (0 > i1) i1 += len;
909
+ if (arguments.length < 3) i0 = 0;
910
+ if (i0 > i1) return x;
911
+ var i, k, l=i1-i0+1, l1, lr, r, q;
912
+ if (true === reverse)
913
+ {
914
+ l1=l-1; r=l&15; q=r&1; lr=l1-r;
915
+ if (q) F(x[i1]);
916
+ for (i=l1-q; i>lr; i-=2)
917
+ {
918
+ k = i0+i;
919
+ F(x[k ]);
920
+ F(x[k-1]);
921
+ }
922
+ for (i=lr; i>=0; i-=16)
923
+ {
924
+ k = i0+i;
925
+ F(x[k ] );
926
+ F(x[k-1] );
927
+ F(x[k-2] );
928
+ F(x[k-3] );
929
+ F(x[k-4] );
930
+ F(x[k-5] );
931
+ F(x[k-6] );
932
+ F(x[k-7] );
933
+ F(x[k-8] );
934
+ F(x[k-9] );
935
+ F(x[k-10]);
936
+ F(x[k-11]);
937
+ F(x[k-12]);
938
+ F(x[k-13]);
939
+ F(x[k-14]);
940
+ F(x[k-15]);
941
+ }
942
+ }
943
+ else
944
+ {
945
+ r=l&15; q=r&1;
946
+ if (q) F(x[i0]);
947
+ for (i=q; i<r; i+=2)
948
+ {
949
+ k = i0+i;
950
+ F(x[k ]);
951
+ F(x[k+1]);
952
+ }
953
+ for (i=r; i<l; i+=16)
954
+ {
955
+ k = i0+i;
956
+ F(x[k ] );
957
+ F(x[k+1] );
958
+ F(x[k+2] );
959
+ F(x[k+3] );
960
+ F(x[k+4] );
961
+ F(x[k+5] );
962
+ F(x[k+6] );
963
+ F(x[k+7] );
964
+ F(x[k+8] );
965
+ F(x[k+9] );
966
+ F(x[k+10]);
967
+ F(x[k+11]);
968
+ F(x[k+12]);
969
+ F(x[k+13]);
970
+ F(x[k+14]);
971
+ F(x[k+15]);
972
+ }
973
+ }
974
+ return x;
975
+ }
976
+ };
977
+ /**
978
+ * MOD3 MeshProxy Super Class
979
+ **/
980
+ function dispose(o)
981
+ {
982
+ o.dispose();
983
+ }
984
+ function reset(o)
985
+ {
986
+ o.reset();
987
+ }
988
+ function collapse(o)
989
+ {
990
+ o.collapse();
991
+ }
992
+
993
+ MOD3.FaceProxy = MOD3.Class(null, {
994
+ constructor: function FaceProxy() {
995
+ this.vertices = [];
996
+ },
997
+
998
+ name: "FaceProxy",
999
+ vertices: null,
1000
+
1001
+ dispose: function() {
1002
+ var self = this;
1003
+ self.vertices = null;
1004
+ return self;
1005
+ },
1006
+
1007
+ addVertex: function(v) {
1008
+ this.vertices.push(v);
1009
+ },
1010
+
1011
+ getVertices: function() {
1012
+ return this.vertices;
1013
+ }
1014
+ });
1015
+
1016
+ MOD3.VertexProxy = MOD3.Class(null, {
1017
+ constructor: function VertexProxy(vertex, mesh) {
1018
+ var self = this;
1019
+ self.mesh = mesh || null;
1020
+ // use internal typed-arrays for speed
1021
+ self.original = new MOD3.VecArray([0,0,0]);
1022
+ self.ratio = new MOD3.VecArray([0,0,0]);
1023
+ // vertex can be zero
1024
+ if (null != vertex) self.setVertex(vertex);
1025
+ },
1026
+
1027
+ name: "VertexProxy",
1028
+ mesh: null,
1029
+ vertex: null,
1030
+ original: null,
1031
+ ratio: null,
1032
+
1033
+ dispose: function() {
1034
+ var self = this;
1035
+ self.mesh = null;
1036
+ self.vertex = null;
1037
+ self.original = null;
1038
+ self.ratio = null;
1039
+ return self;
1040
+ },
1041
+
1042
+ setVertex: function(vt) {
1043
+ // override
1044
+ var self = this;
1045
+ self.vertex = vt;
1046
+ return self;
1047
+ },
1048
+
1049
+ getRatioVector: function() {
1050
+ var r = this.ratio, rv = new MOD3.VecArray(3);
1051
+ rv[0] = r[0]; rv[1] = r[1]; rv[2] = r[2];
1052
+ return rv;
1053
+ },
1054
+
1055
+ getRatio: function(axis) {
1056
+ return this.ratio[MOD3.XYZi[axis]] || 0;
1057
+ },
1058
+
1059
+ setRatios: function(rx, ry, rz) {
1060
+ var r = this.ratio;
1061
+ r[0] = rx || 0;
1062
+ r[1] = ry || 0;
1063
+ r[2] = rz || 0;
1064
+ return this;
1065
+ },
1066
+
1067
+ getOriginalValue: function(axis) {
1068
+ return this.original[MOD3.XYZi[axis]] || 0;
1069
+ },
1070
+
1071
+ setOriginalPosition: function(ox, oy, oz) {
1072
+ var o = this.original;
1073
+ o[0] = ox || 0;
1074
+ o[1] = oy || 0;
1075
+ o[2] = oz || 0;
1076
+ return this;
1077
+ },
1078
+
1079
+ getXYZ: function() {
1080
+ // override
1081
+ return new MOD3.VecArray([0,0,0]);
1082
+ },
1083
+
1084
+ getX: function() {
1085
+ // override
1086
+ return 0;
1087
+ },
1088
+
1089
+ getY: function() {
1090
+ // override
1091
+ return 0;
1092
+ },
1093
+
1094
+ getZ: function() {
1095
+ // override
1096
+ return 0;
1097
+ },
1098
+
1099
+ getValue: function(axis) {
1100
+ var self = this;
1101
+ // override
1102
+ return MOD3.ModConstant.X === axis
1103
+ ? self.getX()
1104
+ : (MOD3.ModConstant.Y === axis
1105
+ ? self.getY()
1106
+ : (MOD3.ModConstant.Z === axis
1107
+ ? self.getZ()
1108
+ : 0))
1109
+ ;
1110
+ },
1111
+
1112
+ setXYZ: function(xyz) {
1113
+ // override
1114
+ return this;
1115
+ },
1116
+
1117
+ setX: function(vo) {
1118
+ // override
1119
+ return this;
1120
+ },
1121
+
1122
+ setY: function(vo) {
1123
+ // override
1124
+ return this;
1125
+ },
1126
+
1127
+ setZ: function(vo) {
1128
+ // override
1129
+ return this;
1130
+ },
1131
+
1132
+ setValue: function(axis, vo) {
1133
+ var self = this;
1134
+ // override
1135
+ if (MOD3.ModConstant.X === axis) self.setX(vo);
1136
+ else if (MOD3.ModConstant.Y === axis) self.setY(vo);
1137
+ else if (MOD3.ModConstant.Z === axis) self.setZ(vo);
1138
+ return self;
1139
+ },
1140
+
1141
+ reset: function() {
1142
+ // override
1143
+ var self = this;
1144
+ self.setXYZ(self.original);
1145
+ return self;
1146
+ },
1147
+
1148
+ collapse: function() {
1149
+ // override
1150
+ var self = this, xyz = self.getXYZ(), o = self.original;
1151
+ o[0] = xyz[0]; o[1] = xyz[1]; o[2] = xyz[2];
1152
+ return self;
1153
+ }
1154
+ });
1155
+
1156
+ MOD3.MeshProxy = MOD3.Class(null, {
1157
+ constructor: function MeshProxy(mesh) {
1158
+ var self = this;
1159
+ self.maxX = 0;
1160
+ self.maxY = 0;
1161
+ self.maxZ = 0;
1162
+
1163
+ self.minX = 0;
1164
+ self.minY = 0;
1165
+ self.minZ = 0;
1166
+
1167
+ self.maxAxis = 0;
1168
+ self.midAxis = 0;
1169
+ self.minAxis = 0;
1170
+
1171
+ self.width = 0;
1172
+ self.height = 0;
1173
+ self.depth = 0;
1174
+
1175
+ self.vertices = null;
1176
+ self.faces = null;
1177
+ self.mesh = null;
1178
+
1179
+ if (null != mesh) self.setMesh(mesh);
1180
+ },
1181
+
1182
+ name: "MeshProxy",
1183
+
1184
+ maxX: 0,
1185
+ maxY: 0,
1186
+ maxZ: 0,
1187
+ minX: 0,
1188
+ minY: 0,
1189
+ minZ: 0,
1190
+
1191
+ maxAxis: 0,
1192
+ midAxis: 0,
1193
+ minAxis: 0,
1194
+
1195
+ width: 0,
1196
+ height: 0,
1197
+ depth: 0,
1198
+
1199
+ vertices : null,
1200
+ faces : null,
1201
+ mesh : null,
1202
+ v: null,
1203
+
1204
+ dispose: function() {
1205
+ var self = this;
1206
+ self.maxX = null;
1207
+ self.maxY = null;
1208
+ self.maxZ = null;
1209
+ self.minX = null;
1210
+ self.minY = null;
1211
+ self.minZ = null;
1212
+
1213
+ self.maxAxis = null;
1214
+ self.midAxis = null;
1215
+ self.minAxis = null;
1216
+
1217
+ self.width = null;
1218
+ self.height = null;
1219
+ self.depth = null;
1220
+
1221
+ self.disposeFaces();
1222
+ self.disposeVertices();
1223
+ self.mesh = null;
1224
+ self.v = null;
1225
+ return self;
1226
+ },
1227
+
1228
+ disposeVertices: function() {
1229
+ var self = this;
1230
+ if (self.vertices) MOD3.List.each(self.vertices, dispose);
1231
+ self.vertices = null;
1232
+ return self;
1233
+ },
1234
+
1235
+ disposeFaces: function() {
1236
+ var self = this;
1237
+ if (self.faces) MOD3.List.each(self.faces, dispose);
1238
+ self.faces = null;
1239
+ return self;
1240
+ },
1241
+
1242
+ init: function(mesh) {
1243
+ var self = this;
1244
+ self.mesh = mesh;
1245
+ //self.vertices = [];
1246
+ // not used
1247
+ //self.faces = [];
1248
+ return self;
1249
+ },
1250
+
1251
+ setMesh: function(mesh) {
1252
+ var self = this;
1253
+ self.init(mesh);
1254
+ self.preApply();
1255
+ self.analyzeGeometry()
1256
+ self.postApply();
1257
+ return self;
1258
+ },
1259
+
1260
+ getVertices: function() {
1261
+ return this.vertices;
1262
+ },
1263
+
1264
+ getFaces: function() {
1265
+ return this.faces;
1266
+ },
1267
+
1268
+ applyModifiers: function(modStack) {
1269
+ var self = this, sl, i;
1270
+ for (i=0,sl=modStack.length; i<sl; ++i)
1271
+ {
1272
+ modStack[i].enabled && modStack[i].apply(self);
1273
+ }
1274
+ return self;
1275
+ },
1276
+
1277
+ analyzeGeometry: function() {
1278
+ var self = this,
1279
+ vertices = self.vertices,
1280
+ minX = 0, minY = 0, minZ = 0,
1281
+ maxX = 0, maxY = 0, maxZ = 0,
1282
+ width = 0, height = 0, depth = 0,
1283
+ maxe, mine, w
1284
+ ;
1285
+ if (!vertices || !vertices.length) return self;
1286
+
1287
+ w = vertices[0].getXYZ();
1288
+ minX = w[0];
1289
+ minY = w[1];
1290
+ minZ = w[2];
1291
+
1292
+ maxX = w[0];
1293
+ maxY = w[1];
1294
+ maxZ = w[2];
1295
+
1296
+ MOD3.List.each(vertices, function(v) {
1297
+ var xyz = v.getXYZ(), x = xyz[0], y = xyz[1], z = xyz[2];
1298
+ minX = stdMath.min(minX, x);
1299
+ minY = stdMath.min(minY, y);
1300
+ minZ = stdMath.min(minZ, z);
1301
+
1302
+ maxX = stdMath.max(maxX, x);
1303
+ maxY = stdMath.max(maxY, y);
1304
+ maxZ = stdMath.max(maxZ, z);
1305
+ v.setOriginalPosition(x, y, z);
1306
+ });
1307
+
1308
+ width = maxX - minX;
1309
+ height = maxY - minY;
1310
+ depth = maxZ - minZ;
1311
+
1312
+ self.width = width;
1313
+ self.height = height;
1314
+ self.depth = depth;
1315
+ self.minX = minX;
1316
+ self.maxX = maxX;
1317
+ self.minY = minY;
1318
+ self.maxY = maxY;
1319
+ self.minZ = minZ;
1320
+ self.maxZ = maxZ;
1321
+
1322
+ maxe = stdMath.max(width, height, depth);
1323
+ mine = stdMath.min(width, height, depth);
1324
+
1325
+ if ((maxe === width) && (mine === height))
1326
+ {
1327
+ self.minAxis = MOD3.ModConstant.Y;
1328
+ self.midAxis = MOD3.ModConstant.Z;
1329
+ self.maxAxis = MOD3.ModConstant.X;
1330
+ }
1331
+ else if ((maxe === width) && (mine === depth))
1332
+ {
1333
+ self.minAxis = MOD3.ModConstant.Z;
1334
+ self.midAxis = MOD3.ModConstant.Y;
1335
+ self.maxAxis = MOD3.ModConstant.X;
1336
+ }
1337
+ else if ((maxe === height) && (mine === width))
1338
+ {
1339
+ self.minAxis = MOD3.ModConstant.X;
1340
+ self.midAxis = MOD3.ModConstant.Z;
1341
+ self.maxAxis = MOD3.ModConstant.Y;
1342
+ }
1343
+ else if ((maxe === height) && (mine === depth))
1344
+ {
1345
+ self.minAxis = MOD3.ModConstant.Z;
1346
+ self.midAxis = MOD3.ModConstant.X;
1347
+ self.maxAxis = MOD3.ModConstant.Y;
1348
+ }
1349
+ else if ((maxe === depth) && (mine === width))
1350
+ {
1351
+ self.minAxis = MOD3.ModConstant.X;
1352
+ self.midAxis = MOD3.ModConstant.Y;
1353
+ self.maxAxis = MOD3.ModConstant.Z;
1354
+ }
1355
+ else if ((maxe === depth) && (mine === height))
1356
+ {
1357
+ self.minAxis = MOD3.ModConstant.Y;
1358
+ self.midAxis = MOD3.ModConstant.X;
1359
+ self.maxAxis = MOD3.ModConstant.Z;
1360
+ }
1361
+
1362
+ MOD3.List.each(vertices, function(v) {
1363
+ var xyz = v.getXYZ();
1364
+ v.setRatios(width > 0 ? (xyz[0] - minX) / width : 0, height > 0 ? (xyz[1] - minY) / height : 0, depth > 0 ? (xyz[2] - minZ) / depth : 0);
1365
+ });
1366
+ return self;
1367
+ },
1368
+
1369
+ resetGeometry: function() {
1370
+ var self = this;
1371
+ MOD3.List.each(self.vertices, reset);
1372
+ return self;
1373
+ },
1374
+
1375
+ collapseGeometry: function() {
1376
+ var self = this;
1377
+ MOD3.List.each(self.vertices, collapse);
1378
+ self.analyzeGeometry();
1379
+ return self;
1380
+ },
1381
+
1382
+ getMin: function(axis) {
1383
+ var self = this;
1384
+ return MOD3.ModConstant.X === axis
1385
+ ? self.minX
1386
+ : (MOD3.ModConstant.Y === axis
1387
+ ? self.minY
1388
+ : (MOD3.ModConstant.Z === axis
1389
+ ? self.minZ
1390
+ : -1))
1391
+ ;
1392
+ },
1393
+
1394
+ getMax: function(axis) {
1395
+ var self = this;
1396
+ return MOD3.ModConstant.X === axis
1397
+ ? self.maxX
1398
+ : (MOD3.ModConstant.Y === axis
1399
+ ? self.maxY
1400
+ : (MOD3.ModConstant.Z === axis
1401
+ ? self.maxZ
1402
+ : -1))
1403
+ ;
1404
+ },
1405
+
1406
+ getSize: function(axis) {
1407
+ var self = this;
1408
+ return MOD3.ModConstant.X === axis
1409
+ ? self.width
1410
+ : (MOD3.ModConstant.Y === axis
1411
+ ? self.height
1412
+ : (MOD3.ModConstant.Z === axis
1413
+ ? self.depth
1414
+ : -1))
1415
+ ;
1416
+ },
1417
+
1418
+ update: function() {
1419
+ // do nothing
1420
+ return this;
1421
+ },
1422
+
1423
+ preApply: function() {
1424
+ // do nothing
1425
+ return this;
1426
+ },
1427
+
1428
+ postApply: function() {
1429
+ // do nothing
1430
+ return this;
1431
+ },
1432
+
1433
+ updateMeshPosition: function(p) {
1434
+ // do nothing
1435
+ return this;
1436
+ }
1437
+ });
1438
+
1439
+ MOD3.Library3d = {
1440
+ id : "Library3d",
1441
+ Mesh : MOD3.MeshProxy,
1442
+ Vertex : MOD3.VertexProxy
1443
+ };
1444
+
1445
+ MOD3.Factory = {
1446
+ getLibrary: function(json) {
1447
+ if (json && json.library && MOD3[json.library]) return MOD3[json.library];
1448
+ // dummy, default
1449
+ return MOD3.Library3d;
1450
+ }
1451
+
1452
+ ,getMeshProxy: function(lib3D) {
1453
+ if (arguments.length) return lib3D.Mesh ? new lib3D.Mesh() : null;
1454
+ return null;
1455
+ }
1456
+
1457
+ ,getModifier: function(json) {
1458
+ if (json && json.modifier && MOD3[json.modifier]) return new MOD3[json.modifier]();
1459
+ return null;
1460
+ }
1461
+
1462
+ /*
1463
+ ,getMesh: function(json) {
1464
+ if (json && json.mesh && MOD3[json.mesh] ) return new MOD3.MeshProxy().unserialize(json);
1465
+ // dummy, default
1466
+ return new MOD3.MeshProxy();
1467
+ }
1468
+
1469
+ ,getVertex: function(json) {
1470
+ if (json && json.vertex && MOD3[json.vertex]) return new MOD3.VertexProxy().unserialize(json);
1471
+ // dummy, default
1472
+ return new MOD3.VertexProxy();
1473
+ }*/
1474
+ };
1475
+ /**
1476
+ * MOD3 Modifier & ModifierStack Classes
1477
+ **/
1478
+ var _modCount = 0;
1479
+
1480
+ MOD3.Modifier = MOD3.Class({
1481
+ constructor: function Modifier() {
1482
+ var self = this;
1483
+ self.id = ++_modCount;
1484
+ self.name = 'Modifier';
1485
+ self.axes = MOD3.ModConstant.NONE;
1486
+ self.constraint = MOD3.ModConstant.NONE;
1487
+ self.enabled = true;
1488
+ },
1489
+
1490
+ id: null,
1491
+ name: 'Modifier',
1492
+ axes: null,
1493
+ constraint: null,
1494
+ enabled: true,
1495
+
1496
+ dispose: function() {
1497
+ var self = this;
1498
+ self.name = null;
1499
+ self.axes = null;
1500
+ self.constraint = null;
1501
+ return self;
1502
+ },
1503
+
1504
+ enable: function(enabled) {
1505
+ if (arguments.length)
1506
+ {
1507
+ this.enabled = !!enabled;
1508
+ return this;
1509
+ }
1510
+ return this.enabled;
1511
+ },
1512
+
1513
+ constraintAxes: function(axes) {
1514
+ this.axes = axes || MOD3.ModConstant.NONE;
1515
+ return this;
1516
+ },
1517
+
1518
+ setConstraint: function(c) {
1519
+ this.constraint = c || MOD3.ModConstant.NONE;
1520
+ return this;
1521
+ },
1522
+
1523
+ // override
1524
+ apply: function(modifiable) {
1525
+ return this;
1526
+ },
1527
+
1528
+ toString: function() {
1529
+ return '[Modifier '+this.name+']';
1530
+ }
1531
+ });
1532
+
1533
+ MOD3.ModifierStack = MOD3.Class({
1534
+ constructor: function ModifierStack(lib3d, mesh) {
1535
+ var self = this;
1536
+ if (!(self instanceof ModifierStack)) return new ModifierStack(lib3d, mesh);
1537
+ self.stack = [];
1538
+ self.setModifiable(MOD3.Factory.getMeshProxy(lib3d), mesh);
1539
+ },
1540
+
1541
+ name: "ModifierStack",
1542
+ modifiable: null,
1543
+ stack: null,
1544
+
1545
+ dispose: function(withModifiers) {
1546
+ var self = this;
1547
+ if (withModifiers && self.stack) while (self.stack.length) self.stack.pop().dispose();
1548
+ if (self.modifiable) self.modifiable.dispose();
1549
+ self.stack = null;
1550
+ self.modifiable = null;
1551
+ return self;
1552
+ },
1553
+
1554
+ getModifiable: function() {
1555
+ return this.modifiable;
1556
+ },
1557
+
1558
+ setModifiable: function(modifiable, mesh) {
1559
+ var self = this;
1560
+ self.modifiable = modifiable;
1561
+ if (mesh) self.modifiable.setMesh(mesh);
1562
+ return self;
1563
+ },
1564
+
1565
+ add: function(modifier) {
1566
+ var self = this;
1567
+ if (modifier) self.stack.push(modifier);
1568
+ return self;
1569
+ },
1570
+
1571
+ apply: function() {
1572
+ var self = this, modifiable = self.modifiable, stack = self.stack;
1573
+ if (modifiable && stack && stack.length)
1574
+ modifiable
1575
+ .preApply()
1576
+ .resetGeometry()
1577
+ .applyModifiers(stack)
1578
+ .postApply()
1579
+ .update()
1580
+ ;
1581
+ return self;
1582
+ },
1583
+
1584
+ collapse: function() {
1585
+ var self = this, modifiable = self.modifiable, stack = self.stack;
1586
+ if (modifiable && stack && stack.length)
1587
+ {
1588
+ modifiable
1589
+ .preApply()
1590
+ .resetGeometry()
1591
+ .applyModifiers(stack)
1592
+ .collapseGeometry()
1593
+ .postApply()
1594
+ .update()
1595
+ ;
1596
+ stack.length = 0;
1597
+ }
1598
+ return self;
1599
+ },
1600
+
1601
+ clear: function() {
1602
+ var self = this;
1603
+ if (self.stack) self.stack.length = 0;
1604
+ return self;
1605
+ }
1606
+ });
1607
+ // aliases
1608
+ MOD3.ModifierStack.prototype.getMeshInfo = MOD3.ModifierStack.prototype.getModifiable;
1609
+ MOD3.ModifierStack.prototype.addModifier = MOD3.ModifierStack.prototype.add;
1610
+ !function(MOD3) {
1611
+ "use strict";
1612
+ /**
1613
+ * MOD3 Pivot Modifier
1614
+ **/
1615
+
1616
+ /**[DOC_MD]
1617
+ * ### Pivot modifier
1618
+ *
1619
+ * Allows to move the pivot point of a 3D mesh.
1620
+ *
1621
+ * @author Bartek Drozdz
1622
+ *
1623
+ [/DOC_MD]**/
1624
+ MOD3.Pivot = MOD3.Class(MOD3.Modifier, {
1625
+ constructor: function Pivot(x, y, z) {
1626
+ var self = this;
1627
+ if (!(self instanceof Pivot)) return new Pivot(x, y, z);
1628
+ self.$super('constructor');
1629
+ self.name = 'Pivot';
1630
+ self.vector = new MOD3.Vector3(x||0, y||0, z||0);
1631
+ },
1632
+
1633
+ vector: null,
1634
+
1635
+ dispose: function() {
1636
+ var self = this;
1637
+ self.vector.dispose();
1638
+ self.vector = null;
1639
+ self.$super('dispose');
1640
+ return self;
1641
+ },
1642
+
1643
+ setMeshCenter: function(modifiable) {
1644
+ var self = this;
1645
+ self.vector = new MOD3.Vector3(
1646
+ -(modifiable.minX + 0.5*modifiable.width),
1647
+ -(modifiable.minY + 0.5*modifiable.height),
1648
+ -(modifiable.minZ + 0.5*modifiable.depth)
1649
+ );
1650
+ return self;
1651
+ },
1652
+
1653
+ apply: function(modifiable) {
1654
+ var self = this, pivot = self.vector, pv = pivot.xyz;
1655
+
1656
+ MOD3.List.each(modifiable.vertices, function(v) {
1657
+ v.setXYZ(MOD3.Vector3.add(v.getXYZ(), pv));
1658
+ });
1659
+ modifiable.updateMeshPosition(pivot.negate());
1660
+ return self;
1661
+ }
1662
+ });
1663
+ }(MOD3);!function(MOD3) {
1664
+ "use strict";
1665
+ /**
1666
+ * MOD3 Bend Modifier
1667
+ **/
1668
+
1669
+ /**[DOC_MD]
1670
+ * ### Bend modifier
1671
+ *
1672
+ * Bends an object along an axis.
1673
+ *
1674
+ * @author Bartek Drozdz
1675
+ *
1676
+ [/DOC_MD]**/
1677
+ var stdMath = Math, PI = stdMath.PI,
1678
+ TWO_PI = 2*PI, HALF_PI = PI/2;
1679
+
1680
+ MOD3.Bend = MOD3.Class(MOD3.Modifier, {
1681
+ constructor: function Bend(force, offset, angle) {
1682
+ var self = this;
1683
+ if (!(self instanceof Bend)) return new Bend(force, offset, angle);
1684
+ self.$super('constructor');
1685
+ self.name = 'Bend';
1686
+ self.constraint = MOD3.ModConstant.NONE;
1687
+ self.switchAxes = false;
1688
+ self.force = force || 0;
1689
+ self.offset = offset || 0;
1690
+ self.angle = angle || 0;
1691
+ },
1692
+
1693
+ force: 0,
1694
+ offset: 0,
1695
+ angle: 0,
1696
+ switchAxes: false,
1697
+
1698
+ dispose: function() {
1699
+ var self = this;
1700
+ self.force = null;
1701
+ self.offset = null;
1702
+ self.angle = null;
1703
+ self.switchAxes = null;
1704
+ self.$super('dispose');
1705
+ return self;
1706
+ },
1707
+
1708
+ apply: function(modifiable) {
1709
+ var self = this;
1710
+
1711
+ if (0 === self.force) return self;
1712
+
1713
+ var constraint = self.constraint, switchAxes = self.switchAxes,
1714
+ force = self.force, offset = stdMath.min(1, stdMath.max(0, self.offset)), a = self.angle,
1715
+ max = switchAxes ? modifiable.midAxis : modifiable.maxAxis,
1716
+ min = modifiable.minAxis,
1717
+ mid = switchAxes ? modifiable.maxAxis : modifiable.midAxis,
1718
+ width = modifiable.getSize(max),
1719
+ height = modifiable.getSize(mid),
1720
+ origin = modifiable.getMin(max),
1721
+ //diagAngle = stdMath.atan2(height, width),
1722
+ m1 = new MOD3.Matrix().rotate(a),
1723
+ m2 = new MOD3.Matrix().rotate(-a),
1724
+ distance = origin + width * offset,
1725
+ radius = width / PI / force,
1726
+ bendAngle = TWO_PI * (width / (radius * TWO_PI))
1727
+ ;
1728
+
1729
+ MOD3.List.each(modifiable.vertices, function(v) {
1730
+ var xyz = v.getXYZ(),
1731
+ vmax = xyz[MOD3.XYZi[max]],
1732
+ vmid = xyz[MOD3.XYZi[mid]],
1733
+ vmin = xyz[MOD3.XYZi[min]],
1734
+ np = MOD3.Matrix.transform(m1, [vmax, vmid]),
1735
+ p, fa, op, ow, np2
1736
+ ;
1737
+ vmax = np[0]; vmid = np[1];
1738
+
1739
+ p = (vmax - origin) / width;
1740
+
1741
+ if (
1742
+ ((MOD3.ModConstant.LEFT === constraint) && (p <= offset)) ||
1743
+ ((MOD3.ModConstant.RIGHT === constraint) && (p >= offset))
1744
+ )
1745
+ {
1746
+ /* do nothing */
1747
+ }
1748
+ else
1749
+ {
1750
+ fa = (HALF_PI - bendAngle * offset) + (bendAngle * p);
1751
+ op = stdMath.sin(fa) * (radius + vmin);
1752
+ ow = stdMath.cos(fa) * (radius + vmin);
1753
+ vmin = op - radius;
1754
+ vmax = distance - ow;
1755
+ }
1756
+
1757
+ np2 = MOD3.Matrix.transform(m2, [vmax, vmid]);
1758
+ vmax = np2[0]; vmid = np2[1];
1759
+ xyz[MOD3.XYZi[max]] = vmax;
1760
+ xyz[MOD3.XYZi[mid]] = vmid;
1761
+ xyz[MOD3.XYZi[min]] = vmin;
1762
+ v.setXYZ(xyz);
1763
+ });
1764
+ return self;
1765
+ }
1766
+ });
1767
+ }(MOD3);!function(MOD3) {
1768
+ "use strict";
1769
+ /**
1770
+ * MOD3 Bloat Modifier
1771
+ **/
1772
+
1773
+ /**[DOC_MD]
1774
+ * ### Bloat modifier
1775
+ *
1776
+ * Bloats a mesh by forcing vertices out of specified sphere
1777
+ *
1778
+ * @author makc
1779
+ *
1780
+ [/DOC_MD]**/
1781
+ var stdMath = Math;
1782
+
1783
+ MOD3.Bloat = MOD3.Class(MOD3.Modifier, {
1784
+ constructor: function Bloat(radius, a, center) {
1785
+ var self = this;
1786
+ if (!(self instanceof Bloat)) return new Bloat(radius, a, center);
1787
+ self.$super('constructor');
1788
+ self.name = 'Bloat';
1789
+ self.radius = radius || 0;
1790
+ self.a = null == a ? 0.01 : a;
1791
+ self.center = center || MOD3.Vector3.ZERO();
1792
+ //self.u = MOD3.Vector3.ZERO();
1793
+ },
1794
+
1795
+ radius: 0,
1796
+ a: 0.01,
1797
+ center: null,
1798
+ //u: null,
1799
+
1800
+ dispose: function() {
1801
+ var self = this;
1802
+ self.center.dispose();
1803
+ self.center = null;
1804
+ self.radius = null;
1805
+ self.a = null;
1806
+ self.$super('dispose');
1807
+ return self;
1808
+ },
1809
+
1810
+ apply: function(modifiable) {
1811
+ var self = this, center = self.center.xyz,
1812
+ radius = stdMath.max(0, self.radius), a = stdMath.max(0, self.a);
1813
+
1814
+ MOD3.List.each(modifiable.vertices, function(v) {
1815
+ // get a vector towards vertex
1816
+ // change norm to norm + r * exp (-a * norm)
1817
+ var uu = MOD3.Vector3.sub(v.getXYZ(), center), magn = MOD3.Vector3.mod(uu);
1818
+ MOD3.Vector3.muls(MOD3.Vector3.norm(uu), magn + radius * stdMath.exp(- magn * a));
1819
+ // move vertex accordingly
1820
+ v.setXYZ(MOD3.Vector3.add(uu, center));
1821
+ // ?? needed??
1822
+ //self.u=uu;
1823
+ });
1824
+ return self;
1825
+ }
1826
+ });
1827
+ }(MOD3);!function(MOD3) {
1828
+ "use strict";
1829
+ /**
1830
+ * MOD3 Twist Modifier
1831
+ **/
1832
+
1833
+ /**[DOC_MD]
1834
+ * ### Twist modifier
1835
+ *
1836
+ * Twist mesh along an axis
1837
+ * Adapted from the Twist modifier for PV3D
1838
+ *
1839
+ [/DOC_MD]**/
1840
+ MOD3.Twist = MOD3.Class(MOD3.Modifier, {
1841
+ constructor: function Twist(angle, vector, center) {
1842
+ var self = this;
1843
+ if (!(self instanceof Twist)) return new Twist(angle, vector, center);
1844
+ self.$super('constructor');
1845
+ self.name = 'Twist';
1846
+ self.angle = angle || 0;
1847
+ self.vector = vector || MOD3.Vector3.Y();
1848
+ self.center = center || MOD3.Vector3.ZERO();
1849
+ },
1850
+
1851
+ angle: 0,
1852
+ vector: null,
1853
+ center: null,
1854
+
1855
+ dispose: function() {
1856
+ var self = this;
1857
+ self.vector.dispose();
1858
+ self.vector = null;
1859
+ self.angle = null;
1860
+ self.center.dispose();
1861
+ self.center = null;
1862
+ self.$super('dispose');
1863
+ return self;
1864
+ },
1865
+
1866
+ apply: function(modifiable) {
1867
+ var self = this,
1868
+ tvec = self.vector.normalizeSelf().xyz, angle = self.angle, center = self.center.xyz,
1869
+ modulo = MOD3.Vector3.mod([0.5*modifiable.maxX, 0.5*modifiable.maxY, 0.5*modifiable.maxZ]),
1870
+ d = -MOD3.Vector3.dot(tvec, center),
1871
+ m1 = new MOD3.Matrix4(), m2 = new MOD3.Matrix4()
1872
+ ;
1873
+
1874
+ MOD3.List.each(modifiable.vertices, function(v) {
1875
+ var xyz = v.getXYZ(),
1876
+ a = (MOD3.Vector3.dot(xyz, tvec) + d) * angle / modulo,
1877
+ m = MOD3.Matrix4.mult(
1878
+ m2.rotate(tvec[0], tvec[1], tvec[2], a, true),
1879
+ m1.translate(xyz[0], xyz[1], xyz[2], true)
1880
+ )
1881
+ ;
1882
+ v.setXYZ([m.m[3], m.m[7], m.m[11]]);
1883
+ });
1884
+ return self;
1885
+ }
1886
+ });
1887
+ }(MOD3);!function(MOD3) {
1888
+ "use strict";
1889
+ /**
1890
+ * MOD3 Skew Modifier
1891
+ **/
1892
+
1893
+ /**[DOC_MD]
1894
+ * ### Skew modifier
1895
+ *
1896
+ * Skew mesh along an axis
1897
+ *
1898
+ * @author Bartek Drozdz
1899
+ *
1900
+ [/DOC_MD]**/
1901
+ var stdMath = Math;
1902
+
1903
+ MOD3.Skew = MOD3.Class(MOD3.Modifier, {
1904
+ constructor: function Skew(force, offset, power, falloff) {
1905
+ var self = this;
1906
+ if (!(self instanceof Skew)) return new Skew(force, offset, power, falloff);
1907
+ self.$super('constructor');
1908
+ self.name = 'Skew';
1909
+ self.constraint = MOD3.ModConstant.NONE;
1910
+ self.force = force != null ? force : 0;
1911
+ self.offset = offset != null ? offset : 0.5;
1912
+ self.power = power != null ? power : 1;
1913
+ self.falloff = falloff != null ? falloff : 1;
1914
+ self.inverseFalloff = false;
1915
+ self.oneSide = false;
1916
+ self.swapAxes = false;
1917
+ self.skewAxis = 0;
1918
+ },
1919
+
1920
+ force: 0,
1921
+ skewAxis: 0,
1922
+ offset: 0.5,
1923
+ power: 1,
1924
+ falloff: 1,
1925
+ inverseFalloff: false,
1926
+ oneSide: false,
1927
+ swapAxes: false,
1928
+
1929
+ dispose: function() {
1930
+ var self = this;
1931
+ self.force = null;
1932
+ self.skewAxis = null;
1933
+ self.offset = null;
1934
+ self.power = null;
1935
+ self.falloff = null;
1936
+ self.inverseFalloff = null;
1937
+ self.oneSide = null;
1938
+ self.swapAxes = null;
1939
+ self.$super('dispose');
1940
+ return self;
1941
+ },
1942
+
1943
+ apply: function(modifiable) {
1944
+ var self = this,
1945
+ constraint = self.constraint,
1946
+ skewAxis = self.skewAxis || modifiable.maxAxis,
1947
+ swapAxes = self.swapAxes,
1948
+ offset = stdMath.min(1, stdMath.max(0, self.offset)),
1949
+ oneSide = self.oneSide,
1950
+ inverseFalloff = !!self.inverseFalloff,
1951
+ falloff = stdMath.min(1, stdMath.max(0, self.falloff)),
1952
+ mirrorfalloff = 1-falloff,
1953
+ power = self.power,
1954
+ force = self.force,
1955
+ displaceAxis = MOD3.ModConstant.X === skewAxis
1956
+ ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.Y)
1957
+ : (MOD3.ModConstant.Y === skewAxis
1958
+ ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.X)
1959
+ : (MOD3.ModConstant.Z === skewAxis
1960
+ ? (swapAxes ? MOD3.ModConstant.Y : MOD3.ModConstant.X)
1961
+ : 0))
1962
+ ;
1963
+
1964
+ MOD3.List.each(modifiable.vertices, function(v) {
1965
+ var r, dr, f, p, vRatio;
1966
+ vRatio = v.getRatio(skewAxis);
1967
+ if ((MOD3.ModConstant.LEFT === constraint) && (vRatio <= offset)) return;
1968
+ if ((MOD3.ModConstant.RIGHT === constraint) && (vRatio > offset)) return;
1969
+
1970
+ r = vRatio - offset;
1971
+ if (oneSide && (0 > r)) r = -r;
1972
+
1973
+ dr = v.getRatio(displaceAxis);
1974
+ if (inverseFalloff) dr = 1 - dr;
1975
+
1976
+ f = falloff + dr * mirrorfalloff;
1977
+ p = (0 > r ? -1 : 1) * stdMath.pow(stdMath.abs(r), power);
1978
+ v.setValue(displaceAxis, v.getValue(displaceAxis) + force * p * f);
1979
+ });
1980
+ return self;
1981
+ },
1982
+ });
1983
+ }(MOD3);!function(MOD3) {
1984
+ "use strict";
1985
+ /**
1986
+ * MOD3 Taper Modifier
1987
+ **/
1988
+
1989
+ /**[DOC_MD]
1990
+ * ### Taper modifier
1991
+ *
1992
+ * The taper modifier displaces the vertices on two axes proportionally to their position on the third axis.
1993
+ *
1994
+ * @author Bartek Drozdz
1995
+ *
1996
+ [/DOC_MD]**/
1997
+ var stdMath = Math;
1998
+
1999
+ MOD3.Taper = MOD3.Class(MOD3.Modifier, {
2000
+ constructor: function Taper(force, power, v1, v2) {
2001
+ var self = this;
2002
+ if (!(self instanceof Taper)) return new Taper(force, power, v1, v2);
2003
+ self.$super('constructor');
2004
+ self.name = 'Taper';
2005
+ /*self.start = 0;
2006
+ self.end = 1;*/
2007
+ self.force = force != null ? force : 0;
2008
+ self.power = power != null ? power : 1;
2009
+ self.vector = v1 || MOD3.Vector3.Y(false);
2010
+ self.vector2 = v2 || MOD3.Vector3.Y();
2011
+ },
2012
+
2013
+ force: 0,
2014
+ power: 1,
2015
+ /*start: 0,
2016
+ end: 1,*/
2017
+ vector: null,
2018
+ vector2: null,
2019
+
2020
+ /*setFalloff : function(start, end) {
2021
+ this.start = (start!==undef) ? start : 0;
2022
+ this.end = (end!==undef) ? end : 1;
2023
+
2024
+ return this;
2025
+ },*/
2026
+
2027
+ dispose: function() {
2028
+ var self = this;
2029
+ self.vector.dispose();
2030
+ self.vector2.dispose();
2031
+ self.vector = null;
2032
+ self.vector2 = null;
2033
+ self.force = null;
2034
+ self.power = null;
2035
+ self.$super('dispose');
2036
+ return self;
2037
+ },
2038
+
2039
+ apply: function(modifiable) {
2040
+ var self = this,
2041
+ vec = self.vector.xyz, vec2 = self.vector2.xyz,
2042
+ force = self.force, power = self.power, m = new MOD3.Matrix4();
2043
+
2044
+ MOD3.List.each(modifiable.vertices, 1 !== power
2045
+ ? function(v) {
2046
+ var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * stdMath.pow(ar, power);
2047
+ v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ()));
2048
+ }
2049
+ : function(v) {
2050
+ var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * ar;
2051
+ v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ()));
2052
+ }
2053
+ );
2054
+ return self;
2055
+ }
2056
+ });
2057
+ }(MOD3);!function(MOD3) {
2058
+ "use strict";
2059
+ /**
2060
+ * MOD3 Wheel Modifier
2061
+ **/
2062
+
2063
+ /**[DOC_MD]
2064
+ * ### Wheel modifier
2065
+ *
2066
+ * Use it with vehicle models for wheels.
2067
+ *
2068
+ * The usual problem with a 3d wheel in a vahicle is that it is
2069
+ * supposed to turn (steer) and roll in the same time.
2070
+ * So, this code:
2071
+ *
2072
+ * ```javascript
2073
+ * wheel.rotationY = 10; // Steer 10deg to the left
2074
+ * wheel.rotationZ += 5; // Roll with a speed of 5
2075
+ * ```
2076
+ * This will make the wheel roll incorectly.
2077
+ *
2078
+ * A usual way to solve this problem is to put the wheel in another DisplayObject3D/Mesh,
2079
+ * turn the parent and roll the child, like that:
2080
+ * ```javascript
2081
+ * steer.rotationY = 10; // Steer 10deg to the left
2082
+ * steer.wheel.rotationZ += 5; // Roll with a speed of 5
2083
+ * ```
2084
+ * That will make the wheel behave correctly. But it can be uncomfortanble to apply, especially
2085
+ * to imported complex Collada models.
2086
+ *
2087
+ * The Wheel modifier elegantly solves this problem by doind the proper math in order to steer and roll
2088
+ * a single mesh at the same time. The only thing you need to do is to specify a steer vector and
2089
+ * roll vector - usually it will be 2 of the cardinal axes. The default value is:
2090
+ *
2091
+ * * steer - along the Y axis / new Vector3(0, 1, 0)
2092
+ * * roll - along the Z axis / new Vector3(0, 0, 1)
2093
+ *
2094
+ *
2095
+ * It should work with most car models imported from 3D editors as this is the natural position of a wheel.
2096
+ *
2097
+ * *Please note, that Papervision primitive cylinder, which may also be used as wheel, will require different axes
2098
+ * (Y for roll and Z or X for steer).*
2099
+ *
2100
+ * @author Bartek Drozdz
2101
+ *
2102
+ [/DOC_MD]**/
2103
+ MOD3.Wheel = MOD3.Class(MOD3.Modifier, {
2104
+ constructor: function Wheel(speed, turn, roll, steerVector, rollVector) {
2105
+ var self = this;
2106
+ if (!(self instanceof Wheel)) return new Wheel(speed, turn, roll, steerVector, rollVector);
2107
+ self.$super('constructor');
2108
+ self.name = 'Wheel';
2109
+ self.speed = speed || 0;
2110
+ self.turn = turn || 0;
2111
+ self.roll = roll || 0;
2112
+ self.steerVector = steerVector || MOD3.Vector3.Y();
2113
+ self.rollVector = rollVector || MOD3.Vector3.Z();
2114
+ },
2115
+
2116
+ speed: 0,
2117
+ turn: 0,
2118
+ roll: 0,
2119
+ steerVector: null,
2120
+ rollVector: null,
2121
+
2122
+ dispose: function() {
2123
+ var self = this;
2124
+ self.speed = null;
2125
+ self.turn = null;
2126
+ self.roll = null;
2127
+ self.steerVector.dispose();
2128
+ self.rollVector.dispose();
2129
+ self.steerVector = null;
2130
+ self.rollVector = null;
2131
+ self.$super('dispose');
2132
+
2133
+ return self;
2134
+ },
2135
+
2136
+ apply: function(modifiable) {
2137
+ var self = this,
2138
+ steerVector = self.steerVector.normalizeSelf(),
2139
+ rollVector = self.rollVector.normalizeSelf(),
2140
+ turn = self.turn, roll = self.roll,
2141
+ //radius = 0.5*modifiable.width,
2142
+ //step = radius * self.speed / PI,
2143
+ //perimeter = radius * TWO_PI,
2144
+ ms = null, mt = null
2145
+ ;
2146
+
2147
+ self.roll += self.speed;
2148
+
2149
+ if (turn)
2150
+ {
2151
+ mt = new MOD3.Matrix4().rotateFromVector(steerVector, turn);
2152
+ ms = new MOD3.Matrix4().rotateFromVector(mt.multiplyVector(rollVector.clone()), roll);
2153
+ }
2154
+ else
2155
+ {
2156
+ ms = new MOD3.Matrix4().rotateFromVector(rollVector, roll);
2157
+ }
2158
+
2159
+ MOD3.List.each(modifiable.vertices, mt
2160
+ ? function(v) {
2161
+ v.setXYZ(MOD3.Matrix4.multXYZ(ms, MOD3.Matrix4.multXYZ(mt, v.getXYZ())));
2162
+ }
2163
+ : function(v) {
2164
+ v.setXYZ(MOD3.Matrix4.multXYZ(ms, v.getXYZ()));
2165
+ }
2166
+ );
2167
+ return self;
2168
+ }
2169
+ });
2170
+ }(MOD3);!function(MOD3) {
2171
+ "use strict";
2172
+ /**
2173
+ * MOD3 Break Modifier
2174
+ **/
2175
+
2176
+ /**[DOC_MD]
2177
+ * ### Break modifier
2178
+ *
2179
+ * Allow to break a mesh
2180
+ *
2181
+ * @author Bartek Drozdz
2182
+ *
2183
+ [/DOC_MD]**/
2184
+ var stdMath = Math;
2185
+
2186
+ MOD3.Break = MOD3.Class(MOD3.Modifier, {
2187
+ constructor: function Break(offset, angle, vector) {
2188
+ var self = this;
2189
+ if (!(self instanceof Break)) return new Break(offset, angle, vector);
2190
+ self.$super('constructor');
2191
+ self.name = 'Break';
2192
+ self.offset = offset || 0;
2193
+ self.angle = angle || 0;
2194
+ self.vector = vector || MOD3.Vector3.Y();
2195
+ self.range = new MOD3.Range(0, 1);
2196
+ },
2197
+
2198
+ offset: 0,
2199
+ angle: 0,
2200
+ vector: null,
2201
+ range: null,
2202
+
2203
+ dispose: function() {
2204
+ var self = this;
2205
+ self.vector.dispose();
2206
+ self.range.dispose();
2207
+ self.vector = null;
2208
+ self.range = null;
2209
+ self.offset = null;
2210
+ self.angle = null;
2211
+ self.$super('dispose');
2212
+ return self;
2213
+ },
2214
+
2215
+ apply: function(modifiable) {
2216
+ var self = this,
2217
+ offset = stdMath.min(1, stdMath.max(0, self.offset)), range = self.range, angle = self.angle,
2218
+ bv = self.vector.normalizeSelf().xyz, pv, rm;
2219
+
2220
+ pv = modifiable.minZ + modifiable.depth*offset;
2221
+ rm = new MOD3.Matrix4().rotate(bv[0], bv[1], bv[2], angle);
2222
+
2223
+ MOD3.List.each(modifiable.vertices, function(v) {
2224
+ var c = v.getXYZ();
2225
+ c[2] -= pv;
2226
+ if ((0 <= c[2]) && range.isIn(v.ratio[1])) MOD3.Matrix4.multXYZ(rm, c);
2227
+ c[2] += pv;
2228
+ v.setXYZ(c);
2229
+ });
2230
+ return self;
2231
+ }
2232
+ });
2233
+ }(MOD3);!function(MOD3) {
2234
+ "use strict";
2235
+ /**
2236
+ * MOD3 Noise Modifier
2237
+ **/
2238
+
2239
+ /**[DOC_MD]
2240
+ * ### Noise modifier
2241
+ *
2242
+ * Randomly displaces each vertex in all 3 axes
2243
+ *
2244
+ *
2245
+ [/DOC_MD]**/
2246
+ var stdMath = Math;
2247
+
2248
+ MOD3.Noise = MOD3.Class(MOD3.Modifier, {
2249
+ constructor: function Noise(force) {
2250
+ var self = this;
2251
+ if (!(self instanceof Noise)) return new Noise(force);
2252
+ self.$super('constructor');
2253
+ self.name = 'Noise';
2254
+ self.force = force || 0;
2255
+ self.start = 0;
2256
+ self.end = 1;
2257
+ self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z;
2258
+ },
2259
+
2260
+ force: 0,
2261
+ start: 0,
2262
+ end: 1,
2263
+
2264
+ dispose: function() {
2265
+ var self = this;
2266
+ self.force = null;
2267
+ self.start = null;
2268
+ self.end = null;
2269
+ self.$super('dispose');
2270
+ return self;
2271
+ },
2272
+
2273
+ setFalloff: function(start, end) {
2274
+ var self = this;
2275
+ self.start = start != null ? start : 0;
2276
+ self.end = end != null ? end : 1;
2277
+ return self;
2278
+ },
2279
+
2280
+ apply: function(modifiable) {
2281
+ var self = this,
2282
+ axes = self.axes, start = self.start, end = self.end,
2283
+ force = self.force, halfforce = 0.5*force,
2284
+ maxAxis = modifiable.maxAxis;
2285
+
2286
+ if ((0 == axes) || (0 == force)) return self;
2287
+
2288
+ MOD3.List.each(modifiable.vertices, function(v) {
2289
+ var r = stdMath.random() * force - halfforce,
2290
+ p = v.getRatio(maxAxis), rp, xyz;
2291
+ if (start < end)
2292
+ {
2293
+ if (p < start) p = 0;
2294
+ else if (p > end) p = 1;
2295
+ }
2296
+ else if (start > end)
2297
+ {
2298
+ p = 1 - p;
2299
+ if (p > start) p = 0;
2300
+ else if (p < end) p = 1;
2301
+ }
2302
+ else
2303
+ {
2304
+ p = 1;
2305
+ }
2306
+
2307
+ rp = r * p;
2308
+ xyz = v.getXYZ();
2309
+ v.setXYZ([
2310
+ xyz[0] + (axes & MOD3.ModConstant.X ? rp : 0),
2311
+ xyz[1] + (axes & MOD3.ModConstant.Y ? rp : 0),
2312
+ xyz[2] + (axes & MOD3.ModConstant.Z ? rp : 0)
2313
+ ]);
2314
+ });
2315
+ return self;
2316
+ }
2317
+ });
2318
+ }(MOD3);!function(MOD3) {
2319
+ "use strict";
2320
+ /**
2321
+ * MOD3 DisplaceMap (BitmapDisplacement) Modifier
2322
+ **/
2323
+
2324
+ /**[DOC_MD]
2325
+ * ### DisplaceMap (BitmapDisplacement) Modifier
2326
+ *
2327
+ * Displaces vertices based on RGB values of bitmapData pixels.
2328
+ *
2329
+ * BitmapDisplacement is inspired by both the AS3 built-in DisplacementMapFilter. It allows
2330
+ * to use color values for each channels of a bitmap to modify the position of vertices in a mesh.
2331
+ *
2332
+ * The displacement takes place along the cardinal axes, and each axis is mapped to a
2333
+ * channel in the bitmap: X for Red, Y for Green and Z for Blue.
2334
+ *
2335
+ * @author Bartek Drozdz
2336
+ *
2337
+ [/DOC_MD]**/
2338
+ MOD3.DisplaceMap = MOD3.Class(MOD3.Modifier, {
2339
+ constructor: function DisplaceMap(bmp, force, offset) {
2340
+ var self = this;
2341
+ if (!(self instanceof DisplaceMap)) return new DisplaceMap(bmp, force, offset);
2342
+ self.$super('constructor');
2343
+ self.name = 'DisplaceMap';
2344
+ if (+bmp === bmp) // number
2345
+ {
2346
+ self.force = bmp || 1;
2347
+ self.offset = null == force ? 127 : force;// 0x7F;
2348
+ }
2349
+ else
2350
+ {
2351
+ self.setBitmap(bmp);
2352
+ self.force = force || 1;
2353
+ self.offset = null == offset ? 127 : offset;// 0x7F;
2354
+ }
2355
+ self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z;
2356
+ },
2357
+
2358
+ width: null,
2359
+ height: null,
2360
+ bmpData: null,
2361
+ force: 1,
2362
+ offset: 127,
2363
+
2364
+ dispose: function() {
2365
+ var self = this;
2366
+ self.bmpData = null;
2367
+ self.width = null;
2368
+ self.height = null;
2369
+ self.force = null;
2370
+ self.offset = null;
2371
+ self.$super('dispose');
2372
+ return self;
2373
+ },
2374
+
2375
+ setBitmap: function(bmpData) {
2376
+ var self = this;
2377
+ self.bmpData = bmpData ? bmpData.data : null;
2378
+ self.width = bmpData ? bmpData.width : 0;
2379
+ self.height = bmpData ? bmpData.height : 0;
2380
+ return self;
2381
+ },
2382
+
2383
+ apply: function(modifiable) {
2384
+ var self = this,
2385
+ axes = self.axes,
2386
+ w = self.width, h = self.height, bmp = self.bmpData,
2387
+ force = self.force, offset = self.offset;
2388
+
2389
+ if (!axes || !bmp) return self;
2390
+
2391
+ MOD3.List.each(modifiable.vertices, function(v) {
2392
+ var uv, uu, vv, xyz = v.getXYZ();
2393
+
2394
+ uu = ~~((w - 1) * v.ratio[0]/* X */);
2395
+ vv = ~~((h - 1) * v.ratio[2]/* Z */);
2396
+ uv = (vv * w + uu) << 2;
2397
+
2398
+ v.setXYZ([
2399
+ xyz[0] + (axes & MOD3.ModConstant.X ? ((bmp[uv] & 0xff) - offset) * force : 0),
2400
+ xyz[1] + (axes & MOD3.ModConstant.Y ? ((bmp[uv+1] & 0xff) - offset) * force : 0),
2401
+ xyz[2] + (axes & MOD3.ModConstant.Z ? ((bmp[uv+2] & 0xff) - offset) * force : 0)
2402
+ ]);
2403
+ });
2404
+ return self;
2405
+ }
2406
+ });
2407
+ }(MOD3);!function(MOD3) {
2408
+ "use strict";
2409
+ /**
2410
+ * MOD3 Perlin/Simplex Noise Modifier
2411
+ **/
2412
+
2413
+ /**[DOC_MD]
2414
+ * ### Perlin modifier
2415
+ *
2416
+ * Displaces vertices based on a perlin/simplex noise source.
2417
+ *
2418
+ * Accepts a perlin/simplex noise data (with width and height information) and displaces vertices
2419
+ * based on the value of each point of the noise map.
2420
+ *
2421
+ * @author Bartek Drozdz
2422
+ *
2423
+ * @uses: https://github.com/josephg/noisejs for JavaScript
2424
+ *
2425
+ [/DOC_MD]**/
2426
+ function cyclic_shift(a, w, h, dX, dY)
2427
+ {
2428
+ var size = w*h, b = new MOD3.VecArray(size), i, j, i2, j2, index;
2429
+ if (dX < 0) dX += w;
2430
+ if (dY < 0) dY += h;
2431
+ dX = ~~dX; dY = ~~dY;
2432
+ for (i=0,j=0,index=0; index<size; ++index,++i)
2433
+ {
2434
+ if (i >= w) {i = 0; ++j;}
2435
+ i2 = (i + dX) % w; j2 = (j + dY) % h;
2436
+ b[index] = a[i2 + j2 * w];
2437
+ }
2438
+ return b;
2439
+ }
2440
+ /*function generate2d(perlinNoise2d, w, h)
2441
+ {
2442
+ var size = w*h, a = new MOD3.VecArray(size), i, j, index;
2443
+ for (i=0,j=0,index=0; index<size; ++index,++i)
2444
+ {
2445
+ if (i >= w) {i = 0; ++j;}
2446
+ a[index] = perlinNoise2d(i/w, j/h);
2447
+ }
2448
+ return a;
2449
+ }*/
2450
+ MOD3.Perlin = MOD3.Class(MOD3.Modifier, {
2451
+ constructor: function Perlin(force, noise, autoRun) {
2452
+ var self = this;
2453
+ if (!(self instanceof Perlin)) return new Perlin(force, noise, autoRun);
2454
+ self.$super('constructor');
2455
+ self.name = 'Perlin';
2456
+ self.force = null != force ? force : 1;
2457
+ self.perlin = noise;
2458
+ self.autoRun = null != autoRun ? !!autoRun : true;
2459
+ self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z;
2460
+ },
2461
+
2462
+ speedX: 1,
2463
+ speedY: 1,
2464
+ perlin: null,
2465
+ force: 1,
2466
+ offset: 0,
2467
+ autoRun: true,
2468
+
2469
+ dispose: function() {
2470
+ var self = this;
2471
+ self.perlin = null;
2472
+ self.speedX = null;
2473
+ self.speedY = null;
2474
+ self.force = null;
2475
+ self.offset = null;
2476
+ self.autoRun = null;
2477
+ self.$super('dispose');
2478
+
2479
+ return self;
2480
+ },
2481
+
2482
+ setSpeed: function(dX, dY) {
2483
+ var self = this;
2484
+ self.speedX = dX;
2485
+ self.speedY = dY;
2486
+ return self;
2487
+ },
2488
+
2489
+ apply: function(modifiable) {
2490
+ var self = this,
2491
+ axes = self.axes, force = self.force,
2492
+ offset = self.offset, pn = self.perlin,
2493
+ w, h;
2494
+
2495
+ if (!axes || !pn) return self;
2496
+ w = pn.width; h = pn.height;
2497
+ if (self.autoRun)
2498
+ {
2499
+ pn = self.perlin = cyclic_shift(pn, w, h, self.speedX, self.speedY);
2500
+ pn.width = w; pn.height = h;
2501
+ }
2502
+
2503
+ MOD3.List.each(modifiable.vertices, function(v) {
2504
+ var xyz = v.getXYZ(),
2505
+ uu = ~~((w - 1) * v.ratio[0]/* u */),
2506
+ vv = ~~((h - 1) * v.ratio[2]/* v */),
2507
+ uv = uu + vv * w;
2508
+
2509
+ v.setXYZ([
2510
+ xyz[0] + (axes & MOD3.ModConstant.X ? (pn[uv] - offset) * force : 0),
2511
+ xyz[1] + (axes & MOD3.ModConstant.Y ? (pn[uv/*+1*/] - offset) * force : 0),
2512
+ xyz[2] + (axes & MOD3.ModConstant.Z ? (pn[uv/*+2*/] - offset) * force : 0)
2513
+ ]);
2514
+ });
2515
+ return self;
2516
+ }
2517
+ });
2518
+ }(MOD3);// export it
2519
+ return MOD3;
2520
+ });
libs/pdf.js ADDED
The diff for this file is too large to render. See raw diff
 
libs/pdf.worker.js ADDED
The diff for this file is too large to render. See raw diff
 
libs/three.js ADDED
The diff for this file is too large to render. See raw diff