lexgui 0.5.2 → 0.5.4

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.
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  var LX = {
9
- version: "0.5.2",
9
+ version: "0.5.4",
10
10
  ready: false,
11
11
  components: [], // Specific pre-build components
12
12
  signals: {}, // Events and triggers
@@ -777,7 +777,7 @@ function _createCommandbar( root )
777
777
  className: "gs-tabs"
778
778
  } );
779
779
 
780
- const gsTabs = tabArea.addTabs();
780
+ const gsTabs = tabArea.addTabs( { parentClass: "p-2" } );
781
781
  let gsFilter = null;
782
782
 
783
783
  // These tabs will serve as buttons by now
@@ -933,6 +933,7 @@ function _createCommandbar( root )
933
933
  * @param {Object} options
934
934
  * container: Root location for the gui (default is the document body)
935
935
  * id: Id of the main area
936
+ * rootClass: Extra class to the root container
936
937
  * skipRoot: Skip adding LX root container
937
938
  * skipDefaultArea: Skip creation of main area
938
939
  * strictViewport: Use only window area
@@ -949,8 +950,14 @@ function init( options = { } )
949
950
 
950
951
  var root = document.createElement( 'div' );
951
952
  root.id = "lexroot";
953
+ root.className = "lexcontainer";
952
954
  root.tabIndex = -1;
953
955
 
956
+ if( options.rootClass )
957
+ {
958
+ root.className += ` ${ options.rootClass }`;
959
+ }
960
+
954
961
  var modal = document.createElement( 'div' );
955
962
  modal.id = "modal";
956
963
 
@@ -963,7 +970,7 @@ function init( options = { } )
963
970
 
964
971
  if( options.container )
965
972
  {
966
- this.container = document.getElementById( options.container );
973
+ this.container = options.container.constructor === String ? document.getElementById( options.container ) : options.container;
967
974
  }
968
975
 
969
976
  this.usingStrictViewport = options.strictViewport ?? true;
@@ -1001,7 +1008,7 @@ function init( options = { } )
1001
1008
  this.notifications.className = "";
1002
1009
  this.notifications.iWidth = 0;
1003
1010
  notifSection.appendChild( this.notifications );
1004
- this.container.appendChild( notifSection );
1011
+ document.body.appendChild( notifSection );
1005
1012
 
1006
1013
  this.notifications.addEventListener( "mouseenter", () => {
1007
1014
  this.notifications.classList.add( "list" );
@@ -1318,6 +1325,7 @@ LX.toast = toast;
1318
1325
  * @param {String} className
1319
1326
  * @param {Object} options
1320
1327
  * style: Style attributes to override
1328
+ * asElement: Returns the badge as HTMLElement [false]
1321
1329
  */
1322
1330
 
1323
1331
  function badge( text, className, options = {} )
@@ -1326,7 +1334,7 @@ function badge( text, className, options = {} )
1326
1334
  container.innerHTML = text;
1327
1335
  container.className = "lexbadge " + ( className ?? "" );
1328
1336
  Object.assign( container.style, options.style ?? {} );
1329
- return container.outerHTML;
1337
+ return ( options.asElement ?? false ) ? container : container.outerHTML;
1330
1338
  }
1331
1339
 
1332
1340
  LX.badge = badge;
@@ -1335,21 +1343,84 @@ LX.badge = badge;
1335
1343
  * @method makeContainer
1336
1344
  * @param {Array} size
1337
1345
  * @param {String} className
1346
+ * @param {String} innerHTML
1347
+ * @param {HTMLElement} parent
1338
1348
  * @param {Object} overrideStyle
1339
1349
  */
1340
1350
 
1341
- function makeContainer( size, className, overrideStyle = {} )
1351
+ function makeContainer( size, className, innerHTML, parent, overrideStyle = {} )
1342
1352
  {
1343
1353
  const container = document.createElement( "div" );
1344
1354
  container.className = "lexcontainer " + ( className ?? "" );
1355
+ container.innerHTML = innerHTML ?? "";
1345
1356
  container.style.width = size && size[ 0 ] ? size[ 0 ] : "100%";
1346
1357
  container.style.height = size && size[ 1 ] ? size[ 1 ] : "100%";
1347
1358
  Object.assign( container.style, overrideStyle );
1359
+
1360
+ if( parent )
1361
+ {
1362
+ if( parent.attach ) // Use attach method if possible
1363
+ {
1364
+ parent.attach( container );
1365
+ }
1366
+ else // its a native HTMLElement
1367
+ {
1368
+ parent.appendChild( container );
1369
+ }
1370
+ }
1371
+
1348
1372
  return container;
1349
1373
  }
1350
1374
 
1351
1375
  LX.makeContainer = makeContainer;
1352
1376
 
1377
+ /**
1378
+ * @method asTooltip
1379
+ * @param {HTMLElement} trigger
1380
+ * @param {String} content
1381
+ */
1382
+
1383
+ function asTooltip( trigger, content )
1384
+ {
1385
+ console.assert( trigger, "You need a trigger to generate a tooltip!" );
1386
+
1387
+ let tooltipDom = null;
1388
+
1389
+ trigger.addEventListener( "mouseenter", function(e) {
1390
+
1391
+ console.log(e.target);
1392
+
1393
+ LX.root.querySelectorAll( ".lextooltip" ).forEach( e => e.remove() );
1394
+
1395
+ let rect = this.getBoundingClientRect();
1396
+ rect.x += document.scrollingElement.scrollLeft;
1397
+ rect.y += document.scrollingElement.scrollTop;
1398
+
1399
+ tooltipDom = document.createElement( "div" );
1400
+ tooltipDom.className = "lextooltip";
1401
+ tooltipDom.innerHTML = content;
1402
+
1403
+ doAsync( () => {
1404
+ tooltipDom.style.top = ( rect.y - tooltipDom.offsetHeight - 6 ) + "px";
1405
+ tooltipDom.style.left = ( rect.x + rect.width * 0.5 - tooltipDom.offsetWidth * 0.5 ) + "px";
1406
+ } )
1407
+
1408
+ LX.root.appendChild( tooltipDom );
1409
+ } );
1410
+
1411
+ trigger.addEventListener( "mouseleave", function(e) {
1412
+ if( !tooltipDom ) return;
1413
+
1414
+ tooltipDom.dataset[ "closed" ] = true;
1415
+
1416
+ doAsync( () => {
1417
+ tooltipDom.remove();
1418
+ }, 300 )
1419
+ } )
1420
+ }
1421
+
1422
+ LX.asTooltip = asTooltip;
1423
+
1353
1424
  /*
1354
1425
  * Events and Signals
1355
1426
  */
@@ -1592,7 +1663,7 @@ class DropdownMenu {
1592
1663
  }
1593
1664
 
1594
1665
  const menuItem = document.createElement('div');
1595
- menuItem.className = "lexdropdownmenuitem" + ( item.name ? "" : " label" ) + ( item.disabled ?? false ? " disabled" : "" );
1666
+ menuItem.className = "lexdropdownmenuitem" + ( item.name ? "" : " label" ) + ( item.disabled ?? false ? " disabled" : "" ) + ( ` ${ item.className ?? "" }` );
1596
1667
  menuItem.id = pKey;
1597
1668
  menuItem.innerHTML = `<span>${ key }</span>`;
1598
1669
 
@@ -1625,7 +1696,7 @@ class DropdownMenu {
1625
1696
  {
1626
1697
  f.call( this, key, menuItem, v );
1627
1698
  }
1628
- });
1699
+ }, { className: "accent" });
1629
1700
  const input = checkbox.root.querySelector( "input" );
1630
1701
  menuItem.prepend( input );
1631
1702
 
@@ -1789,7 +1860,7 @@ class Area {
1789
1860
  root.className += " " + options.className;
1790
1861
  }
1791
1862
 
1792
- var width = options.width || "calc( 100% )";
1863
+ var width = options.width || "100%";
1793
1864
  var height = options.height || "100%";
1794
1865
 
1795
1866
  // This has default options..
