@trops/dash-core 0.1.156 → 0.1.158

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.
@@ -1,41 +1,41 @@
1
1
  'use strict';
2
2
 
3
- var require$$0$1 = require('electron');
4
- var require$$1 = require('electron-store');
5
- var require$$1$1 = require('path');
6
- var require$$0$2 = require('fs');
3
+ var require$$0$2 = require('electron');
4
+ var require$$1$1 = require('electron-store');
5
+ var require$$1$2 = require('path');
6
+ var require$$0$3 = require('fs');
7
7
  var require$$5 = require('objects-to-csv');
8
- var require$$1$2 = require('readline');
8
+ var require$$1$3 = require('readline');
9
9
  var require$$2 = require('xtreamer');
10
10
  var require$$3 = require('xml2js');
11
11
  var require$$4 = require('JSONStream');
12
- var require$$0$3 = require('stream');
12
+ var require$$0$4 = require('stream');
13
13
  var require$$6 = require('csv-parser');
14
- var require$$0$4 = require('image-downloader');
14
+ var require$$0$5 = require('image-downloader');
15
15
  var require$$2$1 = require('get-pixels');
16
16
  var require$$3$1 = require('extract-colors');
17
- var require$$8$1 = require('https');
18
- var require$$0$6 = require('@modelcontextprotocol/sdk/client/index.js');
19
- var require$$1$3 = require('@modelcontextprotocol/sdk/client/stdio.js');
20
- var require$$0$5 = require('pkce-challenge');
17
+ var require$$8 = require('https');
18
+ var require$$0$7 = require('@modelcontextprotocol/sdk/client/index.js');
19
+ var require$$1$4 = require('@modelcontextprotocol/sdk/client/stdio.js');
20
+ var require$$0$6 = require('pkce-challenge');
21
21
  var require$$5$1 = require('child_process');
22
22
  var require$$2$2 = require('algoliasearch');
23
23
  var require$$3$2 = require('node:path');
24
- var require$$0$7 = require('openai');
24
+ var require$$0$8 = require('openai');
25
25
  require('live-plugin-manager');
26
- var require$$0$8 = require('@anthropic-ai/sdk');
26
+ var require$$0$9 = require('@anthropic-ai/sdk');
27
27
  var require$$3$3 = require('adm-zip');
28
28
  var require$$2$4 = require('os');
29
29
  var require$$4$1 = require('url');
30
30
  var require$$2$3 = require('vm');
31
- var require$$1$4 = require('croner');
32
- var require$$0$b = require('events');
31
+ var require$$1$5 = require('croner');
32
+ var require$$0$c = require('events');
33
33
  var require$$2$5 = require('http');
34
34
  var require$$3$4 = require('net');
35
35
  var require$$4$2 = require('tls');
36
- var require$$1$5 = require('crypto');
37
- var require$$0$9 = require('zlib');
38
- var require$$0$a = require('buffer');
36
+ var require$$1$6 = require('crypto');
37
+ var require$$0$a = require('zlib');
38
+ var require$$0$b = require('buffer');
39
39
 
40
40
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
41
41
 
