littlejsengine 1.18.26 → 1.18.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/littlejs.d.ts +22 -0
- package/dist/littlejs.esm.js +70 -6
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +66 -6
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +66 -6
- package/package.json +2 -1
- package/plugins/threejs.js +3 -0
- package/src/engine.js +1 -1
- package/src/engineDraw.js +15 -0
- package/src/engineExport.js +4 -0
- package/src/engineInput.js +34 -5
- package/src/engineSettings.js +13 -0
package/dist/littlejs.release.js
CHANGED
|
@@ -35,7 +35,7 @@ const engineName = 'LittleJS';
|
|
|
35
35
|
* @type {string}
|
|
36
36
|
* @default
|
|
37
37
|
* @memberof Engine */
|
|
38
|
-
const engineVersion = '1.18.
|
|
38
|
+
const engineVersion = '1.18.27';
|
|
39
39
|
|
|
40
40
|
/** Frames per second to update
|
|
41
41
|
* @type {number}
|
|
@@ -2346,6 +2346,14 @@ let gamepadsEnable = true;
|
|
|
2346
2346
|
* @memberof Settings */
|
|
2347
2347
|
let gamepadDirectionEmulateStick = true;
|
|
2348
2348
|
|
|
2349
|
+
/** If true, axes that do not rest near center are ignored on gamepads without
|
|
2350
|
+
* standard mapping. Steering wheels and flight sticks report pedal and throttle
|
|
2351
|
+
* axes that rest at full deflection, which otherwise reads as a stick held down.
|
|
2352
|
+
* @type {boolean}
|
|
2353
|
+
* @default
|
|
2354
|
+
* @memberof Settings */
|
|
2355
|
+
let gamepadAxisFilterEnable = true;
|
|
2356
|
+
|
|
2349
2357
|
/** If true the WASD keys are also routed to the direction keys (for better accessibility)
|
|
2350
2358
|
* @type {boolean}
|
|
2351
2359
|
* @default
|
|
@@ -2684,6 +2692,11 @@ function setGamepadsEnable(enable) { gamepadsEnable = enable; }
|
|
|
2684
2692
|
* @memberof Settings */
|
|
2685
2693
|
function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
|
|
2686
2694
|
|
|
2695
|
+
/** Set if axes that do not rest near center are ignored on non-standard gamepads
|
|
2696
|
+
* @param {boolean} enable
|
|
2697
|
+
* @memberof Settings */
|
|
2698
|
+
function setGamepadAxisFilterEnable(enable) { gamepadAxisFilterEnable = enable; }
|
|
2699
|
+
|
|
2687
2700
|
/** Set if true the WASD keys are also routed to the direction keys
|
|
2688
2701
|
* @param {boolean} enable
|
|
2689
2702
|
* @memberof Settings */
|
|
@@ -3428,6 +3441,12 @@ let workReadCanvas;
|
|
|
3428
3441
|
* @memberof Draw */
|
|
3429
3442
|
let workReadContext;
|
|
3430
3443
|
|
|
3444
|
+
/** Extra canvas to composite behind the engine canvases when combining canvases
|
|
3445
|
+
* Set by plugins that render to their own canvas below the LittleJS canvases
|
|
3446
|
+
* @type {HTMLCanvasElement}
|
|
3447
|
+
* @memberof Draw */
|
|
3448
|
+
let backgroundCanvas;
|
|
3449
|
+
|
|
3431
3450
|
/** The size of the main canvas (and other secondary canvases)
|
|
3432
3451
|
* @type {Vector2}
|
|
3433
3452
|
* @memberof Draw */
|
|
@@ -4579,6 +4598,13 @@ function setAdditiveBlendMode(additive=true)
|
|
|
4579
4598
|
drawContext.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
4580
4599
|
}
|
|
4581
4600
|
|
|
4601
|
+
/** Set an extra canvas to composite behind the engine canvases when combining
|
|
4602
|
+
* Plugins that insert their own canvas below the LittleJS canvases should set
|
|
4603
|
+
* this so it appears in screenshots and video capture
|
|
4604
|
+
* @param {HTMLCanvasElement} [canvas]
|
|
4605
|
+
* @memberof Draw */
|
|
4606
|
+
function setBackgroundCanvas(canvas) { backgroundCanvas = canvas; }
|
|
4607
|
+
|
|
4582
4608
|
/** Combines LittleJS canvases onto the main canvas
|
|
4583
4609
|
* This is necessary for things like screenshots and video
|
|
4584
4610
|
* @memberof Draw */
|
|
@@ -4591,6 +4617,8 @@ function combineCanvases()
|
|
|
4591
4617
|
// leaving workContext.fillStyle transparent can't silently no-op this
|
|
4592
4618
|
workContext.fillStyle = '#000';
|
|
4593
4619
|
workContext.fillRect(0,0,w,h);
|
|
4620
|
+
if (backgroundCanvas)
|
|
4621
|
+
workContext.drawImage(backgroundCanvas, 0, 0, w, h);
|
|
4594
4622
|
glCopyToContext(workContext);
|
|
4595
4623
|
workContext.drawImage(mainCanvas, 0, 0);
|
|
4596
4624
|
mainContext.drawImage(workCanvas, 0, 0);
|
|
@@ -4989,6 +5017,7 @@ function inputClear()
|
|
|
4989
5017
|
touchGamepadStickPointerId.length = 0; // release floating sticks so they re-anchor
|
|
4990
5018
|
gamepadStickData.length = 0;
|
|
4991
5019
|
gamepadDpadData.length = 0;
|
|
5020
|
+
gamepadAxisCentered.length = 0;
|
|
4992
5021
|
}
|
|
4993
5022
|
|
|
4994
5023
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -5226,6 +5255,11 @@ const inputData = [[]];
|
|
|
5226
5255
|
|
|
5227
5256
|
// gamepad internal variables
|
|
5228
5257
|
const gamepadStickData = [], gamepadDpadData = [], gamepadHadInput = [];
|
|
5258
|
+
// per gamepad, how many consecutive frames each axis has rested inside the
|
|
5259
|
+
// dead zone, used to tell stick axes from axes that rest at full deflection
|
|
5260
|
+
const gamepadAxisCentered = [];
|
|
5261
|
+
// how long an axis must rest inside the dead zone before it counts as a stick
|
|
5262
|
+
const gamepadAxisCenteredFrames = 15;
|
|
5229
5263
|
|
|
5230
5264
|
// touch gamepad internal variables
|
|
5231
5265
|
const touchGamepadTimer = new Timer, touchGamepadButtons = [], touchGamepadSticks = [];
|
|
@@ -5474,7 +5508,7 @@ function inputUpdate()
|
|
|
5474
5508
|
// gamepad: any button held or stick moved
|
|
5475
5509
|
let gamepadActive = false;
|
|
5476
5510
|
for (let s = gamepadStickCount(); s-- && !gamepadActive;)
|
|
5477
|
-
gamepadActive = gamepadStick(s).lengthSquared() > .
|
|
5511
|
+
gamepadActive = gamepadStick(s).lengthSquared() > .2;
|
|
5478
5512
|
for (let b = 17; b-- && !gamepadActive;)
|
|
5479
5513
|
gamepadActive = gamepadIsDown(b);
|
|
5480
5514
|
|
|
@@ -5502,12 +5536,12 @@ function inputUpdate()
|
|
|
5502
5536
|
// gamepads are updated by engine every frame automatically
|
|
5503
5537
|
function gamepadsUpdate()
|
|
5504
5538
|
{
|
|
5539
|
+
const deadZoneMin=.3, deadZoneMax=.8;
|
|
5505
5540
|
const applyDeadZones = (v)=>
|
|
5506
5541
|
{
|
|
5507
|
-
const min=.3, max=.8;
|
|
5508
5542
|
const deadZone = (v)=>
|
|
5509
|
-
v >
|
|
5510
|
-
v < -
|
|
5543
|
+
v > deadZoneMin ? percent(v, deadZoneMin, deadZoneMax) :
|
|
5544
|
+
v < -deadZoneMin ? -percent(-v, deadZoneMin, deadZoneMax) : 0;
|
|
5511
5545
|
return vec2(deadZone(v.x), deadZone(-v.y)).clampLength();
|
|
5512
5546
|
};
|
|
5513
5547
|
|
|
@@ -5591,6 +5625,7 @@ function inputUpdate()
|
|
|
5591
5625
|
gamepadStickData[i] = undefined;
|
|
5592
5626
|
gamepadDpadData[i] = undefined;
|
|
5593
5627
|
gamepadHadInput[i] = undefined;
|
|
5628
|
+
gamepadAxisCentered[i] = undefined;
|
|
5594
5629
|
continue;
|
|
5595
5630
|
}
|
|
5596
5631
|
|
|
@@ -5599,8 +5634,30 @@ function inputUpdate()
|
|
|
5599
5634
|
const dpad = gamepadDpadData[i] ?? (gamepadDpadData[i] = vec2());
|
|
5600
5635
|
|
|
5601
5636
|
// read analog sticks
|
|
5637
|
+
// gamepads without standard mapping (steering wheels, flight sticks)
|
|
5638
|
+
// can report axes that rest at full deflection instead of center,
|
|
5639
|
+
// which would otherwise read as a stick held down forever, so only
|
|
5640
|
+
// trust an axis once it has rested inside the dead zone for a moment
|
|
5641
|
+
const isStandard = gamepad.mapping === 'standard';
|
|
5642
|
+
const centered = gamepadAxisCentered[i] ?? (gamepadAxisCentered[i] = []);
|
|
5643
|
+
const readAxis = (j)=>
|
|
5644
|
+
{
|
|
5645
|
+
const v = gamepad.axes[j];
|
|
5646
|
+
if (isStandard && j < 4)
|
|
5647
|
+
return v; // spec guarantees axes 0-3 are the two sticks
|
|
5648
|
+
if (!gamepadAxisFilterEnable)
|
|
5649
|
+
return v;
|
|
5650
|
+
|
|
5651
|
+
// once an axis has proven it rests at center it stays trusted,
|
|
5652
|
+
// otherwise moving it would immediately disqualify it again
|
|
5653
|
+
const frames = centered[j] | 0;
|
|
5654
|
+
if (frames > gamepadAxisCenteredFrames)
|
|
5655
|
+
return v;
|
|
5656
|
+
centered[j] = abs(v) < deadZoneMin ? frames + 1 : 0;
|
|
5657
|
+
return 0;
|
|
5658
|
+
};
|
|
5602
5659
|
for (let j = 0; j < gamepad.axes.length-1; j+=2)
|
|
5603
|
-
sticks[j>>1] = applyDeadZones(vec2(
|
|
5660
|
+
sticks[j>>1] = applyDeadZones(vec2(readAxis(j), readAxis(j+1)));
|
|
5604
5661
|
|
|
5605
5662
|
// read buttons
|
|
5606
5663
|
let hadInput = false;
|
|
@@ -16117,6 +16174,9 @@ class ThreeJSPlugin
|
|
|
16117
16174
|
rootElement.insertBefore(threeCanvas, rootElement.firstChild);
|
|
16118
16175
|
threeCanvas.style.cssText = mainCanvas.style.cssText;
|
|
16119
16176
|
|
|
16177
|
+
// composite the 3D canvas into screenshots and video capture
|
|
16178
|
+
setBackgroundCanvas(threeCanvas);
|
|
16179
|
+
|
|
16120
16180
|
// render automatically each frame after the engine renders
|
|
16121
16181
|
engineAddPlugin(undefined, ()=> this.render());
|
|
16122
16182
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "littlejsengine",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.27",
|
|
4
4
|
"description": "LittleJS - Tiny and Fast HTML5 Game Engine",
|
|
5
5
|
"main": "dist/littlejs.esm.js",
|
|
6
6
|
"types": "dist/littlejs.d.ts",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "node src/engineBuild.mjs",
|
|
41
41
|
"build-docs": "node tools/buildDocs.mjs",
|
|
42
|
+
"build-release": "node tools/buildRelease.mjs",
|
|
42
43
|
"test": "node --test --import ./test/setup.mjs \"test/**/*.test.mjs\""
|
|
43
44
|
},
|
|
44
45
|
"engines": {
|
package/plugins/threejs.js
CHANGED
|
@@ -57,6 +57,9 @@ class ThreeJSPlugin
|
|
|
57
57
|
rootElement.insertBefore(threeCanvas, rootElement.firstChild);
|
|
58
58
|
threeCanvas.style.cssText = mainCanvas.style.cssText;
|
|
59
59
|
|
|
60
|
+
// composite the 3D canvas into screenshots and video capture
|
|
61
|
+
setBackgroundCanvas(threeCanvas);
|
|
62
|
+
|
|
60
63
|
// render automatically each frame after the engine renders
|
|
61
64
|
engineAddPlugin(undefined, ()=> this.render());
|
|
62
65
|
}
|
package/src/engine.js
CHANGED
package/src/engineDraw.js
CHANGED
|
@@ -57,6 +57,12 @@ let workReadCanvas;
|
|
|
57
57
|
* @memberof Draw */
|
|
58
58
|
let workReadContext;
|
|
59
59
|
|
|
60
|
+
/** Extra canvas to composite behind the engine canvases when combining canvases
|
|
61
|
+
* Set by plugins that render to their own canvas below the LittleJS canvases
|
|
62
|
+
* @type {HTMLCanvasElement}
|
|
63
|
+
* @memberof Draw */
|
|
64
|
+
let backgroundCanvas;
|
|
65
|
+
|
|
60
66
|
/** The size of the main canvas (and other secondary canvases)
|
|
61
67
|
* @type {Vector2}
|
|
62
68
|
* @memberof Draw */
|
|
@@ -1208,6 +1214,13 @@ function setAdditiveBlendMode(additive=true)
|
|
|
1208
1214
|
drawContext.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
1209
1215
|
}
|
|
1210
1216
|
|
|
1217
|
+
/** Set an extra canvas to composite behind the engine canvases when combining
|
|
1218
|
+
* Plugins that insert their own canvas below the LittleJS canvases should set
|
|
1219
|
+
* this so it appears in screenshots and video capture
|
|
1220
|
+
* @param {HTMLCanvasElement} [canvas]
|
|
1221
|
+
* @memberof Draw */
|
|
1222
|
+
function setBackgroundCanvas(canvas) { backgroundCanvas = canvas; }
|
|
1223
|
+
|
|
1211
1224
|
/** Combines LittleJS canvases onto the main canvas
|
|
1212
1225
|
* This is necessary for things like screenshots and video
|
|
1213
1226
|
* @memberof Draw */
|
|
@@ -1220,6 +1233,8 @@ function combineCanvases()
|
|
|
1220
1233
|
// leaving workContext.fillStyle transparent can't silently no-op this
|
|
1221
1234
|
workContext.fillStyle = '#000';
|
|
1222
1235
|
workContext.fillRect(0,0,w,h);
|
|
1236
|
+
if (backgroundCanvas)
|
|
1237
|
+
workContext.drawImage(backgroundCanvas, 0, 0, w, h);
|
|
1223
1238
|
glCopyToContext(workContext);
|
|
1224
1239
|
workContext.drawImage(mainCanvas, 0, 0);
|
|
1225
1240
|
mainContext.drawImage(workCanvas, 0, 0);
|
package/src/engineExport.js
CHANGED
|
@@ -84,6 +84,7 @@ export
|
|
|
84
84
|
glCircleSides,
|
|
85
85
|
gamepadsEnable,
|
|
86
86
|
gamepadDirectionEmulateStick,
|
|
87
|
+
gamepadAxisFilterEnable,
|
|
87
88
|
inputWASDEmulateDirection,
|
|
88
89
|
touchInputEnable,
|
|
89
90
|
touchGamepadEnable,
|
|
@@ -140,6 +141,7 @@ export
|
|
|
140
141
|
setTouchInputEnable,
|
|
141
142
|
setGamepadsEnable,
|
|
142
143
|
setGamepadDirectionEmulateStick,
|
|
144
|
+
setGamepadAxisFilterEnable,
|
|
143
145
|
setInputWASDEmulateDirection,
|
|
144
146
|
setTouchGamepadEnable,
|
|
145
147
|
setTouchGamepadPassthrough,
|
|
@@ -255,6 +257,7 @@ export
|
|
|
255
257
|
workContext,
|
|
256
258
|
workReadCanvas,
|
|
257
259
|
workReadContext,
|
|
260
|
+
backgroundCanvas,
|
|
258
261
|
mainCanvasSize,
|
|
259
262
|
textureInfos,
|
|
260
263
|
drawCount,
|
|
@@ -280,6 +283,7 @@ export
|
|
|
280
283
|
drawText,
|
|
281
284
|
drawTextScreen,
|
|
282
285
|
setAdditiveBlendMode,
|
|
286
|
+
setBackgroundCanvas,
|
|
283
287
|
combineCanvases,
|
|
284
288
|
engineImageFont,
|
|
285
289
|
ImageFont,
|
package/src/engineInput.js
CHANGED
|
@@ -124,6 +124,7 @@ function inputClear()
|
|
|
124
124
|
touchGamepadStickPointerId.length = 0; // release floating sticks so they re-anchor
|
|
125
125
|
gamepadStickData.length = 0;
|
|
126
126
|
gamepadDpadData.length = 0;
|
|
127
|
+
gamepadAxisCentered.length = 0;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -361,6 +362,11 @@ const inputData = [[]];
|
|
|
361
362
|
|
|
362
363
|
// gamepad internal variables
|
|
363
364
|
const gamepadStickData = [], gamepadDpadData = [], gamepadHadInput = [];
|
|
365
|
+
// per gamepad, how many consecutive frames each axis has rested inside the
|
|
366
|
+
// dead zone, used to tell stick axes from axes that rest at full deflection
|
|
367
|
+
const gamepadAxisCentered = [];
|
|
368
|
+
// how long an axis must rest inside the dead zone before it counts as a stick
|
|
369
|
+
const gamepadAxisCenteredFrames = 15;
|
|
364
370
|
|
|
365
371
|
// touch gamepad internal variables
|
|
366
372
|
const touchGamepadTimer = new Timer, touchGamepadButtons = [], touchGamepadSticks = [];
|
|
@@ -609,7 +615,7 @@ function inputUpdate()
|
|
|
609
615
|
// gamepad: any button held or stick moved
|
|
610
616
|
let gamepadActive = false;
|
|
611
617
|
for (let s = gamepadStickCount(); s-- && !gamepadActive;)
|
|
612
|
-
gamepadActive = gamepadStick(s).lengthSquared() > .
|
|
618
|
+
gamepadActive = gamepadStick(s).lengthSquared() > .2;
|
|
613
619
|
for (let b = 17; b-- && !gamepadActive;)
|
|
614
620
|
gamepadActive = gamepadIsDown(b);
|
|
615
621
|
|
|
@@ -637,12 +643,12 @@ function inputUpdate()
|
|
|
637
643
|
// gamepads are updated by engine every frame automatically
|
|
638
644
|
function gamepadsUpdate()
|
|
639
645
|
{
|
|
646
|
+
const deadZoneMin=.3, deadZoneMax=.8;
|
|
640
647
|
const applyDeadZones = (v)=>
|
|
641
648
|
{
|
|
642
|
-
const min=.3, max=.8;
|
|
643
649
|
const deadZone = (v)=>
|
|
644
|
-
v >
|
|
645
|
-
v < -
|
|
650
|
+
v > deadZoneMin ? percent(v, deadZoneMin, deadZoneMax) :
|
|
651
|
+
v < -deadZoneMin ? -percent(-v, deadZoneMin, deadZoneMax) : 0;
|
|
646
652
|
return vec2(deadZone(v.x), deadZone(-v.y)).clampLength();
|
|
647
653
|
};
|
|
648
654
|
|
|
@@ -726,6 +732,7 @@ function inputUpdate()
|
|
|
726
732
|
gamepadStickData[i] = undefined;
|
|
727
733
|
gamepadDpadData[i] = undefined;
|
|
728
734
|
gamepadHadInput[i] = undefined;
|
|
735
|
+
gamepadAxisCentered[i] = undefined;
|
|
729
736
|
continue;
|
|
730
737
|
}
|
|
731
738
|
|
|
@@ -734,8 +741,30 @@ function inputUpdate()
|
|
|
734
741
|
const dpad = gamepadDpadData[i] ?? (gamepadDpadData[i] = vec2());
|
|
735
742
|
|
|
736
743
|
// read analog sticks
|
|
744
|
+
// gamepads without standard mapping (steering wheels, flight sticks)
|
|
745
|
+
// can report axes that rest at full deflection instead of center,
|
|
746
|
+
// which would otherwise read as a stick held down forever, so only
|
|
747
|
+
// trust an axis once it has rested inside the dead zone for a moment
|
|
748
|
+
const isStandard = gamepad.mapping === 'standard';
|
|
749
|
+
const centered = gamepadAxisCentered[i] ?? (gamepadAxisCentered[i] = []);
|
|
750
|
+
const readAxis = (j)=>
|
|
751
|
+
{
|
|
752
|
+
const v = gamepad.axes[j];
|
|
753
|
+
if (isStandard && j < 4)
|
|
754
|
+
return v; // spec guarantees axes 0-3 are the two sticks
|
|
755
|
+
if (!gamepadAxisFilterEnable)
|
|
756
|
+
return v;
|
|
757
|
+
|
|
758
|
+
// once an axis has proven it rests at center it stays trusted,
|
|
759
|
+
// otherwise moving it would immediately disqualify it again
|
|
760
|
+
const frames = centered[j] | 0;
|
|
761
|
+
if (frames > gamepadAxisCenteredFrames)
|
|
762
|
+
return v;
|
|
763
|
+
centered[j] = abs(v) < deadZoneMin ? frames + 1 : 0;
|
|
764
|
+
return 0;
|
|
765
|
+
};
|
|
737
766
|
for (let j = 0; j < gamepad.axes.length-1; j+=2)
|
|
738
|
-
sticks[j>>1] = applyDeadZones(vec2(
|
|
767
|
+
sticks[j>>1] = applyDeadZones(vec2(readAxis(j), readAxis(j+1)));
|
|
739
768
|
|
|
740
769
|
// read buttons
|
|
741
770
|
let hadInput = false;
|
package/src/engineSettings.js
CHANGED
|
@@ -236,6 +236,14 @@ let gamepadsEnable = true;
|
|
|
236
236
|
* @memberof Settings */
|
|
237
237
|
let gamepadDirectionEmulateStick = true;
|
|
238
238
|
|
|
239
|
+
/** If true, axes that do not rest near center are ignored on gamepads without
|
|
240
|
+
* standard mapping. Steering wheels and flight sticks report pedal and throttle
|
|
241
|
+
* axes that rest at full deflection, which otherwise reads as a stick held down.
|
|
242
|
+
* @type {boolean}
|
|
243
|
+
* @default
|
|
244
|
+
* @memberof Settings */
|
|
245
|
+
let gamepadAxisFilterEnable = true;
|
|
246
|
+
|
|
239
247
|
/** If true the WASD keys are also routed to the direction keys (for better accessibility)
|
|
240
248
|
* @type {boolean}
|
|
241
249
|
* @default
|
|
@@ -574,6 +582,11 @@ function setGamepadsEnable(enable) { gamepadsEnable = enable; }
|
|
|
574
582
|
* @memberof Settings */
|
|
575
583
|
function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
|
|
576
584
|
|
|
585
|
+
/** Set if axes that do not rest near center are ignored on non-standard gamepads
|
|
586
|
+
* @param {boolean} enable
|
|
587
|
+
* @memberof Settings */
|
|
588
|
+
function setGamepadAxisFilterEnable(enable) { gamepadAxisFilterEnable = enable; }
|
|
589
|
+
|
|
577
590
|
/** Set if true the WASD keys are also routed to the direction keys
|
|
578
591
|
* @param {boolean} enable
|
|
579
592
|
* @memberof Settings */
|