@rm-graph/core 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,19 +1,26 @@
1
1
  # @rm-graph/core
2
2
 
3
- RM-Graphs Core - Framework-agnostic charting library built on SciChart.
3
+ RM-Graphs Core - Framework-agnostic charting library built on SciChart.js. This package provides the core functionality for creating high-performance 2D and 3D charts, including license management with encrypted storage.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @rm-graph/core
9
+ # or
10
+ pnpm add @rm-graph/core
11
+ # or
12
+ yarn add @rm-graph/core
9
13
  ```
10
14
 
11
15
  > `scichart` is automatically installed as a dependency!
12
16
 
13
- ## Usage
17
+ ## Quick Start
14
18
 
15
19
  ```typescript
16
- import { createColumn3DChart, createPRPDChart } from '@rm-graph/core';
20
+ import { createColumn3DChart, createPRPDChart, loadLicense } from '@rm-graph/core';
21
+
22
+ // Load license on app startup (optional - removes watermark)
23
+ await loadLicense();
17
24
 
18
25
  // Create a 3D column chart
19
26
  const chart = await createColumn3DChart('container-id', {
@@ -24,7 +31,7 @@ const chart = await createColumn3DChart('container-id', {
24
31
  zAxisTitle: 'Cycle',
25
32
  });
26
33
 
27
- // Update data
34
+ // Update data dynamically
28
35
  chart.setData([[50, 1600, 1], [95, 2300, 2]]);
29
36
 
30
37
  // Change theme
@@ -34,26 +41,553 @@ chart.setOptions({ theme: 'light' });
34
41
  chart.destroy();
35
42
  ```
36
43
 
44
+ ---
45
+
37
46
  ## Chart Types
38
47
 
39
- - `createColumn3DChart` - 3D column charts for phase-resolved data
40
- - `createPRPDChart` - Phase Resolved Partial Discharge heatmaps
41
- - `createSurface3DChart` - 3D surface visualization
48
+ ### Column3DChart
49
+
50
+ 3D column/bar charts for phase-resolved data visualization.
51
+
52
+ ```typescript
53
+ import { createColumn3DChart, type Column3DDataPoint } from '@rm-graph/core';
54
+
55
+ // Data format: [phaseAngle, amplitude, cycle][]
56
+ const data: Column3DDataPoint[] = [
57
+ [45, 1500, 1], // 45° phase, 1500mV amplitude, cycle 1
58
+ [90, 2200, 2], // 90° phase, 2200mV amplitude, cycle 2
59
+ [180, 1800, 3], // 180° phase, 1800mV amplitude, cycle 3
60
+ ];
61
+
62
+ const chart = await createColumn3DChart('container', {
63
+ data,
64
+ theme: 'dark',
65
+ xAxisTitle: 'Phase Angle (°)',
66
+ yAxisTitle: 'Amplitude (mVp)',
67
+ zAxisTitle: 'Cycle',
68
+ xRange: { min: 0, max: 360 },
69
+ yRange: { min: 0, max: 5000 },
70
+ zRange: { min: 0, max: 50 },
71
+ barFill: '#52aaf2',
72
+ barOpacity: 0.95,
73
+ showSineWave: true,
74
+ });
75
+ ```
76
+
77
+ ### PRPDChart
78
+
79
+ Phase Resolved Partial Discharge heatmap visualization.
80
+
81
+ ```typescript
82
+ import { createPRPDChart, type PRPDDataPoint } from '@rm-graph/core';
83
+
84
+ // Data format: [phaseAngle, amplitude, count][]
85
+ const data: PRPDDataPoint[] = [
86
+ [45, 1500, 10], // 45° phase, 1500mV amplitude, 10 pulses
87
+ [90, 2200, 25], // 90° phase, 2200mV amplitude, 25 pulses
88
+ [180, -1800, 15], // 180° phase, -1800mV amplitude, 15 pulses
89
+ ];
90
+
91
+ const chart = await createPRPDChart('container', {
92
+ data,
93
+ maxPeak: 5000,
94
+ minPeak: -5000,
95
+ maxPhaseAngle: 360,
96
+ showSineWave: true,
97
+ showColorPalette: true,
98
+ });
99
+ ```
100
+
101
+ ### Surface3DChart
102
+
103
+ 3D surface visualization for continuous data.
104
+
105
+ ```typescript
106
+ import { createSurface3DChart } from '@rm-graph/core';
107
+
108
+ const chart = await createSurface3DChart('container', {
109
+ yValues: surfaceData, // 2D array of height values
110
+ theme: 'dark',
111
+ colorMin: 0,
112
+ colorMax: 100,
113
+ });
114
+ ```
115
+
116
+ ---
42
117
 
43
118
  ## Theming
44
119
 
45
120
  Built-in themes: `light`, `dark`, `modern`, `midnight`
46
121
 
47
122
  ```typescript
48
- import { getThemeManager } from '@rm-graph/core';
123
+ import { getThemeManager, lightTheme, darkTheme } from '@rm-graph/core';
124
+
125
+ // Use built-in theme
126
+ const chart = await createColumn3DChart('container', {
127
+ theme: 'dark',
128
+ // ...
129
+ });
49
130
 
50
131
  // Register custom theme
51
132
  getThemeManager().registerTheme({
52
133
  name: 'custom',
53
134
  backgroundColor: '#1a1a2e',
54
- colorPalette: ['#ff6b6b', '#4ecdc4'],
55
- // ...
135
+ textColor: '#ffffff',
136
+ gridLineColor: '#333366',
137
+ colorPalette: ['#ff6b6b', '#4ecdc4', '#45b7d1'],
56
138
  });
139
+
140
+ // Use custom theme
141
+ chart.setOptions({ theme: 'custom' });
142
+ ```
143
+
144
+ ### Theme Configuration
145
+
146
+ ```typescript
147
+ interface ThemeConfig {
148
+ name: string;
149
+ backgroundColor: string;
150
+ textColor: string;
151
+ gridLineColor: string;
152
+ axisColor: string;
153
+ colorPalette: string[];
154
+ // ... more options
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## 🔑 License Management System
161
+
162
+ The core package includes a complete license management system for SciChart.js with **encrypted storage** support.
163
+
164
+ ### Overview
165
+
166
+ SciChart.js requires a valid license key to remove watermarks from charts. The `@rm-graph/core` package provides:
167
+
168
+ - **Encrypted Storage**: License keys are encrypted before storing in localStorage
169
+ - **Multiple Configuration Methods**: UI component, programmatic, or environment variables
170
+ - **Automatic Loading**: Load license on app startup
171
+ - **Status Tracking**: Check if license is stored and applied
172
+
173
+ ### How Licensing Works Internally
174
+
175
+ ```
176
+ ┌─────────────────────────────────────────────────────────────────┐
177
+ │ LICENSE FLOW DIAGRAM │
178
+ ├─────────────────────────────────────────────────────────────────┤
179
+ │ │
180
+ │ User enters license key │
181
+ │ │ │
182
+ │ ▼ │
183
+ │ ┌─────────────────┐ │
184
+ │ │ validateFormat()│ ──── Invalid ───► Show error message │
185
+ │ └────────┬────────┘ │
186
+ │ │ Valid │
187
+ │ ▼ │
188
+ │ ┌─────────────────────────────────────────┐ │
189
+ │ │ encryptLicense(key, passphrase) │ │
190
+ │ │ - Uses AES-256-GCM (Web Crypto API) │ │
191
+ │ │ - Falls back to Base64 if no HTTPS │ │
192
+ │ └────────┬────────────────────────────────┘ │
193
+ │ │ │
194
+ │ ▼ │
195
+ │ ┌─────────────────────────────────────────┐ │
196
+ │ │ localStorage.setItem( │ │
197
+ │ │ 'RMGRAPH_LICENSE_DATA', │ │
198
+ │ │ encryptedData │ │
199
+ │ │ ) │ │
200
+ │ └────────┬────────────────────────────────┘ │
201
+ │ │ │
202
+ │ ▼ │
203
+ │ ┌─────────────────────────────────────────┐ │
204
+ │ │ SciChartSurface.setRuntimeLicenseKey() │ │
205
+ │ │ - Applies license to SciChart │ │
206
+ │ │ - Removes watermark from charts │ │
207
+ │ └─────────────────────────────────────────┘ │
208
+ │ │
209
+ └─────────────────────────────────────────────────────────────────┘
210
+ ```
211
+
212
+ ### Encryption Details
213
+
214
+ The license system uses **two-tier encryption**:
215
+
216
+ #### Primary: AES-256-GCM (Secure Contexts)
217
+
218
+ When Web Crypto API is available (HTTPS or localhost):
219
+
220
+ ```typescript
221
+ // Encryption process:
222
+ 1. Derive key from passphrase using PBKDF2 (100,000 iterations, SHA-256)
223
+ 2. Generate random 12-byte IV (Initialization Vector)
224
+ 3. Encrypt license key using AES-256-GCM
225
+ 4. Combine IV + encrypted data
226
+ 5. Encode as Base64 for storage
227
+
228
+ // Storage format in localStorage:
229
+ "RMGRAPH_LICENSE_DATA": "base64(IV + AES-GCM-encrypted-data)"
230
+ ```
231
+
232
+ #### Fallback: Base64 Obfuscation (Insecure Contexts)
233
+
234
+ When Web Crypto API is NOT available (HTTP over IP):
235
+
236
+ ```typescript
237
+ // Simple obfuscation:
238
+ 1. Prepend "rmgraph:" prefix
239
+ 2. Encode as Base64
240
+
241
+ // Storage format:
242
+ "RMGRAPH_LICENSE_DATA": "base64('rmgraph:' + licenseKey)"
243
+ ```
244
+
245
+ > **Security Note**: Base64 is NOT encryption - it only provides basic obfuscation. For production, always use HTTPS and combine with SciChart's domain-locking.
246
+
247
+ ### License Management API
248
+
249
+ #### Core Functions
250
+
251
+ ```typescript
252
+ import {
253
+ // High-level operations
254
+ setLicense, // Encrypt, store, and apply license
255
+ loadLicense, // Load from storage and apply
256
+ removeLicense, // Remove stored license
257
+ applyLicenseKey, // Apply directly without storing
258
+
259
+ // Status checks
260
+ hasStoredLicense, // Check if license exists in storage
261
+ isLicenseApplied, // Check if license is active in session
262
+ getLicenseStatus, // Get full status object
263
+ validateLicenseFormat, // Validate key format (basic)
264
+
265
+ // Configuration
266
+ configureLicenseEncryption, // Set custom passphrase
267
+
268
+ // Low-level crypto (advanced)
269
+ encryptLicense,
270
+ decryptLicense,
271
+ saveEncryptedLicense,
272
+ loadEncryptedLicense,
273
+ clearStoredLicense,
274
+ getLicenseStorageKey,
275
+
276
+ // Types
277
+ type LicenseConfig,
278
+ type LicenseStatus,
279
+ } from '@rm-graph/core';
280
+ ```
281
+
282
+ #### Function Reference
283
+
284
+ ##### `setLicense(licenseKey: string): Promise<boolean>`
285
+
286
+ Encrypts and stores a license key, then applies it to SciChart.
287
+
288
+ ```typescript
289
+ const success = await setLicense('your-scichart-license-key');
290
+ if (success) {
291
+ console.log('License saved and applied!');
292
+ } else {
293
+ console.log('Failed to save license');
294
+ }
295
+ ```
296
+
297
+ ##### `loadLicense(): Promise<boolean>`
298
+
299
+ Loads license from encrypted storage and applies to SciChart.
300
+
301
+ ```typescript
302
+ // Call on app startup
303
+ const loaded = await loadLicense();
304
+ if (loaded) {
305
+ console.log('License loaded from storage');
306
+ } else {
307
+ console.log('No license found - charts will show watermark');
308
+ }
309
+ ```
310
+
311
+ ##### `removeLicense(): void`
312
+
313
+ Removes the stored license from localStorage.
314
+
315
+ ```typescript
316
+ removeLicense();
317
+ // Note: Page reload required to remove license from SciChart
318
+ ```
319
+
320
+ ##### `hasStoredLicense(): boolean`
321
+
322
+ Checks if a license exists in localStorage (without decrypting).
323
+
324
+ ```typescript
325
+ if (hasStoredLicense()) {
326
+ console.log('License found in storage');
327
+ }
328
+ ```
329
+
330
+ ##### `isLicenseApplied(): boolean`
331
+
332
+ Checks if a license has been applied to SciChart in the current session.
333
+
334
+ ```typescript
335
+ if (isLicenseApplied()) {
336
+ console.log('License is active');
337
+ }
57
338
  ```
58
339
 
59
- See main README for full documentation.
340
+ ##### `getLicenseStatus(): LicenseStatus`
341
+
342
+ Returns complete license status.
343
+
344
+ ```typescript
345
+ const status = getLicenseStatus();
346
+ // { hasLicense: true, isApplied: true }
347
+ ```
348
+
349
+ ##### `validateLicenseFormat(licenseKey: string): boolean`
350
+
351
+ Basic format validation (length check only - doesn't verify with SciChart).
352
+
353
+ ```typescript
354
+ if (validateLicenseFormat(userInput)) {
355
+ await setLicense(userInput);
356
+ }
357
+ ```
358
+
359
+ ##### `configureLicenseEncryption(config: LicenseConfig): void`
360
+
361
+ Configure custom passphrase for encryption (optional).
362
+
363
+ ```typescript
364
+ // Call before setLicense/loadLicense if using custom passphrase
365
+ configureLicenseEncryption({
366
+ passphrase: 'my-app-secret-key'
367
+ });
368
+ ```
369
+
370
+ ### Usage Examples
371
+
372
+ #### Example 1: Basic Setup
373
+
374
+ ```typescript
375
+ import { loadLicense, createColumn3DChart } from '@rm-graph/core';
376
+
377
+ async function initApp() {
378
+ // Load license on startup
379
+ await loadLicense();
380
+
381
+ // Create charts (will be watermark-free if license is valid)
382
+ const chart = await createColumn3DChart('container', {
383
+ data: myData,
384
+ });
385
+ }
386
+
387
+ initApp();
388
+ ```
389
+
390
+ #### Example 2: Programmatic License Configuration
391
+
392
+ ```typescript
393
+ import { setLicense, loadLicense, hasStoredLicense } from '@rm-graph/core';
394
+
395
+ async function configureLicense(licenseKey: string) {
396
+ // Check if already configured
397
+ if (hasStoredLicense()) {
398
+ console.log('License already stored');
399
+ await loadLicense();
400
+ return;
401
+ }
402
+
403
+ // Save new license
404
+ const success = await setLicense(licenseKey);
405
+ if (success) {
406
+ console.log('License configured successfully');
407
+ }
408
+ }
409
+ ```
410
+
411
+ #### Example 3: Environment Variable Setup
412
+
413
+ ```typescript
414
+ import { setupSciChartLicense } from '@rm-graph/core';
415
+
416
+ // .env file:
417
+ // VITE_SCICHART_LICENSE_KEY=your-license-key
418
+
419
+ // In main.ts:
420
+ await setupSciChartLicense({
421
+ fromEnv: true, // Check VITE_SCICHART_LICENSE_KEY
422
+ fromLocalStorage: true, // Also check encrypted storage
423
+ });
424
+ ```
425
+
426
+ #### Example 4: Custom Passphrase
427
+
428
+ ```typescript
429
+ import {
430
+ configureLicenseEncryption,
431
+ setLicense,
432
+ loadLicense
433
+ } from '@rm-graph/core';
434
+
435
+ // Use custom passphrase for extra security
436
+ configureLicenseEncryption({
437
+ passphrase: 'my-unique-app-identifier-2024'
438
+ });
439
+
440
+ // Now save/load will use this passphrase
441
+ await setLicense('your-license-key');
442
+ await loadLicense();
443
+ ```
444
+
445
+ ### Types
446
+
447
+ ```typescript
448
+ interface LicenseConfig {
449
+ /** Custom passphrase for encryption/decryption */
450
+ passphrase?: string;
451
+ }
452
+
453
+ interface LicenseStatus {
454
+ /** Whether a license is stored in localStorage */
455
+ hasLicense: boolean;
456
+ /** Whether the license was successfully applied to SciChart */
457
+ isApplied: boolean;
458
+ /** Error message if license operation failed */
459
+ error?: string;
460
+ }
461
+ ```
462
+
463
+ ### Storage Details
464
+
465
+ | Key | Value | Description |
466
+ |-----|-------|-------------|
467
+ | `RMGRAPH_LICENSE_DATA` | Base64 encoded encrypted data | Encrypted license key |
468
+
469
+ ### Security Considerations
470
+
471
+ 1. **Client-Side Encryption**: The encryption happens in the browser. While AES-256-GCM is strong, the decryption key (passphrase) is in the client code.
472
+
473
+ 2. **Domain Locking**: For production security, always use SciChart's domain-locking feature. Register your domains at [SciChart License Portal](https://www.scichart.com/licensing-scichart-js/).
474
+
475
+ 3. **HTTPS Required**: Full AES encryption requires HTTPS or localhost. HTTP over IP will use Base64 fallback.
476
+
477
+ 4. **Don't Commit Keys**: Never commit license keys to source control. Use environment variables.
478
+
479
+ ---
480
+
481
+ ## Utilities
482
+
483
+ ```typescript
484
+ import {
485
+ generateId, // Generate unique IDs
486
+ parseSize, // Parse CSS size values
487
+ deepMerge, // Deep merge objects
488
+ debounce, // Debounce function calls
489
+ throttle, // Throttle function calls
490
+ hexToRgba, // Convert hex to RGBA
491
+ formatNumber, // Format numbers
492
+ clamp, // Clamp value to range
493
+ lerp, // Linear interpolation
494
+ } from '@rm-graph/core';
495
+ ```
496
+
497
+ ---
498
+
499
+ ## WebAssembly Configuration
500
+
501
+ SciChart uses WebAssembly for high performance. The package auto-configures to use CDN:
502
+
503
+ ```typescript
504
+ import { configureSciChart } from '@rm-graph/core';
505
+
506
+ // Default: Uses CDN (auto-configured)
507
+
508
+ // Custom WASM location:
509
+ configureSciChart({
510
+ wasmUrl: '/path/to/scichart2d.wasm'
511
+ });
512
+ ```
513
+
514
+ ---
515
+
516
+ ## Framework Integrations
517
+
518
+ This core package is framework-agnostic. For framework-specific components:
519
+
520
+ - **React**: `@rm-graph/react` - React components and hooks
521
+ - **Angular**: `@rm-graph/angular` - Angular components
522
+
523
+ Both packages re-export all core functionality plus framework-specific UI components like `LicenseManager`.
524
+
525
+ ---
526
+
527
+ ## API Reference
528
+
529
+ ### Chart Factory Functions
530
+
531
+ | Function | Description |
532
+ |----------|-------------|
533
+ | `createColumn3DChart(container, config)` | Create 3D column chart |
534
+ | `createPRPDChart(container, config)` | Create PRPD heatmap |
535
+ | `createSurface3DChart(container, config)` | Create 3D surface |
536
+
537
+ ### Chart Instance Methods
538
+
539
+ | Method | Description |
540
+ |--------|-------------|
541
+ | `setData(data)` | Update chart data |
542
+ | `setOptions(options)` | Update chart options |
543
+ | `destroy()` | Cleanup and remove chart |
544
+
545
+ ### Theme Functions
546
+
547
+ | Function | Description |
548
+ |----------|-------------|
549
+ | `getThemeManager()` | Get theme manager instance |
550
+ | `lightTheme` | Built-in light theme |
551
+ | `darkTheme` | Built-in dark theme |
552
+ | `modernTheme` | Built-in modern theme |
553
+ | `midnightTheme` | Built-in midnight theme |
554
+
555
+ ### License Functions
556
+
557
+ | Function | Description |
558
+ |----------|-------------|
559
+ | `setLicense(key)` | Save and apply license |
560
+ | `loadLicense()` | Load license from storage |
561
+ | `removeLicense()` | Remove stored license |
562
+ | `hasStoredLicense()` | Check if license exists |
563
+ | `isLicenseApplied()` | Check if license is active |
564
+ | `getLicenseStatus()` | Get full status |
565
+
566
+ ---
567
+
568
+ ## Troubleshooting
569
+
570
+ ### Charts show watermark
571
+
572
+ 1. Verify license is loaded: `console.log(getLicenseStatus())`
573
+ 2. Check browser console for license errors
574
+ 3. Ensure domain is registered in SciChart portal
575
+ 4. Try reloading page after setting license
576
+
577
+ ### Crypto errors on HTTP
578
+
579
+ Web Crypto API requires secure context (HTTPS or localhost). The system will fallback to Base64 encoding automatically.
580
+
581
+ ### License not persisting
582
+
583
+ Check if localStorage is available and not blocked by browser settings.
584
+
585
+ ---
586
+
587
+ ## License
588
+
589
+ MIT
590
+
591
+ ---
592
+
593
+ See framework-specific packages for UI components and additional documentation.
@@ -6,7 +6,28 @@ import { SciChartSurface } from 'scichart';
6
6
  var ALGORITHM = "AES-GCM";
7
7
  var KEY_LENGTH = 256;
8
8
  var STORAGE_KEY = "RMGRAPH_LICENSE_DATA";
9
+ function isCryptoAvailable() {
10
+ return typeof window !== "undefined" && typeof crypto !== "undefined" && crypto.subtle !== void 0;
11
+ }
12
+ function simpleEncode(data) {
13
+ const obfuscated = `rmgraph:${data}`;
14
+ return btoa(obfuscated);
15
+ }
16
+ function simpleDecode(encoded) {
17
+ try {
18
+ const decoded = atob(encoded);
19
+ if (decoded.startsWith("rmgraph:")) {
20
+ return decoded.substring(8);
21
+ }
22
+ return null;
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
9
27
  async function deriveKey(passphrase) {
28
+ if (!isCryptoAvailable()) {
29
+ throw new Error("Web Crypto API is not available. Requires HTTPS or localhost.");
30
+ }
10
31
  const encoder = new TextEncoder();
11
32
  const keyMaterial = await crypto.subtle.importKey(
12
33
  "raw",
@@ -30,6 +51,9 @@ async function deriveKey(passphrase) {
30
51
  );
31
52
  }
32
53
  async function encryptLicense(licenseKey, passphrase) {
54
+ if (!isCryptoAvailable()) {
55
+ return simpleEncode(licenseKey);
56
+ }
33
57
  const key = await deriveKey(passphrase);
34
58
  const encoder = new TextEncoder();
35
59
  const iv = crypto.getRandomValues(new Uint8Array(12));
@@ -45,6 +69,13 @@ async function encryptLicense(licenseKey, passphrase) {
45
69
  }
46
70
  async function decryptLicense(encryptedData, passphrase) {
47
71
  try {
72
+ const simpleDecoded = simpleDecode(encryptedData);
73
+ if (simpleDecoded !== null) {
74
+ return simpleDecoded;
75
+ }
76
+ if (!isCryptoAvailable()) {
77
+ return null;
78
+ }
48
79
  const key = await deriveKey(passphrase);
49
80
  const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));
50
81
  const iv = combined.slice(0, 12);
@@ -164,5 +195,5 @@ function validateLicenseFormat(licenseKey) {
164
195
  }
165
196
 
166
197
  export { applyLicenseKey, clearStoredLicense, configureLicenseEncryption, decryptLicense, encryptLicense, getCurrentPassphrase, getLicenseStatus, getLicenseStorageKey, hasEncryptedLicense, hasStoredLicense, isLicenseApplied, loadEncryptedLicense, loadLicense, removeLicense, resetPassphrase, saveEncryptedLicense, setLicense, validateLicenseFormat };
167
- //# sourceMappingURL=chunk-BNXHM7UU.mjs.map
168
- //# sourceMappingURL=chunk-BNXHM7UU.mjs.map
198
+ //# sourceMappingURL=chunk-PKJHVSFI.mjs.map
199
+ //# sourceMappingURL=chunk-PKJHVSFI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/license/crypto.ts","../src/license/index.ts"],"names":[],"mappings":"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","file":"chunk-PKJHVSFI.mjs","sourcesContent":["/**\r\n * Generic encryption/decryption utilities using Web Crypto API\r\n * Provides obfuscation for license keys stored in localStorage\r\n * \r\n * Note: This provides obfuscation, not true security.\r\n * The decryption key is in client code, so determined attackers can still decrypt.\r\n * For production, combine with SciChart's domain-locking for real protection.\r\n */\r\n\r\nconst ALGORITHM = 'AES-GCM';\r\nconst KEY_LENGTH = 256;\r\nconst STORAGE_KEY = 'RMGRAPH_LICENSE_DATA';\r\n\r\n/**\r\n * Check if Web Crypto API is available\r\n * Web Crypto API requires HTTPS or localhost (secure context)\r\n */\r\nfunction isCryptoAvailable(): boolean {\r\n return (\r\n typeof window !== 'undefined' &&\r\n typeof crypto !== 'undefined' &&\r\n crypto.subtle !== undefined\r\n );\r\n}\r\n\r\n/**\r\n * Simple base64 encoding fallback when Web Crypto is not available\r\n * This provides basic obfuscation (not encryption)\r\n */\r\nfunction simpleEncode(data: string): string {\r\n // Add a simple obfuscation prefix to distinguish from plain text\r\n const obfuscated = `rmgraph:${data}`;\r\n return btoa(obfuscated);\r\n}\r\n\r\n/**\r\n * Simple base64 decoding fallback\r\n */\r\nfunction simpleDecode(encoded: string): string | null {\r\n try {\r\n const decoded = atob(encoded);\r\n if (decoded.startsWith('rmgraph:')) {\r\n return decoded.substring(8); // Remove prefix\r\n }\r\n return null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Derive a consistent cryptographic key from a passphrase\r\n */\r\nasync function deriveKey(passphrase: string): Promise<CryptoKey> {\r\n if (!isCryptoAvailable()) {\r\n throw new Error('Web Crypto API is not available. Requires HTTPS or localhost.');\r\n }\r\n\r\n const encoder = new TextEncoder();\r\n const keyMaterial = await crypto.subtle!.importKey(\r\n 'raw',\r\n encoder.encode(passphrase),\r\n 'PBKDF2',\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n // Use a fixed salt for consistency across encrypt/decrypt\r\n const salt = encoder.encode('rmgraph-license-salt-v1');\r\n\r\n return crypto.subtle!.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt,\r\n iterations: 100000,\r\n hash: 'SHA-256',\r\n },\r\n keyMaterial,\r\n { name: ALGORITHM, length: KEY_LENGTH },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n}\r\n\r\n/**\r\n * Encrypt a license key string\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase to derive encryption key from\r\n * @returns Base64 encoded encrypted data\r\n */\r\nexport async function encryptLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<string> {\r\n // Fallback to simple encoding if Web Crypto is not available\r\n if (!isCryptoAvailable()) {\r\n return simpleEncode(licenseKey);\r\n }\r\n\r\n const key = await deriveKey(passphrase);\r\n const encoder = new TextEncoder();\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n\r\n const encrypted = await crypto.subtle!.encrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n encoder.encode(licenseKey)\r\n );\r\n\r\n // Combine IV + encrypted data and encode as base64\r\n const combined = new Uint8Array(iv.length + encrypted.byteLength);\r\n combined.set(iv);\r\n combined.set(new Uint8Array(encrypted), iv.length);\r\n\r\n return btoa(String.fromCharCode(...combined));\r\n}\r\n\r\n/**\r\n * Decrypt an encrypted license key\r\n * @param encryptedData - Base64 encoded encrypted data\r\n * @param passphrase - The passphrase to derive decryption key from\r\n * @returns The decrypted license key or null if decryption fails\r\n */\r\nexport async function decryptLicense(\r\n encryptedData: string,\r\n passphrase: string\r\n): Promise<string | null> {\r\n try {\r\n // Try simple decode first (for fallback encoding)\r\n const simpleDecoded = simpleDecode(encryptedData);\r\n if (simpleDecoded !== null) {\r\n return simpleDecoded;\r\n }\r\n\r\n // If Web Crypto is not available, we can't decrypt AES-encrypted data\r\n if (!isCryptoAvailable()) {\r\n return null;\r\n }\r\n\r\n // Try AES decryption\r\n const key = await deriveKey(passphrase);\r\n const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));\r\n\r\n const iv = combined.slice(0, 12);\r\n const data = combined.slice(12);\r\n\r\n const decrypted = await crypto.subtle!.decrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n data\r\n );\r\n\r\n return new TextDecoder().decode(decrypted);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Save encrypted license to localStorage\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase for encryption\r\n */\r\nexport async function saveEncryptedLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<void> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n throw new Error('localStorage is not available');\r\n }\r\n const encrypted = await encryptLicense(licenseKey, passphrase);\r\n localStorage.setItem(STORAGE_KEY, encrypted);\r\n}\r\n\r\n/**\r\n * Load and decrypt license from localStorage\r\n * @param passphrase - The passphrase for decryption\r\n * @returns The decrypted license key or null if not found/decryption fails\r\n */\r\nexport async function loadEncryptedLicense(\r\n passphrase: string\r\n): Promise<string | null> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return null;\r\n }\r\n const encrypted = localStorage.getItem(STORAGE_KEY);\r\n if (!encrypted) return null;\r\n return decryptLicense(encrypted, passphrase);\r\n}\r\n\r\n/**\r\n * Check if an encrypted license exists in localStorage\r\n */\r\nexport function hasEncryptedLicense(): boolean {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return false;\r\n }\r\n return localStorage.getItem(STORAGE_KEY) !== null;\r\n}\r\n\r\n/**\r\n * Clear stored license from localStorage\r\n */\r\nexport function clearStoredLicense(): void {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return;\r\n }\r\n localStorage.removeItem(STORAGE_KEY);\r\n}\r\n\r\n/**\r\n * Get the storage key used for license data\r\n */\r\nexport function getLicenseStorageKey(): string {\r\n return STORAGE_KEY;\r\n}\r\n","/**\r\n * License management module for @rm-graph packages\r\n * \r\n * Provides encrypted storage and retrieval of SciChart license keys.\r\n * License keys are encrypted using AES-256-GCM before storing in localStorage.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { setLicense, loadLicense, configureLicenseEncryption } from '@rm-graph/core';\r\n * \r\n * // Optional: Configure custom passphrase\r\n * configureLicenseEncryption({ passphrase: 'your-app-secret' });\r\n * \r\n * // Save a license (encrypts and stores in localStorage)\r\n * await setLicense('your-scichart-license-key');\r\n * \r\n * // Load license on app startup\r\n * await loadLicense();\r\n * ```\r\n */\r\n\r\nimport { SciChartSurface } from 'scichart';\r\nimport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n} from './crypto';\r\n\r\n// Re-export crypto utilities for advanced usage\r\nexport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n};\r\n\r\n/**\r\n * Configuration options for license encryption\r\n */\r\nexport interface LicenseConfig {\r\n /** Custom passphrase for encryption/decryption (optional) */\r\n passphrase?: string;\r\n}\r\n\r\n/**\r\n * License status information\r\n */\r\nexport interface LicenseStatus {\r\n /** Whether a license is stored */\r\n hasLicense: boolean;\r\n /** Whether the license was successfully loaded and applied */\r\n isApplied: boolean;\r\n /** Error message if any */\r\n error?: string;\r\n}\r\n\r\n// Default passphrase (can be overridden by the application)\r\nconst DEFAULT_PASSPHRASE = 'rmgraph-default-key-2024';\r\n\r\n// Current passphrase (mutable)\r\nlet currentPassphrase = DEFAULT_PASSPHRASE;\r\n\r\n// Track if license has been applied\r\nlet licenseApplied = false;\r\n\r\n/**\r\n * Configure the license encryption passphrase\r\n * Call this before saving or loading licenses if you want to use a custom passphrase\r\n * \r\n * @param config - Configuration options\r\n * \r\n * @example\r\n * ```typescript\r\n * configureLicenseEncryption({ passphrase: 'my-app-secret-key' });\r\n * ```\r\n */\r\nexport function configureLicenseEncryption(config: LicenseConfig): void {\r\n if (config.passphrase) {\r\n currentPassphrase = config.passphrase;\r\n }\r\n}\r\n\r\n/**\r\n * Get the current passphrase (for internal use)\r\n */\r\nexport function getCurrentPassphrase(): string {\r\n return currentPassphrase;\r\n}\r\n\r\n/**\r\n * Reset passphrase to default\r\n */\r\nexport function resetPassphrase(): void {\r\n currentPassphrase = DEFAULT_PASSPHRASE;\r\n}\r\n\r\n/**\r\n * Save and apply a SciChart license key\r\n * Encrypts the key and stores it in localStorage, then applies it to SciChart\r\n * \r\n * @param licenseKey - The SciChart license key to save\r\n * @returns Promise resolving to true if successful, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * const success = await setLicense('your-scichart-license-key');\r\n * if (success) {\r\n * console.log('License saved and applied!');\r\n * }\r\n * ```\r\n */\r\nexport async function setLicense(licenseKey: string): Promise<boolean> {\r\n try {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n throw new Error('Invalid license key');\r\n }\r\n\r\n // Save encrypted to localStorage\r\n await saveEncryptedLicense(licenseKey.trim(), currentPassphrase);\r\n\r\n // Apply to SciChart\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to set license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Load license from localStorage and apply to SciChart\r\n * \r\n * @returns Promise resolving to true if license was found and applied, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * // Call on app startup\r\n * const loaded = await loadLicense();\r\n * if (loaded) {\r\n * console.log('License loaded from storage');\r\n * } else {\r\n * console.log('No license found - charts will show watermark');\r\n * }\r\n * ```\r\n */\r\nexport async function loadLicense(): Promise<boolean> {\r\n try {\r\n const licenseKey = await loadEncryptedLicense(currentPassphrase);\r\n\r\n if (licenseKey) {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey);\r\n licenseApplied = true;\r\n return true;\r\n }\r\n\r\n return false;\r\n } catch (error) {\r\n console.error('Failed to load license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a license is stored in localStorage\r\n * \r\n * @returns true if a license exists in storage\r\n */\r\nexport function hasStoredLicense(): boolean {\r\n return hasEncryptedLicense();\r\n}\r\n\r\n/**\r\n * Check if a license has been applied to SciChart in this session\r\n * \r\n * @returns true if a license has been applied\r\n */\r\nexport function isLicenseApplied(): boolean {\r\n return licenseApplied;\r\n}\r\n\r\n/**\r\n * Remove stored license from localStorage\r\n * Note: This doesn't remove the license from SciChart (requires page reload)\r\n */\r\nexport function removeLicense(): void {\r\n clearStoredLicense();\r\n licenseApplied = false;\r\n}\r\n\r\n/**\r\n * Apply a license key directly without storing it\r\n * Useful for temporary/session-only license application\r\n * \r\n * @param licenseKey - The SciChart license key\r\n */\r\nexport function applyLicenseKey(licenseKey: string): void {\r\n if (licenseKey && typeof licenseKey === 'string') {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n }\r\n}\r\n\r\n/**\r\n * Get current license status\r\n * \r\n * @returns License status information\r\n */\r\nexport function getLicenseStatus(): LicenseStatus {\r\n return {\r\n hasLicense: hasStoredLicense(),\r\n isApplied: licenseApplied,\r\n };\r\n}\r\n\r\n/**\r\n * Validate a license key format (basic validation)\r\n * Note: This doesn't validate if the license is actually valid with SciChart\r\n * \r\n * @param licenseKey - The license key to validate\r\n * @returns true if the format appears valid\r\n */\r\nexport function validateLicenseFormat(licenseKey: string): boolean {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n return false;\r\n }\r\n \r\n const trimmed = licenseKey.trim();\r\n \r\n // Basic validation: must be non-empty and have reasonable length\r\n return trimmed.length >= 10 && trimmed.length <= 5000;\r\n}\r\n"]}
@@ -8,7 +8,28 @@ var scichart = require('scichart');
8
8
  var ALGORITHM = "AES-GCM";
9
9
  var KEY_LENGTH = 256;
10
10
  var STORAGE_KEY = "RMGRAPH_LICENSE_DATA";
11
+ function isCryptoAvailable() {
12
+ return typeof window !== "undefined" && typeof crypto !== "undefined" && crypto.subtle !== void 0;
13
+ }
14
+ function simpleEncode(data) {
15
+ const obfuscated = `rmgraph:${data}`;
16
+ return btoa(obfuscated);
17
+ }
18
+ function simpleDecode(encoded) {
19
+ try {
20
+ const decoded = atob(encoded);
21
+ if (decoded.startsWith("rmgraph:")) {
22
+ return decoded.substring(8);
23
+ }
24
+ return null;
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
11
29
  async function deriveKey(passphrase) {
30
+ if (!isCryptoAvailable()) {
31
+ throw new Error("Web Crypto API is not available. Requires HTTPS or localhost.");
32
+ }
12
33
  const encoder = new TextEncoder();
13
34
  const keyMaterial = await crypto.subtle.importKey(
14
35
  "raw",
@@ -32,6 +53,9 @@ async function deriveKey(passphrase) {
32
53
  );
33
54
  }
34
55
  async function encryptLicense(licenseKey, passphrase) {
56
+ if (!isCryptoAvailable()) {
57
+ return simpleEncode(licenseKey);
58
+ }
35
59
  const key = await deriveKey(passphrase);
36
60
  const encoder = new TextEncoder();
37
61
  const iv = crypto.getRandomValues(new Uint8Array(12));
@@ -47,6 +71,13 @@ async function encryptLicense(licenseKey, passphrase) {
47
71
  }
48
72
  async function decryptLicense(encryptedData, passphrase) {
49
73
  try {
74
+ const simpleDecoded = simpleDecode(encryptedData);
75
+ if (simpleDecoded !== null) {
76
+ return simpleDecoded;
77
+ }
78
+ if (!isCryptoAvailable()) {
79
+ return null;
80
+ }
50
81
  const key = await deriveKey(passphrase);
51
82
  const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));
52
83
  const iv = combined.slice(0, 12);
@@ -183,5 +214,5 @@ exports.resetPassphrase = resetPassphrase;
183
214
  exports.saveEncryptedLicense = saveEncryptedLicense;
184
215
  exports.setLicense = setLicense;
185
216
  exports.validateLicenseFormat = validateLicenseFormat;
186
- //# sourceMappingURL=chunk-QFDC4NU3.js.map
187
- //# sourceMappingURL=chunk-QFDC4NU3.js.map
217
+ //# sourceMappingURL=chunk-RLQMHQEV.js.map
218
+ //# sourceMappingURL=chunk-RLQMHQEV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/license/crypto.ts","../src/license/index.ts"],"names":["SciChartSurface"],"mappings":"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","file":"chunk-RLQMHQEV.js","sourcesContent":["/**\r\n * Generic encryption/decryption utilities using Web Crypto API\r\n * Provides obfuscation for license keys stored in localStorage\r\n * \r\n * Note: This provides obfuscation, not true security.\r\n * The decryption key is in client code, so determined attackers can still decrypt.\r\n * For production, combine with SciChart's domain-locking for real protection.\r\n */\r\n\r\nconst ALGORITHM = 'AES-GCM';\r\nconst KEY_LENGTH = 256;\r\nconst STORAGE_KEY = 'RMGRAPH_LICENSE_DATA';\r\n\r\n/**\r\n * Check if Web Crypto API is available\r\n * Web Crypto API requires HTTPS or localhost (secure context)\r\n */\r\nfunction isCryptoAvailable(): boolean {\r\n return (\r\n typeof window !== 'undefined' &&\r\n typeof crypto !== 'undefined' &&\r\n crypto.subtle !== undefined\r\n );\r\n}\r\n\r\n/**\r\n * Simple base64 encoding fallback when Web Crypto is not available\r\n * This provides basic obfuscation (not encryption)\r\n */\r\nfunction simpleEncode(data: string): string {\r\n // Add a simple obfuscation prefix to distinguish from plain text\r\n const obfuscated = `rmgraph:${data}`;\r\n return btoa(obfuscated);\r\n}\r\n\r\n/**\r\n * Simple base64 decoding fallback\r\n */\r\nfunction simpleDecode(encoded: string): string | null {\r\n try {\r\n const decoded = atob(encoded);\r\n if (decoded.startsWith('rmgraph:')) {\r\n return decoded.substring(8); // Remove prefix\r\n }\r\n return null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Derive a consistent cryptographic key from a passphrase\r\n */\r\nasync function deriveKey(passphrase: string): Promise<CryptoKey> {\r\n if (!isCryptoAvailable()) {\r\n throw new Error('Web Crypto API is not available. Requires HTTPS or localhost.');\r\n }\r\n\r\n const encoder = new TextEncoder();\r\n const keyMaterial = await crypto.subtle!.importKey(\r\n 'raw',\r\n encoder.encode(passphrase),\r\n 'PBKDF2',\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n // Use a fixed salt for consistency across encrypt/decrypt\r\n const salt = encoder.encode('rmgraph-license-salt-v1');\r\n\r\n return crypto.subtle!.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt,\r\n iterations: 100000,\r\n hash: 'SHA-256',\r\n },\r\n keyMaterial,\r\n { name: ALGORITHM, length: KEY_LENGTH },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n}\r\n\r\n/**\r\n * Encrypt a license key string\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase to derive encryption key from\r\n * @returns Base64 encoded encrypted data\r\n */\r\nexport async function encryptLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<string> {\r\n // Fallback to simple encoding if Web Crypto is not available\r\n if (!isCryptoAvailable()) {\r\n return simpleEncode(licenseKey);\r\n }\r\n\r\n const key = await deriveKey(passphrase);\r\n const encoder = new TextEncoder();\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n\r\n const encrypted = await crypto.subtle!.encrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n encoder.encode(licenseKey)\r\n );\r\n\r\n // Combine IV + encrypted data and encode as base64\r\n const combined = new Uint8Array(iv.length + encrypted.byteLength);\r\n combined.set(iv);\r\n combined.set(new Uint8Array(encrypted), iv.length);\r\n\r\n return btoa(String.fromCharCode(...combined));\r\n}\r\n\r\n/**\r\n * Decrypt an encrypted license key\r\n * @param encryptedData - Base64 encoded encrypted data\r\n * @param passphrase - The passphrase to derive decryption key from\r\n * @returns The decrypted license key or null if decryption fails\r\n */\r\nexport async function decryptLicense(\r\n encryptedData: string,\r\n passphrase: string\r\n): Promise<string | null> {\r\n try {\r\n // Try simple decode first (for fallback encoding)\r\n const simpleDecoded = simpleDecode(encryptedData);\r\n if (simpleDecoded !== null) {\r\n return simpleDecoded;\r\n }\r\n\r\n // If Web Crypto is not available, we can't decrypt AES-encrypted data\r\n if (!isCryptoAvailable()) {\r\n return null;\r\n }\r\n\r\n // Try AES decryption\r\n const key = await deriveKey(passphrase);\r\n const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));\r\n\r\n const iv = combined.slice(0, 12);\r\n const data = combined.slice(12);\r\n\r\n const decrypted = await crypto.subtle!.decrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n data\r\n );\r\n\r\n return new TextDecoder().decode(decrypted);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Save encrypted license to localStorage\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase for encryption\r\n */\r\nexport async function saveEncryptedLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<void> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n throw new Error('localStorage is not available');\r\n }\r\n const encrypted = await encryptLicense(licenseKey, passphrase);\r\n localStorage.setItem(STORAGE_KEY, encrypted);\r\n}\r\n\r\n/**\r\n * Load and decrypt license from localStorage\r\n * @param passphrase - The passphrase for decryption\r\n * @returns The decrypted license key or null if not found/decryption fails\r\n */\r\nexport async function loadEncryptedLicense(\r\n passphrase: string\r\n): Promise<string | null> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return null;\r\n }\r\n const encrypted = localStorage.getItem(STORAGE_KEY);\r\n if (!encrypted) return null;\r\n return decryptLicense(encrypted, passphrase);\r\n}\r\n\r\n/**\r\n * Check if an encrypted license exists in localStorage\r\n */\r\nexport function hasEncryptedLicense(): boolean {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return false;\r\n }\r\n return localStorage.getItem(STORAGE_KEY) !== null;\r\n}\r\n\r\n/**\r\n * Clear stored license from localStorage\r\n */\r\nexport function clearStoredLicense(): void {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return;\r\n }\r\n localStorage.removeItem(STORAGE_KEY);\r\n}\r\n\r\n/**\r\n * Get the storage key used for license data\r\n */\r\nexport function getLicenseStorageKey(): string {\r\n return STORAGE_KEY;\r\n}\r\n","/**\r\n * License management module for @rm-graph packages\r\n * \r\n * Provides encrypted storage and retrieval of SciChart license keys.\r\n * License keys are encrypted using AES-256-GCM before storing in localStorage.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { setLicense, loadLicense, configureLicenseEncryption } from '@rm-graph/core';\r\n * \r\n * // Optional: Configure custom passphrase\r\n * configureLicenseEncryption({ passphrase: 'your-app-secret' });\r\n * \r\n * // Save a license (encrypts and stores in localStorage)\r\n * await setLicense('your-scichart-license-key');\r\n * \r\n * // Load license on app startup\r\n * await loadLicense();\r\n * ```\r\n */\r\n\r\nimport { SciChartSurface } from 'scichart';\r\nimport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n} from './crypto';\r\n\r\n// Re-export crypto utilities for advanced usage\r\nexport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n};\r\n\r\n/**\r\n * Configuration options for license encryption\r\n */\r\nexport interface LicenseConfig {\r\n /** Custom passphrase for encryption/decryption (optional) */\r\n passphrase?: string;\r\n}\r\n\r\n/**\r\n * License status information\r\n */\r\nexport interface LicenseStatus {\r\n /** Whether a license is stored */\r\n hasLicense: boolean;\r\n /** Whether the license was successfully loaded and applied */\r\n isApplied: boolean;\r\n /** Error message if any */\r\n error?: string;\r\n}\r\n\r\n// Default passphrase (can be overridden by the application)\r\nconst DEFAULT_PASSPHRASE = 'rmgraph-default-key-2024';\r\n\r\n// Current passphrase (mutable)\r\nlet currentPassphrase = DEFAULT_PASSPHRASE;\r\n\r\n// Track if license has been applied\r\nlet licenseApplied = false;\r\n\r\n/**\r\n * Configure the license encryption passphrase\r\n * Call this before saving or loading licenses if you want to use a custom passphrase\r\n * \r\n * @param config - Configuration options\r\n * \r\n * @example\r\n * ```typescript\r\n * configureLicenseEncryption({ passphrase: 'my-app-secret-key' });\r\n * ```\r\n */\r\nexport function configureLicenseEncryption(config: LicenseConfig): void {\r\n if (config.passphrase) {\r\n currentPassphrase = config.passphrase;\r\n }\r\n}\r\n\r\n/**\r\n * Get the current passphrase (for internal use)\r\n */\r\nexport function getCurrentPassphrase(): string {\r\n return currentPassphrase;\r\n}\r\n\r\n/**\r\n * Reset passphrase to default\r\n */\r\nexport function resetPassphrase(): void {\r\n currentPassphrase = DEFAULT_PASSPHRASE;\r\n}\r\n\r\n/**\r\n * Save and apply a SciChart license key\r\n * Encrypts the key and stores it in localStorage, then applies it to SciChart\r\n * \r\n * @param licenseKey - The SciChart license key to save\r\n * @returns Promise resolving to true if successful, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * const success = await setLicense('your-scichart-license-key');\r\n * if (success) {\r\n * console.log('License saved and applied!');\r\n * }\r\n * ```\r\n */\r\nexport async function setLicense(licenseKey: string): Promise<boolean> {\r\n try {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n throw new Error('Invalid license key');\r\n }\r\n\r\n // Save encrypted to localStorage\r\n await saveEncryptedLicense(licenseKey.trim(), currentPassphrase);\r\n\r\n // Apply to SciChart\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to set license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Load license from localStorage and apply to SciChart\r\n * \r\n * @returns Promise resolving to true if license was found and applied, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * // Call on app startup\r\n * const loaded = await loadLicense();\r\n * if (loaded) {\r\n * console.log('License loaded from storage');\r\n * } else {\r\n * console.log('No license found - charts will show watermark');\r\n * }\r\n * ```\r\n */\r\nexport async function loadLicense(): Promise<boolean> {\r\n try {\r\n const licenseKey = await loadEncryptedLicense(currentPassphrase);\r\n\r\n if (licenseKey) {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey);\r\n licenseApplied = true;\r\n return true;\r\n }\r\n\r\n return false;\r\n } catch (error) {\r\n console.error('Failed to load license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a license is stored in localStorage\r\n * \r\n * @returns true if a license exists in storage\r\n */\r\nexport function hasStoredLicense(): boolean {\r\n return hasEncryptedLicense();\r\n}\r\n\r\n/**\r\n * Check if a license has been applied to SciChart in this session\r\n * \r\n * @returns true if a license has been applied\r\n */\r\nexport function isLicenseApplied(): boolean {\r\n return licenseApplied;\r\n}\r\n\r\n/**\r\n * Remove stored license from localStorage\r\n * Note: This doesn't remove the license from SciChart (requires page reload)\r\n */\r\nexport function removeLicense(): void {\r\n clearStoredLicense();\r\n licenseApplied = false;\r\n}\r\n\r\n/**\r\n * Apply a license key directly without storing it\r\n * Useful for temporary/session-only license application\r\n * \r\n * @param licenseKey - The SciChart license key\r\n */\r\nexport function applyLicenseKey(licenseKey: string): void {\r\n if (licenseKey && typeof licenseKey === 'string') {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n }\r\n}\r\n\r\n/**\r\n * Get current license status\r\n * \r\n * @returns License status information\r\n */\r\nexport function getLicenseStatus(): LicenseStatus {\r\n return {\r\n hasLicense: hasStoredLicense(),\r\n isApplied: licenseApplied,\r\n };\r\n}\r\n\r\n/**\r\n * Validate a license key format (basic validation)\r\n * Note: This doesn't validate if the license is actually valid with SciChart\r\n * \r\n * @param licenseKey - The license key to validate\r\n * @returns true if the format appears valid\r\n */\r\nexport function validateLicenseFormat(licenseKey: string): boolean {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n return false;\r\n }\r\n \r\n const trimmed = licenseKey.trim();\r\n \r\n // Basic validation: must be non-empty and have reasonable length\r\n return trimmed.length >= 10 && trimmed.length <= 5000;\r\n}\r\n"]}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunk4JQVY6S5_js = require('./chunk-4JQVY6S5.js');
4
- var chunkQFDC4NU3_js = require('./chunk-QFDC4NU3.js');
4
+ var chunkRLQMHQEV_js = require('./chunk-RLQMHQEV.js');
5
5
  var chunkDGUM43GV_js = require('./chunk-DGUM43GV.js');
6
6
  var scichart = require('scichart');
7
7
  var SciChartJSLightTheme = require('scichart/Charting/Themes/SciChartJSLightTheme');
@@ -1757,7 +1757,7 @@ async function createPRPDChart(container, config) {
1757
1757
  return chart;
1758
1758
  }
1759
1759
  async function setupSciChartLicense(options) {
1760
- const { loadLicense: loadLicense2 } = await import('./license-VBO3ZTOJ.js');
1760
+ const { loadLicense: loadLicense2 } = await import('./license-U7ZNTU6D.js');
1761
1761
  const { SciChartSurface: SciChartSurface4 } = await import('scichart');
1762
1762
  let licenseKey;
1763
1763
  if (options.fromEnv) {
@@ -1841,75 +1841,75 @@ Object.defineProperty(exports, "modernTheme", {
1841
1841
  });
1842
1842
  Object.defineProperty(exports, "applyLicenseKey", {
1843
1843
  enumerable: true,
1844
- get: function () { return chunkQFDC4NU3_js.applyLicenseKey; }
1844
+ get: function () { return chunkRLQMHQEV_js.applyLicenseKey; }
1845
1845
  });
1846
1846
  Object.defineProperty(exports, "clearStoredLicense", {
1847
1847
  enumerable: true,
1848
- get: function () { return chunkQFDC4NU3_js.clearStoredLicense; }
1848
+ get: function () { return chunkRLQMHQEV_js.clearStoredLicense; }
1849
1849
  });
1850
1850
  Object.defineProperty(exports, "configureLicenseEncryption", {
1851
1851
  enumerable: true,
1852
- get: function () { return chunkQFDC4NU3_js.configureLicenseEncryption; }
1852
+ get: function () { return chunkRLQMHQEV_js.configureLicenseEncryption; }
1853
1853
  });
1854
1854
  Object.defineProperty(exports, "decryptLicense", {
1855
1855
  enumerable: true,
1856
- get: function () { return chunkQFDC4NU3_js.decryptLicense; }
1856
+ get: function () { return chunkRLQMHQEV_js.decryptLicense; }
1857
1857
  });
1858
1858
  Object.defineProperty(exports, "encryptLicense", {
1859
1859
  enumerable: true,
1860
- get: function () { return chunkQFDC4NU3_js.encryptLicense; }
1860
+ get: function () { return chunkRLQMHQEV_js.encryptLicense; }
1861
1861
  });
1862
1862
  Object.defineProperty(exports, "getCurrentPassphrase", {
1863
1863
  enumerable: true,
1864
- get: function () { return chunkQFDC4NU3_js.getCurrentPassphrase; }
1864
+ get: function () { return chunkRLQMHQEV_js.getCurrentPassphrase; }
1865
1865
  });
1866
1866
  Object.defineProperty(exports, "getLicenseStatus", {
1867
1867
  enumerable: true,
1868
- get: function () { return chunkQFDC4NU3_js.getLicenseStatus; }
1868
+ get: function () { return chunkRLQMHQEV_js.getLicenseStatus; }
1869
1869
  });
1870
1870
  Object.defineProperty(exports, "getLicenseStorageKey", {
1871
1871
  enumerable: true,
1872
- get: function () { return chunkQFDC4NU3_js.getLicenseStorageKey; }
1872
+ get: function () { return chunkRLQMHQEV_js.getLicenseStorageKey; }
1873
1873
  });
1874
1874
  Object.defineProperty(exports, "hasEncryptedLicense", {
1875
1875
  enumerable: true,
1876
- get: function () { return chunkQFDC4NU3_js.hasEncryptedLicense; }
1876
+ get: function () { return chunkRLQMHQEV_js.hasEncryptedLicense; }
1877
1877
  });
1878
1878
  Object.defineProperty(exports, "hasStoredLicense", {
1879
1879
  enumerable: true,
1880
- get: function () { return chunkQFDC4NU3_js.hasStoredLicense; }
1880
+ get: function () { return chunkRLQMHQEV_js.hasStoredLicense; }
1881
1881
  });
1882
1882
  Object.defineProperty(exports, "isLicenseApplied", {
1883
1883
  enumerable: true,
1884
- get: function () { return chunkQFDC4NU3_js.isLicenseApplied; }
1884
+ get: function () { return chunkRLQMHQEV_js.isLicenseApplied; }
1885
1885
  });
1886
1886
  Object.defineProperty(exports, "loadEncryptedLicense", {
1887
1887
  enumerable: true,
1888
- get: function () { return chunkQFDC4NU3_js.loadEncryptedLicense; }
1888
+ get: function () { return chunkRLQMHQEV_js.loadEncryptedLicense; }
1889
1889
  });
1890
1890
  Object.defineProperty(exports, "loadLicense", {
1891
1891
  enumerable: true,
1892
- get: function () { return chunkQFDC4NU3_js.loadLicense; }
1892
+ get: function () { return chunkRLQMHQEV_js.loadLicense; }
1893
1893
  });
1894
1894
  Object.defineProperty(exports, "removeLicense", {
1895
1895
  enumerable: true,
1896
- get: function () { return chunkQFDC4NU3_js.removeLicense; }
1896
+ get: function () { return chunkRLQMHQEV_js.removeLicense; }
1897
1897
  });
1898
1898
  Object.defineProperty(exports, "resetPassphrase", {
1899
1899
  enumerable: true,
1900
- get: function () { return chunkQFDC4NU3_js.resetPassphrase; }
1900
+ get: function () { return chunkRLQMHQEV_js.resetPassphrase; }
1901
1901
  });
1902
1902
  Object.defineProperty(exports, "saveEncryptedLicense", {
1903
1903
  enumerable: true,
1904
- get: function () { return chunkQFDC4NU3_js.saveEncryptedLicense; }
1904
+ get: function () { return chunkRLQMHQEV_js.saveEncryptedLicense; }
1905
1905
  });
1906
1906
  Object.defineProperty(exports, "setLicense", {
1907
1907
  enumerable: true,
1908
- get: function () { return chunkQFDC4NU3_js.setLicense; }
1908
+ get: function () { return chunkRLQMHQEV_js.setLicense; }
1909
1909
  });
1910
1910
  Object.defineProperty(exports, "validateLicenseFormat", {
1911
1911
  enumerable: true,
1912
- get: function () { return chunkQFDC4NU3_js.validateLicenseFormat; }
1912
+ get: function () { return chunkRLQMHQEV_js.validateLicenseFormat; }
1913
1913
  });
1914
1914
  Object.defineProperty(exports, "SciChartSurface", {
1915
1915
  enumerable: true,
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ThemeManager } from './chunk-7GF5X23V.mjs';
2
2
  export { ThemeManager, darkTheme, getThemeManager, lightTheme, midnightTheme, modernTheme } from './chunk-7GF5X23V.mjs';
3
- export { applyLicenseKey, clearStoredLicense, configureLicenseEncryption, decryptLicense, encryptLicense, getCurrentPassphrase, getLicenseStatus, getLicenseStorageKey, hasEncryptedLicense, hasStoredLicense, isLicenseApplied, loadEncryptedLicense, loadLicense, removeLicense, resetPassphrase, saveEncryptedLicense, setLicense, validateLicenseFormat } from './chunk-BNXHM7UU.mjs';
3
+ export { applyLicenseKey, clearStoredLicense, configureLicenseEncryption, decryptLicense, encryptLicense, getCurrentPassphrase, getLicenseStatus, getLicenseStorageKey, hasEncryptedLicense, hasStoredLicense, isLicenseApplied, loadEncryptedLicense, loadLicense, removeLicense, resetPassphrase, saveEncryptedLicense, setLicense, validateLicenseFormat } from './chunk-PKJHVSFI.mjs';
4
4
  import { __require } from './chunk-BJTO5JO5.mjs';
5
5
  import { SciChart3DSurface, NumericAxis3D, MouseWheelZoomModifier3D, OrbitModifier3D, CameraController, Vector3, UniformGridDataSeries3D, GradientColorPalette, SurfaceMeshRenderableSeries3D, EDrawMeshAs, SciChartJSLightTheme, ResetCamera3DModifier, NumberRange, XyzDataSeries3D, ColumnRenderableSeries3D, CylinderPointMarker3D, PointLineRenderableSeries3D, TooltipModifier3D, SciChartSurface, NumericAxis, EAxisAlignment, ENumericFormat, EAutoRange, CursorModifier, RubberBandXyZoomModifier, ZoomExtentsModifier, HeatmapColorMap, UniformHeatmapDataSeries, UniformHeatmapRenderableSeries, XyDataSeries, FastLineRenderableSeries, HeatmapLegend, NumericLabelProvider } from 'scichart';
6
6
  export { SciChartSurface } from 'scichart';
@@ -1756,7 +1756,7 @@ async function createPRPDChart(container, config) {
1756
1756
  return chart;
1757
1757
  }
1758
1758
  async function setupSciChartLicense(options) {
1759
- const { loadLicense: loadLicense2 } = await import('./license-NCCUYGQL.mjs');
1759
+ const { loadLicense: loadLicense2 } = await import('./license-MTK7WNNA.mjs');
1760
1760
  const { SciChartSurface: SciChartSurface4 } = await import('scichart');
1761
1761
  let licenseKey;
1762
1762
  if (options.fromEnv) {
@@ -1,4 +1,4 @@
1
- export { applyLicenseKey, clearStoredLicense, configureLicenseEncryption, decryptLicense, encryptLicense, getCurrentPassphrase, getLicenseStatus, getLicenseStorageKey, hasEncryptedLicense, hasStoredLicense, isLicenseApplied, loadEncryptedLicense, loadLicense, removeLicense, resetPassphrase, saveEncryptedLicense, setLicense, validateLicenseFormat } from './chunk-BNXHM7UU.mjs';
1
+ export { applyLicenseKey, clearStoredLicense, configureLicenseEncryption, decryptLicense, encryptLicense, getCurrentPassphrase, getLicenseStatus, getLicenseStorageKey, hasEncryptedLicense, hasStoredLicense, isLicenseApplied, loadEncryptedLicense, loadLicense, removeLicense, resetPassphrase, saveEncryptedLicense, setLicense, validateLicenseFormat } from './chunk-PKJHVSFI.mjs';
2
2
  import './chunk-BJTO5JO5.mjs';
3
- //# sourceMappingURL=license-NCCUYGQL.mjs.map
4
- //# sourceMappingURL=license-NCCUYGQL.mjs.map
3
+ //# sourceMappingURL=license-MTK7WNNA.mjs.map
4
+ //# sourceMappingURL=license-MTK7WNNA.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"license-NCCUYGQL.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"license-MTK7WNNA.mjs"}
@@ -1,81 +1,81 @@
1
1
  'use strict';
2
2
 
3
- var chunkQFDC4NU3_js = require('./chunk-QFDC4NU3.js');
3
+ var chunkRLQMHQEV_js = require('./chunk-RLQMHQEV.js');
4
4
  require('./chunk-DGUM43GV.js');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "applyLicenseKey", {
9
9
  enumerable: true,
10
- get: function () { return chunkQFDC4NU3_js.applyLicenseKey; }
10
+ get: function () { return chunkRLQMHQEV_js.applyLicenseKey; }
11
11
  });
12
12
  Object.defineProperty(exports, "clearStoredLicense", {
13
13
  enumerable: true,
14
- get: function () { return chunkQFDC4NU3_js.clearStoredLicense; }
14
+ get: function () { return chunkRLQMHQEV_js.clearStoredLicense; }
15
15
  });
16
16
  Object.defineProperty(exports, "configureLicenseEncryption", {
17
17
  enumerable: true,
18
- get: function () { return chunkQFDC4NU3_js.configureLicenseEncryption; }
18
+ get: function () { return chunkRLQMHQEV_js.configureLicenseEncryption; }
19
19
  });
20
20
  Object.defineProperty(exports, "decryptLicense", {
21
21
  enumerable: true,
22
- get: function () { return chunkQFDC4NU3_js.decryptLicense; }
22
+ get: function () { return chunkRLQMHQEV_js.decryptLicense; }
23
23
  });
24
24
  Object.defineProperty(exports, "encryptLicense", {
25
25
  enumerable: true,
26
- get: function () { return chunkQFDC4NU3_js.encryptLicense; }
26
+ get: function () { return chunkRLQMHQEV_js.encryptLicense; }
27
27
  });
28
28
  Object.defineProperty(exports, "getCurrentPassphrase", {
29
29
  enumerable: true,
30
- get: function () { return chunkQFDC4NU3_js.getCurrentPassphrase; }
30
+ get: function () { return chunkRLQMHQEV_js.getCurrentPassphrase; }
31
31
  });
32
32
  Object.defineProperty(exports, "getLicenseStatus", {
33
33
  enumerable: true,
34
- get: function () { return chunkQFDC4NU3_js.getLicenseStatus; }
34
+ get: function () { return chunkRLQMHQEV_js.getLicenseStatus; }
35
35
  });
36
36
  Object.defineProperty(exports, "getLicenseStorageKey", {
37
37
  enumerable: true,
38
- get: function () { return chunkQFDC4NU3_js.getLicenseStorageKey; }
38
+ get: function () { return chunkRLQMHQEV_js.getLicenseStorageKey; }
39
39
  });
40
40
  Object.defineProperty(exports, "hasEncryptedLicense", {
41
41
  enumerable: true,
42
- get: function () { return chunkQFDC4NU3_js.hasEncryptedLicense; }
42
+ get: function () { return chunkRLQMHQEV_js.hasEncryptedLicense; }
43
43
  });
44
44
  Object.defineProperty(exports, "hasStoredLicense", {
45
45
  enumerable: true,
46
- get: function () { return chunkQFDC4NU3_js.hasStoredLicense; }
46
+ get: function () { return chunkRLQMHQEV_js.hasStoredLicense; }
47
47
  });
48
48
  Object.defineProperty(exports, "isLicenseApplied", {
49
49
  enumerable: true,
50
- get: function () { return chunkQFDC4NU3_js.isLicenseApplied; }
50
+ get: function () { return chunkRLQMHQEV_js.isLicenseApplied; }
51
51
  });
52
52
  Object.defineProperty(exports, "loadEncryptedLicense", {
53
53
  enumerable: true,
54
- get: function () { return chunkQFDC4NU3_js.loadEncryptedLicense; }
54
+ get: function () { return chunkRLQMHQEV_js.loadEncryptedLicense; }
55
55
  });
56
56
  Object.defineProperty(exports, "loadLicense", {
57
57
  enumerable: true,
58
- get: function () { return chunkQFDC4NU3_js.loadLicense; }
58
+ get: function () { return chunkRLQMHQEV_js.loadLicense; }
59
59
  });
60
60
  Object.defineProperty(exports, "removeLicense", {
61
61
  enumerable: true,
62
- get: function () { return chunkQFDC4NU3_js.removeLicense; }
62
+ get: function () { return chunkRLQMHQEV_js.removeLicense; }
63
63
  });
64
64
  Object.defineProperty(exports, "resetPassphrase", {
65
65
  enumerable: true,
66
- get: function () { return chunkQFDC4NU3_js.resetPassphrase; }
66
+ get: function () { return chunkRLQMHQEV_js.resetPassphrase; }
67
67
  });
68
68
  Object.defineProperty(exports, "saveEncryptedLicense", {
69
69
  enumerable: true,
70
- get: function () { return chunkQFDC4NU3_js.saveEncryptedLicense; }
70
+ get: function () { return chunkRLQMHQEV_js.saveEncryptedLicense; }
71
71
  });
72
72
  Object.defineProperty(exports, "setLicense", {
73
73
  enumerable: true,
74
- get: function () { return chunkQFDC4NU3_js.setLicense; }
74
+ get: function () { return chunkRLQMHQEV_js.setLicense; }
75
75
  });
76
76
  Object.defineProperty(exports, "validateLicenseFormat", {
77
77
  enumerable: true,
78
- get: function () { return chunkQFDC4NU3_js.validateLicenseFormat; }
78
+ get: function () { return chunkRLQMHQEV_js.validateLicenseFormat; }
79
79
  });
80
- //# sourceMappingURL=license-VBO3ZTOJ.js.map
81
- //# sourceMappingURL=license-VBO3ZTOJ.js.map
80
+ //# sourceMappingURL=license-U7ZNTU6D.js.map
81
+ //# sourceMappingURL=license-U7ZNTU6D.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"license-VBO3ZTOJ.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"license-U7ZNTU6D.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rm-graph/core",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "RM-Graphs Core - Charting library built on SciChart",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/license/crypto.ts","../src/license/index.ts"],"names":[],"mappings":"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","file":"chunk-BNXHM7UU.mjs","sourcesContent":["/**\r\n * Generic encryption/decryption utilities using Web Crypto API\r\n * Provides obfuscation for license keys stored in localStorage\r\n * \r\n * Note: This provides obfuscation, not true security.\r\n * The decryption key is in client code, so determined attackers can still decrypt.\r\n * For production, combine with SciChart's domain-locking for real protection.\r\n */\r\n\r\nconst ALGORITHM = 'AES-GCM';\r\nconst KEY_LENGTH = 256;\r\nconst STORAGE_KEY = 'RMGRAPH_LICENSE_DATA';\r\n\r\n/**\r\n * Derive a consistent cryptographic key from a passphrase\r\n */\r\nasync function deriveKey(passphrase: string): Promise<CryptoKey> {\r\n const encoder = new TextEncoder();\r\n const keyMaterial = await crypto.subtle.importKey(\r\n 'raw',\r\n encoder.encode(passphrase),\r\n 'PBKDF2',\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n // Use a fixed salt for consistency across encrypt/decrypt\r\n const salt = encoder.encode('rmgraph-license-salt-v1');\r\n\r\n return crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt,\r\n iterations: 100000,\r\n hash: 'SHA-256',\r\n },\r\n keyMaterial,\r\n { name: ALGORITHM, length: KEY_LENGTH },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n}\r\n\r\n/**\r\n * Encrypt a license key string\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase to derive encryption key from\r\n * @returns Base64 encoded encrypted data\r\n */\r\nexport async function encryptLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<string> {\r\n const key = await deriveKey(passphrase);\r\n const encoder = new TextEncoder();\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n encoder.encode(licenseKey)\r\n );\r\n\r\n // Combine IV + encrypted data and encode as base64\r\n const combined = new Uint8Array(iv.length + encrypted.byteLength);\r\n combined.set(iv);\r\n combined.set(new Uint8Array(encrypted), iv.length);\r\n\r\n return btoa(String.fromCharCode(...combined));\r\n}\r\n\r\n/**\r\n * Decrypt an encrypted license key\r\n * @param encryptedData - Base64 encoded encrypted data\r\n * @param passphrase - The passphrase to derive decryption key from\r\n * @returns The decrypted license key or null if decryption fails\r\n */\r\nexport async function decryptLicense(\r\n encryptedData: string,\r\n passphrase: string\r\n): Promise<string | null> {\r\n try {\r\n const key = await deriveKey(passphrase);\r\n const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));\r\n\r\n const iv = combined.slice(0, 12);\r\n const data = combined.slice(12);\r\n\r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n data\r\n );\r\n\r\n return new TextDecoder().decode(decrypted);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Save encrypted license to localStorage\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase for encryption\r\n */\r\nexport async function saveEncryptedLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<void> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n throw new Error('localStorage is not available');\r\n }\r\n const encrypted = await encryptLicense(licenseKey, passphrase);\r\n localStorage.setItem(STORAGE_KEY, encrypted);\r\n}\r\n\r\n/**\r\n * Load and decrypt license from localStorage\r\n * @param passphrase - The passphrase for decryption\r\n * @returns The decrypted license key or null if not found/decryption fails\r\n */\r\nexport async function loadEncryptedLicense(\r\n passphrase: string\r\n): Promise<string | null> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return null;\r\n }\r\n const encrypted = localStorage.getItem(STORAGE_KEY);\r\n if (!encrypted) return null;\r\n return decryptLicense(encrypted, passphrase);\r\n}\r\n\r\n/**\r\n * Check if an encrypted license exists in localStorage\r\n */\r\nexport function hasEncryptedLicense(): boolean {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return false;\r\n }\r\n return localStorage.getItem(STORAGE_KEY) !== null;\r\n}\r\n\r\n/**\r\n * Clear stored license from localStorage\r\n */\r\nexport function clearStoredLicense(): void {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return;\r\n }\r\n localStorage.removeItem(STORAGE_KEY);\r\n}\r\n\r\n/**\r\n * Get the storage key used for license data\r\n */\r\nexport function getLicenseStorageKey(): string {\r\n return STORAGE_KEY;\r\n}\r\n","/**\r\n * License management module for @rm-graph packages\r\n * \r\n * Provides encrypted storage and retrieval of SciChart license keys.\r\n * License keys are encrypted using AES-256-GCM before storing in localStorage.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { setLicense, loadLicense, configureLicenseEncryption } from '@rm-graph/core';\r\n * \r\n * // Optional: Configure custom passphrase\r\n * configureLicenseEncryption({ passphrase: 'your-app-secret' });\r\n * \r\n * // Save a license (encrypts and stores in localStorage)\r\n * await setLicense('your-scichart-license-key');\r\n * \r\n * // Load license on app startup\r\n * await loadLicense();\r\n * ```\r\n */\r\n\r\nimport { SciChartSurface } from 'scichart';\r\nimport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n} from './crypto';\r\n\r\n// Re-export crypto utilities for advanced usage\r\nexport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n};\r\n\r\n/**\r\n * Configuration options for license encryption\r\n */\r\nexport interface LicenseConfig {\r\n /** Custom passphrase for encryption/decryption (optional) */\r\n passphrase?: string;\r\n}\r\n\r\n/**\r\n * License status information\r\n */\r\nexport interface LicenseStatus {\r\n /** Whether a license is stored */\r\n hasLicense: boolean;\r\n /** Whether the license was successfully loaded and applied */\r\n isApplied: boolean;\r\n /** Error message if any */\r\n error?: string;\r\n}\r\n\r\n// Default passphrase (can be overridden by the application)\r\nconst DEFAULT_PASSPHRASE = 'rmgraph-default-key-2024';\r\n\r\n// Current passphrase (mutable)\r\nlet currentPassphrase = DEFAULT_PASSPHRASE;\r\n\r\n// Track if license has been applied\r\nlet licenseApplied = false;\r\n\r\n/**\r\n * Configure the license encryption passphrase\r\n * Call this before saving or loading licenses if you want to use a custom passphrase\r\n * \r\n * @param config - Configuration options\r\n * \r\n * @example\r\n * ```typescript\r\n * configureLicenseEncryption({ passphrase: 'my-app-secret-key' });\r\n * ```\r\n */\r\nexport function configureLicenseEncryption(config: LicenseConfig): void {\r\n if (config.passphrase) {\r\n currentPassphrase = config.passphrase;\r\n }\r\n}\r\n\r\n/**\r\n * Get the current passphrase (for internal use)\r\n */\r\nexport function getCurrentPassphrase(): string {\r\n return currentPassphrase;\r\n}\r\n\r\n/**\r\n * Reset passphrase to default\r\n */\r\nexport function resetPassphrase(): void {\r\n currentPassphrase = DEFAULT_PASSPHRASE;\r\n}\r\n\r\n/**\r\n * Save and apply a SciChart license key\r\n * Encrypts the key and stores it in localStorage, then applies it to SciChart\r\n * \r\n * @param licenseKey - The SciChart license key to save\r\n * @returns Promise resolving to true if successful, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * const success = await setLicense('your-scichart-license-key');\r\n * if (success) {\r\n * console.log('License saved and applied!');\r\n * }\r\n * ```\r\n */\r\nexport async function setLicense(licenseKey: string): Promise<boolean> {\r\n try {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n throw new Error('Invalid license key');\r\n }\r\n\r\n // Save encrypted to localStorage\r\n await saveEncryptedLicense(licenseKey.trim(), currentPassphrase);\r\n\r\n // Apply to SciChart\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to set license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Load license from localStorage and apply to SciChart\r\n * \r\n * @returns Promise resolving to true if license was found and applied, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * // Call on app startup\r\n * const loaded = await loadLicense();\r\n * if (loaded) {\r\n * console.log('License loaded from storage');\r\n * } else {\r\n * console.log('No license found - charts will show watermark');\r\n * }\r\n * ```\r\n */\r\nexport async function loadLicense(): Promise<boolean> {\r\n try {\r\n const licenseKey = await loadEncryptedLicense(currentPassphrase);\r\n\r\n if (licenseKey) {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey);\r\n licenseApplied = true;\r\n return true;\r\n }\r\n\r\n return false;\r\n } catch (error) {\r\n console.error('Failed to load license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a license is stored in localStorage\r\n * \r\n * @returns true if a license exists in storage\r\n */\r\nexport function hasStoredLicense(): boolean {\r\n return hasEncryptedLicense();\r\n}\r\n\r\n/**\r\n * Check if a license has been applied to SciChart in this session\r\n * \r\n * @returns true if a license has been applied\r\n */\r\nexport function isLicenseApplied(): boolean {\r\n return licenseApplied;\r\n}\r\n\r\n/**\r\n * Remove stored license from localStorage\r\n * Note: This doesn't remove the license from SciChart (requires page reload)\r\n */\r\nexport function removeLicense(): void {\r\n clearStoredLicense();\r\n licenseApplied = false;\r\n}\r\n\r\n/**\r\n * Apply a license key directly without storing it\r\n * Useful for temporary/session-only license application\r\n * \r\n * @param licenseKey - The SciChart license key\r\n */\r\nexport function applyLicenseKey(licenseKey: string): void {\r\n if (licenseKey && typeof licenseKey === 'string') {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n }\r\n}\r\n\r\n/**\r\n * Get current license status\r\n * \r\n * @returns License status information\r\n */\r\nexport function getLicenseStatus(): LicenseStatus {\r\n return {\r\n hasLicense: hasStoredLicense(),\r\n isApplied: licenseApplied,\r\n };\r\n}\r\n\r\n/**\r\n * Validate a license key format (basic validation)\r\n * Note: This doesn't validate if the license is actually valid with SciChart\r\n * \r\n * @param licenseKey - The license key to validate\r\n * @returns true if the format appears valid\r\n */\r\nexport function validateLicenseFormat(licenseKey: string): boolean {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n return false;\r\n }\r\n \r\n const trimmed = licenseKey.trim();\r\n \r\n // Basic validation: must be non-empty and have reasonable length\r\n return trimmed.length >= 10 && trimmed.length <= 5000;\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/license/crypto.ts","../src/license/index.ts"],"names":["SciChartSurface"],"mappings":"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","file":"chunk-QFDC4NU3.js","sourcesContent":["/**\r\n * Generic encryption/decryption utilities using Web Crypto API\r\n * Provides obfuscation for license keys stored in localStorage\r\n * \r\n * Note: This provides obfuscation, not true security.\r\n * The decryption key is in client code, so determined attackers can still decrypt.\r\n * For production, combine with SciChart's domain-locking for real protection.\r\n */\r\n\r\nconst ALGORITHM = 'AES-GCM';\r\nconst KEY_LENGTH = 256;\r\nconst STORAGE_KEY = 'RMGRAPH_LICENSE_DATA';\r\n\r\n/**\r\n * Derive a consistent cryptographic key from a passphrase\r\n */\r\nasync function deriveKey(passphrase: string): Promise<CryptoKey> {\r\n const encoder = new TextEncoder();\r\n const keyMaterial = await crypto.subtle.importKey(\r\n 'raw',\r\n encoder.encode(passphrase),\r\n 'PBKDF2',\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n // Use a fixed salt for consistency across encrypt/decrypt\r\n const salt = encoder.encode('rmgraph-license-salt-v1');\r\n\r\n return crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt,\r\n iterations: 100000,\r\n hash: 'SHA-256',\r\n },\r\n keyMaterial,\r\n { name: ALGORITHM, length: KEY_LENGTH },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n}\r\n\r\n/**\r\n * Encrypt a license key string\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase to derive encryption key from\r\n * @returns Base64 encoded encrypted data\r\n */\r\nexport async function encryptLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<string> {\r\n const key = await deriveKey(passphrase);\r\n const encoder = new TextEncoder();\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n encoder.encode(licenseKey)\r\n );\r\n\r\n // Combine IV + encrypted data and encode as base64\r\n const combined = new Uint8Array(iv.length + encrypted.byteLength);\r\n combined.set(iv);\r\n combined.set(new Uint8Array(encrypted), iv.length);\r\n\r\n return btoa(String.fromCharCode(...combined));\r\n}\r\n\r\n/**\r\n * Decrypt an encrypted license key\r\n * @param encryptedData - Base64 encoded encrypted data\r\n * @param passphrase - The passphrase to derive decryption key from\r\n * @returns The decrypted license key or null if decryption fails\r\n */\r\nexport async function decryptLicense(\r\n encryptedData: string,\r\n passphrase: string\r\n): Promise<string | null> {\r\n try {\r\n const key = await deriveKey(passphrase);\r\n const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));\r\n\r\n const iv = combined.slice(0, 12);\r\n const data = combined.slice(12);\r\n\r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: ALGORITHM, iv },\r\n key,\r\n data\r\n );\r\n\r\n return new TextDecoder().decode(decrypted);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Save encrypted license to localStorage\r\n * @param licenseKey - The plain text license key\r\n * @param passphrase - The passphrase for encryption\r\n */\r\nexport async function saveEncryptedLicense(\r\n licenseKey: string,\r\n passphrase: string\r\n): Promise<void> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n throw new Error('localStorage is not available');\r\n }\r\n const encrypted = await encryptLicense(licenseKey, passphrase);\r\n localStorage.setItem(STORAGE_KEY, encrypted);\r\n}\r\n\r\n/**\r\n * Load and decrypt license from localStorage\r\n * @param passphrase - The passphrase for decryption\r\n * @returns The decrypted license key or null if not found/decryption fails\r\n */\r\nexport async function loadEncryptedLicense(\r\n passphrase: string\r\n): Promise<string | null> {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return null;\r\n }\r\n const encrypted = localStorage.getItem(STORAGE_KEY);\r\n if (!encrypted) return null;\r\n return decryptLicense(encrypted, passphrase);\r\n}\r\n\r\n/**\r\n * Check if an encrypted license exists in localStorage\r\n */\r\nexport function hasEncryptedLicense(): boolean {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return false;\r\n }\r\n return localStorage.getItem(STORAGE_KEY) !== null;\r\n}\r\n\r\n/**\r\n * Clear stored license from localStorage\r\n */\r\nexport function clearStoredLicense(): void {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return;\r\n }\r\n localStorage.removeItem(STORAGE_KEY);\r\n}\r\n\r\n/**\r\n * Get the storage key used for license data\r\n */\r\nexport function getLicenseStorageKey(): string {\r\n return STORAGE_KEY;\r\n}\r\n","/**\r\n * License management module for @rm-graph packages\r\n * \r\n * Provides encrypted storage and retrieval of SciChart license keys.\r\n * License keys are encrypted using AES-256-GCM before storing in localStorage.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { setLicense, loadLicense, configureLicenseEncryption } from '@rm-graph/core';\r\n * \r\n * // Optional: Configure custom passphrase\r\n * configureLicenseEncryption({ passphrase: 'your-app-secret' });\r\n * \r\n * // Save a license (encrypts and stores in localStorage)\r\n * await setLicense('your-scichart-license-key');\r\n * \r\n * // Load license on app startup\r\n * await loadLicense();\r\n * ```\r\n */\r\n\r\nimport { SciChartSurface } from 'scichart';\r\nimport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n} from './crypto';\r\n\r\n// Re-export crypto utilities for advanced usage\r\nexport {\r\n encryptLicense,\r\n decryptLicense,\r\n saveEncryptedLicense,\r\n loadEncryptedLicense,\r\n hasEncryptedLicense,\r\n clearStoredLicense,\r\n getLicenseStorageKey,\r\n};\r\n\r\n/**\r\n * Configuration options for license encryption\r\n */\r\nexport interface LicenseConfig {\r\n /** Custom passphrase for encryption/decryption (optional) */\r\n passphrase?: string;\r\n}\r\n\r\n/**\r\n * License status information\r\n */\r\nexport interface LicenseStatus {\r\n /** Whether a license is stored */\r\n hasLicense: boolean;\r\n /** Whether the license was successfully loaded and applied */\r\n isApplied: boolean;\r\n /** Error message if any */\r\n error?: string;\r\n}\r\n\r\n// Default passphrase (can be overridden by the application)\r\nconst DEFAULT_PASSPHRASE = 'rmgraph-default-key-2024';\r\n\r\n// Current passphrase (mutable)\r\nlet currentPassphrase = DEFAULT_PASSPHRASE;\r\n\r\n// Track if license has been applied\r\nlet licenseApplied = false;\r\n\r\n/**\r\n * Configure the license encryption passphrase\r\n * Call this before saving or loading licenses if you want to use a custom passphrase\r\n * \r\n * @param config - Configuration options\r\n * \r\n * @example\r\n * ```typescript\r\n * configureLicenseEncryption({ passphrase: 'my-app-secret-key' });\r\n * ```\r\n */\r\nexport function configureLicenseEncryption(config: LicenseConfig): void {\r\n if (config.passphrase) {\r\n currentPassphrase = config.passphrase;\r\n }\r\n}\r\n\r\n/**\r\n * Get the current passphrase (for internal use)\r\n */\r\nexport function getCurrentPassphrase(): string {\r\n return currentPassphrase;\r\n}\r\n\r\n/**\r\n * Reset passphrase to default\r\n */\r\nexport function resetPassphrase(): void {\r\n currentPassphrase = DEFAULT_PASSPHRASE;\r\n}\r\n\r\n/**\r\n * Save and apply a SciChart license key\r\n * Encrypts the key and stores it in localStorage, then applies it to SciChart\r\n * \r\n * @param licenseKey - The SciChart license key to save\r\n * @returns Promise resolving to true if successful, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * const success = await setLicense('your-scichart-license-key');\r\n * if (success) {\r\n * console.log('License saved and applied!');\r\n * }\r\n * ```\r\n */\r\nexport async function setLicense(licenseKey: string): Promise<boolean> {\r\n try {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n throw new Error('Invalid license key');\r\n }\r\n\r\n // Save encrypted to localStorage\r\n await saveEncryptedLicense(licenseKey.trim(), currentPassphrase);\r\n\r\n // Apply to SciChart\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to set license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Load license from localStorage and apply to SciChart\r\n * \r\n * @returns Promise resolving to true if license was found and applied, false otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * // Call on app startup\r\n * const loaded = await loadLicense();\r\n * if (loaded) {\r\n * console.log('License loaded from storage');\r\n * } else {\r\n * console.log('No license found - charts will show watermark');\r\n * }\r\n * ```\r\n */\r\nexport async function loadLicense(): Promise<boolean> {\r\n try {\r\n const licenseKey = await loadEncryptedLicense(currentPassphrase);\r\n\r\n if (licenseKey) {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey);\r\n licenseApplied = true;\r\n return true;\r\n }\r\n\r\n return false;\r\n } catch (error) {\r\n console.error('Failed to load license:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a license is stored in localStorage\r\n * \r\n * @returns true if a license exists in storage\r\n */\r\nexport function hasStoredLicense(): boolean {\r\n return hasEncryptedLicense();\r\n}\r\n\r\n/**\r\n * Check if a license has been applied to SciChart in this session\r\n * \r\n * @returns true if a license has been applied\r\n */\r\nexport function isLicenseApplied(): boolean {\r\n return licenseApplied;\r\n}\r\n\r\n/**\r\n * Remove stored license from localStorage\r\n * Note: This doesn't remove the license from SciChart (requires page reload)\r\n */\r\nexport function removeLicense(): void {\r\n clearStoredLicense();\r\n licenseApplied = false;\r\n}\r\n\r\n/**\r\n * Apply a license key directly without storing it\r\n * Useful for temporary/session-only license application\r\n * \r\n * @param licenseKey - The SciChart license key\r\n */\r\nexport function applyLicenseKey(licenseKey: string): void {\r\n if (licenseKey && typeof licenseKey === 'string') {\r\n SciChartSurface.setRuntimeLicenseKey(licenseKey.trim());\r\n licenseApplied = true;\r\n }\r\n}\r\n\r\n/**\r\n * Get current license status\r\n * \r\n * @returns License status information\r\n */\r\nexport function getLicenseStatus(): LicenseStatus {\r\n return {\r\n hasLicense: hasStoredLicense(),\r\n isApplied: licenseApplied,\r\n };\r\n}\r\n\r\n/**\r\n * Validate a license key format (basic validation)\r\n * Note: This doesn't validate if the license is actually valid with SciChart\r\n * \r\n * @param licenseKey - The license key to validate\r\n * @returns true if the format appears valid\r\n */\r\nexport function validateLicenseFormat(licenseKey: string): boolean {\r\n if (!licenseKey || typeof licenseKey !== 'string') {\r\n return false;\r\n }\r\n \r\n const trimmed = licenseKey.trim();\r\n \r\n // Basic validation: must be non-empty and have reasonable length\r\n return trimmed.length >= 10 && trimmed.length <= 5000;\r\n}\r\n"]}