@@ -1813,9 +1884,9 @@ class Area {
1813
1884
  this.sections = [];
1814
1885
  this.panels = [];
1815
1886
 
1816
- if( !options.skipAppend )
1887
+ let lexroot = document.getElementById("lexroot");
1888
+ if( lexroot && !options.skipAppend )
1817
1889
  {
1818
- let lexroot = document.getElementById("lexroot");
1819
1890
  lexroot.appendChild( this.root );
1820
1891
  }
1821
1892
 
@@ -1962,7 +2033,7 @@ class Area {
1962
2033
  attach( content ) {
1963
2034
 
1964
2035
  // Append to last split section if area has been split
1965
- if( this.sections.length)
2036
+ if( this.sections.length )
1966
2037
  {
1967
2038
  this.sections[ 1 ].attach( content );
1968
2039
  return;
@@ -1998,7 +2069,7 @@ class Area {
1998
2069
 
1999
2070
  const type = options.type || "horizontal";
2000
2071
  const sizes = options.sizes || [ "50%", "50%" ];
2001
- const auto = (options.sizes === 'auto');
2072
+ const auto = (options.sizes === 'auto') || ( options.sizes && options.sizes[ 0 ] == "auto" && options.sizes[ 1 ] == "auto" );
2002
2073
 
2003
2074
  if( !sizes[ 1 ] )
2004
2075
  {
@@ -2102,8 +2173,8 @@ class Area {
2102
2173
  const resizeObserver = new ResizeObserver( entries => {
2103
2174
  for ( const entry of entries )
2104
2175
  {
2105
- const bb = entry.contentRect;
2106
- area2.root.style.height = "calc(100% - " + ( bb.height + 4) + "px )";
2176
+ const size = entry.target.getComputedSize();
2177
+ area2.root.style.height = "calc(100% - " + ( size.height ) + "px )";
2107
2178
  }
2108
2179
  });
2109
2180
 
@@ -2381,7 +2452,12 @@ class Area {
2381
2452
 
2382
2453
  if( options.sticky ?? true )
2383
2454
  {
2384
- bar.root.classList.add( "sticky" );
2455
+ bar.root.className += " sticky top-0";
2456
+ }
2457
+
2458
+ if( options.parentClass )
2459
+ {
2460
+ bar.root.className += ` ${ options.parentClass }`;
2385
2461
  }
2386
2462
 
2387
2463
  return menubar;
@@ -2415,6 +2491,11 @@ class Area {
2415
2491
  bar.attach( sidebar );
2416
2492
  bar.isSidebar = true;
2417
2493
 
2494
+ if( options.parentClass )
2495
+ {
2496
+ bar.root.className += ` ${ options.parentClass }`;
2497
+ }
2498
+
2418
2499
  return sidebar;
2419
2500
  }
2420
2501
 
@@ -2478,7 +2559,8 @@ class Area {
2478
2559
  selected: b.selected,
2479
2560
  icon: b.icon,
2480
2561
  img: b.img,
2481
- className: b.class
2562
+ className: b.class ?? "",
2563
+ title: b.name
2482
2564
  };
2483
2565
 
2484
2566
  if( group )
@@ -2516,7 +2598,10 @@ class Area {
2516
2598
  }
2517
2599
  }
2518
2600
 
2519
- callback( value, event, button.root );
2601
+ if( callback )
2602
+ {
2603
+ callback( value, event, button.root );
2604
+ }
2520
2605
 
2521
2606
  }, _options );
2522
2607
  }
@@ -2573,6 +2658,7 @@ class Area {
2573
2658
  /**
2574
2659
  * @method addTabs
2575
2660
  * @param {Object} options:
2661
+ * parentClass: Add extra class to tab buttons container
2576
2662
  */
2577
2663
 
2578
2664
  addTabs( options = {} ) {
@@ -2692,7 +2778,6 @@ function flushCss(element) {
2692
2778
 
2693
2779
  class Tabs {
2694
2780
 
2695
- static TAB_SIZE = 28;
2696
2781
  static TAB_ID = 0;
2697
2782
 
2698
2783
  constructor( area, options = {} ) {
@@ -2700,10 +2785,10 @@ class Tabs {
2700
2785
  this.onclose = options.onclose;
2701
2786
 
2702
2787
  let container = document.createElement('div');
2703
- container.className = "lexareatabs " + (options.fit ? "fit" : "row");
2788
+ container.className = "lexareatabs " + ( options.fit ? "fit" : "row" );
2704
2789
 
2705
2790
  const folding = options.folding ?? false;
2706
- if(folding) container.classList.add("folding");
2791
+ if( folding ) container.classList.add("folding");
2707
2792
 
2708
2793
  let that = this;
2709
2794
 
@@ -2776,11 +2861,22 @@ class Tabs {
2776
2861
 
2777
2862
  area.root.classList.add( "lexareatabscontainer" );
2778
2863
 
2779
- area.split({ type: 'vertical', sizes: options.sizes ?? "auto", resize: false, top: 6 });
2780
- area.sections[ 0 ].attach( container );
2864
+ const [ tabButtons, content ] = area.split({ type: 'vertical', sizes: options.sizes ?? "auto", resize: false, top: 2 });
2865
+ tabButtons.attach( container );
2866
+
2867
+ if( options.parentClass )
2868
+ {
2869
+ container.parentElement.className += ` ${ options.parentClass }`;
2870
+ }
2781
2871
 
2782
- this.area = area.sections[1];
2872
+ this.area = content;
2783
2873
  this.area.root.className += " lexareatabscontent";
2874
+
2875
+ if( options.contentClass )
2876
+ {
2877
+ this.area.root.className += ` ${ options.contentClass }`;
2878
+ }
2879
+
2784
2880
  this.selected = null;
2785
2881
  this.root = container;
2786
2882
  this.tabs = {};
@@ -2800,8 +2896,7 @@ class Tabs {
2800
2896
  var transition = this.thumb.style.transition;
2801
2897
  this.thumb.style.transition = "none";
2802
2898
  this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2803
- this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
2804
- this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
2899
+ this.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2805
2900
  flushCss( this.thumb );
2806
2901
  this.thumb.style.transition = transition;
2807
2902
  });
@@ -2843,7 +2938,7 @@ class Tabs {
2843
2938
  if( isSelected )
2844
2939
  {
2845
2940
  this.root.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ) );
2846
- this.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
2941
+ this.area.root.querySelectorAll( ':scope > .lextabcontent' ).forEach( c => c.style.display = 'none' );
2847
2942
  }
2848
2943
 
2849
2944
  isSelected = !Object.keys( this.tabs ).length && !this.folding ? true : isSelected;
@@ -2901,7 +2996,7 @@ class Tabs {
2901
2996
  tabEl.parentElement.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ));
2902
2997
  tabEl.classList.toggle('selected', ( this.folding && tabEl.selected ));
2903
2998
  // Manage visibility
2904
- scope.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
2999
+ scope.area.root.querySelectorAll( ':scope > .lextabcontent' ).forEach( c => c.style.display = 'none' );
2905
3000
  contentEl.style.display = contentEl.originalDisplay;
2906
3001
  scope.selected = tabEl.dataset.name;
2907
3002
  }
@@ -2920,8 +3015,7 @@ class Tabs {
2920
3015
  if( scope.thumb )
2921
3016
  {
2922
3017
  scope.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2923
- scope.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
2924
- scope.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
3018
+ scope.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2925
3019
  scope.thumb.item = tabEl;
2926
3020
  }
2927
3021
  });
@@ -2973,8 +3067,7 @@ class Tabs {
2973
3067
  if( isSelected && this.thumb )
2974
3068
  {
2975
3069
  this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2976
- this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
2977
- this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
3070
+ this.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2978
3071
  this.thumb.item = tabEl;
2979
3072
  }
2980
3073
 
@@ -3106,7 +3199,7 @@ class Menubar {
3106
3199
  const hasSubmenu = subitem[ subkey ].length;
3107
3200
  const isCheckbox = subitem[ 'type' ] == 'checkbox';
3108
3201
  let subentry = document.createElement('div');
3109
- subentry.tabIndex = "1";
3202
+ subentry.tabIndex = "-1";
3110
3203
  subentry.className = "lexmenuboxentry";
3111
3204
  subentry.className += (i == o[k].length - 1 ? " last" : "") + ( subitem.disabled ? " disabled" : "" );
3112
3205
 
@@ -3193,12 +3286,10 @@ class Menubar {
3193
3286
  });
3194
3287
 
3195
3288
  subentry.addEventListener("blur", e => {
3196
-
3197
- if( e.target && e.target.className.includes( "lexmenu" ) )
3289
+ if( e.relatedTarget && !e.relatedTarget.className.includes( "lexmenu" ) )
3198
3290
  {
3199
- return;
3291
+ this._resetMenubar();
3200
3292
  }
3201
- this._resetMenubar();
3202
3293
  });
3203
3294
 
3204
3295
  // Add icon if has submenu, else check for shortcut
@@ -3654,6 +3745,7 @@ class SideBar {
3654
3745
 
3655
3746
  /**
3656
3747
  * @param {Object} options
3748
+ * className: Extra class to customize root element
3657
3749
  * filter: Add search bar to filter entries [false]
3658
3750
  * displaySelected: Indicate if an entry is displayed as selected
3659
3751
  * skipHeader: Do not use sidebar header [false]
@@ -3677,7 +3769,7 @@ class SideBar {
3677
3769
  constructor( options = {} ) {
3678
3770
 
3679
3771
  this.root = document.createElement( "div" );
3680
- this.root.className = "lexsidebar";
3772
+ this.root.className = "lexsidebar " + ( options.className ?? "" );
3681
3773
 
3682
3774
  this._displaySelected = options.displaySelected ?? false;
3683
3775
 
@@ -3738,12 +3830,11 @@ class SideBar {
3738
3830
  // Entry filter
3739
3831
  if( ( options.filter ?? false ) )
3740
3832
  {
3741
- const panel = new Panel();
3742
- panel.addText(null, "", (value, event) => {
3833
+ const filterTextInput = new TextInput(null, "", (value, event) => {
3743
3834
  this.filterString = value;
3744
3835
  this.update();
3745
- }, { placeholder: "Search...", icon: "fa-solid fa-magnifying-glass" });
3746
- this.filter = panel.root.childNodes[ 0 ];
3836
+ }, { inputClass: "outline", placeholder: "Search...", icon: "fa-solid fa-magnifying-glass", className: "lexsidebarfilter" });
3837
+ this.filter = filterTextInput.root;
3747
3838
  this.root.appendChild( this.filter );
3748
3839
  }
3749
3840
 
@@ -3765,10 +3856,10 @@ class SideBar {
3765
3856
 
3766
3857
  // Set width depending on header/footer
3767
3858
  doAsync( () => {
3768
- // This account for header, footer and all inner paddings
3769
- const contentOffset = 32 + ( this.header?.offsetHeight ?? 0 ) +
3770
- ( this.filter?.offsetHeight ?? 0 ) +
3771
- ( this.footer?.offsetHeight ?? 0 );
3859
+ // This account for header, footer and all inner margins
3860
+ const contentOffset = ( parseInt( this.header?.getComputedSize().height ) ?? 0 ) +
3861
+ ( parseInt( this.filter?.getComputedSize().height ) ?? 0 ) +
3862
+ ( parseInt( this.footer?.getComputedSize().height ) ?? 0 );
3772
3863
  this.content.style.height = `calc(100% - ${ contentOffset }px)`;
3773
3864
  }, 10 );
3774
3865
 
@@ -4054,8 +4145,13 @@ class SideBar {
4054
4145
  let currentGroup = null;
4055
4146
 
4056
4147
  let entry = document.createElement( 'div' );
4057
- entry.className = "lexsidebarentry " + ( options.className ?? "" );
4058
4148
  entry.id = item.name = pKey;
4149
+ entry.className = "lexsidebarentry " + ( options.className ?? "" );
4150
+
4151
+ if( this.displaySelected && options.selected )
4152
+ {
4153
+ entry.classList.add( "selected" );
4154
+ }
4059
4155
 
4060
4156
  if( item.group )
4061
4157
  {
@@ -4125,6 +4221,7 @@ class SideBar {
4125
4221
  }
4126
4222
 
4127
4223
  let itemDom = document.createElement( 'div' );
4224
+ itemDom.className = "lexsidebarentrycontent";
4128
4225
  entry.appendChild( itemDom );
4129
4226
  item.dom = entry;
4130
4227
 
@@ -4138,21 +4235,38 @@ class SideBar {
4138
4235
  const f = options.callback;
4139
4236
  item.value = value;
4140
4237
  if( f ) f.call( this, key, value, event );
4141
- }, { label: key, signal: ( "@checkbox_" + key ) });
4238
+ }, { className: "accent", label: key, signal: ( "@checkbox_" + key ) });
4142
4239
  itemDom.appendChild( panel.root.childNodes[ 0 ] );
4143
4240
  }
4144
4241
  else
4145
4242
  {
4146
4243
  if( options.icon )
4147
4244
  {
4148
- let itemIcon = document.createElement( 'i' );
4149
- itemIcon.className = options.icon;
4245
+ let itemIcon = null;
4246
+
4247
+ // @legacy
4248
+ if( options.icon.includes( "fa-" ) )
4249
+ {
4250
+ itemIcon = document.createElement( 'i' );
4251
+ itemIcon.className = options.icon;
4252
+ }
4253
+ else
4254
+ {
4255
+ itemIcon = LX.makeIcon( options.icon );
4256
+ }
4257
+
4258
+ itemIcon.classList.add( "lexsidebarentryicon" );
4150
4259
  itemDom.appendChild( itemIcon );
4151
4260
  }
4152
4261
 
4153
4262
  let itemName = document.createElement( 'a' );
4154
4263
  itemName.innerHTML = key;
4155
4264
  itemDom.appendChild( itemName );
4265
+
4266
+ if( options.content )
4267
+ {
4268
+ itemDom.appendChild( options.content );
4269
+ }
4156
4270
  }
4157
4271
 
4158
4272
  const isCollapsable = options.collapsable != undefined ? options.collapsable : ( options.collapsable || item[ key ].length );
@@ -4378,8 +4492,6 @@ class Widget {
4378
4492
 
4379
4493
  if( type != Widget.TITLE )
4380
4494
  {
4381
- // root.style.width = "calc(100% - " + (this._currentBranch || type == Widget.FILE || type == Widget.TREE ? 10 : 20) + "px)";
4382
-
4383
4495
  if( options.width )
4384
4496
  {
4385
4497
  root.style.width = root.style.minWidth = options.width;
@@ -4415,6 +4527,7 @@ class Widget {
4415
4527
  domName.innerHTML = name;
4416
4528
  domName.title = options.title ?? domName.innerHTML;
4417
4529
  domName.style.width = options.nameWidth || LX.DEFAULT_NAME_WIDTH;
4530
+ domName.style.minWidth = domName.style.width;
4418
4531
 
4419
4532
  root.appendChild( domName );
4420
4533
  root.domName = domName;
@@ -4645,16 +4758,18 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
4645
4758
  container.className = "lexcustomcontainer";
4646
4759
  container.style.width = "100%";
4647
4760
  element.appendChild( container );
4761
+ element.dataset["opened"] = false;
4648
4762
 
4649
- let buttonName = "<a class='fa-solid " + (options.icon ?? "fa-cube") + "' style='float:left'></a>";
4763
+ let buttonName = "<a class='fa-solid " + (options.icon ?? "fa-cube") + "'></a>";
4650
4764
  buttonName += customWidgetName + (!instance ? " [empty]" : "");
4651
4765
  // Add always icon to keep spacing right
4652
- buttonName += "<a class='fa-solid " + (instance ? "fa-bars-staggered" : " ") + " menu' style='float:right; width:5%;'></a>";
4766
+ buttonName += "<a class='fa-solid " + (instance ? "fa-bars-staggered" : " ") + " menu'></a>";
4653
4767
 
4654
4768
  let buttonEl = this.addButton(null, buttonName, (value, event) => {
4655
4769
  if( instance )
4656
4770
  {
4657
4771
  element.querySelector(".lexcustomitems").toggleAttribute('hidden');
4772
+ element.dataset["opened"] = !element.querySelector(".lexcustomitems").hasAttribute("hidden");
4658
4773
  }
4659
4774
  else
4660
4775
  {
@@ -4663,6 +4778,7 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
4663
4778
  instance = {};
4664
4779
  refresh_widget();
4665
4780
  element.querySelector(".lexcustomitems").toggleAttribute('hidden', false);
4781
+ element.dataset["opened"] = !element.querySelector(".lexcustomitems").hasAttribute("hidden");
4666
4782
  });
4667
4783
  });
4668
4784
  }
@@ -4777,7 +4893,7 @@ class NodeTree {
4777
4893
  _createItem( parent, node, level = 0, selectedId ) {
4778
4894
 
4779
4895
  const that = this;
4780
- const nodeFilterInput = this.domEl.querySelector( "#lexnodetree_filter" );
4896
+ const nodeFilterInput = this.domEl.querySelector( ".lexnodetree_filter" );
4781
4897
 
4782
4898
  node.children = node.children ?? [];
4783
4899
  if( nodeFilterInput && nodeFilterInput.value != "" && !node.id.includes( nodeFilterInput.value ) )
@@ -5356,14 +5472,7 @@ class TextInput extends Widget {
5356
5472
 
5357
5473
  this._lastValueTriggered = value = newValue;
5358
5474
 
5359
- if( options.disabled )
5360
- {
5361
- wValue.innerText = newValue;
5362
- }
5363
- else
5364
- {
5365
- wValue.value = newValue;
5366
- }
5475
+ wValue.value = newValue;
5367
5476
 
5368
5477
  if( !skipCallback )
5369
5478
  {
@@ -5384,21 +5493,18 @@ class TextInput extends Widget {
5384
5493
  };
5385
5494
 
5386
5495
  let container = document.createElement( 'div' );
5387
- container.className = "lextext" + ( options.warning ? " lexwarning" : "" );
5496
+ container.className = ( options.warning ? " lexwarning" : "" );
5388
5497
  container.style.display = "flex";
5498
+ container.style.position = "relative";
5389
5499
  this.root.appendChild( container );
5390
5500
 
5391
- if( options.textClass )
5392
- {
5393
- container.classList.add( options.textClass );
5394
- }
5395
-
5396
5501
  this.disabled = ( options.disabled || options.warning ) ?? ( options.url ? true : false );
5397
5502
  let wValue = null;
5398
5503
 
5399
5504
  if( !this.disabled )
5400
5505
  {
5401
5506
  wValue = document.createElement( 'input' );
5507
+ wValue.className = "lextext " + ( options.inputClass ?? "" );
5402
5508
  wValue.type = options.type || "";
5403
5509
  wValue.value = wValue.iValue = value || "";
5404
5510
  wValue.style.width = "100%";
@@ -5445,27 +5551,36 @@ class TextInput extends Widget {
5445
5551
 
5446
5552
  if( options.icon )
5447
5553
  {
5554
+ wValue.style.paddingLeft = "1.75rem";
5448
5555
  let icon = document.createElement( 'a' );
5449
5556
  icon.className = "inputicon " + options.icon;
5450
5557
  container.appendChild( icon );
5451
5558
  }
5452
5559
 
5453
5560
  }
5454
- else
5561
+ else if( options.url )
5455
5562
  {
5456
- wValue = document.createElement( options.url ? 'a' : 'div' );
5457
-
5458
- if( options.url )
5459
- {
5460
- wValue.href = options.url;
5461
- wValue.target = "_blank";
5462
- }
5563
+ wValue = document.createElement( 'a' );
5564
+ wValue.href = options.url;
5565
+ wValue.target = "_blank";
5463
5566
 
5464
5567
  const icon = options.warning ? '<i class="fa-solid fa-triangle-exclamation"></i>' : '';
5465
5568
  wValue.innerHTML = ( icon + value ) || "";
5466
5569
  wValue.style.width = "100%";
5467
5570
  wValue.style.textAlign = options.float ?? "";
5468
- wValue.className = "ellipsis-overflow";
5571
+ wValue.className = "lextext ellipsis-overflow";
5572
+ }
5573
+ else
5574
+ {
5575
+ wValue = document.createElement( 'input' );
5576
+
5577
+ const icon = options.warning ? '<i class="fa-solid fa-triangle-exclamation"></i>' : '';
5578
+ wValue.disabled = true;
5579
+ wValue.innerHTML = icon;
5580
+ wValue.value = value;
5581
+ wValue.style.width = "100%";
5582
+ wValue.style.textAlign = options.float ?? "";
5583
+ wValue.className = "lextext ellipsis-overflow " + ( options.inputClass ?? "" );
5469
5584
  }
5470
5585
 
5471
5586
  Object.assign( wValue.style, options.style ?? {} );
@@ -5475,7 +5590,7 @@ class TextInput extends Widget {
5475
5590
  }
5476
5591
  }
5477
5592
 
5478
- LX.Text = Text;
5593
+ LX.TextInput = TextInput;
5479
5594
 
5480
5595
  /**
5481
5596
  * @class TextArea
@@ -5513,6 +5628,13 @@ class TextArea extends Widget {
5513
5628
  this.root.appendChild( container );
5514
5629
 
5515
5630
  let wValue = document.createElement( "textarea" );
5631
+
5632
+ if( !( options.resize ?? true ) )
5633
+ {
5634
+ wValue.style.resize = "none";
5635
+ }
5636
+
5637
+ wValue.className = ( options.inputClass ?? "" );
5516
5638
  wValue.value = wValue.iValue = value || "";
5517
5639
  wValue.style.width = "100%";
5518
5640
  wValue.style.textAlign = options.float ?? "";
@@ -5583,9 +5705,36 @@ class Button extends Widget {
5583
5705
  };
5584
5706
 
5585
5707
  this.onSetValue = ( newValue, skipCallback, event ) => {
5586
- wValue.innerHTML =
5587
- ( options.icon ? "<a class='" + options.icon + "'></a>" :
5588
- ( options.img ? "<img src='" + options.img + "'>" : "<span>" + ( newValue || "" ) + "</span>" ) );
5708
+
5709
+ wValue.innerHTML = `<span></span>`;
5710
+
5711
+ if( options.icon )
5712
+ {
5713
+ let icon = null;
5714
+
5715
+ // @legacy
5716
+ if( options.icon.includes( "fa-" ) )
5717
+ {
5718
+ icon = document.createElement( 'a' );
5719
+ icon.className = options.icon;
5720
+ }
5721
+ else
5722
+ {
5723
+ icon = LX.makeIcon( options.icon );
5724
+ }
5725
+
5726
+ wValue.prepend( icon );
5727
+ }
5728
+ else if( options.img )
5729
+ {
5730
+ let img = document.createElement( 'img' );
5731
+ img.src = options.img;
5732
+ wValue.prepend( img );
5733
+ }
5734
+ else
5735
+ {
5736
+ wValue.innerHTML = `<span>${ ( newValue || "" ) }</span>`;
5737
+ }
5589
5738
  };
5590
5739
 
5591
5740
  this.onResize = ( rect ) => {
@@ -5594,8 +5743,14 @@ class Button extends Widget {
5594
5743
  };
5595
5744
 
5596
5745
  var wValue = document.createElement( 'button' );
5597
- wValue.title = options.title ?? "";
5746
+ wValue.title = options.tooltip ? "" : ( options.title ?? "" );
5598
5747
  wValue.className = "lexbutton " + ( options.buttonClass ?? "" );
5748
+
5749
+ if( options.icon )
5750
+ {
5751
+ wValue.classList.add( "justify-center" );
5752
+ }
5753
+
5599
5754
  this.root.appendChild( wValue );
5600
5755
 
5601
5756
  if( options.selected )
@@ -5603,9 +5758,7 @@ class Button extends Widget {
5603
5758
  wValue.classList.add( "selected" );
5604
5759
  }
5605
5760
 
5606
- wValue.innerHTML =
5607
- ( options.icon ? "<a class='" + options.icon + "'></a>" :
5608
- ( options.img ? "<img src='" + options.img + "'>" : "<span>" + ( value || "" ) + "</span>" ) );
5761
+ this.onSetValue( value, true );
5609
5762
 
5610
5763
  if( options.disabled )
5611
5764
  {
@@ -5626,6 +5779,11 @@ class Button extends Widget {
5626
5779
  this._trigger( new IEvent( name, value, e ), callback );
5627
5780
  });
5628
5781
 
5782
+ if( options.tooltip )
5783
+ {
5784
+ LX.asTooltip( wValue, options.title ?? name );
5785
+ }
5786
+
5629
5787
  doAsync( this.onResize.bind( this ) );
5630
5788
  }
5631
5789
  }
@@ -5902,7 +6060,7 @@ class Form extends Widget {
5902
6060
  }
5903
6061
 
5904
6062
  entryData.placeholder = entryData.placeholder ?? entry;
5905
- entryData.width = "calc(100% - 10px)";
6063
+ entryData.width = "100%";
5906
6064
 
5907
6065
  // this.addLabel( entry, { textClass: "formlabel" } );
5908
6066
 
@@ -5932,7 +6090,7 @@ class Form extends Widget {
5932
6090
  {
5933
6091
  callback( container.formData, event );
5934
6092
  }
5935
- }, { buttonClass: "primary", width: "calc(100% - 10px)" } );
6093
+ }, { buttonClass: "primary" } );
5936
6094
 
5937
6095
  container.appendChild( submitButton.root );
5938
6096
  }
@@ -5975,7 +6133,7 @@ class Select extends Widget {
5975
6133
  // Reset filter
5976
6134
  if( filter )
5977
6135
  {
5978
- filter.querySelector( "input" ).value = "";
6136
+ filter.root.querySelector( "input" ).value = "";
5979
6137
  const filteredOptions = this._filterOptions( values, "" );
5980
6138
  list.refresh( filteredOptions );
5981
6139
  }
@@ -6002,7 +6160,7 @@ class Select extends Widget {
6002
6160
 
6003
6161
  // Add select widget button
6004
6162
  let buttonName = value;
6005
- buttonName += "<a class='fa-solid fa-angle-down' style='float:right; margin-right: 3px;'></a>";
6163
+ buttonName += "<a class='fa-solid fa-angle-down'></a>";
6006
6164
 
6007
6165
  const _placeOptions = ( parent ) => {
6008
6166
 
@@ -6028,6 +6186,7 @@ class Select extends Widget {
6028
6186
  {
6029
6187
  const rect = nestedDialog.getBoundingClientRect();
6030
6188
  topPosition -= rect.y;
6189
+ maxY -= rect.y;
6031
6190
  }
6032
6191
 
6033
6192
  parent.style.top = ( topPosition + selectRoot.offsetHeight ) + 'px';
@@ -6093,7 +6252,7 @@ class Select extends Widget {
6093
6252
 
6094
6253
  if( filter )
6095
6254
  {
6096
- filter.querySelector( "input" ).focus();
6255
+ filter.root.querySelector( "input" ).focus();
6097
6256
  }
6098
6257
 
6099
6258
  }, { buttonClass: "array", skipInlineCount: true, disabled: options.disabled } );
@@ -6132,7 +6291,7 @@ class Select extends Widget {
6132
6291
  this.unfocus_event = true;
6133
6292
  setTimeout( () => delete this.unfocus_event, 200 );
6134
6293
  }
6135
- else if ( e.relatedTarget && e.relatedTarget.tagName == "INPUT" )
6294
+ else if ( e.relatedTarget && ( e.relatedTarget.tagName == "INPUT" || e.relatedTarget.classList.contains("lexoptions") ) )
6136
6295
  {
6137
6296
  return;
6138
6297
  }
@@ -6153,12 +6312,13 @@ class Select extends Widget {
6153
6312
  filterOptions.trigger = "input";
6154
6313
  filterOptions.icon = "fa-solid fa-magnifying-glass";
6155
6314
  filterOptions.className = "lexfilter";
6315
+ filterOptions.inputClass = "outline";
6156
6316
 
6157
- let filter = new TextInput(null, options.filterValue ?? "", ( v ) => {
6317
+ filter = new TextInput(null, options.filterValue ?? "", ( v ) => {
6158
6318
  const filteredOptions = this._filterOptions( values, v );
6159
6319
  list.refresh( filteredOptions );
6160
6320
  }, filterOptions );
6161
- filter.root.querySelector( ".lextext" ).classList.remove( "lextext" );
6321
+ filter.root.querySelector( ".lextext" ).style.border = "1px solid transparent";
6162
6322
 
6163
6323
  const input = filter.root.querySelector( "input" );
6164
6324
 
@@ -6179,12 +6339,12 @@ class Select extends Widget {
6179
6339
  list.appendChild( listOptions );
6180
6340
 
6181
6341
  // Add select options list
6182
- list.refresh = ( options ) => {
6342
+ list.refresh = ( currentOptions ) => {
6183
6343
 
6184
6344
  // Empty list
6185
6345
  listOptions.innerHTML = "";
6186
6346
 
6187
- if( !options.length )
6347
+ if( !currentOptions.length )
6188
6348
  {
6189
6349
  let iValue = options.emptyMsg ?? "No options found.";
6190
6350
 
@@ -6200,9 +6360,9 @@ class Select extends Widget {
6200
6360
  return;
6201
6361
  }
6202
6362
 
6203
- for( let i = 0; i < options.length; i++ )
6363
+ for( let i = 0; i < currentOptions.length; i++ )
6204
6364
  {
6205
- let iValue = options[ i ];
6365
+ let iValue = currentOptions[ i ];
6206
6366
  let li = document.createElement( "li" );
6207
6367
  let option = document.createElement( "div" );
6208
6368
  option.className = "option";
@@ -6527,13 +6687,15 @@ class ItemArray extends Widget {
6527
6687
  container.className = "lexarray";
6528
6688
  container.style.width = "100%";
6529
6689
  this.root.appendChild( container );
6690
+ this.root.dataset["opened"] = false;
6530
6691
 
6531
- const angleDown = `<a class='fa-solid fa-angle-down' style='float:right; margin-right: 3px;'></a>`;
6692
+ const angleDown = `<a class='fa-solid fa-angle-down'></a>`;
6532
6693
 
6533
6694
  let buttonName = "Array (size " + values.length + ")";
6534
6695
  buttonName += angleDown;
6535
6696
 
6536
6697
  const toggleButton = new Button(null, buttonName, () => {
6698
+ this.root.dataset["opened"] = this.root.dataset["opened"] == "true" ? false : true;
6537
6699
  this.root.querySelector(".lexarrayitems").toggleAttribute('hidden');
6538
6700
  }, { buttonClass: 'array' });
6539
6701
  container.appendChild( toggleButton.root );
@@ -6597,7 +6759,7 @@ class ItemArray extends Widget {
6597
6759
  }
6598
6760
 
6599
6761
  buttonName = "Add item";
6600
- buttonName += "<a class='fa-solid fa-plus' style='float:right; margin-right: 3px; margin-top: 2px;'></a>";
6762
+ buttonName += "<a class='fa-solid fa-plus'></a>";
6601
6763
 
6602
6764
  const addButton = new Button(null, buttonName, (v, event) => {
6603
6765
  values.push( options.innerValues ? options.innerValues[ 0 ] : "" );
@@ -6847,7 +7009,7 @@ class Checkbox extends Widget {
6847
7009
 
6848
7010
  let checkbox = document.createElement( "input" );
6849
7011
  checkbox.type = "checkbox";
6850
- checkbox.className = "lexcheckbox " + ( options.className ?? "" );
7012
+ checkbox.className = "lexcheckbox " + ( options.className ?? "primary" );
6851
7013
  checkbox.checked = value;
6852
7014
  checkbox.disabled = options.disabled ?? false;
6853
7015
  container.appendChild( checkbox );
@@ -7068,8 +7230,7 @@ class ColorInput extends Widget {
7068
7230
  newValue = hexToRgb( newValue );
7069
7231
  }
7070
7232
 
7071
- // Means it was called from the color input listener, not the text
7072
- if( event )
7233
+ if( !this._skipTextUpdate )
7073
7234
  {
7074
7235
  textWidget.set( newValue, true, event );
7075
7236
  }
@@ -7095,9 +7256,8 @@ class ColorInput extends Widget {
7095
7256
  color.style.width = "32px";
7096
7257
  color.type = 'color';
7097
7258
  color.className = "colorinput";
7098
- color.id = "color" + simple_guidGenerator();
7099
7259
  color.useRGB = options.useRGB ?? false;
7100
- color.value = color.iValue = value;
7260
+ color.value = value;
7101
7261
  container.appendChild( color );
7102
7262
 
7103
7263
  if( options.disabled )
@@ -7110,8 +7270,10 @@ class ColorInput extends Widget {
7110
7270
  }, false );
7111
7271
 
7112
7272
  const textWidget = new TextInput( null, color.value, v => {
7273
+ this._skipTextUpdate = true;
7113
7274
  this.set( v );
7114
- }, { width: "calc( 100% - 32px )"});
7275
+ delete this._skipTextUpdate;
7276
+ }, { width: "calc( 100% - 32px )", disabled: options.disabled });
7115
7277
 
7116
7278
  textWidget.root.style.marginLeft = "4px";
7117
7279
  container.appendChild( textWidget.root );
@@ -7163,12 +7325,23 @@ class RangeInput extends Widget {
7163
7325
 
7164
7326
  let slider = document.createElement( 'input' );
7165
7327
  slider.className = "lexrangeslider " + ( options.className ?? "" );
7166
- slider.value = slider.iValue = value;
7167
7328
  slider.min = options.min ?? 0;
7168
7329
  slider.max = options.max ?? 100;
7169
7330
  slider.step = options.step ?? 1;
7170
7331
  slider.type = "range";
7171
7332
  slider.disabled = options.disabled ?? false;
7333
+
7334
+ if( value.constructor == Number )
7335
+ {
7336
+ value = clamp( value, +slider.min, +slider.max );
7337
+ }
7338
+
7339
+ if( options.left )
7340
+ {
7341
+ value = ( ( +slider.max ) - value + ( +slider.min ) );
7342
+ }
7343
+
7344
+ slider.value = value;
7172
7345
  container.appendChild( slider );
7173
7346
 
7174
7347
  if( options.left ?? false )
@@ -7207,11 +7380,6 @@ class RangeInput extends Widget {
7207
7380
  Widget._dispatchEvent( slider, "input", true );
7208
7381
  };
7209
7382
 
7210
- if( value.constructor == Number )
7211
- {
7212
- value = clamp( value, +slider.min, +slider.max );
7213
- }
7214
-
7215
7383
  doAsync( this.onResize.bind( this ) );
7216
7384
  }
7217
7385
  }
@@ -8133,7 +8301,7 @@ class FileInput extends Widget {
8133
8301
  {
8134
8302
  let settingsDialog = null;
8135
8303
 
8136
- const settingButton = new Button(null, "<a style='margin-top: 0px;' class='fa-solid fa-gear'></a>", () => {
8304
+ const settingButton = new Button(null, "", () => {
8137
8305
 
8138
8306
  if( settingsDialog )
8139
8307
  {
@@ -8145,7 +8313,7 @@ class FileInput extends Widget {
8145
8313
  p.addButton( null, "Reload", v => { input.dispatchEvent( new Event( 'change' ) ) } );
8146
8314
  }, { onclose: ( root ) => { root.remove(); settingsDialog = null; } } );
8147
8315
 
8148
- }, { className: "micro", skipInlineCount: true, title: "Settings" });
8316
+ }, { skipInlineCount: true, title: "Settings", disabled: options.disabled, icon: "fa-solid fa-gear" });
8149
8317
 
8150
8318
  this.root.appendChild( settingButton.root );
8151
8319
  }
@@ -8208,9 +8376,9 @@ class Tree extends Widget {
8208
8376
  if( options.filter )
8209
8377
  {
8210
8378
  nodeFilterInput = document.createElement('input');
8211
- nodeFilterInput.id = "lexnodetree_filter";
8379
+ nodeFilterInput.className = "lexnodetree_filter";
8212
8380
  nodeFilterInput.setAttribute("placeholder", "Filter..");
8213
- nodeFilterInput.style.width = "calc( 100% - 17px )";
8381
+ nodeFilterInput.style.width = "100%";
8214
8382
  nodeFilterInput.addEventListener('input', () => {
8215
8383
  this.innerTree.refresh();
8216
8384
  });
@@ -8360,11 +8528,11 @@ class Counter extends Widget {
8360
8528
  container.className = "lexcounter";
8361
8529
  this.root.appendChild( container );
8362
8530
 
8363
- const substrButton = new Button(null, "<a style='margin-top: 0px;' class='fa-solid fa-minus'></a>", ( value, e ) => {
8531
+ const substrButton = new Button(null, "", ( value, e ) => {
8364
8532
  let mult = step ?? 1;
8365
8533
  if( e.shiftKey ) mult *= 10;
8366
8534
  this.set( counterText.count - mult, false, e );
8367
- }, { className: "micro", skipInlineCount: true, title: "Minus" });
8535
+ }, { skipInlineCount: true, title: "Minus", icon: "fa-solid fa-minus" });
8368
8536
 
8369
8537
  container.appendChild( substrButton.root );
8370
8538
 
@@ -8386,11 +8554,11 @@ class Counter extends Widget {
8386
8554
  containerBox.appendChild( counterLabel );
8387
8555
  }
8388
8556
 
8389
- const addButton = new Button(null, "<a style='margin-top: 0px;' class='fa-solid fa-plus'></a>", ( value, e ) => {
8557
+ const addButton = new Button(null, "", ( value, e ) => {
8390
8558
  let mult = step ?? 1;
8391
8559
  if( e.shiftKey ) mult *= 10;
8392
8560
  this.set( counterText.count + mult, false, e );
8393
- }, { className: "micro", skipInlineCount: true, title: "Plus" });
8561
+ }, { skipInlineCount: true, title: "Plus", icon: "fa-solid fa-plus" });
8394
8562
  container.appendChild( addButton.root );
8395
8563
  }
8396
8564
  }
@@ -8453,7 +8621,7 @@ class Table extends Widget {
8453
8621
  // Append header
8454
8622
  if( this.filter || this.customFilters || this.toggleColumns )
8455
8623
  {
8456
- const headerContainer = LX.makeContainer( [ "100%", "auto" ] );
8624
+ const headerContainer = LX.makeContainer( [ "100%", "auto" ], "flex flex-row" );
8457
8625
 
8458
8626
  if( this.filter )
8459
8627
  {
@@ -8461,7 +8629,7 @@ class Table extends Widget {
8461
8629
  filterOptions.placeholder = `Filter ${ this.filter }...`;
8462
8630
  filterOptions.skipWidget = true;
8463
8631
  filterOptions.trigger = "input";
8464
- filterOptions.textClass = "outline";
8632
+ filterOptions.inputClass = "outline";
8465
8633
 
8466
8634
  let filter = new TextInput(null, "", ( v ) => {
8467
8635
  this._currentFilter = v;
@@ -8494,7 +8662,7 @@ class Table extends Widget {
8494
8662
  return item;
8495
8663
  } );
8496
8664
  new DropdownMenu( customFilterBtn.root, menuOptions, { side: "bottom", align: "start" });
8497
- }, { buttonClass: "dashed" } );
8665
+ }, { buttonClass: " primary dashed" } );
8498
8666
  headerContainer.appendChild( customFilterBtn.root );
8499
8667
  }
8500
8668
 
@@ -8569,7 +8737,7 @@ class Table extends Widget {
8569
8737
  th.style.width = "0px";
8570
8738
  const input = document.createElement( 'input' );
8571
8739
  input.type = "checkbox";
8572
- input.className = "lexcheckbox";
8740
+ input.className = "lexcheckbox accent";
8573
8741
  input.checked = data.checkMap[ ":root" ] ?? false;
8574
8742
  th.appendChild( input );
8575
8743
 
@@ -8736,7 +8904,7 @@ class Table extends Widget {
8736
8904
 
8737
8905
  const row = document.createElement( 'tr' );
8738
8906
  const rowId = LX.getSupportedDOMName( bodyData.join( '-' ) );
8739
- row.setAttribute( "rowId", rowId.substr(0, 16) );
8907
+ row.setAttribute( "rowId", rowId.substr(0, 32) );
8740
8908
 
8741
8909
  if( options.sortable )
8742
8910
  {
@@ -8787,7 +8955,7 @@ class Table extends Widget {
8787
8955
  const td = document.createElement( 'td' );
8788
8956
  const input = document.createElement( 'input' );
8789
8957
  input.type = "checkbox";
8790
- input.className = "lexcheckbox";
8958
+ input.className = "lexcheckbox accent";
8791
8959
  input.checked = data.checkMap[ rowId ];
8792
8960
  td.appendChild( input );
8793
8961
 
@@ -8934,7 +9102,7 @@ class Panel {
8934
9102
  root.className += " " + options.className;
8935
9103
  }
8936
9104
 
8937
- root.style.width = options.width || "calc( 100% - 6px )";
9105
+ root.style.width = options.width || "100%";
8938
9106
  root.style.height = options.height || "100%";
8939
9107
  Object.assign( root.style, options.style ?? {} );
8940
9108
 
@@ -9049,10 +9217,11 @@ class Panel {
9049
9217
 
9050
9218
  /**
9051
9219
  * @method endLine
9220
+ * @param {String} className Extra class to customize inline widgets parent container
9052
9221
  * @description Stop inlining widgets. Use it only if the number of widgets to be inlined is NOT specified.
9053
9222
  */
9054
9223
 
9055
- endLine( justifyContent ) {
9224
+ endLine( className ) {
9056
9225
 
9057
9226
  if( this._inlineWidgetsLeft == -1 )
9058
9227
  {
@@ -9067,9 +9236,9 @@ class Panel {
9067
9236
  this._inlineContainer = document.createElement('div');
9068
9237
  this._inlineContainer.className = "lexinlinewidgets";
9069
9238
 
9070
- if( justifyContent )
9239
+ if( className )
9071
9240
  {
9072
- this._inlineContainer.style.justifyContent = justifyContent;
9241
+ this._inlineContainer.className += ` ${ className }`;
9073
9242
  }
9074
9243
  }
9075
9244
 
@@ -9212,7 +9381,7 @@ class Panel {
9212
9381
  }
9213
9382
  else
9214
9383
  {
9215
- el.classList.add("nobranch");
9384
+ el.className += " nobranch w-full";
9216
9385
  this.root.appendChild( el );
9217
9386
  }
9218
9387
  }
@@ -9276,7 +9445,7 @@ class Panel {
9276
9445
  let input = document.createElement('input');
9277
9446
  input.className = 'lexinput-filter';
9278
9447
  input.setAttribute( "placeholder", options.placeholder );
9279
- input.style.width = "calc( 100% - 17px )";
9448
+ input.style.width = "100%";
9280
9449
  input.value = options.filterValue || "";
9281
9450
 
9282
9451
  let searchIcon = document.createElement('a');
@@ -9451,9 +9620,11 @@ class Panel {
9451
9620
  * disabled: Make the widget disabled [false]
9452
9621
  * required: Make the input required
9453
9622
  * placeholder: Add input placeholder
9623
+ * icon: Icon (if any) to append at the input start
9454
9624
  * pattern: Regular expression that value must match
9455
9625
  * trigger: Choose onchange trigger (default, input) [default]
9456
9626
  * inputWidth: Width of the text input
9627
+ * inputClass: Class to add to the native input element
9457
9628
  * skipReset: Don't add the reset value button when value changes
9458
9629
  * float: Justify input text content
9459
9630
  * justifyName: Justify name content
@@ -9473,6 +9644,7 @@ class Panel {
9473
9644
  * hideName: Don't use name as label [false]
9474
9645
  * disabled: Make the widget disabled [false]
9475
9646
  * placeholder: Add input placeholder
9647
+ * resize: Allow resize [true]
9476
9648
  * trigger: Choose onchange trigger (default, input) [default]
9477
9649
  * inputWidth: Width of the text input
9478
9650
  * float: Justify input text content
@@ -9493,6 +9665,7 @@ class Panel {
9493
9665
 
9494
9666
  addLabel( value, options = {} ) {
9495
9667
  options.disabled = true;
9668
+ options.inputClass = ( options.inputClass ?? "" ) + " nobg";
9496
9669
  const widget = this.addText( null, value, null, options );
9497
9670
  widget.type = Widget.LABEL;
9498
9671
  return widget;
@@ -9509,6 +9682,7 @@ class Panel {
9509
9682
  * icon: Icon class to show as button value
9510
9683
  * img: Path to image to show as button value
9511
9684
  * title: Text to show in native Element title
9685
+ * buttonClass: Class to add to the native button element
9512
9686
  */
9513
9687
 
9514
9688
  addButton( name, value, callback, options = {} ) {
@@ -10048,7 +10222,6 @@ class Branch {
10048
10222
  root.className += " " + options.className;
10049
10223
  }
10050
10224
 
10051
- root.style.width = "calc(100% - 7px)";
10052
10225
  root.style.margin = "0 auto";
10053
10226
 
10054
10227
  var that = this;
@@ -10086,7 +10259,7 @@ class Branch {
10086
10259
  this.grabber.setAttribute( "hidden", true );
10087
10260
  doAsync( () => {
10088
10261
  this.content.setAttribute( "hidden", true );
10089
- }, 15 );
10262
+ }, 10 );
10090
10263
  }
10091
10264
 
10092
10265
  this.onclick = function( e ) {
@@ -10236,6 +10409,7 @@ class Branch {
10236
10409
  let value = element.children[ 1 ];
10237
10410
 
10238
10411
  name.style.width = size;
10412
+ name.style.minWidth = size;
10239
10413
 
10240
10414
  switch( widget.type )
10241
10415
  {
@@ -10270,9 +10444,13 @@ class Footer {
10270
10444
  root.className = "lexfooter";
10271
10445
 
10272
10446
  const wrapper = document.createElement( "div" );
10273
- wrapper.className = "wrapper";
10447
+ wrapper.style.minHeight = "48px";
10448
+ wrapper.className = "w-full";
10274
10449
  root.appendChild( wrapper );
10275
10450
 
10451
+ // const hr = document.createElement( "hr" );
10452
+ // wrapper.appendChild( hr );
10453
+
10276
10454
  if( options.columns && options.columns.constructor == Array )
10277
10455
  {
10278
10456
  const cols = document.createElement( "div" );
@@ -10309,9 +10487,6 @@ class Footer {
10309
10487
 
10310
10488
  if( options.credits || options.socials )
10311
10489
  {
10312
- const hr = document.createElement( "hr" );
10313
- wrapper.appendChild( hr );
10314
-
10315
10490
  const creditsSocials = document.createElement( "div" );
10316
10491
  creditsSocials.className = "credits-and-socials";
10317
10492
  wrapper.appendChild( creditsSocials );
@@ -10345,6 +10520,10 @@ class Footer {
10345
10520
  // Append directly to body
10346
10521
  const parent = options.parent ?? document.body;
10347
10522
  parent.appendChild( root );
10523
+
10524
+ // Set always at bottom
10525
+ root.previousElementSibling.style.height = "unset";
10526
+ root.previousElementSibling.style.flexGrow = "1";
10348
10527
  }
10349
10528
 
10350
10529
  }
@@ -10543,7 +10722,6 @@ class Dialog {
10543
10722
  root.style.left = position[ 0 ] ?? "50%";
10544
10723
  root.style.top = position[ 1 ] ?? "50%";
10545
10724
 
10546
- panel.root.style.width = "calc( 100% - 30px )";
10547
10725
  panel.root.style.height = title ? "calc( 100% - " + ( titleDiv.offsetHeight + 30 ) + "px )" : "calc( 100% - 51px )";
10548
10726
  }
10549
10727
 
@@ -10615,8 +10793,8 @@ class PocketDialog extends Dialog {
10615
10793
  this.root.style.top = dragMargin + "px";
10616
10794
  }
10617
10795
 
10618
- this.panel.root.style.width = "calc( 100% - 12px )";
10619
- this.panel.root.style.height = "calc( 100% - 40px )";
10796
+ this.panel.root.style.width = "100%";
10797
+ this.panel.root.style.height = "100%";
10620
10798
  this.dock_pos = PocketDialog.TOP;
10621
10799
 
10622
10800
  this.minimized = false;
@@ -11017,8 +11195,8 @@ class CanvasCurve {
11017
11195
  element.style.minHeight = "20px";
11018
11196
 
11019
11197
  element.bgcolor = options.bgColor || LX.getThemeColor( "global-intense-background" );
11020
- element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected" );
11021
- element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-selected-light" );
11198
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-color-accent" );
11199
+ element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-color-accent-light" );
11022
11200
  element.linecolor = options.lineColor || "#555";
11023
11201
  element.value = value || [];
11024
11202
  element.xrange = options.xrange || [ 0, 1 ]; // min, max
@@ -11034,8 +11212,8 @@ class CanvasCurve {
11034
11212
 
11035
11213
  LX.addSignal( "@on_new_color_scheme", (el, value) => {
11036
11214
  element.bgcolor = options.bgColor || LX.getThemeColor( "global-intense-background" );
11037
- element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected" );
11038
- element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-selected-light" );
11215
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-color-accent" );
11216
+ element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-color-accent-light" );
11039
11217
  this.redraw();
11040
11218
  } );
11041
11219
 
@@ -11364,7 +11542,7 @@ class CanvasDial {
11364
11542
  element.style.minWidth = element.style.minHeight = "50px";
11365
11543
 
11366
11544
  element.bgcolor = options.bgColor || LX.getThemeColor( "global-dark-background" );
11367
- element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected-light" );
11545
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-color-accent-light" );
11368
11546
  element.linecolor = options.lineColor || "#555";
11369
11547
  element.value = value || [];
11370
11548
  element.xrange = options.xrange || [ 0, 1 ]; // min, max
@@ -12022,11 +12200,15 @@ class AssetView {
12022
12200
  this.rightPanel.sameLine();
12023
12201
  this.rightPanel.addSelect( "Filter", this.allowedTypes, this.allowedTypes[ 0 ], v => this._refreshContent.call(this, null, v), { width: "30%", minWidth: "128px" } );
12024
12202
  this.rightPanel.addText( null, this.searchValue ?? "", v => this._refreshContent.call(this, v, null), { placeholder: "Search assets.." } );
12025
- this.rightPanel.addButton( null, "<a class='fa fa-arrow-up-short-wide'></a>", on_sort.bind(this), { className: "micro", title: "Sort" } );
12026
- this.rightPanel.addButton( null, "<a class='fa-solid fa-grip'></a>", on_change_view.bind(this), { className: "micro", title: "View" } );
12203
+ this.rightPanel.addButton( null, "<a class='fa fa-arrow-up-short-wide'></a>", on_sort.bind(this), { title: "Sort" } );
12204
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-grip'></a>", on_change_view.bind(this), { title: "View" } );
12027
12205
  // Content Pages
12028
- this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-left'></a>", on_change_page.bind(this, -1), { className: "micro", title: "Previous Page" } );
12029
- this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-right'></a>", on_change_page.bind(this, 1), { className: "micro", title: "Next Page" } );
12206
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-left'></a>", on_change_page.bind(this, -1), { title: "Previous Page", className: "ml-auto" } );
12207
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-right'></a>", on_change_page.bind(this, 1), { title: "Next Page" } );
12208
+ const textString = "Page " + this.contentPage + " / " + ((((this.currentData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1);
12209
+ this.rightPanel.addText(null, textString, null, {
12210
+ inputClass: "nobg", disabled: true, signal: "@on_page_change", maxWidth: "16ch" }
12211
+ );
12030
12212
  this.rightPanel.endLine();
12031
12213
 
12032
12214
  if( !this.skipBrowser )
@@ -12060,9 +12242,13 @@ class AssetView {
12060
12242
  icon: "fa-solid fa-arrows-rotate",
12061
12243
  callback: domEl => { this._refreshContent(); }
12062
12244
  }
12063
- ], { width: "20%", minWidth: "164px", noSelection: true } );
12064
- this.rightPanel.addText(null, this.path.join('/'), null, { width: "70%", maxWidth: "calc(70% - 64px)", minWidth: "164px", disabled: true, signal: "@on_folder_change", style: { fontWeight: "bolder", fontSize: "16px", color: "#aaa" } });
12065
- this.rightPanel.addText(null, "Page " + this.contentPage + " / " + ((((this.currentData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1), null, {disabled: true, signal: "@on_page_change", width: "fit-content"})
12245
+ ], { noSelection: true } );
12246
+
12247
+ this.rightPanel.addText(null, this.path.join('/'), null, {
12248
+ inputClass: "nobg", disabled: true, signal: "@on_folder_change",
12249
+ style: { fontWeight: "600", fontSize: "15px" }
12250
+ });
12251
+
12066
12252
  this.rightPanel.endLine();
12067
12253
  }
12068
12254
 
@@ -12340,7 +12526,9 @@ class AssetView {
12340
12526
  }
12341
12527
 
12342
12528
  this.allowNextPage = filteredData.length - 1 > AssetView.MAX_PAGE_ELEMENTS;
12343
- LX.emit("@on_page_change", "Page " + this.contentPage + " / " + ((((filteredData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1));
12529
+
12530
+ const textString = "Page " + this.contentPage + " / " + ((((filteredData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1);
12531
+ LX.emit( "@on_page_change", textString );
12344
12532
 
12345
12533
  if( this.onRefreshContent )
12346
12534
  {
@@ -12634,44 +12822,44 @@ Object.assign(LX, {
12634
12822
  * Request file from url
12635
12823
  * @method requestText
12636
12824
  * @param {String} url
12637
- * @param {Function} on_complete
12638
- * @param {Function} on_error
12825
+ * @param {Function} onComplete
12826
+ * @param {Function} onError
12639
12827
  **/
12640
- requestText(url, on_complete, on_error ) {
12641
- return this.request({ url: url, dataType:"text", success: on_complete, error: on_error });
12828
+ requestText( url, onComplete, onError ) {
12829
+ return this.request({ url: url, dataType:"text", success: onComplete, error: onError });
12642
12830
  },
12643
12831
 
12644
12832
  /**
12645
12833
  * Request file from url
12646
12834
  * @method requestJSON
12647
12835
  * @param {String} url
12648
- * @param {Function} on_complete
12649
- * @param {Function} on_error
12836
+ * @param {Function} onComplete
12837
+ * @param {Function} onError
12650
12838
  **/
12651
- requestJSON(url, on_complete, on_error ) {
12652
- return this.request({ url: url, dataType:"json", success: on_complete, error: on_error });
12839
+ requestJSON( url, onComplete, onError ) {
12840
+ return this.request({ url: url, dataType:"json", success: onComplete, error: onError });
12653
12841
  },
12654
12842
 
12655
12843
  /**
12656
12844
  * Request binary file from url
12657
12845
  * @method requestBinary
12658
12846
  * @param {String} url
12659
- * @param {Function} on_complete
12660
- * @param {Function} on_error
12847
+ * @param {Function} onComplete
12848
+ * @param {Function} onError
12661
12849
  **/
12662
- requestBinary(url, on_complete, on_error ) {
12663
- return this.request({ url: url, dataType:"binary", success: on_complete, error: on_error });
12850
+ requestBinary( url, onComplete, onError ) {
12851
+ return this.request({ url: url, dataType:"binary", success: onComplete, error: onError });
12664
12852
  },
12665
12853
 
12666
12854
  /**
12667
12855
  * Request script and inserts it in the DOM
12668
12856
  * @method requireScript
12669
12857
  * @param {String|Array} url the url of the script or an array containing several urls
12670
- * @param {Function} on_complete
12671
- * @param {Function} on_error
12672
- * @param {Function} on_progress (if several files are required, on_progress is called after every file is added to the DOM)
12858
+ * @param {Function} onComplete
12859
+ * @param {Function} onError
12860
+ * @param {Function} onProgress (if several files are required, onProgress is called after every file is added to the DOM)
12673
12861
  **/
12674
- requireScript(url, on_complete, on_error, on_progress, version ) {
12862
+ requireScript( url, onComplete, onError, onProgress, version ) {
12675
12863
 
12676
12864
  if(!url)
12677
12865
  throw("invalid URL");
@@ -12696,15 +12884,17 @@ Object.assign(LX, {
12696
12884
  loaded_scripts.push(this);
12697
12885
  if(total)
12698
12886
  {
12699
- if(on_progress)
12700
- on_progress(this.original_src, this.num);
12887
+ if( onProgress )
12888
+ {
12889
+ onProgress( this.original_src, this.num );
12890
+ }
12701
12891
  }
12702
- else if(on_complete)
12703
- on_complete( loaded_scripts );
12892
+ else if(onComplete)
12893
+ onComplete( loaded_scripts );
12704
12894
  };
12705
- if(on_error)
12895
+ if(onError)
12706
12896
  script.onerror = function(err) {
12707
- on_error(err, this.original_src, this.num );
12897
+ onError(err, this.original_src, this.num );
12708
12898
  }
12709
12899
  document.getElementsByTagName('head')[0].appendChild(script);
12710
12900
  }
@@ -12793,10 +12983,11 @@ Element.prototype.addClass = function( className ) {
12793
12983
  }
12794
12984
 
12795
12985
  Element.prototype.getComputedSize = function() {
12796
- const cs = getComputedStyle( this );
12986
+ // Since we use "box-sizing: border-box" now,
12987
+ // it's all included in offsetWidth/offsetHeight
12797
12988
  return {
12798
- width: this.offsetWidth + cs.getPropertyValue('marginLeft') + cs.getPropertyValue('marginRight'),
12799
- height: this.offsetHeight + cs.getPropertyValue('marginTop') + cs.getPropertyValue('marginBottom')
12989
+ width: this.offsetWidth,
12990
+ height: this.offsetHeight
12800
12991
  }
12801
12992
  }
12802
12993
 
@@ -12808,6 +12999,18 @@ Element.prototype.getParentArea = function() {
12808
12999
  }
12809
13000
  }
12810
13001
 
13002
+ Element.prototype.listen = function( eventName, callback, callbackName ) {
13003
+ callbackName = callbackName ?? ( "_on" + eventName );
13004
+ this[ callbackName ] = callback;
13005
+ this.addEventListener( eventName, callback );
13006
+ }
13007
+
13008
+ Element.prototype.ignore = function( eventName, callbackName ) {
13009
+ callbackName = callbackName ?? ( "_on" + eventName );
13010
+ const callback = this[ callbackName ];
13011
+ this.removeEventListener( eventName, callback );
13012
+ }
13013
+
12811
13014
  LX.UTILS = {
12812
13015
  getTime() { return new Date().getTime() },
12813
13016
  compareThreshold( v, p, n, t ) { return Math.abs(v - p) >= t || Math.abs(v - n) >= t },
@@ -12908,6 +13111,7 @@ LX.ICONS = {
12908
13111
  "edit": [512, 512, [], "regular", "M441 58.9L453.1 71c9.4 9.4 9.4 24.6 0 33.9L424 134.1 377.9 88 407 58.9c9.4-9.4 24.6-9.4 33.9 0zM209.8 256.2L344 121.9 390.1 168 255.8 302.2c-2.9 2.9-6.5 5-10.4 6.1l-58.5 16.7 16.7-58.5c1.1-3.9 3.2-7.5 6.1-10.4zM373.1 25L175.8 222.2c-8.7 8.7-15 19.4-18.3 31.1l-28.6 100c-2.4 8.4-.1 17.4 6.1 23.6s15.2 8.5 23.6 6.1l100-28.6c11.8-3.4 22.5-9.7 31.1-18.3L487 138.9c28.1-28.1 28.1-73.7 0-101.8L474.9 25C446.8-3.1 401.2-3.1 373.1 25zM88 64C39.4 64 0 103.4 0 152L0 424c0 48.6 39.4 88 88 88l272 0c48.6 0 88-39.4 88-88l0-112c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 112c0 22.1-17.9 40-40 40L88 464c-22.1 0-40-17.9-40-40l0-272c0-22.1 17.9-40 40-40l112 0c13.3 0 24-10.7 24-24s-10.7-24-24-24L88 64z"],
12909
13112
  "envelope": [512, 512, [], "regular", "M64 112c-8.8 0-16 7.2-16 16l0 22.1L220.5 291.7c20.7 17 50.4 17 71.1 0L464 150.1l0-22.1c0-8.8-7.2-16-16-16L64 112zM48 212.2L48 384c0 8.8 7.2 16 16 16l384 0c8.8 0 16-7.2 16-16l0-171.8L322 328.8c-38.4 31.5-93.7 31.5-132 0L48 212.2zM0 128C0 92.7 28.7 64 64 64l384 0c35.3 0 64 28.7 64 64l0 256c0 35.3-28.7 64-64 64L64 448c-35.3 0-64-28.7-64-64L0 128z"],
12910
13113
  "envelope-open": [512, 512, [], "regular", "M255.4 48.2c.2-.1 .4-.2 .6-.2s.4 .1 .6 .2L460.6 194c2.1 1.5 3.4 3.9 3.4 6.5l0 13.6L291.5 355.7c-20.7 17-50.4 17-71.1 0L48 214.1l0-13.6c0-2.6 1.2-5 3.4-6.5L255.4 48.2zM48 276.2L190 392.8c38.4 31.5 93.7 31.5 132 0L464 276.2 464 456c0 4.4-3.6 8-8 8L56 464c-4.4 0-8-3.6-8-8l0-179.8zM256 0c-10.2 0-20.2 3.2-28.5 9.1L23.5 154.9C8.7 165.4 0 182.4 0 200.5L0 456c0 30.9 25.1 56 56 56l400 0c30.9 0 56-25.1 56-56l0-255.5c0-18.1-8.7-35.1-23.4-45.6L284.5 9.1C276.2 3.2 266.2 0 256 0z"],
13114
+ "inbox": [24, 24, [], "regular", "M22 12H16l-2 3h-4l-2-3H2M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11Z", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
12911
13115
  "map": [576, 512, [], "regular", "M565.6 36.2C572.1 40.7 576 48.1 576 56l0 336c0 10-6.2 18.9-15.5 22.4l-168 64c-5.2 2-10.9 2.1-16.1 .3L192.5 417.5l-160 61c-7.4 2.8-15.7 1.8-22.2-2.7S0 463.9 0 456L0 120c0-10 6.1-18.9 15.5-22.4l168-64c5.2-2 10.9-2.1 16.1-.3L383.5 94.5l160-61c7.4-2.8 15.7-1.8 22.2 2.7zM48 136.5l0 284.6 120-45.7 0-284.6L48 136.5zM360 422.7l0-285.4-144-48 0 285.4 144 48zm48-1.5l120-45.7 0-284.6L408 136.5l0 284.6z"],
12912
13116
  "note-sticky": [448, 512, ["sticky-note"], "regular", "M64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l224 0 0-80c0-17.7 14.3-32 32-32l80 0 0-224c0-8.8-7.2-16-16-16L64 80zM288 480L64 480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 224 0 5.5c0 17-6.7 33.3-18.7 45.3l-90.5 90.5c-12 12-28.3 18.7-45.3 18.7l-5.5 0z"],
12913
13117
  "file": [384, 512, [], "regular", "M320 464c8.8 0 16-7.2 16-16l0-288-80 0c-17.7 0-32-14.3-32-32l0-80L64 48c-8.8 0-16 7.2-16 16l0 384c0 8.8 7.2 16 16 16l256 0zM0 64C0 28.7 28.7 0 64 0L229.5 0c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3L384 448c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 64z"],
@@ -12915,7 +13119,10 @@ LX.ICONS = {
12915
13119
  "file-code": [384, 512, [], "regular", "M64 464c-8.8 0-16-7.2-16-16L48 64c0-8.8 7.2-16 16-16l160 0 0 80c0 17.7 14.3 32 32 32l80 0 0 288c0 8.8-7.2 16-16 16L64 464zM64 0C28.7 0 0 28.7 0 64L0 448c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-293.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0L64 0zm97 289c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L79 303c-9.4 9.4-9.4 24.6 0 33.9l48 48c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-31-31 31-31zM257 255c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l31 31-31 31c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l48-48c9.4-9.4 9.4-24.6 0-33.9l-48-48z"],
12916
13120
  "file-zip": [384, 512, [], "regular", "M64 464c-8.8 0-16-7.2-16-16L48 64c0-8.8 7.2-16 16-16l48 0c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l48 0 0 80c0 17.7 14.3 32 32 32l80 0 0 288c0 8.8-7.2 16-16 16L64 464zM64 0C28.7 0 0 28.7 0 64L0 448c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-293.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0L64 0zm48 112c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm0 64c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm-6.3 71.8L82.1 335.9c-1.4 5.4-2.1 10.9-2.1 16.4c0 35.2 28.8 63.7 64 63.7s64-28.5 64-63.7c0-5.5-.7-11.1-2.1-16.4l-23.5-88.2c-3.7-14-16.4-23.8-30.9-23.8l-14.8 0c-14.5 0-27.2 9.7-30.9 23.8zM128 336l32 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16s7.2-16 16-16z"],
12917
13121
  "file-pdf": [512, 512, [], "regular", "M64 464l48 0 0 48-48 0c-35.3 0-64-28.7-64-64L0 64C0 28.7 28.7 0 64 0L229.5 0c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3L384 304l-48 0 0-144-80 0c-17.7 0-32-14.3-32-32l0-80L64 48c-8.8 0-16 7.2-16 16l0 384c0 8.8 7.2 16 16 16zM176 352l32 0c30.9 0 56 25.1 56 56s-25.1 56-56 56l-16 0 0 32c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-48 0-80c0-8.8 7.2-16 16-16zm32 80c13.3 0 24-10.7 24-24s-10.7-24-24-24l-16 0 0 48 16 0zm96-80l32 0c26.5 0 48 21.5 48 48l0 64c0 26.5-21.5 48-48 48l-32 0c-8.8 0-16-7.2-16-16l0-128c0-8.8 7.2-16 16-16zm32 128c8.8 0 16-7.2 16-16l0-64c0-8.8-7.2-16-16-16l-16 0 0 96 16 0zm80-112c0-8.8 7.2-16 16-16l48 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-32 0 0 32 32 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-32 0 0 48c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-64 0-64z"],
13122
+ "box-archive": [24, 24, [], "regular", "M2 3a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H2V3Zm2 5h16v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Zm6 4h4", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
13123
+ "box-archive-x": [24, 24, [], "regular", "M3 3h18a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1ZM4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8M9.5 17l5-5m-5-0l5 5", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
12918
13124
  "scroll": [576, 512, ["script"], "solid", "M0 80l0 48c0 17.7 14.3 32 32 32l16 0 48 0 0-80c0-26.5-21.5-48-48-48S0 53.5 0 80zM112 32c10 13.4 16 30 16 48l0 304c0 35.3 28.7 64 64 64s64-28.7 64-64l0-5.3c0-32.4 26.3-58.7 58.7-58.7L480 320l0-192c0-53-43-96-96-96L112 32zM464 480c61.9 0 112-50.1 112-112c0-8.8-7.2-16-16-16l-245.3 0c-14.7 0-26.7 11.9-26.7 26.7l0 5.3c0 53-43 96-96 96l176 0 96 0z"],
13125
+ "paper-plane": [512, 512, [], "", "M16.1 260.2c-22.6 12.9-20.5 47.3 3.6 57.3L160 376l0 103.3c0 18.1 14.6 32.7 32.7 32.7c9.7 0 18.9-4.3 25.1-11.8l62-74.3 123.9 51.6c18.9 7.9 40.8-4.5 43.9-24.7l64-416c1.9-12.1-3.4-24.3-13.5-31.2s-23.3-7.5-34-1.4l-448 256zm52.1 25.5L409.7 90.6 190.1 336l1.2 1L68.2 285.7zM403.3 425.4L236.7 355.9 450.8 116.6 403.3 425.4z"],
12919
13126
  "floppy-disk": [448, 512, ["save"], "regular", "M48 96l0 320c0 8.8 7.2 16 16 16l320 0c8.8 0 16-7.2 16-16l0-245.5c0-4.2-1.7-8.3-4.7-11.3l33.9-33.9c12 12 18.7 28.3 18.7 45.3L448 416c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l245.5 0c17 0 33.3 6.7 45.3 18.7l74.5 74.5-33.9 33.9L320.8 84.7c-.3-.3-.5-.5-.8-.8L320 184c0 13.3-10.7 24-24 24l-192 0c-13.3 0-24-10.7-24-24L80 80 64 80c-8.8 0-16 7.2-16 16zm80-16l0 80 144 0 0-80L128 80zm32 240a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z"],
12920
13127
  "download": [512, 512, [], "solid", "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 242.7-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7 288 32zM64 352c-35.3 0-64 28.7-64 64l0 32c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-32c0-35.3-28.7-64-64-64l-101.5 0-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352 64 352zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"],
12921
13128
  "upload": [512, 512, [], "solid", "M288 109.3L288 352c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-242.7-73.4 73.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l128-128c12.5-12.5 32.8-12.5 45.3 0l128 128c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L288 109.3zM64 352l128 0c0 35.3 28.7 64 64 64s64-28.7 64-64l128 0c35.3 0 64 28.7 64 64l0 32c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64l0-32c0-35.3 28.7-64 64-64zM432 456a24 24 0 1 0 0-48 24 24 0 1 0 0 48z"],
@@ -12925,6 +13132,7 @@ LX.ICONS = {
12925
13132
  "eye": [576, 512, [], "regular", "M288 80c-65.2 0-118.8 29.6-159.9 67.7C89.6 183.5 63 226 49.4 256c13.6 30 40.2 72.5 78.6 108.3C169.2 402.4 222.8 432 288 432s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256c-13.6-30-40.2-72.5-78.6-108.3C406.8 109.6 353.2 80 288 80zM95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1c3.3 7.9 3.3 16.7 0 24.6c-14.9 35.7-46.2 87.7-93 131.1C433.5 443.2 368.8 480 288 480s-145.5-36.8-192.6-80.6C48.6 356 17.3 304 2.5 268.3c-3.3-7.9-3.3-16.7 0-24.6C17.3 208 48.6 156 95.4 112.6zM288 336c44.2 0 80-35.8 80-80s-35.8-80-80-80c-.7 0-1.3 0-2 0c1.3 5.1 2 10.5 2 16c0 35.3-28.7 64-64 64c-5.5 0-10.9-.7-16-2c0 .7 0 1.3 0 2c0 44.2 35.8 80 80 80zm0-208a128 128 0 1 1 0 256 128 128 0 1 1 0-256z"],
12926
13133
  "eye-slash": [640, 512, [], "regular", "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zm151 118.3C226 97.7 269.5 80 320 80c65.2 0 118.8 29.6 159.9 67.7C518.4 183.5 545 226 558.6 256c-12.6 28-36.6 66.8-70.9 100.9l-53.8-42.2c9.1-17.6 14.2-37.5 14.2-58.7c0-70.7-57.3-128-128-128c-32.2 0-61.7 11.9-84.2 31.5l-46.1-36.1zM394.9 284.2l-81.5-63.9c4.2-8.5 6.6-18.2 6.6-28.3c0-5.5-.7-10.9-2-16c.7 0 1.3 0 2 0c44.2 0 80 35.8 80 80c0 9.9-1.8 19.4-5.1 28.2zm9.4 130.3C378.8 425.4 350.7 432 320 432c-65.2 0-118.8-29.6-159.9-67.7C121.6 328.5 95 286 81.4 256c8.3-18.4 21.5-41.5 39.4-64.8L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5l-41.9-33zM192 256c0 70.7 57.3 128 128 128c13.3 0 26.1-2 38.2-5.8L302 334c-23.5-5.4-43.1-21.2-53.7-42.3l-56.1-44.2c-.2 2.8-.3 5.6-.3 8.5z"],
12927
13134
  "comment": [512, 512, [], "regular", "M123.6 391.3c12.9-9.4 29.6-11.8 44.6-6.4c26.5 9.6 56.2 15.1 87.8 15.1c124.7 0 208-80.5 208-160s-83.3-160-208-160S48 160.5 48 240c0 32 12.4 62.8 35.7 89.2c8.6 9.7 12.8 22.5 11.8 35.5c-1.4 18.1-5.7 34.7-11.3 49.4c17-7.9 31.1-16.7 39.4-22.7zM21.2 431.9c1.8-2.7 3.5-5.4 5.1-8.1c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208s-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6c-15.1 6.6-32.3 12.6-50.1 16.1c-.8 .2-1.6 .3-2.4 .5c-4.4 .8-8.7 1.5-13.2 1.9c-.2 0-.5 .1-.7 .1c-5.1 .5-10.2 .8-15.3 .8c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c4.1-4.2 7.8-8.7 11.3-13.5c1.7-2.3 3.3-4.6 4.8-6.9l.3-.5z"],
13135
+ "comments": [640, 512, [], "regular", "M88.2 309.1c9.8-18.3 6.8-40.8-7.5-55.8C59.4 230.9 48 204 48 176c0-63.5 63.8-128 160-128s160 64.5 160 128s-63.8 128-160 128c-13.1 0-25.8-1.3-37.8-3.6c-10.4-2-21.2-.6-30.7 4.2c-4.1 2.1-8.3 4.1-12.6 6c-16 7.2-32.9 13.5-49.9 18c2.8-4.6 5.4-9.1 7.9-13.6c1.1-1.9 2.2-3.9 3.2-5.9zM208 352c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176c0 41.8 17.2 80.1 45.9 110.3c-.9 1.7-1.9 3.5-2.8 5.1c-10.3 18.4-22.3 36.5-36.6 52.1c-6.6 7-8.3 17.2-4.6 25.9C5.8 378.3 14.4 384 24 384c43 0 86.5-13.3 122.7-29.7c4.8-2.2 9.6-4.5 14.2-6.8c15.1 3 30.9 4.5 47.1 4.5zM432 480c16.2 0 31.9-1.6 47.1-4.5c4.6 2.3 9.4 4.6 14.2 6.8C529.5 498.7 573 512 616 512c9.6 0 18.2-5.7 22-14.5c3.8-8.8 2-19-4.6-25.9c-14.2-15.6-26.2-33.7-36.6-52.1c-.9-1.7-1.9-3.4-2.8-5.1C622.8 384.1 640 345.8 640 304c0-94.4-87.9-171.5-198.2-175.8c4.1 15.2 6.2 31.2 6.2 47.8l0 .6c87.2 6.7 144 67.5 144 127.4c0 28-11.4 54.9-32.7 77.2c-14.3 15-17.3 37.6-7.5 55.8c1.1 2 2.2 4 3.2 5.9c2.5 4.5 5.2 9 7.9 13.6c-17-4.5-33.9-10.7-49.9-18c-4.3-1.9-8.5-3.9-12.6-6c-9.5-4.8-20.3-6.2-30.7-4.2c-12.1 2.4-24.8 3.6-37.8 3.6c-61.7 0-110-26.5-136.8-62.3c-16 5.4-32.8 9.4-50 11.8C279 439.8 350 480 432 480z"],
12928
13136
  "message": [512, 512, [], "regular", "M160 368c26.5 0 48 21.5 48 48l0 16 72.5-54.4c8.3-6.2 18.4-9.6 28.8-9.6L448 368c8.8 0 16-7.2 16-16l0-288c0-8.8-7.2-16-16-16L64 48c-8.8 0-16 7.2-16 16l0 288c0 8.8 7.2 16 16 16l96 0zm48 124l-.2 .2-5.1 3.8-17.1 12.8c-4.8 3.6-11.3 4.2-16.8 1.5s-8.8-8.2-8.8-14.3l0-21.3 0-6.4 0-.3 0-4 0-48-48 0-48 0c-35.3 0-64-28.7-64-64L0 64C0 28.7 28.7 0 64 0L448 0c35.3 0 64 28.7 64 64l0 288c0 35.3-28.7 64-64 64l-138.7 0L208 492z"],
12929
13137
  "folder": [512, 512, [], "regular", "M0 96C0 60.7 28.7 32 64 32l132.1 0c19.1 0 37.4 7.6 50.9 21.1L289.9 96 448 96c35.3 0 64 28.7 64 64l0 256c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zM64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l384 0c8.8 0 16-7.2 16-16l0-256c0-8.8-7.2-16-16-16l-161.4 0c-10.6 0-20.8-4.2-28.3-11.7L213.1 87c-4.5-4.5-10.6-7-17-7L64 80z"],
12930
13138
  "folder-closed": [512, 512, [], "regular", "M251.7 127.6s0 0 0 0c10.5 10.5 24.7 16.4 39.6 16.4L448 144c8.8 0 16 7.2 16 16l0 32L48 192l0-96c0-8.8 7.2-16 16-16l133.5 0c4.2 0 8.3 1.7 11.3 4.7l33.9-33.9L208.8 84.7l42.9 42.9zM48 240l416 0 0 176c0 8.8-7.2 16-16 16L64 432c-8.8 0-16-7.2-16-16l0-176zM285.7 93.7L242.7 50.7c-12-12-28.3-18.7-45.3-18.7L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64L291.3 96c-2.1 0-4.2-.8-5.7-2.3z"],
@@ -12938,27 +13146,33 @@ LX.ICONS = {
12938
13146
  "up": [448, 512, [], "solid", "M201.4 137.4c12.5-12.5 32.8-12.5 45.3 0l160 160c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L224 205.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l160-160z"],
12939
13147
  "down": [448, 512, [], "solid", "M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z"],
12940
13148
  "arrows": [512, 512, ["arrows-up-down-left-right"], "solid", "M278.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l9.4-9.4L224 224l-114.7 0 9.4-9.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-64 64c-12.5 12.5-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-9.4-9.4L224 288l0 114.7-9.4-9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-9.4 9.4L288 288l114.7 0-9.4 9.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l9.4 9.4L288 224l0-114.7 9.4 9.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-64-64z"],
13149
+ "arrow-pointer": [320, 512, [], "solid", "M0 55.2L0 426c0 12.2 9.9 22 22 22c6.3 0 12.4-2.7 16.6-7.5L121.2 346l58.1 116.3c7.9 15.8 27.1 22.2 42.9 14.3s22.2-27.1 14.3-42.9L179.8 320l118.1 0c12.2 0 22.1-9.9 22.1-22.1c0-6.3-2.7-12.3-7.4-16.5L38.6 37.9C34.3 34.1 28.9 32 23.2 32C10.4 32 0 42.4 0 55.2z"],
13150
+ "reply": [24, 24, [], "regular", "M9 17L4 12L9 7M4 12H16A4 4 0 0 1 20 16V18", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
13151
+ "reply-all": [24, 24, [], "regular", "M7 17L2 12L7 7M12 17L7 12L12 7M7 12H18A4 4 0 0 1 22 16V18", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
13152
+ "forward": [24, 24, [], "regular", "M15 17L20 12L15 7M4 18V16A4 4 0 0 1 8 12H20", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
12941
13153
  "rotate": [512, 512, [], "solid", "M142.9 142.9c-17.5 17.5-30.1 38-37.8 59.8c-5.9 16.7-24.2 25.4-40.8 19.5s-25.4-24.2-19.5-40.8C55.6 150.7 73.2 122 97.6 97.6c87.2-87.2 228.3-87.5 315.8-1L455 55c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 128c0 13.3-10.7 24-24 24l-8.4 0c0 0 0 0 0 0L344 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l41.1-41.1c-62.6-61.5-163.1-61.2-225.3 1zM16 312c0-13.3 10.7-24 24-24l7.6 0 .7 0L168 288c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-41.1 41.1c62.6 61.5 163.1 61.2 225.3-1c17.5-17.5 30.1-38 37.8-59.8c5.9-16.7 24.2-25.4 40.8-19.5s25.4 24.2 19.5 40.8c-10.8 30.6-28.4 59.3-52.9 83.8c-87.2 87.2-228.3 87.5-315.8 1L57 457c-6.9 6.9-17.2 8.9-26.2 5.2S16 449.7 16 440l0-119.6 0-.7 0-7.6z"],
12942
13154
  "rotate-right": [512, 512, ["rotate-forward"], "solid", "M463.5 224l8.5 0c13.3 0 24-10.7 24-24l0-128c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8l119.5 0z"],
12943
13155
  "rotate-left": [512, 512, ["rotate-back"], "solid", "M48.5 224L40 224c-13.3 0-24-10.7-24-24L16 72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8L48.5 224z"],
12944
- "arrow-pointer": [320, 512, [], "solid", "M0 55.2L0 426c0 12.2 9.9 22 22 22c6.3 0 12.4-2.7 16.6-7.5L121.2 346l58.1 116.3c7.9 15.8 27.1 22.2 42.9 14.3s22.2-27.1 14.3-42.9L179.8 320l118.1 0c12.2 0 22.1-9.9 22.1-22.1c0-6.3-2.7-12.3-7.4-16.5L38.6 37.9C34.3 34.1 28.9 32 23.2 32C10.4 32 0 42.4 0 55.2z"],
12945
13156
  "hand-pointer": [448, 512, [], "regular", "M160 64c0-8.8 7.2-16 16-16s16 7.2 16 16l0 136c0 10.3 6.6 19.5 16.4 22.8s20.6-.1 26.8-8.3c3-3.9 7.6-6.4 12.8-6.4c8.8 0 16 7.2 16 16c0 10.3 6.6 19.5 16.4 22.8s20.6-.1 26.8-8.3c3-3.9 7.6-6.4 12.8-6.4c7.8 0 14.3 5.6 15.7 13c1.6 8.2 7.3 15.1 15.1 18s16.7 1.6 23.3-3.6c2.7-2.1 6.1-3.4 9.9-3.4c8.8 0 16 7.2 16 16l0 16 0 104c0 39.8-32.2 72-72 72l-56 0-59.8 0-.9 0c-37.4 0-72.4-18.7-93.2-49.9L50.7 312.9c-4.9-7.4-2.9-17.3 4.4-22.2s17.3-2.9 22.2 4.4L116 353.2c5.9 8.8 16.8 12.7 26.9 9.7s17-12.4 17-23l0-19.9 0-256zM176 0c-35.3 0-64 28.7-64 64l0 197.7C91.2 238 55.5 232.8 28.5 250.7C-.9 270.4-8.9 310.1 10.8 339.5L78.3 440.8c29.7 44.5 79.6 71.2 133.1 71.2l.9 0 59.8 0 56 0c66.3 0 120-53.7 120-120l0-104 0-16c0-35.3-28.7-64-64-64c-4.5 0-8.8 .5-13 1.3c-11.7-15.4-30.2-25.3-51-25.3c-6.9 0-13.5 1.1-19.7 3.1C288.7 170.7 269.6 160 248 160c-2.7 0-5.4 .2-8 .5L240 64c0-35.3-28.7-64-64-64zm48 304c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 96c0 8.8 7.2 16 16 16s16-7.2 16-16l0-96zm48-16c-8.8 0-16 7.2-16 16l0 96c0 8.8 7.2 16 16 16s16-7.2 16-16l0-96c0-8.8-7.2-16-16-16zm80 16c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 96c0 8.8 7.2 16 16 16s16-7.2 16-16l0-96z"],
12946
13157
  "log-in": [512, 512, [], "solid", "M352 96l64 0c17.7 0 32 14.3 32 32l0 256c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l64 0c53 0 96-43 96-96l0-256c0-53-43-96-96-96l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32zm-9.4 182.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L242.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128z"],
12947
13158
  "log-out": [512, 512, [], "solid", "M502.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 224 192 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128zM160 96c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 32C43 32 0 75 0 128L0 384c0 53 43 96 96 96l64 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-64 0c-17.7 0-32-14.3-32-32l0-256c0-17.7 14.3-32 32-32l64 0z"],
12948
- "menu-arrows": [512, 512, [], "solid", "M352 144l96 112-96 112M160 144L64 256l96 112", "transform=rotate(90)", "fill=none stroke=currentColor stroke-width=60 stroke-linejoin=round stroke-linecap=round"],
13159
+ "menu-arrows": [512, 512, [], "solid", "M352 144l96 112-96 112M160 144L64 256l96 112", "transform=rotate(90)", "fill=none stroke-width=60 stroke-linejoin=round stroke-linecap=round"],
12949
13160
  "more": [128, 512, [], "solid", "M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z"],
12950
13161
  "minus": [448, 512, [], "solid", "M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"],
12951
13162
  "more-horizontal": [448, 512, [], "solid", "M8 256a56 56 0 1 1 112 0A56 56 0 1 1 8 256zm160 0a56 56 0 1 1 112 0 56 56 0 1 1 -112 0zm216-56a56 56 0 1 1 0 112 56 56 0 1 1 0-112z"],
12952
13163
  "plus": [448, 512, [], "solid", "M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 144L48 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l144 0 0 144c0 17.7 14.3 32 32 32s32-14.3 32-32l0-144 144 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-144 0 0-144z"],
12953
13164
  "circle-plus": [24, 24, [], "regular", "M12 8V16M8 12H16M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
13165
+ "circle-info": [24, 24, [], "regular", "M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20ZM12 8v4M12 16h.01", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
12954
13166
  "search": [512, 512, [], "solid", "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"],
12955
13167
  "compass": [512, 512, [], "regular", "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm306.7 69.1L162.4 380.6c-19.4 7.5-38.5-11.6-31-31l55.5-144.3c3.3-8.5 9.9-15.1 18.4-18.4l144.3-55.5c19.4-7.5 38.5 11.6 31 31L325.1 306.7c-3.2 8.5-9.9 15.1-18.4 18.4zM288 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"],
12956
- "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=currentColor stroke-width=50 stroke-linejoin=round stroke-linecap=round"],
13168
+ "clock": [512, 512, [], "regular", "M464 256A208 208 0 1 1 48 256a208 208 0 1 1 416 0zM0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM232 120l0 136c0 8 4 15.5 10.7 20l96 64c11 7.4 25.9 4.4 33.3-6.7s4.4-25.9-6.7-33.3L280 243.2 280 120c0-13.3-10.7-24-24-24s-24 10.7-24 24z"],
13169
+ "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"],
12957
13170
  "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"],
12958
13171
  "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"],
12959
13172
  "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"],
12960
13173
  "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"],
12961
13174
  "shuffle": [512, 512, [], "solid", "M403.8 34.4c12-5 25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6l0-32-32 0c-10.1 0-19.6 4.7-25.6 12.8L284 229.3 244 176l31.2-41.6C293.3 110.2 321.8 96 352 96l32 0 0-32c0-12.9 7.8-24.6 19.8-29.6zM164 282.7L204 336l-31.2 41.6C154.7 401.8 126.2 416 96 416l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64 0c10.1 0 19.6-4.7 25.6-12.8L164 282.7zm274.6 188c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6l0-32-32 0c-30.2 0-58.7-14.2-76.8-38.4L121.6 172.8c-6-8.1-15.5-12.8-25.6-12.8l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64 0c30.2 0 58.7 14.2 76.8 38.4L326.4 339.2c6 8.1 15.5 12.8 25.6 12.8l32 0 0-32c0-12.9 7.8-24.6 19.8-29.6s25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64z"],
13175
+ "shopping-cart": [24, 24, [], "regular", "M8 20a1 1 0 1 0 0 2 1 1 0 0 0 0-2ZM19 20a1 1 0 1 0 0 2 1 1 0 0 0 0-2ZM2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
12962
13176
  "credit-card": [576, 512, [], "regular", "M512 80c8.8 0 16 7.2 16 16l0 32L48 128l0-32c0-8.8 7.2-16 16-16l448 0zm16 144l0 192c0 8.8-7.2 16-16 16L64 432c-8.8 0-16-7.2-16-16l0-192 480 0zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l448 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm56 304c-13.3 0-24 10.7-24 24s10.7 24 24 24l48 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-48 0zm128 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l112 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-112 0z"],
12963
13177
  "lock": [448, 512, [], "solid", "M144 144l0 48 160 0 0-48c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192l0-48C80 64.5 144.5 0 224 0s144 64.5 144 144l0 48 16 0c35.3 0 64 28.7 64 64l0 192c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 256c0-35.3 28.7-64 64-64l16 0z"],
12964
13178
  "lock-open": [576, 512, [], "solid", "M352 144c0-44.2 35.8-80 80-80s80 35.8 80 80l0 48c0 17.7 14.3 32 32 32s32-14.3 32-32l0-48C576 64.5 511.5 0 432 0S288 64.5 288 144l0 48L64 192c-35.3 0-64 28.7-64 64L0 448c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-192c0-35.3-28.7-64-64-64l-32 0 0-48z"],