lexgui 0.5.8 → 0.5.9
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/build/lexgui.css +558 -99
- package/build/lexgui.js +531 -148
- package/build/lexgui.min.css +2 -6
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +531 -148
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +12 -1
- package/demo.js +2 -2
- package/examples/all_widgets.html +12 -2
- package/package.json +1 -1
- package/build/utilities.css +0 -421
package/build/lexgui.js
CHANGED
|
@@ -12,7 +12,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
var LX = {
|
|
15
|
-
version: "0.5.
|
|
15
|
+
version: "0.5.9",
|
|
16
16
|
ready: false,
|
|
17
17
|
components: [], // Specific pre-build components
|
|
18
18
|
signals: {}, // Events and triggers
|
|
@@ -779,7 +779,7 @@ LX.makeKbd = makeKbd;
|
|
|
779
779
|
* @description Gets an SVG element using one of LX.ICONS
|
|
780
780
|
* @param {String} iconName
|
|
781
781
|
* @param {Object} options
|
|
782
|
-
*
|
|
782
|
+
* title
|
|
783
783
|
* extraClass
|
|
784
784
|
* svgClass
|
|
785
785
|
*/
|
|
@@ -788,7 +788,7 @@ function makeIcon( iconName, options = { } )
|
|
|
788
788
|
let data = LX.ICONS[ iconName ];
|
|
789
789
|
console.assert( data, `No icon named _${ iconName }_` );
|
|
790
790
|
|
|
791
|
-
const iconTitle = options.
|
|
791
|
+
const iconTitle = options.title;
|
|
792
792
|
const iconClass = options.iconClass;
|
|
793
793
|
const svgClass = options.svgClass;
|
|
794
794
|
|
|
@@ -1647,7 +1647,7 @@ function toast( title, description, options = {} )
|
|
|
1647
1647
|
if( options.action )
|
|
1648
1648
|
{
|
|
1649
1649
|
const panel = new Panel();
|
|
1650
|
-
panel.addButton(null, options.action.name ?? "Accept", options.action.callback.bind( this, toast ), { width: "auto", maxWidth: "150px", className: "right", buttonClass: "
|
|
1650
|
+
panel.addButton(null, options.action.name ?? "Accept", options.action.callback.bind( this, toast ), { width: "auto", maxWidth: "150px", className: "right", buttonClass: "border" });
|
|
1651
1651
|
toast.appendChild( panel.root.childNodes[ 0 ] );
|
|
1652
1652
|
}
|
|
1653
1653
|
|
|
@@ -1947,6 +1947,158 @@ LX.addSignal = addSignal;
|
|
|
1947
1947
|
* DOM Elements
|
|
1948
1948
|
*/
|
|
1949
1949
|
|
|
1950
|
+
/**
|
|
1951
|
+
* @class Popover
|
|
1952
|
+
*/
|
|
1953
|
+
|
|
1954
|
+
class Popover {
|
|
1955
|
+
|
|
1956
|
+
static activeElement = false;
|
|
1957
|
+
|
|
1958
|
+
constructor( trigger, content, options = {} ) {
|
|
1959
|
+
|
|
1960
|
+
console.assert( trigger, "Popover needs a DOM element as trigger!" );
|
|
1961
|
+
|
|
1962
|
+
if( Popover.activeElement )
|
|
1963
|
+
{
|
|
1964
|
+
Popover.activeElement.destroy();
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
this._trigger = trigger;
|
|
1969
|
+
trigger.classList.add( "triggered" );
|
|
1970
|
+
trigger.active = this;
|
|
1971
|
+
|
|
1972
|
+
this._windowPadding = 4;
|
|
1973
|
+
this.side = options.side ?? "bottom";
|
|
1974
|
+
this.align = options.align ?? "center";
|
|
1975
|
+
this.avoidCollisions = options.avoidCollisions ?? true;
|
|
1976
|
+
|
|
1977
|
+
this.root = document.createElement( "div" );
|
|
1978
|
+
this.root.dataset["side"] = this.side;
|
|
1979
|
+
this.root.tabIndex = "1";
|
|
1980
|
+
this.root.className = "lexpopover";
|
|
1981
|
+
LX.root.appendChild( this.root );
|
|
1982
|
+
|
|
1983
|
+
this.root.addEventListener( "keydown", (e) => {
|
|
1984
|
+
if( e.key == "Escape" )
|
|
1985
|
+
{
|
|
1986
|
+
e.preventDefault();
|
|
1987
|
+
e.stopPropagation();
|
|
1988
|
+
this.destroy();
|
|
1989
|
+
}
|
|
1990
|
+
} )
|
|
1991
|
+
|
|
1992
|
+
if( content )
|
|
1993
|
+
{
|
|
1994
|
+
content = [].concat( content );
|
|
1995
|
+
content.forEach( e => {
|
|
1996
|
+
const domNode = e.root ?? e;
|
|
1997
|
+
this.root.appendChild( domNode );
|
|
1998
|
+
if( e.onPopover )
|
|
1999
|
+
{
|
|
2000
|
+
e.onPopover();
|
|
2001
|
+
}
|
|
2002
|
+
} );
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
Popover.activeElement = this;
|
|
2006
|
+
|
|
2007
|
+
doAsync( () => {
|
|
2008
|
+
this._adjustPosition();
|
|
2009
|
+
|
|
2010
|
+
this.root.focus();
|
|
2011
|
+
|
|
2012
|
+
this._onClick = e => {
|
|
2013
|
+
if( e.target && ( this.root.contains( e.target ) || e.target == this._trigger ) )
|
|
2014
|
+
{
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
this.destroy();
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
document.body.addEventListener( "mousedown", this._onClick, true );
|
|
2021
|
+
document.body.addEventListener( "focusin", this._onClick, true );
|
|
2022
|
+
}, 10 );
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
destroy() {
|
|
2026
|
+
|
|
2027
|
+
this._trigger.classList.remove( "triggered" );
|
|
2028
|
+
|
|
2029
|
+
delete this._trigger.active;
|
|
2030
|
+
|
|
2031
|
+
document.body.removeEventListener( "click", this._onClick );
|
|
2032
|
+
|
|
2033
|
+
this.root.remove();
|
|
2034
|
+
|
|
2035
|
+
Popover.activeElement = null;
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
_adjustPosition() {
|
|
2039
|
+
|
|
2040
|
+
const position = [ 0, 0 ];
|
|
2041
|
+
|
|
2042
|
+
// Place menu using trigger position and user options
|
|
2043
|
+
{
|
|
2044
|
+
const rect = this._trigger.getBoundingClientRect();
|
|
2045
|
+
|
|
2046
|
+
let alignWidth = true;
|
|
2047
|
+
|
|
2048
|
+
switch( this.side )
|
|
2049
|
+
{
|
|
2050
|
+
case "left":
|
|
2051
|
+
position[ 0 ] += ( rect.x - this.root.offsetWidth );
|
|
2052
|
+
alignWidth = false;
|
|
2053
|
+
break;
|
|
2054
|
+
case "right":
|
|
2055
|
+
position[ 0 ] += ( rect.x + rect.width );
|
|
2056
|
+
alignWidth = false;
|
|
2057
|
+
break;
|
|
2058
|
+
case "top":
|
|
2059
|
+
position[ 1 ] += ( rect.y - this.root.offsetHeight );
|
|
2060
|
+
alignWidth = true;
|
|
2061
|
+
break;
|
|
2062
|
+
case "bottom":
|
|
2063
|
+
position[ 1 ] += ( rect.y + rect.height );
|
|
2064
|
+
alignWidth = true;
|
|
2065
|
+
break;
|
|
2066
|
+
default:
|
|
2067
|
+
break;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
switch( this.align )
|
|
2071
|
+
{
|
|
2072
|
+
case "start":
|
|
2073
|
+
if( alignWidth ) { position[ 0 ] += rect.x; }
|
|
2074
|
+
else { position[ 1 ] += rect.y; }
|
|
2075
|
+
break;
|
|
2076
|
+
case "center":
|
|
2077
|
+
if( alignWidth ) { position[ 0 ] += ( rect.x + rect.width * 0.5 ) - this.root.offsetWidth * 0.5; }
|
|
2078
|
+
else { position[ 1 ] += ( rect.y + rect.height * 0.5 ) - this.root.offsetHeight * 0.5; }
|
|
2079
|
+
break;
|
|
2080
|
+
case "end":
|
|
2081
|
+
if( alignWidth ) { position[ 0 ] += rect.x - this.root.offsetWidth + rect.width; }
|
|
2082
|
+
else { position[ 1 ] += rect.y - this.root.offsetHeight + rect.height; }
|
|
2083
|
+
break;
|
|
2084
|
+
default:
|
|
2085
|
+
break;
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
if( this.avoidCollisions )
|
|
2090
|
+
{
|
|
2091
|
+
position[ 0 ] = LX.clamp( position[ 0 ], 0, window.innerWidth - this.root.offsetWidth - this._windowPadding );
|
|
2092
|
+
position[ 1 ] = LX.clamp( position[ 1 ], 0, window.innerHeight - this.root.offsetHeight - this._windowPadding );
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2095
|
+
this.root.style.left = `${ position[ 0 ] }px`;
|
|
2096
|
+
this.root.style.top = `${ position[ 1 ] }px`;
|
|
2097
|
+
}
|
|
2098
|
+
};
|
|
2099
|
+
|
|
2100
|
+
LX.Popover = Popover;
|
|
2101
|
+
|
|
1950
2102
|
/**
|
|
1951
2103
|
* @class DropdownMenu
|
|
1952
2104
|
*/
|
|
@@ -2244,14 +2396,8 @@ class ColorPicker {
|
|
|
2244
2396
|
|
|
2245
2397
|
static currentPicker = false;
|
|
2246
2398
|
|
|
2247
|
-
constructor( hexValue,
|
|
2248
|
-
|
|
2249
|
-
console.assert( trigger, "ColorPicker needs a DOM element as trigger!" );
|
|
2399
|
+
constructor( hexValue, options = {} ) {
|
|
2250
2400
|
|
|
2251
|
-
this._windowPadding = 4;
|
|
2252
|
-
this.side = options.side ?? "bottom";
|
|
2253
|
-
this.align = options.align ?? "center";
|
|
2254
|
-
this.avoidCollisions = options.avoidCollisions ?? true;
|
|
2255
2401
|
this.colorModel = options.colorModel ?? "Hex";
|
|
2256
2402
|
this.useAlpha = options.useAlpha ?? false;
|
|
2257
2403
|
this.callback = options.onChange;
|
|
@@ -2261,32 +2407,8 @@ class ColorPicker {
|
|
|
2261
2407
|
console.warn( "Define a callback in _options.onChange_ to allow getting new Color values!" );
|
|
2262
2408
|
}
|
|
2263
2409
|
|
|
2264
|
-
if( ColorPicker.currentPicker )
|
|
2265
|
-
{
|
|
2266
|
-
ColorPicker.currentPicker.destroy();
|
|
2267
|
-
return;
|
|
2268
|
-
}
|
|
2269
|
-
|
|
2270
|
-
this._trigger = trigger;
|
|
2271
|
-
trigger.classList.add( "triggered" );
|
|
2272
|
-
trigger.picker = this;
|
|
2273
|
-
|
|
2274
2410
|
this.root = document.createElement( "div" );
|
|
2275
|
-
this.root.tabIndex = "1";
|
|
2276
2411
|
this.root.className = "lexcolorpicker";
|
|
2277
|
-
this.root.dataset["side"] = this.side;
|
|
2278
|
-
LX.root.appendChild( this.root );
|
|
2279
|
-
|
|
2280
|
-
this.root.addEventListener( "keydown", (e) => {
|
|
2281
|
-
if( e.key == "Escape" )
|
|
2282
|
-
{
|
|
2283
|
-
e.preventDefault();
|
|
2284
|
-
e.stopPropagation();
|
|
2285
|
-
this.destroy();
|
|
2286
|
-
}
|
|
2287
|
-
} )
|
|
2288
|
-
|
|
2289
|
-
ColorPicker.currentPicker = this;
|
|
2290
2412
|
|
|
2291
2413
|
this.markerHalfSize = 8;
|
|
2292
2414
|
this.markerSize = this.markerHalfSize * 2;
|
|
@@ -2305,8 +2427,6 @@ class ColorPicker {
|
|
|
2305
2427
|
this.intSatMarker.style.backgroundColor = this.currentColor.hex;
|
|
2306
2428
|
this.colorPickerBackground.appendChild( this.intSatMarker );
|
|
2307
2429
|
|
|
2308
|
-
doAsync( this._svToPosition.bind( this, this.currentColor.hsv.s, this.currentColor.hsv.v ) );
|
|
2309
|
-
|
|
2310
2430
|
let pickerRect = null;
|
|
2311
2431
|
|
|
2312
2432
|
let innerMouseDown = e => {
|
|
@@ -2386,11 +2506,6 @@ class ColorPicker {
|
|
|
2386
2506
|
this.hueMarker.style.backgroundColor = `rgb(${ hueColor.css.r }, ${ hueColor.css.g }, ${ hueColor.css.b })`;
|
|
2387
2507
|
this.colorPickerTracker.appendChild( this.hueMarker );
|
|
2388
2508
|
|
|
2389
|
-
doAsync( () => {
|
|
2390
|
-
const hueLeft = LX.remapRange( this.currentColor.hsv.h, 0, 360, 0, this.colorPickerTracker.offsetWidth - this.markerSize );
|
|
2391
|
-
this.hueMarker.style.left = hueLeft + "px";
|
|
2392
|
-
} );
|
|
2393
|
-
|
|
2394
2509
|
const _fromHueX = ( hueX ) => {
|
|
2395
2510
|
this.hueMarker.style.left = hueX + "px";
|
|
2396
2511
|
this.currentColor.hsv.h = LX.remapRange( hueX, 0, this.colorPickerTracker.offsetWidth - this.markerSize, 0, 360 );
|
|
@@ -2453,11 +2568,6 @@ class ColorPicker {
|
|
|
2453
2568
|
this.alphaMarker.style.backgroundColor = `rgb(${ this.currentColor.css.r }, ${ this.currentColor.css.g }, ${ this.currentColor.css.b },${ this.currentColor.css.a })`;
|
|
2454
2569
|
this.alphaTracker.appendChild( this.alphaMarker );
|
|
2455
2570
|
|
|
2456
|
-
doAsync( () => {
|
|
2457
|
-
const alphaLeft = LX.remapRange( this.currentColor.hsv.a, 0, 1, 0, this.alphaTracker.offsetWidth - this.markerSize );
|
|
2458
|
-
this.alphaMarker.style.left = alphaLeft + "px";
|
|
2459
|
-
} );
|
|
2460
|
-
|
|
2461
2571
|
const _fromAlphaX = ( alphaX ) => {
|
|
2462
2572
|
this.alphaMarker.style.left = alphaX + "px";
|
|
2463
2573
|
this.currentColor.hsv.a = LX.remapRange( alphaX, 0, this.alphaTracker.offsetWidth - this.markerSize, 0, 1 );
|
|
@@ -2535,62 +2645,34 @@ class ColorPicker {
|
|
|
2535
2645
|
|
|
2536
2646
|
this._updateColorValue( hexValue, true );
|
|
2537
2647
|
|
|
2538
|
-
doAsync( ()
|
|
2539
|
-
this._adjustPosition();
|
|
2540
|
-
|
|
2541
|
-
this.root.focus();
|
|
2542
|
-
|
|
2543
|
-
this._onClick = e => {
|
|
2544
|
-
if( e.target && ( this.root.contains( e.target ) || e.target == this._trigger ) )
|
|
2545
|
-
{
|
|
2546
|
-
return;
|
|
2547
|
-
}
|
|
2548
|
-
this.destroy();
|
|
2549
|
-
};
|
|
2648
|
+
doAsync( this._placeMarkers.bind( this ) );
|
|
2550
2649
|
|
|
2551
|
-
|
|
2552
|
-
document.body.addEventListener( "focusin", this._onClick, true );
|
|
2553
|
-
}, 10 );
|
|
2650
|
+
this.onPopover = this._placeMarkers.bind( this );
|
|
2554
2651
|
}
|
|
2555
2652
|
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
this.currentColor.setHex( hexColor );
|
|
2559
|
-
|
|
2560
|
-
// Decompose into HSV
|
|
2561
|
-
const { h, s, v } = this.currentColor.hsv;
|
|
2562
|
-
this._svToPosition( s, v );
|
|
2653
|
+
_placeMarkers() {
|
|
2563
2654
|
|
|
2564
|
-
|
|
2565
|
-
this.hueMarker.style.backgroundColor = this.colorPickerBackground.style.backgroundColor = `rgb(${ hueColor.css.r }, ${ hueColor.css.g }, ${ hueColor.css.b })`;
|
|
2566
|
-
this.hueMarker.style.left = LX.remapRange( h, 0, 360, -this.markerHalfSize, this.colorPickerTracker.offsetWidth - this.markerHalfSize ) + "px";
|
|
2655
|
+
this._svToPosition( this.currentColor.hsv.s, this.currentColor.hsv.v );
|
|
2567
2656
|
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
destroy() {
|
|
2657
|
+
const hueLeft = LX.remapRange( this.currentColor.hsv.h, 0, 360, 0, this.colorPickerTracker.offsetWidth - this.markerSize );
|
|
2658
|
+
this.hueMarker.style.left = hueLeft + "px";
|
|
2572
2659
|
|
|
2573
|
-
this.
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
document.body.removeEventListener( "focusin", this._onClick, true );
|
|
2579
|
-
|
|
2580
|
-
LX.root.querySelectorAll( ".lexcolorpicker" ).forEach( m => { m.remove(); } );
|
|
2581
|
-
|
|
2582
|
-
ColorPicker.currentPicker = null;
|
|
2660
|
+
if( this.useAlpha )
|
|
2661
|
+
{
|
|
2662
|
+
const alphaLeft = LX.remapRange( this.currentColor.hsv.a, 0, 1, 0, this.alphaTracker.offsetWidth - this.markerSize );
|
|
2663
|
+
this.alphaMarker.style.left = alphaLeft + "px";
|
|
2664
|
+
}
|
|
2583
2665
|
}
|
|
2584
2666
|
|
|
2585
2667
|
_svToPosition( s, v ) {
|
|
2586
2668
|
this.intSatMarker.style.left = `${ LX.remapRange( s, 0, 1, -this.markerHalfSize, this.colorPickerBackground.offsetWidth - this.markerHalfSize ) }px`;
|
|
2587
2669
|
this.intSatMarker.style.top = `${ LX.remapRange( 1 - v, 0, 1, -this.markerHalfSize, this.colorPickerBackground.offsetHeight - this.markerHalfSize ) }px`
|
|
2588
|
-
}
|
|
2670
|
+
}
|
|
2589
2671
|
|
|
2590
2672
|
_positionToSv( left, top ) {
|
|
2591
2673
|
this.currentColor.hsv.s = LX.remapRange( left, -this.markerHalfSize, this.colorPickerBackground.offsetWidth - this.markerHalfSize, 0, 1 );
|
|
2592
2674
|
this.currentColor.hsv.v = 1 - LX.remapRange( top, -this.markerHalfSize, this.colorPickerBackground.offsetHeight - this.markerHalfSize, 0, 1 );
|
|
2593
|
-
}
|
|
2675
|
+
}
|
|
2594
2676
|
|
|
2595
2677
|
_updateColorValue( newHexValue, skipCallback = false ) {
|
|
2596
2678
|
|
|
@@ -2633,71 +2715,274 @@ class ColorPicker {
|
|
|
2633
2715
|
if( this.useAlpha ) components.push( toFixed( a ) );
|
|
2634
2716
|
this.labelWidget.set( components.join( ' ' ) );
|
|
2635
2717
|
}
|
|
2636
|
-
}
|
|
2718
|
+
}
|
|
2637
2719
|
|
|
2638
|
-
|
|
2720
|
+
fromHexColor( hexColor ) {
|
|
2639
2721
|
|
|
2640
|
-
|
|
2722
|
+
this.currentColor.setHex( hexColor );
|
|
2641
2723
|
|
|
2642
|
-
//
|
|
2724
|
+
// Decompose into HSV
|
|
2725
|
+
const { h, s, v } = this.currentColor.hsv;
|
|
2726
|
+
this._svToPosition( s, v );
|
|
2727
|
+
|
|
2728
|
+
const hueColor = new Color( { h, s: 1, v: 1 } );
|
|
2729
|
+
this.hueMarker.style.backgroundColor = this.colorPickerBackground.style.backgroundColor = `rgb(${ hueColor.css.r }, ${ hueColor.css.g }, ${ hueColor.css.b })`;
|
|
2730
|
+
this.hueMarker.style.left = LX.remapRange( h, 0, 360, -this.markerHalfSize, this.colorPickerTracker.offsetWidth - this.markerHalfSize ) + "px";
|
|
2731
|
+
|
|
2732
|
+
this._updateColorValue( hexColor );
|
|
2733
|
+
}
|
|
2734
|
+
};
|
|
2735
|
+
|
|
2736
|
+
LX.ColorPicker = ColorPicker;
|
|
2737
|
+
|
|
2738
|
+
class Calendar {
|
|
2739
|
+
|
|
2740
|
+
/**
|
|
2741
|
+
* @constructor Calendar
|
|
2742
|
+
* @param {String} dateString D/M/Y
|
|
2743
|
+
* @param {Object} options
|
|
2744
|
+
* onChange: Function to call on date changes
|
|
2745
|
+
*/
|
|
2746
|
+
|
|
2747
|
+
constructor( dateString, options = {} ) {
|
|
2748
|
+
|
|
2749
|
+
this.root = LX.makeContainer( ["256px", "auto"], "border p-3 bg-primary rounded-lg text-md" );
|
|
2750
|
+
|
|
2751
|
+
this.onChange = options.onChange;
|
|
2752
|
+
this.untilToday = options.untilToday;
|
|
2753
|
+
this.fromToday = options.fromToday;
|
|
2754
|
+
|
|
2755
|
+
if( dateString )
|
|
2643
2756
|
{
|
|
2644
|
-
|
|
2757
|
+
this.fromDateString( dateString );
|
|
2758
|
+
}
|
|
2759
|
+
else
|
|
2760
|
+
{
|
|
2761
|
+
const date = new Date();
|
|
2762
|
+
this.month = date.getMonth() + 1;
|
|
2763
|
+
this.year = date.getFullYear();
|
|
2764
|
+
this.fromMonthYear( this.month, this.year );
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2645
2767
|
|
|
2646
|
-
|
|
2768
|
+
_getCurrentDate() {
|
|
2769
|
+
return {
|
|
2770
|
+
day: this.day,
|
|
2771
|
+
month: this.month,
|
|
2772
|
+
year: this.year,
|
|
2773
|
+
fullDate: this.getFullDate()
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2647
2776
|
|
|
2648
|
-
|
|
2777
|
+
_previousMonth() {
|
|
2778
|
+
|
|
2779
|
+
this.month = Math.max( 0, this.month - 1 );
|
|
2780
|
+
|
|
2781
|
+
if( this.month == 0 )
|
|
2782
|
+
{
|
|
2783
|
+
this.month = 12;
|
|
2784
|
+
this.year--;
|
|
2785
|
+
}
|
|
2786
|
+
|
|
2787
|
+
this.fromMonthYear( this.month, this.year );
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
_nextMonth() {
|
|
2791
|
+
|
|
2792
|
+
this.month = Math.min( this.month + 1, 12 );
|
|
2793
|
+
|
|
2794
|
+
if( this.month == 12 )
|
|
2795
|
+
{
|
|
2796
|
+
this.month = 0;
|
|
2797
|
+
this.year++;
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
this.fromMonthYear( this.month, this.year );
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2803
|
+
refresh() {
|
|
2804
|
+
|
|
2805
|
+
this.root.innerHTML = "";
|
|
2806
|
+
|
|
2807
|
+
// Header
|
|
2808
|
+
{
|
|
2809
|
+
const header = LX.makeContainer( ["100%", "auto"], "flex flex-row p-1", "", this.root );
|
|
2810
|
+
|
|
2811
|
+
const prevMonthIcon = LX.makeIcon( "left", { title: "Previous Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
|
|
2812
|
+
header.appendChild( prevMonthIcon );
|
|
2813
|
+
prevMonthIcon.addEventListener( "click", () => {
|
|
2814
|
+
this._previousMonth();
|
|
2815
|
+
} );
|
|
2816
|
+
|
|
2817
|
+
const monthYearLabel = LX.makeContainer( ["100%", "auto"], "text-center font-medium select-none", `${ this.monthName } ${ this.year }`, header );
|
|
2818
|
+
|
|
2819
|
+
const nextMonthIcon = LX.makeIcon( "right", { title: "Next Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
|
|
2820
|
+
header.appendChild( nextMonthIcon );
|
|
2821
|
+
nextMonthIcon.addEventListener( "click", () => {
|
|
2822
|
+
this._nextMonth();
|
|
2823
|
+
} );
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
// Body
|
|
2827
|
+
{
|
|
2828
|
+
const daysTable = document.createElement( "table" );
|
|
2829
|
+
daysTable.className = "w-full";
|
|
2830
|
+
this.root.appendChild( daysTable );
|
|
2831
|
+
|
|
2832
|
+
// Table Head
|
|
2649
2833
|
{
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
alignWidth = true;
|
|
2665
|
-
break;
|
|
2666
|
-
default:
|
|
2667
|
-
break;
|
|
2834
|
+
const head = document.createElement( 'thead' );
|
|
2835
|
+
daysTable.appendChild( head );
|
|
2836
|
+
|
|
2837
|
+
const hrow = document.createElement( 'tr' );
|
|
2838
|
+
|
|
2839
|
+
for( const headData of [ "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su" ] )
|
|
2840
|
+
{
|
|
2841
|
+
const th = document.createElement( 'th' );
|
|
2842
|
+
th.className = "fg-tertiary text-sm font-normal select-none";
|
|
2843
|
+
th.innerHTML = `<span>${ headData }</span>`;
|
|
2844
|
+
hrow.appendChild( th );
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
head.appendChild( hrow );
|
|
2668
2848
|
}
|
|
2669
2849
|
|
|
2670
|
-
|
|
2850
|
+
// Table Body
|
|
2671
2851
|
{
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2852
|
+
const body = document.createElement( 'tbody' );
|
|
2853
|
+
daysTable.appendChild( body );
|
|
2854
|
+
|
|
2855
|
+
for( let week = 0; week < 6; week++ )
|
|
2856
|
+
{
|
|
2857
|
+
const hrow = document.createElement( 'tr' );
|
|
2858
|
+
const weekDays = this.calendarDays.slice( week * 7, week * 7 + 7 );
|
|
2859
|
+
|
|
2860
|
+
for( const dayData of weekDays )
|
|
2861
|
+
{
|
|
2862
|
+
const th = document.createElement( 'th' );
|
|
2863
|
+
th.className = "leading-loose font-normal rounded select-none cursor-pointer";
|
|
2864
|
+
|
|
2865
|
+
const dayDate = new Date( `${ this.month }/${ dayData.day }/${ this.year }` );
|
|
2866
|
+
const date = new Date();
|
|
2867
|
+
const beforeToday = this.untilToday ? ( dayDate.getTime() < date.getTime() ) : true;
|
|
2868
|
+
const afterToday = this.fromToday ? ( dayDate.getTime() > date.getTime() ) : true;
|
|
2869
|
+
const selectable = dayData.currentMonth && beforeToday && afterToday;
|
|
2870
|
+
|
|
2871
|
+
if( this.currentDate && ( dayData.day == this.currentDate.day ) && ( this.month == this.currentDate.month )
|
|
2872
|
+
&& ( this.year == this.currentDate.year ) && dayData.currentMonth )
|
|
2873
|
+
{
|
|
2874
|
+
th.className += ` bg-contrast fg-contrast`;
|
|
2875
|
+
}
|
|
2876
|
+
else
|
|
2877
|
+
{
|
|
2878
|
+
th.className += ` ${ selectable ? "fg-primary" : "fg-tertiary" } hover:bg-secondary`;
|
|
2879
|
+
}
|
|
2880
|
+
|
|
2881
|
+
th.innerHTML = `<span>${ dayData.day }</span>`;
|
|
2882
|
+
hrow.appendChild( th );
|
|
2883
|
+
|
|
2884
|
+
if( selectable )
|
|
2885
|
+
{
|
|
2886
|
+
th.addEventListener( "click", () => {
|
|
2887
|
+
this.day = dayData.day;
|
|
2888
|
+
this.currentDate = this._getCurrentDate();
|
|
2889
|
+
if( this.onChange )
|
|
2890
|
+
{
|
|
2891
|
+
this.onChange( this.currentDate );
|
|
2892
|
+
}
|
|
2893
|
+
} );
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
body.appendChild( hrow );
|
|
2898
|
+
}
|
|
2686
2899
|
}
|
|
2687
2900
|
}
|
|
2901
|
+
}
|
|
2688
2902
|
|
|
2689
|
-
|
|
2903
|
+
fromDateString( dateString ) {
|
|
2904
|
+
|
|
2905
|
+
const tokens = dateString.split( '/' );
|
|
2906
|
+
|
|
2907
|
+
this.day = parseInt( tokens[ 0 ] );
|
|
2908
|
+
this.month = parseInt( tokens[ 1 ] );
|
|
2909
|
+
this.year = parseInt( tokens[ 2 ] );
|
|
2910
|
+
|
|
2911
|
+
this.currentDate = this._getCurrentDate();
|
|
2912
|
+
|
|
2913
|
+
this.fromMonthYear( this.month, this.year );
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2916
|
+
fromMonthYear( month, year ) {
|
|
2917
|
+
|
|
2918
|
+
// Month is 0-based (0 = January, ... 11 = December)
|
|
2919
|
+
month--;
|
|
2920
|
+
|
|
2921
|
+
year = year ?? new Date().getFullYear();
|
|
2922
|
+
|
|
2923
|
+
const weekDay = new Date( year, month, 1 ).getDay();
|
|
2924
|
+
const firstDay = weekDay === 0 ? 6 : weekDay - 1; // 0 = Monday, 1 = Tuesday...
|
|
2925
|
+
const daysInMonth = new Date( year, month + 1, 0 ).getDate();
|
|
2926
|
+
|
|
2927
|
+
// Previous month
|
|
2928
|
+
const prevMonth = month === 0 ? 11 : month - 1;
|
|
2929
|
+
const prevYear = month === 0 ? year - 1 : year;
|
|
2930
|
+
const daysInPrevMonth = new Date( prevYear, prevMonth + 1, 0 ).getDate();
|
|
2931
|
+
|
|
2932
|
+
// Prepare full grid (up to 6 weeks = 42 days)
|
|
2933
|
+
const calendarDays = [];
|
|
2934
|
+
|
|
2935
|
+
// Fill in days from previous month
|
|
2936
|
+
for( let i = firstDay - 1; i >= 0; i--)
|
|
2690
2937
|
{
|
|
2691
|
-
|
|
2692
|
-
position[ 1 ] = LX.clamp( position[ 1 ], 0, window.innerHeight - this.root.offsetHeight - this._windowPadding );
|
|
2938
|
+
calendarDays.push( { day: daysInPrevMonth - i, currentMonth: false } );
|
|
2693
2939
|
}
|
|
2694
2940
|
|
|
2695
|
-
|
|
2696
|
-
|
|
2941
|
+
// Fill in current month days
|
|
2942
|
+
for ( let i = 1; i <= daysInMonth; i++ )
|
|
2943
|
+
{
|
|
2944
|
+
calendarDays.push( { day: i, currentMonth: true } );
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2947
|
+
// Fill in next month days to complete the grid (if needed)
|
|
2948
|
+
const remaining = 42 - calendarDays.length;
|
|
2949
|
+
for( let i = 1; i <= remaining; i++ )
|
|
2950
|
+
{
|
|
2951
|
+
calendarDays.push( { day: i, currentMonth: false } );
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
this.monthName = this.getMonthName( month );
|
|
2955
|
+
this.firstDay = firstDay;
|
|
2956
|
+
this.daysInMonth = daysInMonth;
|
|
2957
|
+
this.calendarDays = calendarDays;
|
|
2958
|
+
|
|
2959
|
+
this.refresh();
|
|
2697
2960
|
}
|
|
2698
|
-
};
|
|
2699
2961
|
|
|
2700
|
-
|
|
2962
|
+
getMonthName( monthIndex, locale = "en-US" ) {
|
|
2963
|
+
const formatter = new Intl.DateTimeFormat( locale, { month: "long" } );
|
|
2964
|
+
return formatter.format( new Date( 2000, monthIndex, 1 ) );
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
getFullDate() {
|
|
2968
|
+
return `${ this.monthName } ${ this.day }${ this._getOrdinalSuffix( this.day ) }, ${ this.year }`;
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
_getOrdinalSuffix( day ) {
|
|
2972
|
+
if ( day > 3 && day < 21 ) return "th";
|
|
2973
|
+
switch ( day % 10 )
|
|
2974
|
+
{
|
|
2975
|
+
case 1: return "st";
|
|
2976
|
+
case 2: return "nd";
|
|
2977
|
+
case 3: return "rd";
|
|
2978
|
+
default: return "th";
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
LX.Calendar = Calendar;
|
|
2984
|
+
|
|
2985
|
+
/* Layout Classes */
|
|
2701
2986
|
|
|
2702
2987
|
class Area {
|
|
2703
2988
|
|
|
@@ -5303,8 +5588,9 @@ class Widget {
|
|
|
5303
5588
|
static COUNTER = 33;
|
|
5304
5589
|
static TABLE = 34;
|
|
5305
5590
|
static TABS = 35;
|
|
5306
|
-
static
|
|
5307
|
-
static
|
|
5591
|
+
static DATE = 36;
|
|
5592
|
+
static LABEL = 37;
|
|
5593
|
+
static BLANK = 38;
|
|
5308
5594
|
|
|
5309
5595
|
static NO_CONTEXT_TYPES = [
|
|
5310
5596
|
Widget.BUTTON,
|
|
@@ -5542,6 +5828,7 @@ class Widget {
|
|
|
5542
5828
|
case Widget.COUNTER: return "Counter";
|
|
5543
5829
|
case Widget.TABLE: return "Table";
|
|
5544
5830
|
case Widget.TABS: return "Tabs";
|
|
5831
|
+
case Widget.DATE: return "Date";
|
|
5545
5832
|
case Widget.LABEL: return "Label";
|
|
5546
5833
|
case Widget.BLANK: return "Blank";
|
|
5547
5834
|
case Widget.CUSTOM: return this.customName;
|
|
@@ -6142,8 +6429,11 @@ class NodeTree {
|
|
|
6142
6429
|
actionEl.className = "lexicon " + a.icon;
|
|
6143
6430
|
actionEl.title = a.name;
|
|
6144
6431
|
actionEl.addEventListener("click", function( e ) {
|
|
6145
|
-
a.callback
|
|
6146
|
-
|
|
6432
|
+
if( a.callback )
|
|
6433
|
+
{
|
|
6434
|
+
a.callback( node, actionEl );
|
|
6435
|
+
e.stopPropagation();
|
|
6436
|
+
}
|
|
6147
6437
|
});
|
|
6148
6438
|
|
|
6149
6439
|
inputContainer.appendChild( actionEl );
|
|
@@ -6244,6 +6534,8 @@ class NodeTree {
|
|
|
6244
6534
|
}
|
|
6245
6535
|
}
|
|
6246
6536
|
|
|
6537
|
+
LX.NodeTree = NodeTree;
|
|
6538
|
+
|
|
6247
6539
|
/**
|
|
6248
6540
|
* @class Blank
|
|
6249
6541
|
* @description Blank Widget
|
|
@@ -6634,6 +6926,7 @@ class Button extends Widget {
|
|
|
6634
6926
|
wValue.querySelector( "a" ).classList.add( "swap-off" );
|
|
6635
6927
|
|
|
6636
6928
|
const input = document.createElement( "input" );
|
|
6929
|
+
input.className = "p-0 border-0";
|
|
6637
6930
|
input.type = "checkbox";
|
|
6638
6931
|
wValue.prepend( input );
|
|
6639
6932
|
|
|
@@ -8194,6 +8487,16 @@ class ColorInput extends Widget {
|
|
|
8194
8487
|
container.className = "lexcolor";
|
|
8195
8488
|
this.root.appendChild( container );
|
|
8196
8489
|
|
|
8490
|
+
this.picker = new ColorPicker( value, {
|
|
8491
|
+
colorModel: options.useRGB ? "RGB" : "Hex",
|
|
8492
|
+
useAlpha,
|
|
8493
|
+
onChange: ( color ) => {
|
|
8494
|
+
this._fromColorPicker = true;
|
|
8495
|
+
this.set( color.hex );
|
|
8496
|
+
delete this._fromColorPicker;
|
|
8497
|
+
}
|
|
8498
|
+
} );
|
|
8499
|
+
|
|
8197
8500
|
let sampleContainer = LX.makeContainer( ["18px", "18px"], "flex flex-row bg-contrast rounded overflow-hidden", "", container );
|
|
8198
8501
|
sampleContainer.tabIndex = "1";
|
|
8199
8502
|
sampleContainer.addEventListener( "click", e => {
|
|
@@ -8201,15 +8504,8 @@ class ColorInput extends Widget {
|
|
|
8201
8504
|
{
|
|
8202
8505
|
return;
|
|
8203
8506
|
}
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
useAlpha,
|
|
8207
|
-
onChange: ( color ) => {
|
|
8208
|
-
this._fromColorPicker = true;
|
|
8209
|
-
this.set( color.hex );
|
|
8210
|
-
delete this._fromColorPicker;
|
|
8211
|
-
}
|
|
8212
|
-
} );
|
|
8507
|
+
|
|
8508
|
+
this._popover = new Popover( sampleContainer, [ this.picker ] );
|
|
8213
8509
|
} );
|
|
8214
8510
|
|
|
8215
8511
|
let colorSampleRGB = document.createElement( 'div' );
|
|
@@ -10202,6 +10498,75 @@ class Table extends Widget {
|
|
|
10202
10498
|
|
|
10203
10499
|
LX.Table = Table;
|
|
10204
10500
|
|
|
10501
|
+
/**
|
|
10502
|
+
* @class DatePicker
|
|
10503
|
+
* @description DatePicker Widget
|
|
10504
|
+
*/
|
|
10505
|
+
|
|
10506
|
+
class DatePicker extends Widget {
|
|
10507
|
+
|
|
10508
|
+
constructor( name, dateString, callback, options = { } ) {
|
|
10509
|
+
|
|
10510
|
+
super( Widget.DATE, name, null, options );
|
|
10511
|
+
|
|
10512
|
+
if( options.today )
|
|
10513
|
+
{
|
|
10514
|
+
const date = new Date();
|
|
10515
|
+
dateString = `${ date.getDate() }/${ date.getMonth() + 1 }/${ date.getFullYear() }`;
|
|
10516
|
+
}
|
|
10517
|
+
|
|
10518
|
+
this.onGetValue = () => {
|
|
10519
|
+
return dateString;
|
|
10520
|
+
}
|
|
10521
|
+
|
|
10522
|
+
this.onSetValue = ( newValue, skipCallback, event ) => {
|
|
10523
|
+
|
|
10524
|
+
dateString = newValue;
|
|
10525
|
+
|
|
10526
|
+
this.calendar.fromDateString( newValue );
|
|
10527
|
+
|
|
10528
|
+
refresh( this.calendar.getFullDate() );
|
|
10529
|
+
|
|
10530
|
+
if( !skipCallback )
|
|
10531
|
+
{
|
|
10532
|
+
this._trigger( new IEvent( name, newValue, event ), callback );
|
|
10533
|
+
}
|
|
10534
|
+
}
|
|
10535
|
+
|
|
10536
|
+
this.onResize = ( rect ) => {
|
|
10537
|
+
const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
|
|
10538
|
+
container.style.width = `calc( 100% - ${ realNameWidth })`;
|
|
10539
|
+
};
|
|
10540
|
+
|
|
10541
|
+
const container = document.createElement('div');
|
|
10542
|
+
container.className = "lexdate";
|
|
10543
|
+
this.root.appendChild( container );
|
|
10544
|
+
|
|
10545
|
+
this.calendar = new Calendar( dateString, { onChange: ( date ) => {
|
|
10546
|
+
this.set( `${ date.day }/${ date.month }/${ date.year }` )
|
|
10547
|
+
}, ...options });
|
|
10548
|
+
|
|
10549
|
+
const refresh = ( currentDate ) => {
|
|
10550
|
+
container.innerHTML = "";
|
|
10551
|
+
const calendarIcon = LX.makeIcon( "calendar" );
|
|
10552
|
+
const calendarButton = new Button( null, currentDate ?? "Pick a date", () => {
|
|
10553
|
+
this._popover = new Popover( calendarButton.root, ( popoverRoot ) => {
|
|
10554
|
+
popoverRoot.appendChild( this.calendar.root );
|
|
10555
|
+
} );
|
|
10556
|
+
}, { buttonClass: `flex flex-row px-3 ${ currentDate ? "" : "fg-tertiary" } justify-between` } );
|
|
10557
|
+
|
|
10558
|
+
calendarButton.root.querySelector( "button" ).appendChild( calendarIcon );
|
|
10559
|
+
container.appendChild( calendarButton.root );
|
|
10560
|
+
};
|
|
10561
|
+
|
|
10562
|
+
refresh( dateString ? this.calendar.getFullDate(): null );
|
|
10563
|
+
|
|
10564
|
+
doAsync( this.onResize.bind( this ) );
|
|
10565
|
+
}
|
|
10566
|
+
}
|
|
10567
|
+
|
|
10568
|
+
LX.DatePicker = DatePicker;
|
|
10569
|
+
|
|
10205
10570
|
/**
|
|
10206
10571
|
* @class Panel
|
|
10207
10572
|
*/
|
|
@@ -11348,6 +11713,23 @@ class Panel {
|
|
|
11348
11713
|
const widget = new Table( name, data, options );
|
|
11349
11714
|
return this._attachWidget( widget );
|
|
11350
11715
|
}
|
|
11716
|
+
|
|
11717
|
+
/**
|
|
11718
|
+
* @method addDate
|
|
11719
|
+
* @param {String} name Widget name
|
|
11720
|
+
* @param {String} dateString
|
|
11721
|
+
* @param {Function} callback
|
|
11722
|
+
* @param {Object} options:
|
|
11723
|
+
* hideName: Don't use name as label [false]
|
|
11724
|
+
* today: Set current day as selected by default
|
|
11725
|
+
* untilToday: Allow dates only until current day
|
|
11726
|
+
* fromToday: Allow dates only from current day
|
|
11727
|
+
*/
|
|
11728
|
+
|
|
11729
|
+
addDate( name, dateString, callback, options = { } ) {
|
|
11730
|
+
const widget = new DatePicker( name, dateString, callback, options );
|
|
11731
|
+
return this._attachWidget( widget );
|
|
11732
|
+
}
|
|
11351
11733
|
}
|
|
11352
11734
|
|
|
11353
11735
|
LX.Panel = Panel;
|
|
@@ -14380,6 +14762,7 @@ LX.ICONS = {
|
|
|
14380
14762
|
"sidebar": [512, 512, [], "regular", "M64 64h384a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H64a32 32 0 0 1-32-32V96a32 32 0 0 1 32-32zm128 0v384", null, "fill=none stroke-width=50 stroke-linejoin=round stroke-linecap=round"],
|
|
14381
14763
|
"table-cells": [512, 512, [], "solid", "M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm88 64l0 64-88 0 0-64 88 0zm56 0l88 0 0 64-88 0 0-64zm240 0l0 64-88 0 0-64 88 0zM64 224l88 0 0 64-88 0 0-64zm232 0l0 64-88 0 0-64 88 0zm64 0l88 0 0 64-88 0 0-64zM152 352l0 64-88 0 0-64 88 0zm56 0l88 0 0 64-88 0 0-64zm240 0l0 64-88 0 0-64 88 0z"],
|
|
14382
14764
|
"table-cells-large": [512, 512, [], "solid", "M448 96l0 128-160 0 0-128 160 0zm0 192l0 128-160 0 0-128 160 0zM224 224L64 224 64 96l160 0 0 128zM64 288l160 0 0 128L64 416l0-128zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32z"],
|
|
14765
|
+
"frame": [24, 24, [], "solid", "M2 6h20M2 18h20M6 2v20M18 2v20", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
|
|
14383
14766
|
"lightbulb": [384, 512, [], "regular", "M297.2 248.9C311.6 228.3 320 203.2 320 176c0-70.7-57.3-128-128-128S64 105.3 64 176c0 27.2 8.4 52.3 22.8 72.9c3.7 5.3 8.1 11.3 12.8 17.7c0 0 0 0 0 0c12.9 17.7 28.3 38.9 39.8 59.8c10.4 19 15.7 38.8 18.3 57.5L109 384c-2.2-12-5.9-23.7-11.8-34.5c-9.9-18-22.2-34.9-34.5-51.8c0 0 0 0 0 0s0 0 0 0c-5.2-7.1-10.4-14.2-15.4-21.4C27.6 247.9 16 213.3 16 176C16 78.8 94.8 0 192 0s176 78.8 176 176c0 37.3-11.6 71.9-31.4 100.3c-5 7.2-10.2 14.3-15.4 21.4c0 0 0 0 0 0s0 0 0 0c-12.3 16.8-24.6 33.7-34.5 51.8c-5.9 10.8-9.6 22.5-11.8 34.5l-48.6 0c2.6-18.7 7.9-38.6 18.3-57.5c11.5-20.9 26.9-42.1 39.8-59.8c0 0 0 0 0 0s0 0 0 0s0 0 0 0c4.7-6.4 9-12.4 12.7-17.7zM192 128c-26.5 0-48 21.5-48 48c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-44.2 35.8-80 80-80c8.8 0 16 7.2 16 16s-7.2 16-16 16zm0 384c-44.2 0-80-35.8-80-80l0-16 160 0 0 16c0 44.2-35.8 80-80 80z"],
|
|
14384
14767
|
"flag": [448, 512, [], "regular", "M48 24C48 10.7 37.3 0 24 0S0 10.7 0 24L0 64 0 350.5 0 400l0 88c0 13.3 10.7 24 24 24s24-10.7 24-24l0-100 80.3-20.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30l0-279.7c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L48 52l0-28zm0 77.5l96.6-24.2c27-6.7 55.5-3.6 80.4 8.8c54.9 27.4 118.7 29.7 175 6.8l0 241.8-24.4 9.1c-33.7 12.6-71.2 10.7-103.4-5.4c-48.2-24.1-103.3-30.1-155.6-17.1L48 338.5l0-237z"],
|
|
14385
14768
|
"newspaper": [512, 512, [], "regular", "M168 80c-13.3 0-24 10.7-24 24l0 304c0 8.4-1.4 16.5-4.1 24L440 432c13.3 0 24-10.7 24-24l0-304c0-13.3-10.7-24-24-24L168 80zM72 480c-39.8 0-72-32.2-72-72L0 112C0 98.7 10.7 88 24 88s24 10.7 24 24l0 296c0 13.3 10.7 24 24 24s24-10.7 24-24l0-304c0-39.8 32.2-72 72-72l272 0c39.8 0 72 32.2 72 72l0 304c0 39.8-32.2 72-72 72L72 480zM176 136c0-13.3 10.7-24 24-24l96 0c13.3 0 24 10.7 24 24l0 80c0 13.3-10.7 24-24 24l-96 0c-13.3 0-24-10.7-24-24l0-80zm200-24l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zM200 272l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z"],
|