@@ -805,11 +805,18 @@ var schedulerEvents$1 = {
805
805
  const THEME_EXTRACT_FROM_URL$1 = "theme-extract-from-url";
806
806
  const THEME_EXTRACT_FROM_URL_COMPLETE = "theme-extract-from-url-complete";
807
807
  const THEME_EXTRACT_FROM_URL_ERROR = "theme-extract-from-url-error";
808
+ const THEME_MAP_PALETTE_TO_THEME$1 = "theme-map-palette-to-theme";
809
+ const THEME_MAP_PALETTE_TO_THEME_COMPLETE =
810
+ "theme-map-palette-to-theme-complete";
811
+ const THEME_MAP_PALETTE_TO_THEME_ERROR = "theme-map-palette-to-theme-error";
808
812
 
809
813
  var themeFromUrlEvents$1 = {
810
814
  THEME_EXTRACT_FROM_URL: THEME_EXTRACT_FROM_URL$1,
811
815
  THEME_EXTRACT_FROM_URL_COMPLETE,
812
816
  THEME_EXTRACT_FROM_URL_ERROR,
817
+ THEME_MAP_PALETTE_TO_THEME: THEME_MAP_PALETTE_TO_THEME$1,
818
+ THEME_MAP_PALETTE_TO_THEME_COMPLETE,
819
+ THEME_MAP_PALETTE_TO_THEME_ERROR,
813
820
  };
814
821
 
815
822
  /**
@@ -930,7 +937,7 @@ var events$8 = {
930
937
  * Open a dialog window for choosing files
931
938
  */
932
939
 
933
- const { dialog: dialog$2 } = require$$0$1;
940
+ const { dialog: dialog$2 } = require$$0$2;
934
941
  const events$7 = events$8;
935
942
 
936
943
  const showDialog$1 = async (win, message, allowFile, extensions = ["*"]) => {
@@ -955,8 +962,8 @@ var dialogController$1 = {
955
962
  * secureStore
956
963
  */
957
964
 
958
- const { safeStorage } = require$$0$1;
959
- const Store$2 = require$$1;
965
+ const { safeStorage } = require$$0$2;
966
+ const Store$2 = require$$1$1;
960
967
  const events$6 = events$8;
961
968
 
962
969
  const schema$1 = {
@@ -1015,7 +1022,7 @@ var secureStoreController$1 = {
1015
1022
  getData: getData$1,
1016
1023
  };
1017
1024
 
1018
- const path$h = require$$1$1;
1025
+ const path$h = require$$1$2;
1019
1026
  const {
1020
1027
  readFileSync,
1021
1028
  writeFileSync: writeFileSync$4,
@@ -1028,7 +1035,7 @@ const {
1028
1035
  unlinkSync,
1029
1036
  readdirSync,
1030
1037
  lstatSync,
1031
- } = require$$0$2;
1038
+ } = require$$0$3;
1032
1039
 
1033
1040
  function ensureDirectoryExistence$2(filePath) {
1034
1041
  try {
@@ -1165,9 +1172,9 @@ var file = {
1165
1172
  checkDirectory: checkDirectory$1,
1166
1173
  };
1167
1174
 
1168
- const { app: app$a } = require$$0$1;
1169
- const path$g = require$$1$1;
1170
- const { writeFileSync: writeFileSync$3 } = require$$0$2;
1175
+ const { app: app$a } = require$$0$2;
1176
+ const path$g = require$$1$2;
1177
+ const { writeFileSync: writeFileSync$3 } = require$$0$3;
1171
1178
  const { getFileContents: getFileContents$7 } = file;
1172
1179
 
1173
1180
  const configFilename$5 = "workspaces.json";
@@ -1417,9 +1424,9 @@ const workspaceController$1 = {
1417
1424
 
1418
1425
  var workspaceController_1 = workspaceController$1;
1419
1426
 
1420
- const { app: app$9 } = require$$0$1;
1421
- const path$f = require$$1$1;
1422
- const { writeFileSync: writeFileSync$2 } = require$$0$2;
1427
+ const { app: app$9 } = require$$0$2;
1428
+ const path$f = require$$1$2;
1429
+ const { writeFileSync: writeFileSync$2 } = require$$0$3;
1423
1430
  const { getFileContents: getFileContents$6 } = file;
1424
1431
 
1425
1432
  const configFilename$4 = "themes.json";
@@ -1566,15 +1573,15 @@ var themeController_1 = themeController$3;
1566
1573
  * - CSV -> JSON
1567
1574
  */
1568
1575
 
1569
- var fs$9 = require$$0$2;
1570
- var readline = require$$1$2;
1576
+ var fs$9 = require$$0$3;
1577
+ var readline = require$$1$3;
1571
1578
  const xtreamer = require$$2;
1572
1579
  var xmlParser = require$$3;
1573
1580
  var JSONStream$1 = require$$4;
1574
- const stream$2 = require$$0$3;
1581
+ const stream$2 = require$$0$4;
1575
1582
  var csv = require$$6;
1576
- const path$e = require$$1$1;
1577
- const { app: app$8 } = require$$0$1;
1583
+ const path$e = require$$1$2;
1584
+ const { app: app$8 } = require$$0$2;
1578
1585
  const { ensureDirectoryExistence: ensureDirectoryExistence$1 } = file;
1579
1586
 
1580
1587
  const TRANSFORM_APP_NAME = "Dashboard";
@@ -3687,7 +3694,7 @@ var ntc_1 = ntc$1;
3687
3694
  * - extractColorsFromImageURL
3688
3695
  */
3689
3696
 
3690
- const download = require$$0$4;
3697
+ const download = require$$0$5;
3691
3698
  const getPixels = require$$2$1;
3692
3699
  const { extractColors: extractColors$1 } = require$$3$1;
3693
3700
  const ntc = ntc_1;
@@ -3731,9 +3738,9 @@ async function extractColorsFromImageURL$2(url, toDirectory) {
3731
3738
 
3732
3739
  var color = { extractColorsFromImageURL: extractColorsFromImageURL$2 };
3733
3740
 
3734
- const { app: app$7 } = require$$0$1;
3735
- var fs$8 = require$$0$2;
3736
- const path$d = require$$1$1;
3741
+ const { app: app$7 } = require$$0$2;
3742
+ var fs$8 = require$$0$3;
3743
+ const path$d = require$$1$2;
3737
3744
  const events$5 = events$8;
3738
3745
  const { getFileContents: getFileContents$5, writeToFile: writeToFile$2 } = file;
3739
3746
 
@@ -3741,7 +3748,7 @@ const { getFileContents: getFileContents$5, writeToFile: writeToFile$2 } = file;
3741
3748
  const ObjectsToCsv = require$$5;
3742
3749
  const Transform = transform;
3743
3750
  const { extractColorsFromImageURL: extractColorsFromImageURL$1 } = color;
3744
- const https$1 = require$$8$1;
3751
+ const https$1 = require$$8;
3745
3752
  const appName$5 = "Dashboard";
3746
3753
 
3747
3754
  const dataController$1 = {
@@ -4218,9 +4225,9 @@ var dataController_1 = dataController$1;
4218
4225
  * settingsController
4219
4226
  */
4220
4227
 
4221
- const { app: app$6 } = require$$0$1;
4222
- const path$c = require$$1$1;
4223
- const fs$7 = require$$0$2;
4228
+ const { app: app$6 } = require$$0$2;
4229
+ const path$c = require$$1$2;
4230
+ const fs$7 = require$$0$3;
4224
4231
  const { getFileContents: getFileContents$4, writeToFile: writeToFile$1 } = file;
4225
4232
 
4226
4233
  const configFilename$3 = "settings.json";
@@ -4700,7 +4707,7 @@ function requireClientCache () {
4700
4707
  * Call this once in the consuming app's electron.js alongside setupWidgetRegistryHandlers().
4701
4708
  */
4702
4709
  setupCacheHandlers() {
4703
- const { ipcMain } = require$$0$1;
4710
+ const { ipcMain } = require$$0$2;
4704
4711
  const responseCache = responseCache_1;
4705
4712
 
4706
4713
  ipcMain.handle(
@@ -4741,9 +4748,9 @@ var hasRequiredProviderController;
4741
4748
  function requireProviderController () {
4742
4749
  if (hasRequiredProviderController) return providerController_1;
4743
4750
  hasRequiredProviderController = 1;
4744
- const { app, safeStorage } = require$$0$1;
4745
- const path = require$$1$1;
4746
- const { writeFileSync, readFileSync, existsSync } = require$$0$2;
4751
+ const { app, safeStorage } = require$$0$2;
4752
+ const path = require$$1$2;
4753
+ const { writeFileSync, readFileSync, existsSync } = require$$0$3;
4747
4754
  const {
4748
4755
  ensureDirectoryExistence,
4749
4756
  getFileContents,
@@ -5072,9 +5079,9 @@ function requireProviderController () {
5072
5079
  return providerController_1;
5073
5080
  }
5074
5081
 
5075
- const { app: app$5 } = require$$0$1;
5076
- const path$b = require$$1$1;
5077
- const { writeFileSync: writeFileSync$1 } = require$$0$2;
5082
+ const { app: app$5 } = require$$0$2;
5083
+ const path$b = require$$1$2;
5084
+ const { writeFileSync: writeFileSync$1 } = require$$0$3;
5078
5085
  const events$4 = events$8;
5079
5086
  const { getFileContents: getFileContents$3 } = file;
5080
5087
 
@@ -5332,7 +5339,7 @@ util$5.normalizeParams = normalizeParams;
5332
5339
  util$5.createTransparentProxy = createTransparentProxy;
5333
5340
  util$5.stringifyPrimitive = stringifyPrimitive;
5334
5341
  util$5.optionalKeys = optionalKeys;
5335
- util$5.pick = pick;
5342
+ util$5.pick = pick$1;
5336
5343
  util$5.omit = omit;
5337
5344
  util$5.extend = extend;
5338
5345
  util$5.safeExtend = safeExtend;
@@ -5680,7 +5687,7 @@ util$5.BIGINT_FORMAT_RANGES = {
5680
5687
  int64: [/* @__PURE__*/ BigInt("-9223372036854775808"), /* @__PURE__*/ BigInt("9223372036854775807")],
5681
5688
  uint64: [/* @__PURE__*/ BigInt(0), /* @__PURE__*/ BigInt("18446744073709551615")],
5682
5689
  };
5683
- function pick(schema, mask) {
5690
+ function pick$1(schema, mask) {
5684
5691
  const currDef = schema._zod.def;
5685
5692
  const checks = currDef.checks;
5686
5693
  const hasChecks = checks && checks.length > 0;
@@ -23980,7 +23987,7 @@ auth$2.exchangeAuthorization = exchangeAuthorization;
23980
23987
  auth$2.refreshAuthorization = refreshAuthorization;
23981
23988
  auth$2.fetchToken = fetchToken;
23982
23989
  auth$2.registerClient = registerClient;
23983
- const pkce_challenge_1 = __importDefault(require$$0$5);
23990
+ const pkce_challenge_1 = __importDefault(require$$0$6);
23984
23991
  const types_js_1$1 = types;
23985
23992
  const auth_js_1$1 = auth$1;
23986
23993
  const auth_js_2 = auth$1;
@@ -25509,15 +25516,15 @@ streamableHttp.StreamableHTTPClientTransport = StreamableHTTPClientTransport$1;
25509
25516
  * Uses @modelcontextprotocol/sdk for protocol handling.
25510
25517
  */
25511
25518
 
25512
- const { Client } = require$$0$6;
25519
+ const { Client } = require$$0$7;
25513
25520
  const {
25514
25521
  StdioClientTransport,
25515
- } = require$$1$3;
25522
+ } = require$$1$4;
25516
25523
  const {
25517
25524
  StreamableHTTPClientTransport,
25518
25525
  } = streamableHttp;
25519
- const path$a = require$$1$1;
25520
- const fs$6 = require$$0$2;
25526
+ const path$a = require$$1$2;
25527
+ const fs$6 = require$$0$3;
25521
25528
 
25522
25529
  /**
25523
25530
  * Cached shell PATH result (resolved once, reused for all spawns).
@@ -25735,7 +25742,7 @@ async function refreshGoogleOAuthToken(tokenRefresh) {
25735
25742
 
25736
25743
  console.log("[mcpController] Refreshing Google OAuth token...");
25737
25744
 
25738
- const https = require$$8$1;
25745
+ const https = require$$8;
25739
25746
  const postData = [
25740
25747
  `client_id=${encodeURIComponent(keyData.client_id)}`,
25741
25748
  `client_secret=${encodeURIComponent(keyData.client_secret)}`,
@@ -26381,7 +26388,7 @@ const mcpController$2 = {
26381
26388
  const sourcePath = credentials?.[from];
26382
26389
  if (sourcePath) {
26383
26390
  const destPath = to.replace(/^~/, process.env.HOME || "");
26384
- const destDir = require$$1$1.dirname(destPath);
26391
+ const destDir = require$$1$2.dirname(destPath);
26385
26392
  try {
26386
26393
  fs$6.mkdirSync(destDir, { recursive: true });
26387
26394
  fs$6.copyFileSync(sourcePath, destPath);
@@ -26516,8 +26523,8 @@ var mcpControllerExports = mcpController$3.exports;
26516
26523
  * - Support two-level browsing: packages (bundles) and widgets within packages
26517
26524
  */
26518
26525
 
26519
- const path$9 = require$$1$1;
26520
- const fs$5 = require$$0$2;
26526
+ const path$9 = require$$1$2;
26527
+ const fs$5 = require$$0$3;
26521
26528
 
26522
26529
  // Default registry API base URL
26523
26530
  const DEFAULT_REGISTRY_API_URL = "https://main.d919rwhuzp7rj.amplifyapp.com";
@@ -26839,7 +26846,7 @@ var registryController$2 = {
26839
26846
  checkUpdates,
26840
26847
  };
26841
26848
 
26842
- var fs$4 = require$$0$2;
26849
+ var fs$4 = require$$0$3;
26843
26850
  var JSONStream = require$$4;
26844
26851
  const algoliasearch$1 = require$$2$2;
26845
26852
  const path$8 = require$$3$2;
@@ -27147,7 +27154,7 @@ var algolia = AlgoliaIndex$1;
27147
27154
  const algoliasearch = require$$2$2;
27148
27155
  const events$3 = events$8;
27149
27156
  const AlgoliaIndex = algolia;
27150
- var fs$3 = require$$0$2;
27157
+ var fs$3 = require$$0$3;
27151
27158
 
27152
27159
  const algoliaController$1 = {
27153
27160
  /**
@@ -27385,7 +27392,7 @@ const algoliaController$1 = {
27385
27392
 
27386
27393
  var algoliaController_1 = algoliaController$1;
27387
27394
 
27388
- const OpenAI = require$$0$7;
27395
+ const OpenAI = require$$0$8;
27389
27396
  const events$2 = events$8;
27390
27397
 
27391
27398
  const openaiController$1 = {
@@ -27426,9 +27433,9 @@ const openaiController$1 = {
27426
27433
 
27427
27434
  var openaiController_1 = openaiController$1;
27428
27435
 
27429
- const { app: app$4 } = require$$0$1;
27430
- const path$7 = require$$1$1;
27431
- const { writeFileSync } = require$$0$2;
27436
+ const { app: app$4 } = require$$0$2;
27437
+ const path$7 = require$$1$2;
27438
+ const { writeFileSync } = require$$0$3;
27432
27439
  const { getFileContents: getFileContents$2 } = file;
27433
27440
 
27434
27441
  const configFilename$1 = "menuItems.json";
@@ -27500,8 +27507,8 @@ const menuItemsController$1 = {
27500
27507
 
27501
27508
  var menuItemsController_1 = menuItemsController$1;
27502
27509
 
27503
- const path$6 = require$$1$1;
27504
- const { app: app$3 } = require$$0$1;
27510
+ const path$6 = require$$1$2;
27511
+ const { app: app$3 } = require$$0$2;
27505
27512
 
27506
27513
  const pluginController$1 = {
27507
27514
  install: (win, packageName, filepath) => {
@@ -27962,7 +27969,7 @@ var cliController_1 = cliController$2;
27962
27969
  * per-request, receiving the full messages array each time.
27963
27970
  */
27964
27971
 
27965
- const Anthropic = require$$0$8;
27972
+ const Anthropic = require$$0$9;
27966
27973
  const mcpController$1 = mcpControllerExports;
27967
27974
  const cliController$1 = cliController_1;
27968
27975
  const {
@@ -28547,7 +28554,7 @@ var properties = {
28547
28554
  }
28548
28555
  };
28549
28556
  var additionalProperties = false;
28550
- var require$$0 = {
28557
+ var require$$0$1 = {
28551
28558
  $schema: $schema,
28552
28559
  $id: $id,
28553
28560
  title: title,
@@ -28568,7 +28575,7 @@ var require$$0 = {
28568
28575
  * without requiring a full JSON Schema validator library.
28569
28576
  */
28570
28577
 
28571
- const schema = require$$0;
28578
+ const schema = require$$0$1;
28572
28579
 
28573
28580
  const CURRENT_SCHEMA_VERSION$1 = "1.0.0";
28574
28581
 
@@ -28813,7 +28820,7 @@ var dashboardConfigValidator$1 = {
28813
28820
  */
28814
28821
 
28815
28822
  // Tailwind color family name → representative hex (500 shade)
28816
- const TAILWIND_COLORS$1 = {
28823
+ const TAILWIND_COLORS$2 = {
28817
28824
  slate: "#64748b",
28818
28825
  gray: "#6b7280",
28819
28826
  zinc: "#71717a",
@@ -28846,16 +28853,16 @@ const TAILWIND_COLORS$1 = {
28846
28853
  function toDisplayColor$2(value) {
28847
28854
  if (!value) return "";
28848
28855
  const lower = value.toLowerCase().trim();
28849
- return TAILWIND_COLORS$1[lower] || value;
28856
+ return TAILWIND_COLORS$2[lower] || value;
28850
28857
  }
28851
28858
 
28852
28859
  var colorUtils = /*#__PURE__*/Object.freeze({
28853
28860
  __proto__: null,
28854
- TAILWIND_COLORS: TAILWIND_COLORS$1,
28861
+ TAILWIND_COLORS: TAILWIND_COLORS$2,
28855
28862
  toDisplayColor: toDisplayColor$2
28856
28863
  });
28857
28864
 
28858
- var require$$8 = /*@__PURE__*/getAugmentedNamespace(colorUtils);
28865
+ var require$$0 = /*@__PURE__*/getAugmentedNamespace(colorUtils);
28859
28866
 
28860
28867
  /**
28861
28868
  * dashboardConfigUtils.js
@@ -29203,7 +29210,7 @@ function checkDashboardCompatibility(
29203
29210
  };
29204
29211
  }
29205
29212
 
29206
- const { toDisplayColor: toDisplayColor$1 } = require$$8;
29213
+ const { toDisplayColor: toDisplayColor$1 } = require$$0;
29207
29214
 
29208
29215
  /**
29209
29216
  * Generate a registry manifest from a dashboard config.
@@ -29499,8 +29506,8 @@ var dynamicWidgetLoader$2 = {exports: {}};
29499
29506
  * Runs in the Electron main process at widget install time.
29500
29507
  */
29501
29508
 
29502
- const fs$2 = require$$0$2;
29503
- const path$5 = require$$1$1;
29509
+ const fs$2 = require$$0$3;
29510
+ const path$5 = require$$1$2;
29504
29511
 
29505
29512
  /**
29506
29513
  * Find the widgets/ directory, handling nested ZIP extraction.
@@ -29699,8 +29706,8 @@ var widgetCompiler$1 = { compileWidget, findWidgetsDir: findWidgetsDir$1 };
29699
29706
  * Integrates with ComponentManager for automatic registration
29700
29707
  */
29701
29708
 
29702
- const fs$1 = require$$0$2;
29703
- const path$4 = require$$1$1;
29709
+ const fs$1 = require$$0$3;
29710
+ const path$4 = require$$1$2;
29704
29711
  const vm = require$$2$3;
29705
29712
  const { findWidgetsDir } = widgetCompiler$1;
29706
29713
 
@@ -29895,8 +29902,8 @@ var dynamicWidgetLoaderExports = dynamicWidgetLoader$2.exports;
29895
29902
  * and dispatching task-fired events to renderer windows.
29896
29903
  */
29897
29904
 
29898
- const Store$1 = require$$1;
29899
- const { Cron } = require$$1$4;
29905
+ const Store$1 = require$$1$1;
29906
+ const { Cron } = require$$1$5;
29900
29907
 
29901
29908
  const store$3 = new Store$1({ name: "dash-scheduler" });
29902
29909
 
@@ -30417,12 +30424,12 @@ var schedulerController_1 = schedulerController$2;
30417
30424
  */
30418
30425
 
30419
30426
  (function (module) {
30420
- const fs = require$$0$2;
30421
- const path = require$$1$1;
30427
+ const fs = require$$0$3;
30428
+ const path = require$$1$2;
30422
30429
  const os = require$$2$4;
30423
30430
  const AdmZip = require$$3$3;
30424
30431
  const { fileURLToPath } = require$$4$1;
30425
- const { app, ipcMain, BrowserWindow } = require$$0$1;
30432
+ const { app, ipcMain, BrowserWindow } = require$$0$2;
30426
30433
  const { dynamicWidgetLoader } = dynamicWidgetLoaderExports;
30427
30434
  const { compileWidget, findWidgetsDir } = widgetCompiler$1;
30428
30435
 
@@ -31394,7 +31401,7 @@ const REGISTRY_BASE_URL$1 =
31394
31401
  let store$2 = null;
31395
31402
  function getStore$1() {
31396
31403
  if (!store$2) {
31397
- const Store = require$$1;
31404
+ const Store = require$$1$1;
31398
31405
  store$2 = new Store({
31399
31406
  name: "dash-registry-auth",
31400
31407
  encryptionKey: "dash-registry-v1",
@@ -31708,8 +31715,8 @@ var registryAuthController$1 = {
31708
31715
  * Handles publishing packages and generating registry URLs.
31709
31716
  */
31710
31717
 
31711
- const fs = require$$0$2;
31712
- const path$3 = require$$1$1;
31718
+ const fs = require$$0$3;
31719
+ const path$3 = require$$1$2;
31713
31720
  const { getStoredToken } = registryAuthController$1;
31714
31721
 
31715
31722
  const REGISTRY_BASE_URL =
@@ -31805,8 +31812,8 @@ var registryApiController$2 = {
31805
31812
  * Mirrors dashboardConfigController patterns for ZIP creation, manifest generation,
31806
31813
  * and registry interaction.
31807
31814
  */
31808
- const path$2 = require$$1$1;
31809
- const { app: app$2, dialog: dialog$1 } = require$$0$1;
31815
+ const path$2 = require$$1$2;
31816
+ const { app: app$2, dialog: dialog$1 } = require$$0$2;
31810
31817
  const AdmZip$1 = require$$3$3;
31811
31818
 
31812
31819
  const themeController$2 = themeController_1;
@@ -31858,9 +31865,9 @@ function generateThemeRegistryManifest(themeData, themeKey, options = {}) {
31858
31865
  }
31859
31866
 
31860
31867
  const {
31861
- TAILWIND_COLORS,
31868
+ TAILWIND_COLORS: TAILWIND_COLORS$1,
31862
31869
  toDisplayColor,
31863
- } = require$$8;
31870
+ } = require$$0;
31864
31871
 
31865
31872
  /**
31866
31873
  * Extract primary/secondary/tertiary/neutral colors from a theme object.
@@ -32214,8 +32221,8 @@ var themeRegistryController$1 = {
32214
32221
  * applies event wiring. (Import is implemented in DASH-13.)
32215
32222
  */
32216
32223
 
32217
- const { app: app$1, dialog } = require$$0$1;
32218
- const path$1 = require$$1$1;
32224
+ const { app: app$1, dialog } = require$$0$2;
32225
+ const path$1 = require$$1$2;
32219
32226
  const AdmZip = require$$3$3;
32220
32227
  const { getFileContents: getFileContents$1 } = file;
32221
32228
  const {
@@ -33433,8 +33440,8 @@ var dashboardConfigController$1 = {
33433
33440
  * and dispatching native Notification instances.
33434
33441
  */
33435
33442
 
33436
- const { Notification } = require$$0$1;
33437
- const Store = require$$1;
33443
+ const { Notification } = require$$0$2;
33444
+ const Store = require$$1$1;
33438
33445
 
33439
33446
  const store$1 = new Store({ name: "dash-notifications" });
33440
33447
 
@@ -38192,7 +38199,7 @@ function requireSourceMapResolve () {
38192
38199
  hasRequiredSourceMapResolve = 1;
38193
38200
  var atob = requireNodeAtob();
38194
38201
  var urlLib = require$$4$1;
38195
- var pathLib = require$$1$1;
38202
+ var pathLib = require$$1$2;
38196
38203
  var decodeUriComponentLib = requireDecodeUriComponent();
38197
38204
 
38198
38205
 
@@ -38583,8 +38590,8 @@ function requireSourceMapSupport () {
38583
38590
  var SourceMap = requireSourceMap().SourceMapGenerator;
38584
38591
  var SourceMapConsumer = requireSourceMap().SourceMapConsumer;
38585
38592
  var sourceMapResolve = requireSourceMapResolve();
38586
- var fs = require$$0$2;
38587
- var path = require$$1$1;
38593
+ var fs = require$$0$3;
38594
+ var path = require$$1$2;
38588
38595
 
38589
38596
  /**
38590
38597
  * Expose `mixin()`.
@@ -38855,7 +38862,7 @@ function rgbToHex({ r, g, b }) {
38855
38862
  }
38856
38863
 
38857
38864
  /** { r, g, b } (0-255) → { h, s, l } (h: 0-360, s/l: 0-100) */
38858
- function rgbToHsl({ r, g, b }) {
38865
+ function rgbToHsl$1({ r, g, b }) {
38859
38866
  r /= 255;
38860
38867
  g /= 255;
38861
38868
  b /= 255;
@@ -38873,7 +38880,7 @@ function rgbToHsl({ r, g, b }) {
38873
38880
  }
38874
38881
 
38875
38882
  /** { r, g, b } (0-255) → { L, a, b } in CIELAB space */
38876
- function rgbToLab({ r, g, b }) {
38883
+ function rgbToLab$1({ r, g, b }) {
38877
38884
  // sRGB → linear
38878
38885
  let rr = r / 255;
38879
38886
  let gg = g / 255;
@@ -38901,7 +38908,7 @@ function rgbToLab({ r, g, b }) {
38901
38908
  }
38902
38909
 
38903
38910
  /** CIE76 deltaE between two Lab colors */
38904
- function deltaE(lab1, lab2) {
38911
+ function deltaE$1(lab1, lab2) {
38905
38912
  return Math.sqrt(
38906
38913
  Math.pow(lab1.L - lab2.L, 2) +
38907
38914
  Math.pow(lab1.a - lab2.a, 2) +
@@ -39074,7 +39081,7 @@ function extractComputedColors(computedStyles) {
39074
39081
  function isBoringColor(hex) {
39075
39082
  const rgb = parseColor(hex);
39076
39083
  if (!rgb) return true;
39077
- const hsl = rgbToHsl(rgb);
39084
+ const hsl = rgbToHsl$1(rgb);
39078
39085
 
39079
39086
  // Near-black or near-white
39080
39087
  if (hsl.l < 5 || hsl.l > 95) return true;
@@ -39101,11 +39108,11 @@ function mergeAndRank(allColors, maxColors = 6) {
39101
39108
  for (const color of allColors) {
39102
39109
  const rgb = parseColor(color.hex);
39103
39110
  if (!rgb) continue;
39104
- const lab = rgbToLab(rgb);
39111
+ const lab = rgbToLab$1(rgb);
39105
39112
 
39106
39113
  let merged = false;
39107
39114
  for (const cluster of clusters) {
39108
- if (deltaE(cluster.lab, lab) < THRESHOLD) {
39115
+ if (deltaE$1(cluster.lab, lab) < THRESHOLD) {
39109
39116
  // Merge into existing cluster — keep the highest-confidence color as representative
39110
39117
  cluster.count++;
39111
39118
  cluster.sources.add(color.source);
@@ -39138,7 +39145,7 @@ function mergeAndRank(allColors, maxColors = 6) {
39138
39145
 
39139
39146
  // Score: confidence * frequency weight * saturation bonus
39140
39147
  const scored = interesting.map((c) => {
39141
- const hsl = rgbToHsl(c.rgb);
39148
+ const hsl = rgbToHsl$1(c.rgb);
39142
39149
  const freqWeight = Math.min(c.count / 3, 1.5); // cap frequency bonus
39143
39150
  const satBonus = 1 + hsl.s / 200; // slight boost for saturated colors
39144
39151
  return {
@@ -39168,7 +39175,7 @@ function mergeAndRank(allColors, maxColors = 6) {
39168
39175
  // append the top boring color as a candidate for the neutral role
39169
39176
  if (boring.length > 0 && palette.length < maxColors) {
39170
39177
  const bestBoring = boring.sort((a, b) => b.confidence - a.confidence)[0];
39171
- const hsl = rgbToHsl(bestBoring.rgb);
39178
+ const hsl = rgbToHsl$1(bestBoring.rgb);
39172
39179
  palette.push({
39173
39180
  hex: bestBoring.hex,
39174
39181
  rgb: {
@@ -39235,6 +39242,630 @@ const themeFromUrlController$1 = {
39235
39242
 
39236
39243
  var themeFromUrlController_1 = themeFromUrlController$1;
39237
39244
 
39245
+ /**
39246
+ * themeGenerator.js
39247
+ *
39248
+ * Utility for generating themes via presets, random generation,
39249
+ * and color-harmony-based generation from a user-selected base color.
39250
+ */
39251
+
39252
+ // Color wheel mapping for Tailwind palettes (approximate hue angles)
39253
+ const COLOR_WHEEL = {
39254
+ red: 0,
39255
+ orange: 30,
39256
+ amber: 45,
39257
+ yellow: 60,
39258
+ lime: 90,
39259
+ green: 120,
39260
+ emerald: 150,
39261
+ teal: 180,
39262
+ cyan: 195,
39263
+ sky: 210,
39264
+ blue: 240,
39265
+ indigo: 260,
39266
+ violet: 275,
39267
+ purple: 285,
39268
+ fuchsia: 300,
39269
+ pink: 330,
39270
+ rose: 350,
39271
+ };
39272
+
39273
+ const NEUTRAL_COLORS = ["gray", "slate", "zinc", "neutral", "stone"];
39274
+
39275
+ const CHROMATIC_COLORS = Object.keys(COLOR_WHEEL);
39276
+
39277
+ /**
39278
+ * Find the nearest Tailwind color name for a given hue angle.
39279
+ */
39280
+ function nearestColor(hue) {
39281
+ const normalized = ((hue % 360) + 360) % 360;
39282
+ let best = CHROMATIC_COLORS[0];
39283
+ let bestDist = 360;
39284
+
39285
+ for (const [name, h] of Object.entries(COLOR_WHEEL)) {
39286
+ const dist = Math.min(
39287
+ Math.abs(normalized - h),
39288
+ 360 - Math.abs(normalized - h),
39289
+ );
39290
+ if (dist < bestDist) {
39291
+ bestDist = dist;
39292
+ best = name;
39293
+ }
39294
+ }
39295
+ return best;
39296
+ }
39297
+
39298
+ /**
39299
+ * Pick a random element from an array.
39300
+ */
39301
+ function pick(arr) {
39302
+ return arr[Math.floor(Math.random() * arr.length)];
39303
+ }
39304
+
39305
+ /**
39306
+ * Generate a fun theme name based on color families.
39307
+ */
39308
+ function generateThemeName(primary, secondary) {
39309
+ const adjectives = {
39310
+ red: "Crimson",
39311
+ orange: "Sunset",
39312
+ amber: "Golden",
39313
+ yellow: "Sunlit",
39314
+ lime: "Vivid",
39315
+ green: "Forest",
39316
+ emerald: "Jade",
39317
+ teal: "Lagoon",
39318
+ cyan: "Arctic",
39319
+ sky: "Horizon",
39320
+ blue: "Ocean",
39321
+ indigo: "Midnight",
39322
+ violet: "Twilight",
39323
+ purple: "Royal",
39324
+ fuchsia: "Neon",
39325
+ pink: "Blossom",
39326
+ rose: "Rosy",
39327
+ gray: "Steel",
39328
+ slate: "Shadow",
39329
+ zinc: "Iron",
39330
+ neutral: "Stone",
39331
+ stone: "Earth",
39332
+ };
39333
+
39334
+ const nouns = {
39335
+ red: "Ember",
39336
+ orange: "Blaze",
39337
+ amber: "Glow",
39338
+ yellow: "Ray",
39339
+ lime: "Spark",
39340
+ green: "Canopy",
39341
+ emerald: "Grove",
39342
+ teal: "Reef",
39343
+ cyan: "Frost",
39344
+ sky: "Breeze",
39345
+ blue: "Depth",
39346
+ indigo: "Night",
39347
+ violet: "Dusk",
39348
+ purple: "Amethyst",
39349
+ fuchsia: "Flash",
39350
+ pink: "Petal",
39351
+ rose: "Dawn",
39352
+ gray: "Mist",
39353
+ slate: "Cloud",
39354
+ zinc: "Storm",
39355
+ neutral: "Haven",
39356
+ stone: "Ridge",
39357
+ };
39358
+
39359
+ const adj = adjectives[primary] || "Custom";
39360
+ const noun = nouns[secondary] || "Theme";
39361
+
39362
+ return `${adj} ${noun}`;
39363
+ }
39364
+
39365
+ /**
39366
+ * Build a raw theme object from color selections.
39367
+ */
39368
+ function buildRawTheme(name, primary, secondary, tertiary, neutral) {
39369
+ return {
39370
+ id: `theme-${Date.now()}-${Math.floor(Math.random() * 1000)}`,
39371
+ name,
39372
+ primary,
39373
+ secondary,
39374
+ tertiary,
39375
+ neutral,
39376
+ dark: {},
39377
+ light: {},
39378
+ };
39379
+ }
39380
+
39381
+ // ─── Presets ─────────────────────────────────────────────────────────────
39382
+
39383
+ function getThemePresets() {
39384
+ return [
39385
+ buildRawTheme("Ocean Depth", "blue", "cyan", "teal", "slate"),
39386
+ buildRawTheme("Sunset Ember", "orange", "rose", "amber", "stone"),
39387
+ buildRawTheme("Forest Canopy", "green", "emerald", "lime", "gray"),
39388
+ buildRawTheme("Arctic Night", "slate", "sky", "indigo", "zinc"),
39389
+ buildRawTheme("Royal Amethyst", "purple", "violet", "fuchsia", "gray"),
39390
+ buildRawTheme("Warm Earth", "stone", "amber", "orange", "neutral"),
39391
+ buildRawTheme("Cyber Pulse", "cyan", "blue", "violet", "slate"),
39392
+ buildRawTheme("Rose Garden", "rose", "pink", "fuchsia", "gray"),
39393
+ buildRawTheme("Golden Hour", "amber", "yellow", "orange", "stone"),
39394
+ buildRawTheme("Midnight Sky", "indigo", "blue", "violet", "slate"),
39395
+ buildRawTheme("Spring Meadow", "emerald", "lime", "green", "gray"),
39396
+ buildRawTheme("Coral Reef", "red", "orange", "pink", "zinc"),
39397
+ buildRawTheme("Nordic Ice", "sky", "cyan", "blue", "slate"),
39398
+ buildRawTheme("Twilight Bloom", "violet", "purple", "pink", "gray"),
39399
+ buildRawTheme("Desert Sand", "amber", "orange", "stone", "neutral"),
39400
+ ];
39401
+ }
39402
+
39403
+ // ─── Random Generation ───────────────────────────────────────────────────
39404
+
39405
+ function generateRandomTheme() {
39406
+ const primary = pick(CHROMATIC_COLORS);
39407
+ const primaryHue = COLOR_WHEEL[primary];
39408
+
39409
+ // Complementary for secondary
39410
+ const secondaryHue = (primaryHue + 180) % 360;
39411
+ const secondary = nearestColor(secondaryHue);
39412
+
39413
+ // Analogous for tertiary
39414
+ const offset = pick([30, -30, 60, -60]);
39415
+ const tertiaryHue = (primaryHue + offset) % 360;
39416
+ const tertiary = nearestColor(tertiaryHue);
39417
+
39418
+ const neutral = pick(NEUTRAL_COLORS);
39419
+ const name = generateThemeName(primary, secondary);
39420
+
39421
+ return buildRawTheme(name, primary, secondary, tertiary, neutral);
39422
+ }
39423
+
39424
+ // ─── Color Harmony Generation ────────────────────────────────────────────
39425
+
39426
+ /**
39427
+ * Generate a theme using color harmony rules from a base color.
39428
+ * @param {string} baseColor - A Tailwind color name (e.g. "blue")
39429
+ * @param {"complementary"|"analogous"|"triadic"|"split-complementary"} strategy
39430
+ */
39431
+ function generateHarmonyTheme(baseColor, strategy = "complementary") {
39432
+ const baseHue = COLOR_WHEEL[baseColor];
39433
+ if (baseHue === undefined) {
39434
+ return generateRandomTheme();
39435
+ }
39436
+
39437
+ let secondaryHue, tertiaryHue;
39438
+
39439
+ switch (strategy) {
39440
+ case "complementary":
39441
+ secondaryHue = (baseHue + 180) % 360;
39442
+ tertiaryHue = (baseHue + 30) % 360;
39443
+ break;
39444
+ case "analogous":
39445
+ secondaryHue = (baseHue + 30) % 360;
39446
+ tertiaryHue = (baseHue + 60) % 360;
39447
+ break;
39448
+ case "triadic":
39449
+ secondaryHue = (baseHue + 120) % 360;
39450
+ tertiaryHue = (baseHue + 240) % 360;
39451
+ break;
39452
+ case "split-complementary":
39453
+ secondaryHue = (baseHue + 150) % 360;
39454
+ tertiaryHue = (baseHue + 210) % 360;
39455
+ break;
39456
+ default:
39457
+ secondaryHue = (baseHue + 180) % 360;
39458
+ tertiaryHue = (baseHue + 30) % 360;
39459
+ }
39460
+
39461
+ const primary = baseColor;
39462
+ const secondary = nearestColor(secondaryHue);
39463
+ const tertiary = nearestColor(tertiaryHue);
39464
+ const neutral = pick(NEUTRAL_COLORS);
39465
+ const name = generateThemeName(primary, secondary);
39466
+
39467
+ return buildRawTheme(name, primary, secondary, tertiary, neutral);
39468
+ }
39469
+
39470
+ /**
39471
+ * Generate a theme from three independently chosen colors.
39472
+ * @param {string} primary - A Tailwind color name
39473
+ * @param {string} secondary - A Tailwind color name
39474
+ * @param {string} tertiary - A Tailwind color name
39475
+ */
39476
+ function generateCustomTheme(primary, secondary, tertiary) {
39477
+ const neutral = pick(NEUTRAL_COLORS);
39478
+ const name = generateThemeName(primary, secondary);
39479
+ return buildRawTheme(name, primary, secondary, tertiary, neutral);
39480
+ }
39481
+
39482
+ /**
39483
+ * All available chromatic colors for the "From Color" picker.
39484
+ */
39485
+ const AVAILABLE_COLORS = CHROMATIC_COLORS;
39486
+
39487
+ /**
39488
+ * Available harmony strategies for the "From Color" picker.
39489
+ */
39490
+ const HARMONY_STRATEGIES = [
39491
+ { value: "complementary", label: "Complementary" },
39492
+ { value: "analogous", label: "Analogous" },
39493
+ { value: "triadic", label: "Triadic" },
39494
+ { value: "split-complementary", label: "Split Complementary" },
39495
+ { value: "custom", label: "Custom" },
39496
+ ];
39497
+
39498
+ var themeGenerator = /*#__PURE__*/Object.freeze({
39499
+ __proto__: null,
39500
+ AVAILABLE_COLORS: AVAILABLE_COLORS,
39501
+ HARMONY_STRATEGIES: HARMONY_STRATEGIES,
39502
+ generateCustomTheme: generateCustomTheme,
39503
+ generateHarmonyTheme: generateHarmonyTheme,
39504
+ generateRandomTheme: generateRandomTheme,
39505
+ generateThemeName: generateThemeName,
39506
+ getThemePresets: getThemePresets
39507
+ });
39508
+
39509
+ var require$$1 = /*@__PURE__*/getAugmentedNamespace(themeGenerator);
39510
+
39511
+ /**
39512
+ * paletteToThemeMapper.js
39513
+ *
39514
+ * Maps an extracted color palette (from themeFromUrlController) to Dash's
39515
+ * 4-role theme model (primary, secondary, tertiary, neutral) and generates
39516
+ * a complete theme object compatible with ThemeModel.
39517
+ */
39518
+
39519
+ const { TAILWIND_COLORS } = require$$0;
39520
+
39521
+ // ─── Color conversion helpers ───────────────────────────────────────────────
39522
+ // These mirror the helpers in themeFromUrlController but are kept local
39523
+ // to avoid coupling the two modules.
39524
+
39525
+ /** Parse hex string "#rrggbb" or "#rgb" → { r, g, b } (0-255). */
39526
+ function parseHex(hex) {
39527
+ if (!hex || typeof hex !== "string") return null;
39528
+ const s = hex.trim().toLowerCase();
39529
+ const m = s.match(/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/);
39530
+ if (!m) return null;
39531
+ let h = m[1];
39532
+ if (h.length === 3 || h.length === 4) {
39533
+ h = h
39534
+ .slice(0, 3)
39535
+ .split("")
39536
+ .map((c) => c + c)
39537
+ .join("");
39538
+ } else {
39539
+ h = h.slice(0, 6);
39540
+ }
39541
+ return {
39542
+ r: parseInt(h.slice(0, 2), 16),
39543
+ g: parseInt(h.slice(2, 4), 16),
39544
+ b: parseInt(h.slice(4, 6), 16),
39545
+ };
39546
+ }
39547
+
39548
+ /** { r, g, b } (0-255) → { h, s, l } (h: 0-360, s/l: 0-100) */
39549
+ function rgbToHsl({ r, g, b }) {
39550
+ r /= 255;
39551
+ g /= 255;
39552
+ b /= 255;
39553
+ const max = Math.max(r, g, b);
39554
+ const min = Math.min(r, g, b);
39555
+ const l = (max + min) / 2;
39556
+ if (max === min) return { h: 0, s: 0, l: l * 100 };
39557
+ const d = max - min;
39558
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
39559
+ let h;
39560
+ if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
39561
+ else if (max === g) h = ((b - r) / d + 2) / 6;
39562
+ else h = ((r - g) / d + 4) / 6;
39563
+ return { h: h * 360, s: s * 100, l: l * 100 };
39564
+ }
39565
+
39566
+ /** { r, g, b } (0-255) → { L, a, b } in CIELAB space */
39567
+ function rgbToLab({ r, g, b }) {
39568
+ let rr = r / 255;
39569
+ let gg = g / 255;
39570
+ let bb = b / 255;
39571
+ rr = rr > 0.04045 ? Math.pow((rr + 0.055) / 1.055, 2.4) : rr / 12.92;
39572
+ gg = gg > 0.04045 ? Math.pow((gg + 0.055) / 1.055, 2.4) : gg / 12.92;
39573
+ bb = bb > 0.04045 ? Math.pow((bb + 0.055) / 1.055, 2.4) : bb / 12.92;
39574
+
39575
+ let x = (rr * 0.4124564 + gg * 0.3575761 + bb * 0.1804375) / 0.95047;
39576
+ let y = rr * 0.2126729 + gg * 0.7151522 + bb * 0.072175;
39577
+ let z = (rr * 0.0193339 + gg * 0.119192 + bb * 0.9503041) / 1.08883;
39578
+
39579
+ const f = (t) => (t > 0.008856 ? Math.cbrt(t) : 7.787 * t + 16 / 116);
39580
+ x = f(x);
39581
+ y = f(y);
39582
+ z = f(z);
39583
+
39584
+ return {
39585
+ L: 116 * y - 16,
39586
+ a: 500 * (x - y),
39587
+ b: 200 * (y - z),
39588
+ };
39589
+ }
39590
+
39591
+ /** CIE76 deltaE between two Lab colors */
39592
+ function deltaE(lab1, lab2) {
39593
+ return Math.sqrt(
39594
+ Math.pow(lab1.L - lab2.L, 2) +
39595
+ Math.pow(lab1.a - lab2.a, 2) +
39596
+ Math.pow(lab1.b - lab2.b, 2),
39597
+ );
39598
+ }
39599
+
39600
+ /** Minimum angular hue distance (0-180) */
39601
+ function hueDistance(h1, h2) {
39602
+ const d = Math.abs(h1 - h2);
39603
+ return Math.min(d, 360 - d);
39604
+ }
39605
+
39606
+ // ─── Pre-compute Tailwind Lab values ────────────────────────────────────────
39607
+
39608
+ const NEUTRAL_FAMILIES = ["slate", "gray", "zinc", "neutral", "stone"];
39609
+
39610
+ const TAILWIND_LAB_CACHE = {};
39611
+ for (const [name, hex] of Object.entries(TAILWIND_COLORS)) {
39612
+ const rgb = parseHex(hex);
39613
+ TAILWIND_LAB_CACHE[name] = {
39614
+ hex,
39615
+ rgb,
39616
+ lab: rgbToLab(rgb),
39617
+ hsl: rgbToHsl(rgb),
39618
+ };
39619
+ }
39620
+
39621
+ // ─── Public API ─────────────────────────────────────────────────────────────
39622
+
39623
+ /**
39624
+ * Match a hex color to the nearest Tailwind color family using CIELAB deltaE.
39625
+ *
39626
+ * @param {string} hex - Hex color string (e.g. "#3B82F6")
39627
+ * @returns {{ family: string, deltaE: number }}
39628
+ */
39629
+ function matchTailwindFamily$1(hex) {
39630
+ const rgb = parseHex(hex);
39631
+ if (!rgb) return { family: "gray", deltaE: Infinity };
39632
+ const lab = rgbToLab(rgb);
39633
+
39634
+ let bestFamily = "gray";
39635
+ let bestDelta = Infinity;
39636
+
39637
+ for (const [name, cached] of Object.entries(TAILWIND_LAB_CACHE)) {
39638
+ const d = deltaE(lab, cached.lab);
39639
+ if (d < bestDelta) {
39640
+ bestDelta = d;
39641
+ bestFamily = name;
39642
+ }
39643
+ }
39644
+
39645
+ return { family: bestFamily, deltaE: Math.round(bestDelta * 100) / 100 };
39646
+ }
39647
+
39648
+ /**
39649
+ * Assign roles (primary, secondary, tertiary, neutral) to extracted palette colors.
39650
+ *
39651
+ * Algorithm:
39652
+ * 1. Sort by confidence * saturation (descending)
39653
+ * 2. Primary = most prominent chromatic color
39654
+ * 3. Secondary = max minimum hue distance from primary
39655
+ * 4. Tertiary = max minimum hue distance from primary + secondary
39656
+ * 5. Neutral = least saturated, or generated from primary if not available
39657
+ *
39658
+ * @param {Array<{hex, rgb?, hsl?, confidence, sources?, isNeutral?}>} palette
39659
+ * @returns {{ primary: string, secondary: string, tertiary: string, neutral: string }}
39660
+ * Each value is a hex string.
39661
+ */
39662
+ function assignRoles$1(palette) {
39663
+ if (!palette || palette.length === 0) {
39664
+ return {
39665
+ primary: "#6b7280",
39666
+ secondary: "#3b82f6",
39667
+ tertiary: "#6366f1",
39668
+ neutral: "#64748b",
39669
+ };
39670
+ }
39671
+
39672
+ // Ensure all entries have hsl
39673
+ const colors = palette.map((c) => {
39674
+ const rgb = c.rgb || parseHex(c.hex);
39675
+ const hsl = c.hsl || (rgb ? rgbToHsl(rgb) : { h: 0, s: 0, l: 50 });
39676
+ return { ...c, rgb, hsl };
39677
+ });
39678
+
39679
+ // Separate chromatic from neutral candidates
39680
+ const chromatic = colors.filter(
39681
+ (c) => !c.isNeutral && c.hsl.s > 10 && c.hsl.l > 5 && c.hsl.l < 95,
39682
+ );
39683
+ const neutralCandidates = colors.filter(
39684
+ (c) => c.isNeutral || c.hsl.s <= 10 || c.hsl.l <= 5 || c.hsl.l >= 95,
39685
+ );
39686
+
39687
+ // Sort chromatic by confidence * saturation
39688
+ chromatic.sort(
39689
+ (a, b) => b.confidence * (b.hsl.s / 100) - a.confidence * (a.hsl.s / 100),
39690
+ );
39691
+
39692
+ // Assign primary
39693
+ const primary = chromatic.length > 0 ? chromatic[0] : colors[0];
39694
+ const assigned = [primary];
39695
+
39696
+ // Assign secondary: max minimum hue distance from primary
39697
+ const remaining = chromatic.filter((c) => c !== primary);
39698
+ let secondary;
39699
+ if (remaining.length > 0) {
39700
+ secondary = remaining.reduce((best, c) => {
39701
+ const dist = hueDistance(c.hsl.h, primary.hsl.h);
39702
+ const bestDist = hueDistance(best.hsl.h, primary.hsl.h);
39703
+ return dist > bestDist ? c : best;
39704
+ }, remaining[0]);
39705
+ } else {
39706
+ // Generate analogous from primary
39707
+ secondary = {
39708
+ ...primary,
39709
+ hsl: { ...primary.hsl, h: (primary.hsl.h + 180) % 360 },
39710
+ };
39711
+ }
39712
+ assigned.push(secondary);
39713
+
39714
+ // Assign tertiary: max minimum hue distance from both assigned
39715
+ const remaining2 = remaining.filter((c) => c !== secondary);
39716
+ let tertiary;
39717
+ if (remaining2.length > 0) {
39718
+ tertiary = remaining2.reduce((best, c) => {
39719
+ const minDist = Math.min(
39720
+ ...assigned.map((a) => hueDistance(c.hsl.h, a.hsl.h)),
39721
+ );
39722
+ const bestMinDist = Math.min(
39723
+ ...assigned.map((a) => hueDistance(best.hsl.h, a.hsl.h)),
39724
+ );
39725
+ return minDist > bestMinDist ? c : best;
39726
+ }, remaining2[0]);
39727
+ } else {
39728
+ // Generate from primary at +60 degrees
39729
+ tertiary = {
39730
+ ...primary,
39731
+ hsl: { ...primary.hsl, h: (primary.hsl.h + 60) % 360 },
39732
+ };
39733
+ }
39734
+
39735
+ // Assign neutral: from neutral candidates, or lowest saturation chromatic, or generate
39736
+ let neutral;
39737
+ if (neutralCandidates.length > 0) {
39738
+ neutral = neutralCandidates[0];
39739
+ } else {
39740
+ // Use the least saturated remaining color
39741
+ const allRemaining = colors.filter(
39742
+ (c) => c !== primary && c !== secondary && c !== tertiary,
39743
+ );
39744
+ if (allRemaining.length > 0) {
39745
+ neutral = allRemaining.reduce((best, c) =>
39746
+ c.hsl.s < best.hsl.s ? c : best,
39747
+ );
39748
+ } else {
39749
+ neutral = { hex: "#64748b", hsl: { h: 215, s: 16, l: 47 } };
39750
+ }
39751
+ }
39752
+
39753
+ return {
39754
+ primary: primary.hex,
39755
+ secondary: secondary.hex,
39756
+ tertiary: tertiary.hex,
39757
+ neutral: neutral.hex,
39758
+ };
39759
+ }
39760
+
39761
+ /**
39762
+ * Generate a complete theme object from an extracted palette.
39763
+ *
39764
+ * Takes the raw palette from themeFromUrlController.extractColorsFromUrl(),
39765
+ * assigns color roles, maps to Tailwind families, and returns a raw theme
39766
+ * object ready for ThemeModel processing.
39767
+ *
39768
+ * @param {Array<{hex, rgb?, hsl?, confidence, sources?, isNeutral?}>} palette
39769
+ * @param {Object} [overrides] - Optional role overrides { primary?, secondary?, tertiary?, neutral? } as hex strings
39770
+ * @returns {{ theme: Object, roleAssignments: Object, familyMatches: Object }}
39771
+ */
39772
+ function generateThemeFromPalette$1(palette, overrides = {}) {
39773
+ // Step 1: Assign roles
39774
+ const roles = assignRoles$1(palette);
39775
+
39776
+ // Apply any user overrides
39777
+ if (overrides.primary) roles.primary = overrides.primary;
39778
+ if (overrides.secondary) roles.secondary = overrides.secondary;
39779
+ if (overrides.tertiary) roles.tertiary = overrides.tertiary;
39780
+ if (overrides.neutral) roles.neutral = overrides.neutral;
39781
+
39782
+ // Step 2: Match each role to nearest Tailwind family
39783
+ const primaryMatch = matchTailwindFamily$1(roles.primary);
39784
+ const secondaryMatch = matchTailwindFamily$1(roles.secondary);
39785
+ const tertiaryMatch = matchTailwindFamily$1(roles.tertiary);
39786
+ const neutralMatch = matchTailwindFamily$1(roles.neutral);
39787
+
39788
+ // For neutral, prefer a neutral family if the match is chromatic and close enough
39789
+ let neutralFamily = neutralMatch.family;
39790
+ if (!NEUTRAL_FAMILIES.includes(neutralFamily)) {
39791
+ // Check if there's a neutral family within reasonable distance
39792
+ const neutralRgb = parseHex(roles.neutral);
39793
+ if (neutralRgb) {
39794
+ const neutralHsl = rgbToHsl(neutralRgb);
39795
+ if (neutralHsl.s < 20) {
39796
+ // Low saturation — force to nearest neutral family
39797
+ const neutralLab = rgbToLab(neutralRgb);
39798
+ let bestNeutral = "slate";
39799
+ let bestDelta = Infinity;
39800
+ for (const nf of NEUTRAL_FAMILIES) {
39801
+ const d = deltaE(neutralLab, TAILWIND_LAB_CACHE[nf].lab);
39802
+ if (d < bestDelta) {
39803
+ bestDelta = d;
39804
+ bestNeutral = nf;
39805
+ }
39806
+ }
39807
+ neutralFamily = bestNeutral;
39808
+ }
39809
+ }
39810
+ }
39811
+
39812
+ // Step 3: Generate theme name from families
39813
+ const { generateThemeName } = require$$1;
39814
+ const themeName = generateThemeName(
39815
+ primaryMatch.family,
39816
+ secondaryMatch.family,
39817
+ );
39818
+
39819
+ // Step 4: Build raw theme object (compatible with ThemeModel)
39820
+ const theme = {
39821
+ id: `theme-url-${Date.now()}-${Math.floor(Math.random() * 1000)}`,
39822
+ name: themeName,
39823
+ primary: primaryMatch.family,
39824
+ secondary: secondaryMatch.family,
39825
+ tertiary: tertiaryMatch.family,
39826
+ neutral: neutralFamily,
39827
+ dark: {},
39828
+ light: {},
39829
+ };
39830
+
39831
+ const familyMatches = {
39832
+ primary: {
39833
+ hex: roles.primary,
39834
+ family: primaryMatch.family,
39835
+ deltaE: primaryMatch.deltaE,
39836
+ },
39837
+ secondary: {
39838
+ hex: roles.secondary,
39839
+ family: secondaryMatch.family,
39840
+ deltaE: secondaryMatch.deltaE,
39841
+ },
39842
+ tertiary: {
39843
+ hex: roles.tertiary,
39844
+ family: tertiaryMatch.family,
39845
+ deltaE: tertiaryMatch.deltaE,
39846
+ },
39847
+ neutral: {
39848
+ hex: roles.neutral,
39849
+ family: neutralFamily,
39850
+ deltaE: neutralMatch.deltaE,
39851
+ },
39852
+ };
39853
+
39854
+ return {
39855
+ theme,
39856
+ roleAssignments: roles,
39857
+ familyMatches,
39858
+ };
39859
+ }
39860
+
39861
+ const paletteToThemeMapper$1 = {
39862
+ assignRoles: assignRoles$1,
39863
+ matchTailwindFamily: matchTailwindFamily$1,
39864
+ generateThemeFromPalette: generateThemeFromPalette$1,
39865
+ };
39866
+
39867
+ var paletteToThemeMapper_1 = paletteToThemeMapper$1;
39868
+
39238
39869
  var bufferUtil$1 = {exports: {}};
39239
39870
 
39240
39871
  const BINARY_TYPES$2 = ['nodebuffer', 'arraybuffer', 'fragments'];
@@ -39444,7 +40075,7 @@ let Limiter$1 = class Limiter {
39444
40075
 
39445
40076
  var limiter = Limiter$1;
39446
40077
 
39447
- const zlib = require$$0$9;
40078
+ const zlib = require$$0$a;
39448
40079
 
39449
40080
  const bufferUtil = bufferUtilExports;
39450
40081
  const Limiter = limiter;
@@ -39975,7 +40606,7 @@ var validation = {exports: {}};
39975
40606
 
39976
40607
  var isValidUTF8_1;
39977
40608
 
39978
- const { isUtf8 } = require$$0$a;
40609
+ const { isUtf8 } = require$$0$b;
39979
40610
 
39980
40611
  const { hasBlob } = constants;
39981
40612
 
@@ -40128,7 +40759,7 @@ if (isUtf8) {
40128
40759
 
40129
40760
  var validationExports = validation.exports;
40130
40761
 
40131
- const { Writable } = require$$0$3;
40762
+ const { Writable } = require$$0$4;
40132
40763
 
40133
40764
  const PerMessageDeflate$3 = permessageDeflate;
40134
40765
  const {
@@ -40834,7 +41465,7 @@ let Receiver$1 = class Receiver extends Writable {
40834
41465
  var receiver = Receiver$1;
40835
41466
 
40836
41467
  /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex" }] */
40837
- const { randomFillSync } = require$$1$5;
41468
+ const { randomFillSync } = require$$1$6;
40838
41469
 
40839
41470
  const PerMessageDeflate$2 = permessageDeflate;
40840
41471
  const { EMPTY_BUFFER: EMPTY_BUFFER$1, kWebSocket: kWebSocket$2, NOOP: NOOP$1 } = constants;
@@ -41927,12 +42558,12 @@ var extension$1 = { format: format$1, parse: parse$2 };
41927
42558
 
41928
42559
  /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$", "caughtErrors": "none" }] */
41929
42560
 
41930
- const EventEmitter$1 = require$$0$b;
41931
- const https = require$$8$1;
42561
+ const EventEmitter$1 = require$$0$c;
42562
+ const https = require$$8;
41932
42563
  const http$1 = require$$2$5;
41933
42564
  const net = require$$3$4;
41934
42565
  const tls = require$$4$2;
41935
- const { randomBytes, createHash: createHash$1 } = require$$1$5;
42566
+ const { randomBytes, createHash: createHash$1 } = require$$1$6;
41936
42567
  const { URL: URL$1 } = require$$4$1;
41937
42568
 
41938
42569
  const PerMessageDeflate$1 = permessageDeflate;
@@ -43317,7 +43948,7 @@ function socketOnError$1() {
43317
43948
  }
43318
43949
 
43319
43950
  /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^WebSocket$" }] */
43320
- const { Duplex } = require$$0$3;
43951
+ const { Duplex } = require$$0$4;
43321
43952
 
43322
43953
  /**
43323
43954
  * Emits the `'close'` event on a stream.
@@ -43538,9 +44169,9 @@ var subprotocol$1 = { parse };
43538
44169
 
43539
44170
  /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex$", "caughtErrors": "none" }] */
43540
44171
 
43541
- const EventEmitter = require$$0$b;
44172
+ const EventEmitter = require$$0$c;
43542
44173
  const http = require$$2$5;
43543
- const { createHash } = require$$1$5;
44174
+ const { createHash } = require$$1$6;
43544
44175
 
43545
44176
  const extension = extension$1;
43546
44177
  const PerMessageDeflate = permessageDeflate;
@@ -44165,7 +44796,7 @@ function interpolate(template, credentials) {
44165
44796
  */
44166
44797
  function broadcastStatusChange(providerName, status, extra = {}) {
44167
44798
  const { WS_STATUS_CHANGE } = webSocketEvents$1;
44168
- const { BrowserWindow } = require$$0$1;
44799
+ const { BrowserWindow } = require$$0$2;
44169
44800
 
44170
44801
  const payload = { provider: providerName, status, ...extra };
44171
44802
  for (const win of BrowserWindow.getAllWindows()) {
@@ -44183,7 +44814,7 @@ function broadcastStatusChange(providerName, status, extra = {}) {
44183
44814
  */
44184
44815
  function broadcastMessage(providerName, data) {
44185
44816
  const { WS_MESSAGE } = webSocketEvents$1;
44186
- const { BrowserWindow } = require$$0$1;
44817
+ const { BrowserWindow } = require$$0$2;
44187
44818
 
44188
44819
  const payload = {
44189
44820
  provider: providerName,
@@ -44620,7 +45251,7 @@ clientCache$1.registerFactory("algolia", (credentials) => {
44620
45251
 
44621
45252
  // --- OpenAI ---
44622
45253
  clientCache$1.registerFactory("openai", (credentials) => {
44623
- const OpenAI = require$$0$7;
45254
+ const OpenAI = require$$0$8;
44624
45255
  return new OpenAI({ apiKey: credentials.apiKey });
44625
45256
  });
44626
45257
 
@@ -44639,7 +45270,7 @@ const MAX_RECENTS = 20;
44639
45270
  let store = null;
44640
45271
  function getStore() {
44641
45272
  if (!store) {
44642
- const Store = require$$1;
45273
+ const Store = require$$1$1;
44643
45274
  store = new Store({ name: "dash-session" });
44644
45275
  }
44645
45276
  return store;
@@ -44823,8 +45454,8 @@ var dashboardRatingsUtils = {
44823
45454
  * Runs in the Electron main process.
44824
45455
  */
44825
45456
 
44826
- const { app } = require$$0$1;
44827
- const path = require$$1$1;
45457
+ const { app } = require$$0$2;
45458
+ const path = require$$1$2;
44828
45459
  const { getFileContents, writeToFile } = file;
44829
45460
  const {
44830
45461
  validateAndBuildRating,
@@ -45023,6 +45654,11 @@ const {
45023
45654
  installThemeFromRegistry,
45024
45655
  getThemePublishPreview,
45025
45656
  } = themeRegistryController$1;
45657
+ const {
45658
+ assignRoles,
45659
+ matchTailwindFamily,
45660
+ generateThemeFromPalette,
45661
+ } = paletteToThemeMapper_1;
45026
45662
 
45027
45663
  var controller = {
45028
45664
  showDialog,
@@ -45102,9 +45738,12 @@ var controller = {
45102
45738
  prepareThemeForPublish,
45103
45739
  installThemeFromRegistry,
45104
45740
  getThemePublishPreview,
45741
+ assignRoles,
45742
+ matchTailwindFamily,
45743
+ generateThemeFromPalette,
45105
45744
  };
45106
45745
 
45107
- const { ipcRenderer: ipcRenderer$o } = require$$0$1;
45746
+ const { ipcRenderer: ipcRenderer$o } = require$$0$2;
45108
45747
  const {
45109
45748
  SECURE_STORE_ENCRYPTION_CHECK,
45110
45749
  SECURE_STORE_SET_DATA,
@@ -45130,7 +45769,7 @@ var secureStoreApi_1 = secureStoreApi$2;
45130
45769
  * Handle the workspace configuration file
45131
45770
  */
45132
45771
 
45133
- const { ipcRenderer: ipcRenderer$n } = require$$0$1;
45772
+ const { ipcRenderer: ipcRenderer$n } = require$$0$2;
45134
45773
  const {
45135
45774
  WORKSPACE_LIST,
45136
45775
  WORKSPACE_SAVE,
@@ -45180,7 +45819,7 @@ var workspaceApi_1 = workspaceApi$2;
45180
45819
  */
45181
45820
 
45182
45821
  // ipcRenderer that must be used to invoke the events
45183
- const { ipcRenderer: ipcRenderer$m } = require$$0$1;
45822
+ const { ipcRenderer: ipcRenderer$m } = require$$0$2;
45184
45823
 
45185
45824
  const { LAYOUT_LIST, LAYOUT_SAVE } = events$8;
45186
45825
 
@@ -45200,7 +45839,7 @@ var layoutApi_1 = layoutApi$2;
45200
45839
  */
45201
45840
 
45202
45841
  // ipcRenderer that must be used to invoke the events
45203
- const { ipcRenderer: ipcRenderer$l } = require$$0$1;
45842
+ const { ipcRenderer: ipcRenderer$l } = require$$0$2;
45204
45843
 
45205
45844
  const {
45206
45845
  DATA_JSON_TO_CSV_FILE,
@@ -45315,7 +45954,7 @@ var dataApi_1 = dataApi$2;
45315
45954
  */
45316
45955
 
45317
45956
  // ipcRenderer that must be used to invoke the events
45318
- const { ipcRenderer: ipcRenderer$k } = require$$0$1;
45957
+ const { ipcRenderer: ipcRenderer$k } = require$$0$2;
45319
45958
 
45320
45959
  const {
45321
45960
  SETTINGS_GET,
@@ -45348,7 +45987,7 @@ var settingsApi_1 = settingsApi$2;
45348
45987
  */
45349
45988
 
45350
45989
  // ipcRenderer that must be used to invoke the events
45351
- const { ipcRenderer: ipcRenderer$j } = require$$0$1;
45990
+ const { ipcRenderer: ipcRenderer$j } = require$$0$2;
45352
45991
 
45353
45992
  const { CHOOSE_FILE } = events$8;
45354
45993
 
@@ -45379,7 +46018,7 @@ var dialogApi_1 = dialogApi$2;
45379
46018
  * mainApi.widgets.uninstall('Weather')
45380
46019
  */
45381
46020
 
45382
- const { ipcRenderer: ipcRenderer$i } = require$$0$1;
46021
+ const { ipcRenderer: ipcRenderer$i } = require$$0$2;
45383
46022
 
45384
46023
  const widgetApi$2 = {
45385
46024
  /**
@@ -45707,7 +46346,7 @@ var widgetApi_1 = widgetApi$2;
45707
46346
  * Communicates with main process via IPC to handle encryption and file storage
45708
46347
  */
45709
46348
 
45710
- const { ipcRenderer: ipcRenderer$h } = require$$0$1;
46349
+ const { ipcRenderer: ipcRenderer$h } = require$$0$2;
45711
46350
  const {
45712
46351
  PROVIDER_SAVE,
45713
46352
  PROVIDER_LIST,
@@ -45878,7 +46517,7 @@ var providerApi_1 = providerApi$2;
45878
46517
  * Communicates with main process via IPC to manage MCP server lifecycle.
45879
46518
  */
45880
46519
 
45881
- const { ipcRenderer: ipcRenderer$g } = require$$0$1;
46520
+ const { ipcRenderer: ipcRenderer$g } = require$$0$2;
45882
46521
  const {
45883
46522
  MCP_START_SERVER,
45884
46523
  MCP_STOP_SERVER,
@@ -46012,7 +46651,7 @@ var mcpApi_1 = mcpApi$2;
46012
46651
  * mainApi.registry.checkUpdates([{ name: "weather-widgets", version: "1.0.0" }])
46013
46652
  */
46014
46653
 
46015
- const { ipcRenderer: ipcRenderer$f } = require$$0$1;
46654
+ const { ipcRenderer: ipcRenderer$f } = require$$0$2;
46016
46655
 
46017
46656
  const registryApi$2 = {
46018
46657
  /**
@@ -46121,7 +46760,7 @@ var registryApi_1 = registryApi$2;
46121
46760
  * Handle the theme configuration file
46122
46761
  */
46123
46762
 
46124
- const { ipcRenderer: ipcRenderer$e } = require$$0$1;
46763
+ const { ipcRenderer: ipcRenderer$e } = require$$0$2;
46125
46764
 
46126
46765
  const {
46127
46766
  THEME_LIST,
@@ -46156,7 +46795,7 @@ var themeApi_1 = themeApi$2;
46156
46795
  */
46157
46796
 
46158
46797
  // ipcRenderer that must be used to invoke the events
46159
- const { ipcRenderer: ipcRenderer$d } = require$$0$1;
46798
+ const { ipcRenderer: ipcRenderer$d } = require$$0$2;
46160
46799
 
46161
46800
  const {
46162
46801
  ALGOLIA_LIST_INDICES,
@@ -46239,7 +46878,7 @@ var algoliaApi_1 = algoliaApi$2;
46239
46878
  * openAI
46240
46879
  */
46241
46880
 
46242
- const { ipcRenderer: ipcRenderer$c } = require$$0$1;
46881
+ const { ipcRenderer: ipcRenderer$c } = require$$0$2;
46243
46882
 
46244
46883
  const { OPENAI_DESCRIBE_IMAGE } = openaiEvents$1;
46245
46884
 
@@ -46257,7 +46896,7 @@ var openaiApi_1 = openaiApi$2;
46257
46896
  */
46258
46897
 
46259
46898
  // ipcRenderer that must be used to invoke the events
46260
- const { ipcRenderer: ipcRenderer$b } = require$$0$1;
46899
+ const { ipcRenderer: ipcRenderer$b } = require$$0$2;
46261
46900
 
46262
46901
  const { MENU_ITEMS_SAVE, MENU_ITEMS_LIST } = events$8;
46263
46902
 
@@ -46276,7 +46915,7 @@ var menuItemsApi_1 = menuItemsApi$2;
46276
46915
  */
46277
46916
 
46278
46917
  // ipcRenderer that must be used to invoke the events
46279
- const { ipcRenderer: ipcRenderer$a } = require$$0$1;
46918
+ const { ipcRenderer: ipcRenderer$a } = require$$0$2;
46280
46919
 
46281
46920
  const pluginApi$2 = {
46282
46921
  install: (packageName, filepath) =>
@@ -46294,7 +46933,7 @@ var pluginApi_1 = pluginApi$2;
46294
46933
  * tool-use events, and request cancellation.
46295
46934
  */
46296
46935
 
46297
- const { ipcRenderer: ipcRenderer$9 } = require$$0$1;
46936
+ const { ipcRenderer: ipcRenderer$9 } = require$$0$2;
46298
46937
  const {
46299
46938
  LLM_SEND_MESSAGE,
46300
46939
  LLM_ABORT_REQUEST,
@@ -46454,7 +47093,7 @@ var llmApi_1 = llmApi$2;
46454
47093
  * and manage the response cache.
46455
47094
  */
46456
47095
 
46457
- const { ipcRenderer: ipcRenderer$8 } = require$$0$1;
47096
+ const { ipcRenderer: ipcRenderer$8 } = require$$0$2;
46458
47097
  const {
46459
47098
  CLIENT_CACHE_INVALIDATE,
46460
47099
  CLIENT_CACHE_INVALIDATE_ALL,
@@ -46504,7 +47143,7 @@ var clientCacheApi_1 = clientCacheApi$2;
46504
47143
  * Exposed via contextBridge through mainApi.
46505
47144
  */
46506
47145
 
46507
- const { ipcRenderer: ipcRenderer$7 } = require$$0$1;
47146
+ const { ipcRenderer: ipcRenderer$7 } = require$$0$2;
46508
47147
  const {
46509
47148
  DASHBOARD_CONFIG_EXPORT,
46510
47149
  DASHBOARD_CONFIG_SELECT_FILE,
@@ -46656,7 +47295,7 @@ var dashboardConfigApi_1 = dashboardConfigApi$2;
46656
47295
  * Exposed via contextBridge through mainApi.
46657
47296
  */
46658
47297
 
46659
- const { ipcRenderer: ipcRenderer$6 } = require$$0$1;
47298
+ const { ipcRenderer: ipcRenderer$6 } = require$$0$2;
46660
47299
  const {
46661
47300
  REGISTRY_AUTH_INITIATE_LOGIN,
46662
47301
  REGISTRY_AUTH_POLL_TOKEN,
@@ -46768,7 +47407,7 @@ var registryAuthApi_1 = registryAuthApi$2;
46768
47407
  * Exposed to the renderer via mainApi.notifications.
46769
47408
  */
46770
47409
 
46771
- const { ipcRenderer: ipcRenderer$5 } = require$$0$1;
47410
+ const { ipcRenderer: ipcRenderer$5 } = require$$0$2;
46772
47411
  const {
46773
47412
  NOTIFICATION_SEND,
46774
47413
  NOTIFICATION_GET_PREFERENCES,
@@ -46846,7 +47485,7 @@ var notificationApi_1 = notificationApi$2;
46846
47485
  * Exposed to the renderer via mainApi.scheduler.
46847
47486
  */
46848
47487
 
46849
- const { ipcRenderer: ipcRenderer$4 } = require$$0$1;
47488
+ const { ipcRenderer: ipcRenderer$4 } = require$$0$2;
46850
47489
  const {
46851
47490
  SCHEDULER_REGISTER_TASK,
46852
47491
  SCHEDULER_REMOVE_TASK,
@@ -46946,18 +47585,23 @@ var schedulerApi_1 = schedulerApi$2;
46946
47585
  /**
46947
47586
  * themeFromUrlApi.js
46948
47587
  *
46949
- * Renderer-side IPC API for theme-from-URL extraction.
47588
+ * Renderer-side IPC API for theme-from-URL extraction and palette mapping.
46950
47589
  */
46951
47590
 
46952
- const { ipcRenderer: ipcRenderer$3 } = require$$0$1;
47591
+ const { ipcRenderer: ipcRenderer$3 } = require$$0$2;
46953
47592
 
46954
- const { THEME_EXTRACT_FROM_URL } = events$8;
47593
+ const {
47594
+ THEME_EXTRACT_FROM_URL,
47595
+ THEME_MAP_PALETTE_TO_THEME,
47596
+ } = events$8;
46955
47597
 
46956
- const themeFromUrlApi$1 = {
47598
+ const themeFromUrlApi$2 = {
46957
47599
  extractFromUrl: (url) => ipcRenderer$3.invoke(THEME_EXTRACT_FROM_URL, { url }),
47600
+ mapPaletteToTheme: (palette, overrides) =>
47601
+ ipcRenderer$3.invoke(THEME_MAP_PALETTE_TO_THEME, { palette, overrides }),
46958
47602
  };
46959
47603
 
46960
- var themeFromUrlApi_1 = themeFromUrlApi$1;
47604
+ var themeFromUrlApi_1 = themeFromUrlApi$2;
46961
47605
 
46962
47606
  /**
46963
47607
  * dashboardRatingsApi.js
@@ -46965,7 +47609,7 @@ var themeFromUrlApi_1 = themeFromUrlApi$1;
46965
47609
  * IPC bridge for dashboard ratings (renderer side).
46966
47610
  */
46967
47611
 
46968
- const { ipcRenderer: ipcRenderer$2 } = require$$0$1;
47612
+ const { ipcRenderer: ipcRenderer$2 } = require$$0$2;
46969
47613
  const {
46970
47614
  DASHBOARD_RATING_SAVE,
46971
47615
  DASHBOARD_RATING_GET,
@@ -47000,7 +47644,7 @@ var dashboardRatingsApi_1 = dashboardRatingsApi$1;
47000
47644
  * Exposed via contextBridge through mainApi.
47001
47645
  */
47002
47646
 
47003
- const { ipcRenderer: ipcRenderer$1 } = require$$0$1;
47647
+ const { ipcRenderer: ipcRenderer$1 } = require$$0$2;
47004
47648
  const {
47005
47649
  SESSION_GET_RECENTS,
47006
47650
  SESSION_ADD_RECENT,
@@ -47070,7 +47714,7 @@ var sessionApi_1 = sessionApi$1;
47070
47714
  * contextBridge.exposeInMainWorld("mainApi", defaultMainApi);
47071
47715
  */
47072
47716
 
47073
- const { ipcRenderer, shell } = require$$0$1;
47717
+ const { ipcRenderer, shell } = require$$0$2;
47074
47718
  const secureStoreApi$1 = secureStoreApi_1;
47075
47719
  const workspaceApi$1 = workspaceApi_1;
47076
47720
  const layoutApi$1 = layoutApi_1;
@@ -47094,6 +47738,7 @@ const registryAuthApi$1 = registryAuthApi_1;
47094
47738
  const sessionApi = sessionApi_1;
47095
47739
  const notificationApi$1 = notificationApi_1;
47096
47740
  const schedulerApi$1 = schedulerApi_1;
47741
+ const themeFromUrlApi$1 = themeFromUrlApi_1;
47097
47742
 
47098
47743
  // Events constants
47099
47744
  const events$1 = events$8;
@@ -47171,6 +47816,7 @@ function createMainApi$1(extensions = {}) {
47171
47816
  session: sessionApi,
47172
47817
  notifications: notificationApi$1,
47173
47818
  scheduler: schedulerApi$1,
47819
+ themeFromUrl: themeFromUrlApi$1,
47174
47820
 
47175
47821
  widgetEvent: {
47176
47822
  publish: (eventType, content) => {
@@ -47223,6 +47869,7 @@ const notificationController = notificationController_1;
47223
47869
  const schedulerController = schedulerController_1;
47224
47870
  const themeRegistryController = themeRegistryController$1;
47225
47871
  const themeFromUrlController = themeFromUrlController_1;
47872
+ const paletteToThemeMapper = paletteToThemeMapper_1;
47226
47873
  const webSocketController = webSocketController_1;
47227
47874
 
47228
47875
  // --- Utils ---
@@ -47297,6 +47944,7 @@ var electron = {
47297
47944
  schedulerController,
47298
47945
  themeRegistryController,
47299
47946
  themeFromUrlController,
47947
+ paletteToThemeMapper,
47300
47948
  webSocketController,
47301
47949
 
47302
47950
  // Controller functions (flat) — spread for convenient destructuring