@gridengine/angular-datagrid-enterprise 0.2.0 → 0.3.0
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.
|
@@ -778,6 +778,311 @@ class UndoRedoManager {
|
|
|
778
778
|
}
|
|
779
779
|
}
|
|
780
780
|
|
|
781
|
+
/**
|
|
782
|
+
* FormulaEngine — evaluates Excel-like formula strings against row data.
|
|
783
|
+
* Formulas start with '=' and reference other columns by field name.
|
|
784
|
+
*
|
|
785
|
+
* Functions: SUM, AVG, MIN, MAX, COUNT, IF, CONCAT, ROUND, ABS, FLOOR, CEIL,
|
|
786
|
+
* LEN, UPPER, LOWER. Bare identifiers that aren't function names are treated as
|
|
787
|
+
* field lookups on the current row.
|
|
788
|
+
*
|
|
789
|
+
* Error values: '#ERROR!', '#DIV/0!', '#REF!', '#CIRCULAR!', '#NAME?'.
|
|
790
|
+
* A formula that directly/transitively references its own cell yields
|
|
791
|
+
* '#CIRCULAR!'.
|
|
792
|
+
*/
|
|
793
|
+
class Parser {
|
|
794
|
+
_src;
|
|
795
|
+
_pos = 0;
|
|
796
|
+
constructor(src) {
|
|
797
|
+
this._src = src.trim();
|
|
798
|
+
}
|
|
799
|
+
parse() {
|
|
800
|
+
const node = this._parseExpr();
|
|
801
|
+
this._skipWS();
|
|
802
|
+
if (this._pos < this._src.length) {
|
|
803
|
+
throw new Error(`Unexpected character at position ${this._pos}: '${this._src[this._pos]}'`);
|
|
804
|
+
}
|
|
805
|
+
return node;
|
|
806
|
+
}
|
|
807
|
+
_skipWS() {
|
|
808
|
+
while (this._pos < this._src.length && /\s/.test(this._src[this._pos])) {
|
|
809
|
+
this._pos++;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
_consume(ch) {
|
|
813
|
+
this._skipWS();
|
|
814
|
+
if (this._src[this._pos] !== ch) {
|
|
815
|
+
throw new Error(`Expected '${ch}' at position ${this._pos}`);
|
|
816
|
+
}
|
|
817
|
+
this._pos++;
|
|
818
|
+
}
|
|
819
|
+
_parseExpr() {
|
|
820
|
+
return this._parseComparison();
|
|
821
|
+
}
|
|
822
|
+
_parseComparison() {
|
|
823
|
+
let left = this._parseAddSub();
|
|
824
|
+
this._skipWS();
|
|
825
|
+
while (this._pos < this._src.length) {
|
|
826
|
+
const ch = this._src[this._pos];
|
|
827
|
+
const ch2 = this._src.slice(this._pos, this._pos + 2);
|
|
828
|
+
if (ch2 === '==' || ch2 === '!=' || ch2 === '<=' || ch2 === '>=') {
|
|
829
|
+
this._pos += 2;
|
|
830
|
+
const right = this._parseAddSub();
|
|
831
|
+
left = { kind: 'binary', op: ch2, left, right };
|
|
832
|
+
}
|
|
833
|
+
else if (ch === '<' || ch === '>') {
|
|
834
|
+
this._pos++;
|
|
835
|
+
const right = this._parseAddSub();
|
|
836
|
+
left = { kind: 'binary', op: ch, left, right };
|
|
837
|
+
}
|
|
838
|
+
else {
|
|
839
|
+
break;
|
|
840
|
+
}
|
|
841
|
+
this._skipWS();
|
|
842
|
+
}
|
|
843
|
+
return left;
|
|
844
|
+
}
|
|
845
|
+
_parseAddSub() {
|
|
846
|
+
let left = this._parseMulDiv();
|
|
847
|
+
this._skipWS();
|
|
848
|
+
while (this._pos < this._src.length &&
|
|
849
|
+
(this._src[this._pos] === '+' || this._src[this._pos] === '-')) {
|
|
850
|
+
const op = this._src[this._pos++];
|
|
851
|
+
const right = this._parseMulDiv();
|
|
852
|
+
left = { kind: 'binary', op, left, right };
|
|
853
|
+
this._skipWS();
|
|
854
|
+
}
|
|
855
|
+
return left;
|
|
856
|
+
}
|
|
857
|
+
_parseMulDiv() {
|
|
858
|
+
let left = this._parseUnary();
|
|
859
|
+
this._skipWS();
|
|
860
|
+
while (this._pos < this._src.length &&
|
|
861
|
+
(this._src[this._pos] === '*' || this._src[this._pos] === '/')) {
|
|
862
|
+
const op = this._src[this._pos++];
|
|
863
|
+
const right = this._parseUnary();
|
|
864
|
+
left = { kind: 'binary', op, left, right };
|
|
865
|
+
this._skipWS();
|
|
866
|
+
}
|
|
867
|
+
return left;
|
|
868
|
+
}
|
|
869
|
+
_parseUnary() {
|
|
870
|
+
this._skipWS();
|
|
871
|
+
if (this._src[this._pos] === '-') {
|
|
872
|
+
this._pos++;
|
|
873
|
+
return { kind: 'unary', op: '-', operand: this._parseUnary() };
|
|
874
|
+
}
|
|
875
|
+
return this._parsePrimary();
|
|
876
|
+
}
|
|
877
|
+
_parsePrimary() {
|
|
878
|
+
this._skipWS();
|
|
879
|
+
const ch = this._src[this._pos];
|
|
880
|
+
if (ch === undefined) {
|
|
881
|
+
throw new Error('Unexpected end of expression');
|
|
882
|
+
}
|
|
883
|
+
if (ch === '(') {
|
|
884
|
+
this._pos++;
|
|
885
|
+
const node = this._parseExpr();
|
|
886
|
+
this._consume(')');
|
|
887
|
+
return node;
|
|
888
|
+
}
|
|
889
|
+
if (ch === '"' || ch === "'") {
|
|
890
|
+
return this._parseString(ch);
|
|
891
|
+
}
|
|
892
|
+
if (ch === '.' || (ch >= '0' && ch <= '9')) {
|
|
893
|
+
return this._parseNumber();
|
|
894
|
+
}
|
|
895
|
+
if (/[A-Za-z_]/.test(ch)) {
|
|
896
|
+
return this._parseIdentifier();
|
|
897
|
+
}
|
|
898
|
+
throw new Error(`Unexpected token at position ${this._pos}: '${ch}'`);
|
|
899
|
+
}
|
|
900
|
+
_parseString(quote) {
|
|
901
|
+
this._pos++; // skip opening quote
|
|
902
|
+
let s = '';
|
|
903
|
+
while (this._pos < this._src.length && this._src[this._pos] !== quote) {
|
|
904
|
+
s += this._src[this._pos++];
|
|
905
|
+
}
|
|
906
|
+
this._pos++; // skip closing quote
|
|
907
|
+
return { kind: 'string', value: s };
|
|
908
|
+
}
|
|
909
|
+
_parseNumber() {
|
|
910
|
+
let s = '';
|
|
911
|
+
while (this._pos < this._src.length && /[\d.]/.test(this._src[this._pos])) {
|
|
912
|
+
s += this._src[this._pos++];
|
|
913
|
+
}
|
|
914
|
+
if (this._src[this._pos] === 'e' || this._src[this._pos] === 'E') {
|
|
915
|
+
s += this._src[this._pos++];
|
|
916
|
+
if (this._src[this._pos] === '+' || this._src[this._pos] === '-') {
|
|
917
|
+
s += this._src[this._pos++];
|
|
918
|
+
}
|
|
919
|
+
while (this._pos < this._src.length && /\d/.test(this._src[this._pos])) {
|
|
920
|
+
s += this._src[this._pos++];
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
return { kind: 'number', value: Number(s) };
|
|
924
|
+
}
|
|
925
|
+
_parseIdentifier() {
|
|
926
|
+
let name = '';
|
|
927
|
+
while (this._pos < this._src.length && /[\w]/.test(this._src[this._pos])) {
|
|
928
|
+
name += this._src[this._pos++];
|
|
929
|
+
}
|
|
930
|
+
this._skipWS();
|
|
931
|
+
if (this._src[this._pos] === '(') {
|
|
932
|
+
this._pos++;
|
|
933
|
+
const args = [];
|
|
934
|
+
this._skipWS();
|
|
935
|
+
if (this._src[this._pos] !== ')') {
|
|
936
|
+
args.push(this._parseExpr());
|
|
937
|
+
this._skipWS();
|
|
938
|
+
while (this._src[this._pos] === ',') {
|
|
939
|
+
this._pos++;
|
|
940
|
+
args.push(this._parseExpr());
|
|
941
|
+
this._skipWS();
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
this._consume(')');
|
|
945
|
+
return { kind: 'call', fn: name.toUpperCase(), args };
|
|
946
|
+
}
|
|
947
|
+
return { kind: 'field', name };
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
const FUNCTIONS = {
|
|
951
|
+
SUM: (args) => args.reduce((acc, v) => acc + (Number(v) || 0), 0),
|
|
952
|
+
AVG: (args) => args.length === 0 ? 0 : args.reduce((acc, v) => acc + (Number(v) || 0), 0) / args.length,
|
|
953
|
+
MIN: (args) => Math.min(...args.map(Number)),
|
|
954
|
+
MAX: (args) => Math.max(...args.map(Number)),
|
|
955
|
+
COUNT: (args) => args.filter((v) => !isNaN(Number(v)) && v !== '' && v != null).length,
|
|
956
|
+
CONCAT: (args) => args.join(''),
|
|
957
|
+
ROUND: ([n, d]) => Number(Number(n).toFixed(Number(d ?? 0))),
|
|
958
|
+
ABS: ([n]) => Math.abs(Number(n)),
|
|
959
|
+
FLOOR: ([n]) => Math.floor(Number(n)),
|
|
960
|
+
CEIL: ([n]) => Math.ceil(Number(n)),
|
|
961
|
+
LEN: ([s]) => String(s ?? '').length,
|
|
962
|
+
UPPER: ([s]) => String(s ?? '').toUpperCase(),
|
|
963
|
+
LOWER: ([s]) => String(s ?? '').toLowerCase(),
|
|
964
|
+
IF: ([cond, t, f]) => (cond ? t : f),
|
|
965
|
+
};
|
|
966
|
+
function evalBinary(op, l, r) {
|
|
967
|
+
switch (op) {
|
|
968
|
+
case '+':
|
|
969
|
+
return typeof l === 'string' || typeof r === 'string'
|
|
970
|
+
? String(l) + String(r)
|
|
971
|
+
: Number(l) + Number(r);
|
|
972
|
+
case '-':
|
|
973
|
+
return Number(l) - Number(r);
|
|
974
|
+
case '*':
|
|
975
|
+
return Number(l) * Number(r);
|
|
976
|
+
case '/': {
|
|
977
|
+
const divisor = Number(r);
|
|
978
|
+
return divisor === 0 ? '#DIV/0!' : Number(l) / divisor;
|
|
979
|
+
}
|
|
980
|
+
case '==':
|
|
981
|
+
return l == r;
|
|
982
|
+
case '!=':
|
|
983
|
+
return l != r;
|
|
984
|
+
case '<':
|
|
985
|
+
return Number(l) < Number(r);
|
|
986
|
+
case '<=':
|
|
987
|
+
return Number(l) <= Number(r);
|
|
988
|
+
case '>':
|
|
989
|
+
return Number(l) > Number(r);
|
|
990
|
+
case '>=':
|
|
991
|
+
return Number(l) >= Number(r);
|
|
992
|
+
default:
|
|
993
|
+
return '#ERROR!';
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
function evaluate(node, row, visiting) {
|
|
997
|
+
switch (node.kind) {
|
|
998
|
+
case 'number':
|
|
999
|
+
return node.value;
|
|
1000
|
+
case 'string':
|
|
1001
|
+
return node.value;
|
|
1002
|
+
case 'field': {
|
|
1003
|
+
const key = node.name;
|
|
1004
|
+
if (visiting.has(key))
|
|
1005
|
+
return '#CIRCULAR!';
|
|
1006
|
+
const raw = row[key];
|
|
1007
|
+
if (typeof raw === 'string' && raw.startsWith('=')) {
|
|
1008
|
+
visiting.add(key);
|
|
1009
|
+
try {
|
|
1010
|
+
const ast = new Parser(raw.slice(1)).parse();
|
|
1011
|
+
return evaluate(ast, row, visiting);
|
|
1012
|
+
}
|
|
1013
|
+
finally {
|
|
1014
|
+
visiting.delete(key);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
if (raw === undefined)
|
|
1018
|
+
return '#REF!';
|
|
1019
|
+
return raw;
|
|
1020
|
+
}
|
|
1021
|
+
case 'unary': {
|
|
1022
|
+
const v = evaluate(node.operand, row, visiting);
|
|
1023
|
+
if (typeof v === 'string' && v.startsWith('#'))
|
|
1024
|
+
return v;
|
|
1025
|
+
return -Number(v);
|
|
1026
|
+
}
|
|
1027
|
+
case 'binary': {
|
|
1028
|
+
const l = evaluate(node.left, row, visiting);
|
|
1029
|
+
const r = evaluate(node.right, row, visiting);
|
|
1030
|
+
if (typeof l === 'string' && l.startsWith('#'))
|
|
1031
|
+
return l;
|
|
1032
|
+
if (typeof r === 'string' && r.startsWith('#'))
|
|
1033
|
+
return r;
|
|
1034
|
+
return evalBinary(node.op, l, r);
|
|
1035
|
+
}
|
|
1036
|
+
case 'call': {
|
|
1037
|
+
const fn = FUNCTIONS[node.fn];
|
|
1038
|
+
if (!fn)
|
|
1039
|
+
return '#NAME?';
|
|
1040
|
+
const args = node.args.map((a) => evaluate(a, row, visiting));
|
|
1041
|
+
const err = args.find((a) => typeof a === 'string' && a.startsWith('#'));
|
|
1042
|
+
if (err)
|
|
1043
|
+
return err;
|
|
1044
|
+
return fn(args);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
class FormulaEngine {
|
|
1049
|
+
_formulaFields;
|
|
1050
|
+
constructor(options) {
|
|
1051
|
+
this._formulaFields = options.formulaFields;
|
|
1052
|
+
}
|
|
1053
|
+
/** Evaluate all formula fields for a row, returning a new (unmutated) row. */
|
|
1054
|
+
evaluateRow(row) {
|
|
1055
|
+
const result = { ...row };
|
|
1056
|
+
for (const [field, formula] of Object.entries(this._formulaFields)) {
|
|
1057
|
+
result[field] = this.evaluateFormula(formula, row, field);
|
|
1058
|
+
}
|
|
1059
|
+
return result;
|
|
1060
|
+
}
|
|
1061
|
+
/** Evaluate a single formula string against a row. */
|
|
1062
|
+
evaluateFormula(formula, row, selfField) {
|
|
1063
|
+
const expr = formula.startsWith('=') ? formula.slice(1) : formula;
|
|
1064
|
+
try {
|
|
1065
|
+
const ast = new Parser(expr).parse();
|
|
1066
|
+
const visiting = selfField ? new Set([selfField]) : new Set();
|
|
1067
|
+
return evaluate(ast, row, visiting);
|
|
1068
|
+
}
|
|
1069
|
+
catch {
|
|
1070
|
+
return '#ERROR!';
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
/** Whether a formula string is parseable (no evaluation). */
|
|
1074
|
+
isValidFormula(formula) {
|
|
1075
|
+
const expr = formula.startsWith('=') ? formula.slice(1) : formula;
|
|
1076
|
+
try {
|
|
1077
|
+
new Parser(expr).parse();
|
|
1078
|
+
return true;
|
|
1079
|
+
}
|
|
1080
|
+
catch {
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
|
|
781
1086
|
/*
|
|
782
1087
|
* Public API Surface of @gridengine/angular-datagrid-enterprise
|
|
783
1088
|
*
|
|
@@ -790,5 +1095,5 @@ class UndoRedoManager {
|
|
|
790
1095
|
* Generated bundle index. Do not edit.
|
|
791
1096
|
*/
|
|
792
1097
|
|
|
793
|
-
export { ClipboardEngine, DataGridPro, FillHandleEngine, GridLicenseWatermark, LicenseManager, PRODUCT_ID, PURCHASE_URL, RangeSelectionEngine, UndoRedoManager, parseTSV, provideGridEngineLicense, toNumber, toTimestamp };
|
|
1098
|
+
export { ClipboardEngine, DataGridPro, FillHandleEngine, FormulaEngine, GridLicenseWatermark, LicenseManager, PRODUCT_ID, PURCHASE_URL, RangeSelectionEngine, UndoRedoManager, parseTSV, provideGridEngineLicense, toNumber, toTimestamp };
|
|
794
1099
|
//# sourceMappingURL=gridengine-angular-datagrid-enterprise.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridengine-angular-datagrid-enterprise.mjs","sources":["../../../projects/enterprise/src/lib/keyring.ts","../../../projects/enterprise/src/lib/license-manager.ts","../../../projects/enterprise/src/lib/license-watermark.ts","../../../projects/enterprise/src/lib/data-grid-pro.ts","../../../projects/enterprise/src/lib/provide-license.ts","../../../projects/enterprise/src/lib/features/range-selection.ts","../../../projects/enterprise/src/lib/features/clipboard.ts","../../../projects/enterprise/src/lib/features/fill-handle.ts","../../../projects/enterprise/src/lib/features/undo-redo.ts","../../../projects/enterprise/src/public-api.ts","../../../projects/enterprise/src/gridengine-angular-datagrid-enterprise.ts"],"sourcesContent":["/**\n * Public verifying keys for GridEngine Angular license keys.\n *\n * These are Ed25519 PUBLIC keys, keyed by `keyId` — safe to ship in the bundle\n * (they can only verify signatures, never mint keys). The matching PRIVATE key\n * lives only in the GridEngine store backend (Azure Key Vault secret\n * `signing-angular-datagrid`). Rotate by adding a new keyId here alongside the\n * old one, until previously issued keys expire.\n */\nimport type { PublicKeyRing } from '@gridengine/license-core';\n\n/** The product id GridEngine license keys are scoped to for this package. */\nexport const PRODUCT_ID = 'angular-datagrid';\n\n/** Where a buyer can purchase / activate a license. */\nexport const PURCHASE_URL = 'https://angular.gridengine.dev/pricing';\n\nexport const PUBLIC_KEYRING: PublicKeyRing = {\n 'angular-datagrid-2026-08-09': 'GJx3r0A-xL2Q3-poGd3WbOh_B0EN9wwWOxMdksxs_S4',\n};\n","/**\n * LicenseManager — validates a `@gridengine/angular-datagrid-enterprise` license key.\n *\n * Verification uses `@gridengine/license-core` (Ed25519, keyring-based) — the\n * same scheme the GridEngine store uses to sign keys after a real purchase. The\n * private signing key lives only in the store's backend (Key Vault); this\n * package ships only the matching PUBLIC verifying key, so it can check a key's\n * authenticity but never mint one.\n *\n * This is soft licensing, not DRM: validation is synchronous and client-side,\n * and a determined user could strip the check from their own bundle. Server-\n * side entitlement checks remain authoritative for anything that matters.\n *\n * Feature access is derived from the license TIER (see `TIER_FEATURES`), with\n * `payload.features` allowed to grant additional flags on top. The support\n * level is metadata only — it never gates any in-bundle behaviour.\n */\nimport {\n validateLicense,\n resolveFeatures as coreResolveFeatures,\n TIER_FEATURES,\n type LicensePayload,\n type LicenseTier,\n type SupportLevel,\n type LicenseStatus,\n type LicenseValidationResult,\n type PublicKeyRing,\n} from '@gridengine/license-core';\nimport { PRODUCT_ID, PURCHASE_URL, PUBLIC_KEYRING } from './keyring';\n\nexport type {\n LicensePayload,\n LicenseTier,\n SupportLevel,\n LicenseStatus,\n LicenseValidationResult,\n};\nexport { TIER_FEATURES };\n\nconst _cache = new Map<string, LicenseValidationResult>();\n\n/**\n * Global license key, set once at app bootstrap (typically via\n * `provideGridEngineLicense(key)`) so every `<gd-data-grid-pro>` in the app\n * picks it up without needing a `licenseKey` input on each instance. A\n * `licenseKey` input, when given, still overrides this for that instance.\n */\nlet _globalLicenseKey: string | undefined;\n\n/** Set the license key once for the whole app (e.g. at app bootstrap). */\nfunction setLicenseKey(key: string | undefined): void {\n _globalLicenseKey = key;\n}\n\n/** The key previously set via `setLicenseKey`, if any. */\nfunction getLicenseKey(): string | undefined {\n return _globalLicenseKey;\n}\n\n/**\n * Validate a key against an arbitrary keyring. Exported (but not part of the\n * public `LicenseManager` API surface) so tests can verify against a throwaway\n * test keypair instead of the real production keyring.\n */\nexport function validateWithKeyring(\n key: string | undefined,\n keys: PublicKeyRing | string,\n): LicenseValidationResult {\n if (!key) {\n return {\n status: 'missing',\n payload: null,\n message:\n 'No @gridengine/angular-datagrid-enterprise license key provided. ' +\n 'A watermark will be displayed. ' +\n `Purchase a license at ${PURCHASE_URL}`,\n };\n }\n return validateLicense(key, keys, PRODUCT_ID);\n}\n\n/**\n * Validate a license key string. Results are cached per key so validation runs\n * at most once per key per session.\n */\nfunction validate(key: string | undefined): LicenseValidationResult {\n if (!key) return validateWithKeyring(key, PUBLIC_KEYRING);\n\n const cached = _cache.get(key);\n if (cached) return cached;\n\n const result = validateWithKeyring(key, PUBLIC_KEYRING);\n _cache.set(key, result);\n return result;\n}\n\n/**\n * The set of feature flags granted by a validated payload: the tier defaults\n * plus any explicit extras in `payload.features`.\n */\nfunction resolveFeatures(payload: LicensePayload): Set<string> {\n return coreResolveFeatures(payload);\n}\n\n/**\n * Check whether a specific feature is enabled for a key, against an arbitrary\n * keyring. Exported (but not part of the public `LicenseManager` API surface)\n * so tests can exercise this without the real production keyring.\n */\nexport function isFeatureEnabledWithKeyring(\n key: string | undefined,\n feature: string,\n keys: PublicKeyRing | string,\n): boolean {\n if (!key) return true; // evaluation mode\n const result = validateWithKeyring(key, keys);\n if (result.status !== 'valid' || !result.payload) return false;\n return resolveFeatures(result.payload).has(feature);\n}\n\n/**\n * Check whether a specific feature is enabled for a given key. Returns true\n * when no key is given (evaluation mode — features accessible but watermarked),\n * and false for any non-valid license.\n */\nfunction isFeatureEnabled(key: string | undefined, feature: string): boolean {\n if (!key) return true; // evaluation mode\n const result = validate(key);\n if (result.status !== 'valid' || !result.payload) return false;\n return resolveFeatures(result.payload).has(feature);\n}\n\nexport const LicenseManager = {\n validate,\n isFeatureEnabled,\n setLicenseKey,\n getLicenseKey,\n TIER_FEATURES,\n} as const;\n","/**\n * GridLicenseWatermark — a subtle, non-blocking evaluation watermark shown in\n * the corner of an enterprise grid when no valid license key is provided.\n *\n * The grid stays fully functional in evaluation mode; this only signals that a\n * license is required for production use. It is rendered automatically by\n * `<gd-data-grid-pro>` but is also exported for advanced consumers who compose\n * the grid themselves.\n */\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { PURCHASE_URL } from './keyring';\n\n@Component({\n selector: 'gd-license-watermark',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"gd-license-watermark\" aria-hidden=\"true\">\n {{ label() }} — unlicensed — <span class=\"gd-license-watermark__url\">{{ url() }}</span>\n </div>\n `,\n styles: [\n `\n .gd-license-watermark {\n position: absolute;\n bottom: 8px;\n right: 12px;\n z-index: 10;\n font-family: sans-serif;\n font-size: 11px;\n letter-spacing: 0.02em;\n color: rgba(0, 0, 0, 0.35);\n pointer-events: none;\n user-select: none;\n }\n .gd-license-watermark__url {\n text-decoration: underline;\n }\n `,\n ],\n})\nexport class GridLicenseWatermark {\n /** Package label shown in the watermark. */\n readonly label = input('@gridengine/angular-datagrid-enterprise');\n /** Purchase URL shown in the watermark. */\n readonly url = input(PURCHASE_URL);\n}\n","/**\n * DataGridPro — the license-aware wrapper for the GridEngine Angular grid.\n *\n * Projects a base `<gd-data-grid>` (or any content) and overlays an evaluation\n * watermark when no valid license key is present. The grid remains fully\n * functional without a license (evaluation mode); this component only adds the\n * watermark + a one-time console warning.\n *\n * ```html\n * <gd-data-grid-pro [licenseKey]=\"key\">\n * <gd-data-grid [rowData]=\"rows\" [columnDefs]=\"cols\" />\n * </gd-data-grid-pro>\n * ```\n *\n * A `[licenseKey]` input overrides the app-wide key set via\n * `provideGridEngineLicense()` / `LicenseManager.setLicenseKey()`.\n */\nimport { ChangeDetectionStrategy, Component, computed, effect, input } from '@angular/core';\nimport type { LicenseValidationResult } from '@gridengine/license-core';\nimport { LicenseManager } from './license-manager';\nimport { GridLicenseWatermark } from './license-watermark';\n\n@Component({\n selector: 'gd-data-grid-pro',\n standalone: true,\n imports: [GridLicenseWatermark],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"gd-data-grid-pro\">\n <ng-content />\n @if (showWatermark()) {\n <gd-license-watermark />\n }\n </div>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n .gd-data-grid-pro {\n position: relative;\n display: block;\n }\n `,\n ],\n})\nexport class DataGridPro {\n /** Per-instance license key; overrides the app-wide key when provided. */\n readonly licenseKey = input<string | undefined>(undefined);\n\n protected readonly licenseResult = computed<LicenseValidationResult>(() =>\n LicenseManager.validate(this.licenseKey() ?? LicenseManager.getLicenseKey()),\n );\n\n protected readonly showWatermark = computed(() => this.licenseResult().status !== 'valid');\n\n private warned = false;\n\n constructor() {\n effect(() => {\n const result = this.licenseResult();\n if (!this.warned && result.status !== 'valid') {\n console.warn(`[@gridengine/angular-datagrid-enterprise] ${result.message}`);\n this.warned = true;\n }\n });\n }\n\n /** The current license validation result (for advanced consumers). */\n getLicenseResult(): LicenseValidationResult {\n return this.licenseResult();\n }\n}\n","/**\n * `provideGridEngineLicense` — register a GridEngine Angular license key once\n * for the whole application at bootstrap.\n *\n * Usage (standalone bootstrap):\n *\n * ```ts\n * bootstrapApplication(App, {\n * providers: [provideGridEngineLicense('BASE64URL.payload.signature')],\n * });\n * ```\n *\n * Every `<gd-data-grid-pro>` in the app then picks the key up automatically via\n * `LicenseManager.getLicenseKey()`; a per-instance `[licenseKey]` input still\n * overrides it for that instance.\n */\nimport { makeEnvironmentProviders, provideEnvironmentInitializer } from '@angular/core';\nimport type { EnvironmentProviders } from '@angular/core';\nimport { LicenseManager } from './license-manager';\n\nexport function provideGridEngineLicense(key: string | undefined): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => LicenseManager.setLicenseKey(key)),\n ]);\n}\n","/**\n * RangeSelectionEngine — tracks a rectangular cell selection (anchor +\n * extension) and notifies a listener on every change. Pure logic, no DOM.\n */\nimport type { CellRange } from './cell-range';\n\nexport interface RangeSelectionEngineOptions {\n /** Called whenever the selection changes. */\n onChange?: (range: CellRange | null) => void;\n}\n\nexport class RangeSelectionEngine {\n private _selection: CellRange | null = null;\n private _anchor: { rowIndex: number; colIndex: number } | null = null;\n private readonly _onChange?: (range: CellRange | null) => void;\n\n constructor(options: RangeSelectionEngineOptions = {}) {\n this._onChange = options.onChange;\n }\n\n /** Begin a new selection at an anchor cell (mouse down / keyboard). */\n startSelection(rowIndex: number, colIndex: number): void {\n this._anchor = { rowIndex, colIndex };\n this._selection = {\n startRowIndex: rowIndex,\n endRowIndex: rowIndex,\n startColIndex: colIndex,\n endColIndex: colIndex,\n };\n this._notify();\n }\n\n /** Extend the selection to a new endpoint (mouse move / Shift+arrow). */\n extendSelection(rowIndex: number, colIndex: number): void {\n if (!this._anchor) {\n this.startSelection(rowIndex, colIndex);\n return;\n }\n this._selection = RangeSelectionEngine._normalize(\n this._anchor.rowIndex,\n this._anchor.colIndex,\n rowIndex,\n colIndex,\n );\n this._notify();\n }\n\n /** Programmatically set the selection range. */\n setSelection(range: CellRange | null): void {\n this._selection = range;\n this._anchor = range\n ? { rowIndex: range.startRowIndex, colIndex: range.startColIndex }\n : null;\n this._notify();\n }\n\n /** Clear the selection. */\n clear(): void {\n this._selection = null;\n this._anchor = null;\n this._notify();\n }\n\n getSelection(): CellRange | null {\n return this._selection;\n }\n\n /** Returns true if the given cell falls within the current selection. */\n isCellSelected(rowIndex: number, colIndex: number): boolean {\n const s = this._selection;\n if (!s) return false;\n return (\n rowIndex >= s.startRowIndex &&\n rowIndex <= s.endRowIndex &&\n colIndex >= s.startColIndex &&\n colIndex <= s.endColIndex\n );\n }\n\n /** Expand/contract the selection one step in a direction (keyboard nav). */\n expandByKey(\n key: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight',\n totalRows: number,\n totalCols: number,\n ): void {\n const s = this._selection;\n if (!s || !this._anchor) return;\n\n let { endRowIndex, endColIndex } = s;\n\n switch (key) {\n case 'ArrowUp':\n endRowIndex = Math.max(0, endRowIndex - 1);\n break;\n case 'ArrowDown':\n endRowIndex = Math.min(totalRows - 1, endRowIndex + 1);\n break;\n case 'ArrowLeft':\n endColIndex = Math.max(0, endColIndex - 1);\n break;\n case 'ArrowRight':\n endColIndex = Math.min(totalCols - 1, endColIndex + 1);\n break;\n }\n\n this._selection = RangeSelectionEngine._normalize(\n this._anchor.rowIndex,\n this._anchor.colIndex,\n endRowIndex,\n endColIndex,\n );\n this._notify();\n }\n\n private _notify(): void {\n this._onChange?.(this._selection);\n }\n\n /** Normalise anchor + endpoint into a top-left / bottom-right rectangle. */\n private static _normalize(r1: number, c1: number, r2: number, c2: number): CellRange {\n return {\n startRowIndex: Math.min(r1, r2),\n endRowIndex: Math.max(r1, r2),\n startColIndex: Math.min(c1, c2),\n endColIndex: Math.max(c1, c2),\n };\n }\n}\n","/**\n * ClipboardEngine — Ctrl+C/X/V over a selected cell range, serialised as TSV\n * (tab-separated) so it round-trips with Excel / Google Sheets. Pure logic;\n * the caller supplies cell get/set accessors.\n */\nimport type { RangeSelectionEngine } from './range-selection';\n\nexport interface ClipboardEngineOptions {\n getCellValue: (rowIndex: number, colIndex: number) => unknown;\n setCellValue: (rowIndex: number, colIndex: number, value: string) => void;\n getTotalCols: () => number;\n getTotalRows: () => number;\n onCopy?: (data: string[][]) => void;\n onPaste?: (data: string[][], startRow: number, startCol: number) => boolean | void;\n rangeSelection: RangeSelectionEngine;\n}\n\n/** Escape a cell value for TSV: quote it if it contains tab/newline/quotes. */\nfunction escapeTSV(value: unknown): string {\n const str = value == null ? '' : String(value);\n if (str.includes('\\t') || str.includes('\\n') || str.includes('\"')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n}\n\n/**\n * Parse TSV text into a 2-D array of strings. Character-by-character so it\n * handles quoted cells with embedded tabs/newlines, escaped quotes (\"\"),\n * trailing tabs, and CRLF/LF line endings.\n */\nexport function parseTSV(tsv: string): string[][] {\n if (!tsv) return [];\n\n const rows: string[][] = [];\n let currentRow: string[] = [];\n let i = 0;\n\n while (i <= tsv.length) {\n if (i === tsv.length) {\n if (currentRow.length > 0) rows.push(currentRow);\n break;\n }\n\n let cell = '';\n\n if (tsv[i] === '\"') {\n i++; // skip opening quote\n while (i < tsv.length) {\n if (tsv[i] === '\"' && tsv[i + 1] === '\"') {\n cell += '\"';\n i += 2;\n } else if (tsv[i] === '\"') {\n i++; // skip closing quote\n break;\n } else {\n cell += tsv[i++];\n }\n }\n } else {\n while (i < tsv.length && tsv[i] !== '\\t' && tsv[i] !== '\\n' && tsv[i] !== '\\r') {\n cell += tsv[i++];\n }\n }\n\n currentRow.push(cell);\n\n if (i < tsv.length) {\n if (tsv[i] === '\\t') {\n i++;\n // A tab at true end-of-string leaves a trailing empty cell; a tab\n // before a newline is handled by the next iteration reading it.\n if (i >= tsv.length) {\n currentRow.push('');\n }\n } else if (tsv[i] === '\\r') {\n i++;\n if (i < tsv.length && tsv[i] === '\\n') i++; // consume \\n of CRLF\n rows.push(currentRow);\n currentRow = [];\n } else if (tsv[i] === '\\n') {\n i++;\n rows.push(currentRow);\n currentRow = [];\n }\n }\n }\n\n return rows;\n}\n\nexport class ClipboardEngine {\n private readonly _opts: ClipboardEngineOptions;\n\n constructor(options: ClipboardEngineOptions) {\n this._opts = options;\n }\n\n /** Copy the selected range to the system clipboard as TSV. */\n async copy(): Promise<void> {\n const data = this._getSelectedData();\n if (!data) return;\n const tsv = data.map((row) => row.map(escapeTSV).join('\\t')).join('\\n');\n await navigator.clipboard.writeText(tsv);\n this._opts.onCopy?.(data);\n }\n\n /** Cut: copy then clear the selected range. */\n async cut(): Promise<void> {\n await this.copy();\n this._clearSelection();\n }\n\n /** Paste from the system clipboard into the top-left of the selection. */\n async paste(): Promise<void> {\n const text = await navigator.clipboard.readText();\n if (!text) return;\n\n const data = parseTSV(text);\n const selection = this._opts.rangeSelection.getSelection();\n const startRow = selection?.startRowIndex ?? 0;\n const startCol = selection?.startColIndex ?? 0;\n\n const shouldProceed = this._opts.onPaste?.(data, startRow, startCol);\n if (shouldProceed === false) return;\n\n const totalRows = this._opts.getTotalRows();\n const totalCols = this._opts.getTotalCols();\n\n for (let r = 0; r < data.length; r++) {\n for (let c = 0; c < data[r].length; c++) {\n const targetRow = startRow + r;\n const targetCol = startCol + c;\n if (targetRow >= totalRows || targetCol >= totalCols) continue;\n this._opts.setCellValue(targetRow, targetCol, data[r][c]);\n }\n }\n\n this._opts.rangeSelection.setSelection({\n startRowIndex: startRow,\n endRowIndex: Math.min(startRow + data.length - 1, totalRows - 1),\n startColIndex: startCol,\n endColIndex: Math.min(startCol + (data[0]?.length ?? 1) - 1, totalCols - 1),\n });\n }\n\n /** The selected cells as a raw string matrix (unescaped). */\n private _getSelectedData(): string[][] | null {\n const selection = this._opts.rangeSelection.getSelection();\n if (!selection) return null;\n\n const { startRowIndex, endRowIndex, startColIndex, endColIndex } = selection;\n const rows: string[][] = [];\n\n for (let r = startRowIndex; r <= endRowIndex; r++) {\n const row: string[] = [];\n for (let c = startColIndex; c <= endColIndex; c++) {\n const v = this._opts.getCellValue(r, c);\n row.push(v == null ? '' : String(v));\n }\n rows.push(row);\n }\n return rows;\n }\n\n private _clearSelection(): void {\n const selection = this._opts.rangeSelection.getSelection();\n if (!selection) return;\n\n const { startRowIndex, endRowIndex, startColIndex, endColIndex } = selection;\n for (let r = startRowIndex; r <= endRowIndex; r++) {\n for (let c = startColIndex; c <= endColIndex; c++) {\n this._opts.setCellValue(r, c, '');\n }\n }\n }\n}\n","/**\n * FillHandleEngine — computes the values to write when the user drags the fill\n * handle at the bottom-right of a range selection. Pure logic, no DOM.\n *\n * Modes:\n * 'copy' — repeat the source values into every target cell.\n * 'series' — continue a detected numeric / date / day-name / month-name\n * series; falls back to 'copy' when no series is detected.\n */\nimport type { CellRange } from './cell-range';\n\nexport type FillDirection = 'down' | 'up' | 'right' | 'left';\n\nexport interface FillCell {\n rowIndex: number;\n colIndex: number;\n value: unknown;\n}\n\nexport interface FillResult {\n direction: FillDirection;\n cells: FillCell[];\n}\n\nexport interface FillHandleEngineOptions {\n mode: 'copy' | 'series';\n getCellValue: (rowIndex: number, colIndex: number) => unknown;\n}\n\n/** Parse a value as a finite number, or null. */\nexport function toNumber(value: unknown): number | null {\n if (typeof value === 'number' && isFinite(value)) return value;\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n const n = Number(trimmed);\n return isFinite(n) ? n : null;\n }\n return null;\n}\n\n/** Parse a value as a Date timestamp (ms), or null. */\nexport function toTimestamp(value: unknown): number | null {\n if (value instanceof Date) return isNaN(value.getTime()) ? null : value.getTime();\n if (typeof value === 'string') {\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d.getTime();\n }\n return null;\n}\n\nconst DAY_NAMES = [\n ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'],\n ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],\n];\nconst MONTH_NAMES = [\n ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],\n ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'],\n];\n\ninterface NamedSeriesMatch {\n list: string[];\n index: number;\n originalCase: 'lower' | 'upper' | 'title';\n}\n\nfunction matchNamedSeries(value: unknown): NamedSeriesMatch | null {\n if (typeof value !== 'string') return null;\n const lower = value.trim().toLowerCase();\n for (const list of [...DAY_NAMES, ...MONTH_NAMES]) {\n const idx = list.indexOf(lower);\n if (idx !== -1) {\n const original = value.trim();\n const originalCase =\n original === original.toUpperCase()\n ? 'upper'\n : original[0] === original[0].toUpperCase()\n ? 'title'\n : 'lower';\n return { list, index: idx, originalCase };\n }\n }\n return null;\n}\n\nfunction applyCase(s: string, caseStyle: 'lower' | 'upper' | 'title'): string {\n if (caseStyle === 'upper') return s.toUpperCase();\n if (caseStyle === 'title') return s[0].toUpperCase() + s.slice(1).toLowerCase();\n return s.toLowerCase();\n}\n\nexport class FillHandleEngine {\n private readonly _opts: FillHandleEngineOptions;\n\n constructor(options: FillHandleEngineOptions) {\n this._opts = options;\n }\n\n /**\n * Compute the cells to fill given a source selection and the extended target\n * selection after dragging the handle. Returns null for an invalid drag.\n */\n computeFill(sourceRange: CellRange, targetRange: CellRange): FillResult | null {\n const direction = this._detectDirection(sourceRange, targetRange);\n if (!direction) return null;\n\n const sourceValues = this._extractSource(sourceRange, direction);\n const targetCells = this._buildTargetCells(sourceRange, targetRange, direction);\n\n const filledValues =\n this._opts.mode === 'series'\n ? this._fillSeries(sourceValues, targetCells.length)\n : this._fillCopy(sourceValues, targetCells.length);\n\n return {\n direction,\n cells: targetCells.map((cell, i) => ({ ...cell, value: filledValues[i] })),\n };\n }\n\n private _detectDirection(source: CellRange, target: CellRange): FillDirection | null {\n if (\n target.startRowIndex > source.startRowIndex ||\n target.endRowIndex < source.endRowIndex ||\n target.startColIndex > source.startColIndex ||\n target.endColIndex < source.endColIndex\n ) {\n return null;\n }\n\n const extendedDown = target.endRowIndex > source.endRowIndex;\n const extendedUp = target.startRowIndex < source.startRowIndex;\n const extendedRight = target.endColIndex > source.endColIndex;\n const extendedLeft = target.startColIndex < source.startColIndex;\n\n const directions = [extendedDown, extendedUp, extendedRight, extendedLeft].filter(Boolean);\n if (directions.length !== 1) return null;\n\n if (extendedDown) return 'down';\n if (extendedUp) return 'up';\n if (extendedRight) return 'right';\n return 'left';\n }\n\n private _extractSource(source: CellRange, direction: FillDirection): unknown[] {\n const values: unknown[] = [];\n if (direction === 'down' || direction === 'up') {\n for (let r = source.startRowIndex; r <= source.endRowIndex; r++) {\n values.push(this._opts.getCellValue(r, source.startColIndex));\n }\n } else {\n for (let c = source.startColIndex; c <= source.endColIndex; c++) {\n values.push(this._opts.getCellValue(source.startRowIndex, c));\n }\n }\n return values;\n }\n\n private _buildTargetCells(\n source: CellRange,\n target: CellRange,\n direction: FillDirection,\n ): { rowIndex: number; colIndex: number }[] {\n const cells: { rowIndex: number; colIndex: number }[] = [];\n\n if (direction === 'down') {\n for (let r = source.endRowIndex + 1; r <= target.endRowIndex; r++) {\n for (let c = source.startColIndex; c <= source.endColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n } else if (direction === 'up') {\n for (let r = target.startRowIndex; r < source.startRowIndex; r++) {\n for (let c = source.startColIndex; c <= source.endColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n } else if (direction === 'right') {\n for (let r = source.startRowIndex; r <= source.endRowIndex; r++) {\n for (let c = source.endColIndex + 1; c <= target.endColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n } else {\n for (let r = source.startRowIndex; r <= source.endRowIndex; r++) {\n for (let c = target.startColIndex; c < source.startColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n }\n\n return cells;\n }\n\n private _fillCopy(source: unknown[], count: number): unknown[] {\n const result: unknown[] = [];\n for (let i = 0; i < count; i++) {\n result.push(source[i % source.length]);\n }\n return result;\n }\n\n private _fillSeries(source: unknown[], count: number): unknown[] {\n if (source.length >= 1) {\n const match = matchNamedSeries(source[0]);\n if (match) return this._fillNamedSeries(source, count, match);\n }\n\n const nums = source.map(toNumber);\n if (nums.every((n) => n !== null)) {\n return this._fillNumericSeries(nums as number[], count);\n }\n\n const timestamps = source.map(toTimestamp);\n if (timestamps.every((t) => t !== null)) {\n return this._fillDateSeries(source, timestamps as number[], count);\n }\n\n return this._fillCopy(source, count);\n }\n\n private _fillNumericSeries(source: number[], count: number): number[] {\n const step = source.length > 1 ? source[1] - source[0] : 1;\n const last = source[source.length - 1];\n const result: number[] = [];\n for (let i = 1; i <= count; i++) {\n result.push(last + step * i);\n }\n return result;\n }\n\n private _fillDateSeries(originalSource: unknown[], timestamps: number[], count: number): string[] {\n const step = timestamps.length > 1 ? timestamps[1] - timestamps[0] : 24 * 60 * 60 * 1000;\n const last = timestamps[timestamps.length - 1];\n\n const sampleStr = typeof originalSource[0] === 'string' ? (originalSource[0] as string) : '';\n const isDateOnly = /^\\d{4}-\\d{2}-\\d{2}$/.test(sampleStr.trim());\n\n return Array.from({ length: count }, (_, i) => {\n const d = new Date(last + step * (i + 1));\n return isDateOnly ? d.toISOString().slice(0, 10) : d.toISOString();\n });\n }\n\n private _fillNamedSeries(source: unknown[], count: number, match: NamedSeriesMatch): string[] {\n const { list, index: firstIndex, originalCase } = match;\n const indexOf = (v: unknown) =>\n typeof v === 'string' ? list.indexOf(v.trim().toLowerCase()) : -1;\n\n const lastIndex = indexOf(source[source.length - 1]);\n const startIndex = lastIndex >= 0 ? lastIndex : firstIndex;\n const secondIndex = source.length > 1 ? indexOf(source[1]) : -1;\n const step =\n secondIndex >= 0 ? ((secondIndex - firstIndex + list.length) % list.length) || 1 : 1;\n\n const result: string[] = [];\n for (let i = 1; i <= count; i++) {\n const nextIndex = (((startIndex + step * i) % list.length) + list.length) % list.length;\n result.push(applyCase(list[nextIndex], originalCase));\n }\n return result;\n }\n}\n","/**\n * UndoRedoManager — a bounded undo/redo command stack. Each command stores\n * enough state to reverse itself; the manager applies changes through the\n * `applyValue` callback the host supplies (it never mutates data directly).\n */\n\nexport interface CellEditCommand {\n type: 'cellEdit';\n rowId: string | number;\n field: string;\n prevValue: unknown;\n nextValue: unknown;\n}\n\nexport interface PasteCommand {\n type: 'paste';\n cells: { rowId: string | number; field: string; prevValue: unknown; nextValue: unknown }[];\n}\n\nexport interface FillCommand {\n type: 'fill';\n cells: { rowId: string | number; field: string; prevValue: unknown; nextValue: unknown }[];\n}\n\nexport interface DeleteCommand {\n type: 'delete';\n cells: { rowId: string | number; field: string; prevValue: unknown }[];\n}\n\nexport type UndoRedoCommand = CellEditCommand | PasteCommand | FillCommand | DeleteCommand;\n\nexport interface UndoRedoManagerOptions {\n /** Maximum number of undo steps to retain. Default: 100 */\n maxStackSize?: number;\n /** Called whenever canUndo or canRedo changes. */\n onChange?: (canUndo: boolean, canRedo: boolean) => void;\n /** Applies a value to a cell — the manager calls this to (un)apply commands. */\n applyValue: (rowId: string | number, field: string, value: unknown) => void;\n}\n\nexport class UndoRedoManager {\n private readonly _undoStack: UndoRedoCommand[] = [];\n private readonly _redoStack: UndoRedoCommand[] = [];\n private readonly _maxStackSize: number;\n private readonly _onChange?: (canUndo: boolean, canRedo: boolean) => void;\n private readonly _applyValue: (rowId: string | number, field: string, value: unknown) => void;\n\n constructor(options: UndoRedoManagerOptions) {\n this._maxStackSize = options.maxStackSize ?? 100;\n this._onChange = options.onChange;\n this._applyValue = options.applyValue;\n }\n\n /** Push a new command onto the undo stack. Clears the redo stack. */\n push(command: UndoRedoCommand): void {\n this._undoStack.push(command);\n if (this._undoStack.length > this._maxStackSize) {\n this._undoStack.shift();\n }\n this._redoStack.length = 0;\n this._notifyChange();\n }\n\n /** Undo the most recent command. */\n undo(): void {\n const command = this._undoStack.pop();\n if (!command) return;\n this._applyCommandReverse(command);\n this._redoStack.push(command);\n this._notifyChange();\n }\n\n /** Redo the most recently undone command. */\n redo(): void {\n const command = this._redoStack.pop();\n if (!command) return;\n this._applyCommandForward(command);\n this._undoStack.push(command);\n this._notifyChange();\n }\n\n canUndo(): boolean {\n return this._undoStack.length > 0;\n }\n\n canRedo(): boolean {\n return this._redoStack.length > 0;\n }\n\n /** Clear both stacks (e.g. after a full data reload). */\n clear(): void {\n this._undoStack.length = 0;\n this._redoStack.length = 0;\n this._notifyChange();\n }\n\n undoStackSize(): number {\n return this._undoStack.length;\n }\n\n redoStackSize(): number {\n return this._redoStack.length;\n }\n\n private _applyCommandReverse(command: UndoRedoCommand): void {\n switch (command.type) {\n case 'cellEdit':\n this._applyValue(command.rowId, command.field, command.prevValue);\n break;\n case 'paste':\n case 'fill':\n case 'delete':\n for (const cell of command.cells) {\n this._applyValue(cell.rowId, cell.field, cell.prevValue);\n }\n break;\n }\n }\n\n private _applyCommandForward(command: UndoRedoCommand): void {\n switch (command.type) {\n case 'cellEdit':\n this._applyValue(command.rowId, command.field, command.nextValue);\n break;\n case 'paste':\n case 'fill':\n for (const cell of command.cells) {\n this._applyValue(cell.rowId, cell.field, cell.nextValue);\n }\n break;\n case 'delete':\n for (const cell of command.cells) {\n this._applyValue(cell.rowId, cell.field, '');\n }\n break;\n }\n }\n\n private _notifyChange(): void {\n this._onChange?.(this.canUndo(), this.canRedo());\n }\n}\n","/*\n * Public API Surface of @gridengine/angular-datagrid-enterprise\n *\n * Re-exports the open-source base grid so consumers need a single import, then\n * adds the license-gated Pro surface on top.\n */\n\n// ── Base grid (full re-export) ──────────────────────────────────────────────\nexport * from '@gridengine/angular-datagrid';\n\n// ── Pro component ───────────────────────────────────────────────────────────\nexport { DataGridPro } from './lib/data-grid-pro';\nexport { GridLicenseWatermark } from './lib/license-watermark';\n\n// ── License ─────────────────────────────────────────────────────────────────\nexport { LicenseManager, TIER_FEATURES } from './lib/license-manager';\nexport type {\n LicensePayload,\n LicenseTier,\n SupportLevel,\n LicenseStatus,\n LicenseValidationResult,\n} from './lib/license-manager';\nexport { provideGridEngineLicense } from './lib/provide-license';\nexport { PRODUCT_ID, PURCHASE_URL } from './lib/keyring';\n\n// ── Spreadsheet feature engines (framework-agnostic, usable standalone) ──────\nexport type { CellRange } from './lib/features/cell-range';\nexport { RangeSelectionEngine } from './lib/features/range-selection';\nexport type { RangeSelectionEngineOptions } from './lib/features/range-selection';\nexport { ClipboardEngine, parseTSV } from './lib/features/clipboard';\nexport type { ClipboardEngineOptions } from './lib/features/clipboard';\nexport { FillHandleEngine, toNumber, toTimestamp } from './lib/features/fill-handle';\nexport type {\n FillDirection,\n FillCell,\n FillResult,\n FillHandleEngineOptions,\n} from './lib/features/fill-handle';\nexport { UndoRedoManager } from './lib/features/undo-redo';\nexport type {\n UndoRedoCommand,\n CellEditCommand,\n PasteCommand,\n FillCommand,\n DeleteCommand,\n UndoRedoManagerOptions,\n} from './lib/features/undo-redo';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["coreResolveFeatures"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gridengine-angular-datagrid-enterprise.mjs","sources":["../../../projects/enterprise/src/lib/keyring.ts","../../../projects/enterprise/src/lib/license-manager.ts","../../../projects/enterprise/src/lib/license-watermark.ts","../../../projects/enterprise/src/lib/data-grid-pro.ts","../../../projects/enterprise/src/lib/provide-license.ts","../../../projects/enterprise/src/lib/features/range-selection.ts","../../../projects/enterprise/src/lib/features/clipboard.ts","../../../projects/enterprise/src/lib/features/fill-handle.ts","../../../projects/enterprise/src/lib/features/undo-redo.ts","../../../projects/enterprise/src/lib/features/formula.ts","../../../projects/enterprise/src/public-api.ts","../../../projects/enterprise/src/gridengine-angular-datagrid-enterprise.ts"],"sourcesContent":["/**\n * Public verifying keys for GridEngine Angular license keys.\n *\n * These are Ed25519 PUBLIC keys, keyed by `keyId` — safe to ship in the bundle\n * (they can only verify signatures, never mint keys). The matching PRIVATE key\n * lives only in the GridEngine store backend (Azure Key Vault secret\n * `signing-angular-datagrid`). Rotate by adding a new keyId here alongside the\n * old one, until previously issued keys expire.\n */\nimport type { PublicKeyRing } from '@gridengine/license-core';\n\n/** The product id GridEngine license keys are scoped to for this package. */\nexport const PRODUCT_ID = 'angular-datagrid';\n\n/** Where a buyer can purchase / activate a license. */\nexport const PURCHASE_URL = 'https://angular.gridengine.dev/pricing';\n\nexport const PUBLIC_KEYRING: PublicKeyRing = {\n 'angular-datagrid-2026-08-09': 'GJx3r0A-xL2Q3-poGd3WbOh_B0EN9wwWOxMdksxs_S4',\n};\n","/**\n * LicenseManager — validates a `@gridengine/angular-datagrid-enterprise` license key.\n *\n * Verification uses `@gridengine/license-core` (Ed25519, keyring-based) — the\n * same scheme the GridEngine store uses to sign keys after a real purchase. The\n * private signing key lives only in the store's backend (Key Vault); this\n * package ships only the matching PUBLIC verifying key, so it can check a key's\n * authenticity but never mint one.\n *\n * This is soft licensing, not DRM: validation is synchronous and client-side,\n * and a determined user could strip the check from their own bundle. Server-\n * side entitlement checks remain authoritative for anything that matters.\n *\n * Feature access is derived from the license TIER (see `TIER_FEATURES`), with\n * `payload.features` allowed to grant additional flags on top. The support\n * level is metadata only — it never gates any in-bundle behaviour.\n */\nimport {\n validateLicense,\n resolveFeatures as coreResolveFeatures,\n TIER_FEATURES,\n type LicensePayload,\n type LicenseTier,\n type SupportLevel,\n type LicenseStatus,\n type LicenseValidationResult,\n type PublicKeyRing,\n} from '@gridengine/license-core';\nimport { PRODUCT_ID, PURCHASE_URL, PUBLIC_KEYRING } from './keyring';\n\nexport type {\n LicensePayload,\n LicenseTier,\n SupportLevel,\n LicenseStatus,\n LicenseValidationResult,\n};\nexport { TIER_FEATURES };\n\nconst _cache = new Map<string, LicenseValidationResult>();\n\n/**\n * Global license key, set once at app bootstrap (typically via\n * `provideGridEngineLicense(key)`) so every `<gd-data-grid-pro>` in the app\n * picks it up without needing a `licenseKey` input on each instance. A\n * `licenseKey` input, when given, still overrides this for that instance.\n */\nlet _globalLicenseKey: string | undefined;\n\n/** Set the license key once for the whole app (e.g. at app bootstrap). */\nfunction setLicenseKey(key: string | undefined): void {\n _globalLicenseKey = key;\n}\n\n/** The key previously set via `setLicenseKey`, if any. */\nfunction getLicenseKey(): string | undefined {\n return _globalLicenseKey;\n}\n\n/**\n * Validate a key against an arbitrary keyring. Exported (but not part of the\n * public `LicenseManager` API surface) so tests can verify against a throwaway\n * test keypair instead of the real production keyring.\n */\nexport function validateWithKeyring(\n key: string | undefined,\n keys: PublicKeyRing | string,\n): LicenseValidationResult {\n if (!key) {\n return {\n status: 'missing',\n payload: null,\n message:\n 'No @gridengine/angular-datagrid-enterprise license key provided. ' +\n 'A watermark will be displayed. ' +\n `Purchase a license at ${PURCHASE_URL}`,\n };\n }\n return validateLicense(key, keys, PRODUCT_ID);\n}\n\n/**\n * Validate a license key string. Results are cached per key so validation runs\n * at most once per key per session.\n */\nfunction validate(key: string | undefined): LicenseValidationResult {\n if (!key) return validateWithKeyring(key, PUBLIC_KEYRING);\n\n const cached = _cache.get(key);\n if (cached) return cached;\n\n const result = validateWithKeyring(key, PUBLIC_KEYRING);\n _cache.set(key, result);\n return result;\n}\n\n/**\n * The set of feature flags granted by a validated payload: the tier defaults\n * plus any explicit extras in `payload.features`.\n */\nfunction resolveFeatures(payload: LicensePayload): Set<string> {\n return coreResolveFeatures(payload);\n}\n\n/**\n * Check whether a specific feature is enabled for a key, against an arbitrary\n * keyring. Exported (but not part of the public `LicenseManager` API surface)\n * so tests can exercise this without the real production keyring.\n */\nexport function isFeatureEnabledWithKeyring(\n key: string | undefined,\n feature: string,\n keys: PublicKeyRing | string,\n): boolean {\n if (!key) return true; // evaluation mode\n const result = validateWithKeyring(key, keys);\n if (result.status !== 'valid' || !result.payload) return false;\n return resolveFeatures(result.payload).has(feature);\n}\n\n/**\n * Check whether a specific feature is enabled for a given key. Returns true\n * when no key is given (evaluation mode — features accessible but watermarked),\n * and false for any non-valid license.\n */\nfunction isFeatureEnabled(key: string | undefined, feature: string): boolean {\n if (!key) return true; // evaluation mode\n const result = validate(key);\n if (result.status !== 'valid' || !result.payload) return false;\n return resolveFeatures(result.payload).has(feature);\n}\n\nexport const LicenseManager = {\n validate,\n isFeatureEnabled,\n setLicenseKey,\n getLicenseKey,\n TIER_FEATURES,\n} as const;\n","/**\n * GridLicenseWatermark — a subtle, non-blocking evaluation watermark shown in\n * the corner of an enterprise grid when no valid license key is provided.\n *\n * The grid stays fully functional in evaluation mode; this only signals that a\n * license is required for production use. It is rendered automatically by\n * `<gd-data-grid-pro>` but is also exported for advanced consumers who compose\n * the grid themselves.\n */\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { PURCHASE_URL } from './keyring';\n\n@Component({\n selector: 'gd-license-watermark',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"gd-license-watermark\" aria-hidden=\"true\">\n {{ label() }} — unlicensed — <span class=\"gd-license-watermark__url\">{{ url() }}</span>\n </div>\n `,\n styles: [\n `\n .gd-license-watermark {\n position: absolute;\n bottom: 8px;\n right: 12px;\n z-index: 10;\n font-family: sans-serif;\n font-size: 11px;\n letter-spacing: 0.02em;\n color: rgba(0, 0, 0, 0.35);\n pointer-events: none;\n user-select: none;\n }\n .gd-license-watermark__url {\n text-decoration: underline;\n }\n `,\n ],\n})\nexport class GridLicenseWatermark {\n /** Package label shown in the watermark. */\n readonly label = input('@gridengine/angular-datagrid-enterprise');\n /** Purchase URL shown in the watermark. */\n readonly url = input(PURCHASE_URL);\n}\n","/**\n * DataGridPro — the license-aware wrapper for the GridEngine Angular grid.\n *\n * Projects a base `<gd-data-grid>` (or any content) and overlays an evaluation\n * watermark when no valid license key is present. The grid remains fully\n * functional without a license (evaluation mode); this component only adds the\n * watermark + a one-time console warning.\n *\n * ```html\n * <gd-data-grid-pro [licenseKey]=\"key\">\n * <gd-data-grid [rowData]=\"rows\" [columnDefs]=\"cols\" />\n * </gd-data-grid-pro>\n * ```\n *\n * A `[licenseKey]` input overrides the app-wide key set via\n * `provideGridEngineLicense()` / `LicenseManager.setLicenseKey()`.\n */\nimport { ChangeDetectionStrategy, Component, computed, effect, input } from '@angular/core';\nimport type { LicenseValidationResult } from '@gridengine/license-core';\nimport { LicenseManager } from './license-manager';\nimport { GridLicenseWatermark } from './license-watermark';\n\n@Component({\n selector: 'gd-data-grid-pro',\n standalone: true,\n imports: [GridLicenseWatermark],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"gd-data-grid-pro\">\n <ng-content />\n @if (showWatermark()) {\n <gd-license-watermark />\n }\n </div>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n .gd-data-grid-pro {\n position: relative;\n display: block;\n }\n `,\n ],\n})\nexport class DataGridPro {\n /** Per-instance license key; overrides the app-wide key when provided. */\n readonly licenseKey = input<string | undefined>(undefined);\n\n protected readonly licenseResult = computed<LicenseValidationResult>(() =>\n LicenseManager.validate(this.licenseKey() ?? LicenseManager.getLicenseKey()),\n );\n\n protected readonly showWatermark = computed(() => this.licenseResult().status !== 'valid');\n\n private warned = false;\n\n constructor() {\n effect(() => {\n const result = this.licenseResult();\n if (!this.warned && result.status !== 'valid') {\n console.warn(`[@gridengine/angular-datagrid-enterprise] ${result.message}`);\n this.warned = true;\n }\n });\n }\n\n /** The current license validation result (for advanced consumers). */\n getLicenseResult(): LicenseValidationResult {\n return this.licenseResult();\n }\n}\n","/**\n * `provideGridEngineLicense` — register a GridEngine Angular license key once\n * for the whole application at bootstrap.\n *\n * Usage (standalone bootstrap):\n *\n * ```ts\n * bootstrapApplication(App, {\n * providers: [provideGridEngineLicense('BASE64URL.payload.signature')],\n * });\n * ```\n *\n * Every `<gd-data-grid-pro>` in the app then picks the key up automatically via\n * `LicenseManager.getLicenseKey()`; a per-instance `[licenseKey]` input still\n * overrides it for that instance.\n */\nimport { makeEnvironmentProviders, provideEnvironmentInitializer } from '@angular/core';\nimport type { EnvironmentProviders } from '@angular/core';\nimport { LicenseManager } from './license-manager';\n\nexport function provideGridEngineLicense(key: string | undefined): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => LicenseManager.setLicenseKey(key)),\n ]);\n}\n","/**\n * RangeSelectionEngine — tracks a rectangular cell selection (anchor +\n * extension) and notifies a listener on every change. Pure logic, no DOM.\n */\nimport type { CellRange } from './cell-range';\n\nexport interface RangeSelectionEngineOptions {\n /** Called whenever the selection changes. */\n onChange?: (range: CellRange | null) => void;\n}\n\nexport class RangeSelectionEngine {\n private _selection: CellRange | null = null;\n private _anchor: { rowIndex: number; colIndex: number } | null = null;\n private readonly _onChange?: (range: CellRange | null) => void;\n\n constructor(options: RangeSelectionEngineOptions = {}) {\n this._onChange = options.onChange;\n }\n\n /** Begin a new selection at an anchor cell (mouse down / keyboard). */\n startSelection(rowIndex: number, colIndex: number): void {\n this._anchor = { rowIndex, colIndex };\n this._selection = {\n startRowIndex: rowIndex,\n endRowIndex: rowIndex,\n startColIndex: colIndex,\n endColIndex: colIndex,\n };\n this._notify();\n }\n\n /** Extend the selection to a new endpoint (mouse move / Shift+arrow). */\n extendSelection(rowIndex: number, colIndex: number): void {\n if (!this._anchor) {\n this.startSelection(rowIndex, colIndex);\n return;\n }\n this._selection = RangeSelectionEngine._normalize(\n this._anchor.rowIndex,\n this._anchor.colIndex,\n rowIndex,\n colIndex,\n );\n this._notify();\n }\n\n /** Programmatically set the selection range. */\n setSelection(range: CellRange | null): void {\n this._selection = range;\n this._anchor = range\n ? { rowIndex: range.startRowIndex, colIndex: range.startColIndex }\n : null;\n this._notify();\n }\n\n /** Clear the selection. */\n clear(): void {\n this._selection = null;\n this._anchor = null;\n this._notify();\n }\n\n getSelection(): CellRange | null {\n return this._selection;\n }\n\n /** Returns true if the given cell falls within the current selection. */\n isCellSelected(rowIndex: number, colIndex: number): boolean {\n const s = this._selection;\n if (!s) return false;\n return (\n rowIndex >= s.startRowIndex &&\n rowIndex <= s.endRowIndex &&\n colIndex >= s.startColIndex &&\n colIndex <= s.endColIndex\n );\n }\n\n /** Expand/contract the selection one step in a direction (keyboard nav). */\n expandByKey(\n key: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight',\n totalRows: number,\n totalCols: number,\n ): void {\n const s = this._selection;\n if (!s || !this._anchor) return;\n\n let { endRowIndex, endColIndex } = s;\n\n switch (key) {\n case 'ArrowUp':\n endRowIndex = Math.max(0, endRowIndex - 1);\n break;\n case 'ArrowDown':\n endRowIndex = Math.min(totalRows - 1, endRowIndex + 1);\n break;\n case 'ArrowLeft':\n endColIndex = Math.max(0, endColIndex - 1);\n break;\n case 'ArrowRight':\n endColIndex = Math.min(totalCols - 1, endColIndex + 1);\n break;\n }\n\n this._selection = RangeSelectionEngine._normalize(\n this._anchor.rowIndex,\n this._anchor.colIndex,\n endRowIndex,\n endColIndex,\n );\n this._notify();\n }\n\n private _notify(): void {\n this._onChange?.(this._selection);\n }\n\n /** Normalise anchor + endpoint into a top-left / bottom-right rectangle. */\n private static _normalize(r1: number, c1: number, r2: number, c2: number): CellRange {\n return {\n startRowIndex: Math.min(r1, r2),\n endRowIndex: Math.max(r1, r2),\n startColIndex: Math.min(c1, c2),\n endColIndex: Math.max(c1, c2),\n };\n }\n}\n","/**\n * ClipboardEngine — Ctrl+C/X/V over a selected cell range, serialised as TSV\n * (tab-separated) so it round-trips with Excel / Google Sheets. Pure logic;\n * the caller supplies cell get/set accessors.\n */\nimport type { RangeSelectionEngine } from './range-selection';\n\nexport interface ClipboardEngineOptions {\n getCellValue: (rowIndex: number, colIndex: number) => unknown;\n setCellValue: (rowIndex: number, colIndex: number, value: string) => void;\n getTotalCols: () => number;\n getTotalRows: () => number;\n onCopy?: (data: string[][]) => void;\n onPaste?: (data: string[][], startRow: number, startCol: number) => boolean | void;\n rangeSelection: RangeSelectionEngine;\n}\n\n/** Escape a cell value for TSV: quote it if it contains tab/newline/quotes. */\nfunction escapeTSV(value: unknown): string {\n const str = value == null ? '' : String(value);\n if (str.includes('\\t') || str.includes('\\n') || str.includes('\"')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n}\n\n/**\n * Parse TSV text into a 2-D array of strings. Character-by-character so it\n * handles quoted cells with embedded tabs/newlines, escaped quotes (\"\"),\n * trailing tabs, and CRLF/LF line endings.\n */\nexport function parseTSV(tsv: string): string[][] {\n if (!tsv) return [];\n\n const rows: string[][] = [];\n let currentRow: string[] = [];\n let i = 0;\n\n while (i <= tsv.length) {\n if (i === tsv.length) {\n if (currentRow.length > 0) rows.push(currentRow);\n break;\n }\n\n let cell = '';\n\n if (tsv[i] === '\"') {\n i++; // skip opening quote\n while (i < tsv.length) {\n if (tsv[i] === '\"' && tsv[i + 1] === '\"') {\n cell += '\"';\n i += 2;\n } else if (tsv[i] === '\"') {\n i++; // skip closing quote\n break;\n } else {\n cell += tsv[i++];\n }\n }\n } else {\n while (i < tsv.length && tsv[i] !== '\\t' && tsv[i] !== '\\n' && tsv[i] !== '\\r') {\n cell += tsv[i++];\n }\n }\n\n currentRow.push(cell);\n\n if (i < tsv.length) {\n if (tsv[i] === '\\t') {\n i++;\n // A tab at true end-of-string leaves a trailing empty cell; a tab\n // before a newline is handled by the next iteration reading it.\n if (i >= tsv.length) {\n currentRow.push('');\n }\n } else if (tsv[i] === '\\r') {\n i++;\n if (i < tsv.length && tsv[i] === '\\n') i++; // consume \\n of CRLF\n rows.push(currentRow);\n currentRow = [];\n } else if (tsv[i] === '\\n') {\n i++;\n rows.push(currentRow);\n currentRow = [];\n }\n }\n }\n\n return rows;\n}\n\nexport class ClipboardEngine {\n private readonly _opts: ClipboardEngineOptions;\n\n constructor(options: ClipboardEngineOptions) {\n this._opts = options;\n }\n\n /** Copy the selected range to the system clipboard as TSV. */\n async copy(): Promise<void> {\n const data = this._getSelectedData();\n if (!data) return;\n const tsv = data.map((row) => row.map(escapeTSV).join('\\t')).join('\\n');\n await navigator.clipboard.writeText(tsv);\n this._opts.onCopy?.(data);\n }\n\n /** Cut: copy then clear the selected range. */\n async cut(): Promise<void> {\n await this.copy();\n this._clearSelection();\n }\n\n /** Paste from the system clipboard into the top-left of the selection. */\n async paste(): Promise<void> {\n const text = await navigator.clipboard.readText();\n if (!text) return;\n\n const data = parseTSV(text);\n const selection = this._opts.rangeSelection.getSelection();\n const startRow = selection?.startRowIndex ?? 0;\n const startCol = selection?.startColIndex ?? 0;\n\n const shouldProceed = this._opts.onPaste?.(data, startRow, startCol);\n if (shouldProceed === false) return;\n\n const totalRows = this._opts.getTotalRows();\n const totalCols = this._opts.getTotalCols();\n\n for (let r = 0; r < data.length; r++) {\n for (let c = 0; c < data[r].length; c++) {\n const targetRow = startRow + r;\n const targetCol = startCol + c;\n if (targetRow >= totalRows || targetCol >= totalCols) continue;\n this._opts.setCellValue(targetRow, targetCol, data[r][c]);\n }\n }\n\n this._opts.rangeSelection.setSelection({\n startRowIndex: startRow,\n endRowIndex: Math.min(startRow + data.length - 1, totalRows - 1),\n startColIndex: startCol,\n endColIndex: Math.min(startCol + (data[0]?.length ?? 1) - 1, totalCols - 1),\n });\n }\n\n /** The selected cells as a raw string matrix (unescaped). */\n private _getSelectedData(): string[][] | null {\n const selection = this._opts.rangeSelection.getSelection();\n if (!selection) return null;\n\n const { startRowIndex, endRowIndex, startColIndex, endColIndex } = selection;\n const rows: string[][] = [];\n\n for (let r = startRowIndex; r <= endRowIndex; r++) {\n const row: string[] = [];\n for (let c = startColIndex; c <= endColIndex; c++) {\n const v = this._opts.getCellValue(r, c);\n row.push(v == null ? '' : String(v));\n }\n rows.push(row);\n }\n return rows;\n }\n\n private _clearSelection(): void {\n const selection = this._opts.rangeSelection.getSelection();\n if (!selection) return;\n\n const { startRowIndex, endRowIndex, startColIndex, endColIndex } = selection;\n for (let r = startRowIndex; r <= endRowIndex; r++) {\n for (let c = startColIndex; c <= endColIndex; c++) {\n this._opts.setCellValue(r, c, '');\n }\n }\n }\n}\n","/**\n * FillHandleEngine — computes the values to write when the user drags the fill\n * handle at the bottom-right of a range selection. Pure logic, no DOM.\n *\n * Modes:\n * 'copy' — repeat the source values into every target cell.\n * 'series' — continue a detected numeric / date / day-name / month-name\n * series; falls back to 'copy' when no series is detected.\n */\nimport type { CellRange } from './cell-range';\n\nexport type FillDirection = 'down' | 'up' | 'right' | 'left';\n\nexport interface FillCell {\n rowIndex: number;\n colIndex: number;\n value: unknown;\n}\n\nexport interface FillResult {\n direction: FillDirection;\n cells: FillCell[];\n}\n\nexport interface FillHandleEngineOptions {\n mode: 'copy' | 'series';\n getCellValue: (rowIndex: number, colIndex: number) => unknown;\n}\n\n/** Parse a value as a finite number, or null. */\nexport function toNumber(value: unknown): number | null {\n if (typeof value === 'number' && isFinite(value)) return value;\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n const n = Number(trimmed);\n return isFinite(n) ? n : null;\n }\n return null;\n}\n\n/** Parse a value as a Date timestamp (ms), or null. */\nexport function toTimestamp(value: unknown): number | null {\n if (value instanceof Date) return isNaN(value.getTime()) ? null : value.getTime();\n if (typeof value === 'string') {\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d.getTime();\n }\n return null;\n}\n\nconst DAY_NAMES = [\n ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'],\n ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],\n];\nconst MONTH_NAMES = [\n ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],\n ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'],\n];\n\ninterface NamedSeriesMatch {\n list: string[];\n index: number;\n originalCase: 'lower' | 'upper' | 'title';\n}\n\nfunction matchNamedSeries(value: unknown): NamedSeriesMatch | null {\n if (typeof value !== 'string') return null;\n const lower = value.trim().toLowerCase();\n for (const list of [...DAY_NAMES, ...MONTH_NAMES]) {\n const idx = list.indexOf(lower);\n if (idx !== -1) {\n const original = value.trim();\n const originalCase =\n original === original.toUpperCase()\n ? 'upper'\n : original[0] === original[0].toUpperCase()\n ? 'title'\n : 'lower';\n return { list, index: idx, originalCase };\n }\n }\n return null;\n}\n\nfunction applyCase(s: string, caseStyle: 'lower' | 'upper' | 'title'): string {\n if (caseStyle === 'upper') return s.toUpperCase();\n if (caseStyle === 'title') return s[0].toUpperCase() + s.slice(1).toLowerCase();\n return s.toLowerCase();\n}\n\nexport class FillHandleEngine {\n private readonly _opts: FillHandleEngineOptions;\n\n constructor(options: FillHandleEngineOptions) {\n this._opts = options;\n }\n\n /**\n * Compute the cells to fill given a source selection and the extended target\n * selection after dragging the handle. Returns null for an invalid drag.\n */\n computeFill(sourceRange: CellRange, targetRange: CellRange): FillResult | null {\n const direction = this._detectDirection(sourceRange, targetRange);\n if (!direction) return null;\n\n const sourceValues = this._extractSource(sourceRange, direction);\n const targetCells = this._buildTargetCells(sourceRange, targetRange, direction);\n\n const filledValues =\n this._opts.mode === 'series'\n ? this._fillSeries(sourceValues, targetCells.length)\n : this._fillCopy(sourceValues, targetCells.length);\n\n return {\n direction,\n cells: targetCells.map((cell, i) => ({ ...cell, value: filledValues[i] })),\n };\n }\n\n private _detectDirection(source: CellRange, target: CellRange): FillDirection | null {\n if (\n target.startRowIndex > source.startRowIndex ||\n target.endRowIndex < source.endRowIndex ||\n target.startColIndex > source.startColIndex ||\n target.endColIndex < source.endColIndex\n ) {\n return null;\n }\n\n const extendedDown = target.endRowIndex > source.endRowIndex;\n const extendedUp = target.startRowIndex < source.startRowIndex;\n const extendedRight = target.endColIndex > source.endColIndex;\n const extendedLeft = target.startColIndex < source.startColIndex;\n\n const directions = [extendedDown, extendedUp, extendedRight, extendedLeft].filter(Boolean);\n if (directions.length !== 1) return null;\n\n if (extendedDown) return 'down';\n if (extendedUp) return 'up';\n if (extendedRight) return 'right';\n return 'left';\n }\n\n private _extractSource(source: CellRange, direction: FillDirection): unknown[] {\n const values: unknown[] = [];\n if (direction === 'down' || direction === 'up') {\n for (let r = source.startRowIndex; r <= source.endRowIndex; r++) {\n values.push(this._opts.getCellValue(r, source.startColIndex));\n }\n } else {\n for (let c = source.startColIndex; c <= source.endColIndex; c++) {\n values.push(this._opts.getCellValue(source.startRowIndex, c));\n }\n }\n return values;\n }\n\n private _buildTargetCells(\n source: CellRange,\n target: CellRange,\n direction: FillDirection,\n ): { rowIndex: number; colIndex: number }[] {\n const cells: { rowIndex: number; colIndex: number }[] = [];\n\n if (direction === 'down') {\n for (let r = source.endRowIndex + 1; r <= target.endRowIndex; r++) {\n for (let c = source.startColIndex; c <= source.endColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n } else if (direction === 'up') {\n for (let r = target.startRowIndex; r < source.startRowIndex; r++) {\n for (let c = source.startColIndex; c <= source.endColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n } else if (direction === 'right') {\n for (let r = source.startRowIndex; r <= source.endRowIndex; r++) {\n for (let c = source.endColIndex + 1; c <= target.endColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n } else {\n for (let r = source.startRowIndex; r <= source.endRowIndex; r++) {\n for (let c = target.startColIndex; c < source.startColIndex; c++) {\n cells.push({ rowIndex: r, colIndex: c });\n }\n }\n }\n\n return cells;\n }\n\n private _fillCopy(source: unknown[], count: number): unknown[] {\n const result: unknown[] = [];\n for (let i = 0; i < count; i++) {\n result.push(source[i % source.length]);\n }\n return result;\n }\n\n private _fillSeries(source: unknown[], count: number): unknown[] {\n if (source.length >= 1) {\n const match = matchNamedSeries(source[0]);\n if (match) return this._fillNamedSeries(source, count, match);\n }\n\n const nums = source.map(toNumber);\n if (nums.every((n) => n !== null)) {\n return this._fillNumericSeries(nums as number[], count);\n }\n\n const timestamps = source.map(toTimestamp);\n if (timestamps.every((t) => t !== null)) {\n return this._fillDateSeries(source, timestamps as number[], count);\n }\n\n return this._fillCopy(source, count);\n }\n\n private _fillNumericSeries(source: number[], count: number): number[] {\n const step = source.length > 1 ? source[1] - source[0] : 1;\n const last = source[source.length - 1];\n const result: number[] = [];\n for (let i = 1; i <= count; i++) {\n result.push(last + step * i);\n }\n return result;\n }\n\n private _fillDateSeries(originalSource: unknown[], timestamps: number[], count: number): string[] {\n const step = timestamps.length > 1 ? timestamps[1] - timestamps[0] : 24 * 60 * 60 * 1000;\n const last = timestamps[timestamps.length - 1];\n\n const sampleStr = typeof originalSource[0] === 'string' ? (originalSource[0] as string) : '';\n const isDateOnly = /^\\d{4}-\\d{2}-\\d{2}$/.test(sampleStr.trim());\n\n return Array.from({ length: count }, (_, i) => {\n const d = new Date(last + step * (i + 1));\n return isDateOnly ? d.toISOString().slice(0, 10) : d.toISOString();\n });\n }\n\n private _fillNamedSeries(source: unknown[], count: number, match: NamedSeriesMatch): string[] {\n const { list, index: firstIndex, originalCase } = match;\n const indexOf = (v: unknown) =>\n typeof v === 'string' ? list.indexOf(v.trim().toLowerCase()) : -1;\n\n const lastIndex = indexOf(source[source.length - 1]);\n const startIndex = lastIndex >= 0 ? lastIndex : firstIndex;\n const secondIndex = source.length > 1 ? indexOf(source[1]) : -1;\n const step =\n secondIndex >= 0 ? ((secondIndex - firstIndex + list.length) % list.length) || 1 : 1;\n\n const result: string[] = [];\n for (let i = 1; i <= count; i++) {\n const nextIndex = (((startIndex + step * i) % list.length) + list.length) % list.length;\n result.push(applyCase(list[nextIndex], originalCase));\n }\n return result;\n }\n}\n","/**\n * UndoRedoManager — a bounded undo/redo command stack. Each command stores\n * enough state to reverse itself; the manager applies changes through the\n * `applyValue` callback the host supplies (it never mutates data directly).\n */\n\nexport interface CellEditCommand {\n type: 'cellEdit';\n rowId: string | number;\n field: string;\n prevValue: unknown;\n nextValue: unknown;\n}\n\nexport interface PasteCommand {\n type: 'paste';\n cells: { rowId: string | number; field: string; prevValue: unknown; nextValue: unknown }[];\n}\n\nexport interface FillCommand {\n type: 'fill';\n cells: { rowId: string | number; field: string; prevValue: unknown; nextValue: unknown }[];\n}\n\nexport interface DeleteCommand {\n type: 'delete';\n cells: { rowId: string | number; field: string; prevValue: unknown }[];\n}\n\nexport type UndoRedoCommand = CellEditCommand | PasteCommand | FillCommand | DeleteCommand;\n\nexport interface UndoRedoManagerOptions {\n /** Maximum number of undo steps to retain. Default: 100 */\n maxStackSize?: number;\n /** Called whenever canUndo or canRedo changes. */\n onChange?: (canUndo: boolean, canRedo: boolean) => void;\n /** Applies a value to a cell — the manager calls this to (un)apply commands. */\n applyValue: (rowId: string | number, field: string, value: unknown) => void;\n}\n\nexport class UndoRedoManager {\n private readonly _undoStack: UndoRedoCommand[] = [];\n private readonly _redoStack: UndoRedoCommand[] = [];\n private readonly _maxStackSize: number;\n private readonly _onChange?: (canUndo: boolean, canRedo: boolean) => void;\n private readonly _applyValue: (rowId: string | number, field: string, value: unknown) => void;\n\n constructor(options: UndoRedoManagerOptions) {\n this._maxStackSize = options.maxStackSize ?? 100;\n this._onChange = options.onChange;\n this._applyValue = options.applyValue;\n }\n\n /** Push a new command onto the undo stack. Clears the redo stack. */\n push(command: UndoRedoCommand): void {\n this._undoStack.push(command);\n if (this._undoStack.length > this._maxStackSize) {\n this._undoStack.shift();\n }\n this._redoStack.length = 0;\n this._notifyChange();\n }\n\n /** Undo the most recent command. */\n undo(): void {\n const command = this._undoStack.pop();\n if (!command) return;\n this._applyCommandReverse(command);\n this._redoStack.push(command);\n this._notifyChange();\n }\n\n /** Redo the most recently undone command. */\n redo(): void {\n const command = this._redoStack.pop();\n if (!command) return;\n this._applyCommandForward(command);\n this._undoStack.push(command);\n this._notifyChange();\n }\n\n canUndo(): boolean {\n return this._undoStack.length > 0;\n }\n\n canRedo(): boolean {\n return this._redoStack.length > 0;\n }\n\n /** Clear both stacks (e.g. after a full data reload). */\n clear(): void {\n this._undoStack.length = 0;\n this._redoStack.length = 0;\n this._notifyChange();\n }\n\n undoStackSize(): number {\n return this._undoStack.length;\n }\n\n redoStackSize(): number {\n return this._redoStack.length;\n }\n\n private _applyCommandReverse(command: UndoRedoCommand): void {\n switch (command.type) {\n case 'cellEdit':\n this._applyValue(command.rowId, command.field, command.prevValue);\n break;\n case 'paste':\n case 'fill':\n case 'delete':\n for (const cell of command.cells) {\n this._applyValue(cell.rowId, cell.field, cell.prevValue);\n }\n break;\n }\n }\n\n private _applyCommandForward(command: UndoRedoCommand): void {\n switch (command.type) {\n case 'cellEdit':\n this._applyValue(command.rowId, command.field, command.nextValue);\n break;\n case 'paste':\n case 'fill':\n for (const cell of command.cells) {\n this._applyValue(cell.rowId, cell.field, cell.nextValue);\n }\n break;\n case 'delete':\n for (const cell of command.cells) {\n this._applyValue(cell.rowId, cell.field, '');\n }\n break;\n }\n }\n\n private _notifyChange(): void {\n this._onChange?.(this.canUndo(), this.canRedo());\n }\n}\n","/**\n * FormulaEngine — evaluates Excel-like formula strings against row data.\n * Formulas start with '=' and reference other columns by field name.\n *\n * Functions: SUM, AVG, MIN, MAX, COUNT, IF, CONCAT, ROUND, ABS, FLOOR, CEIL,\n * LEN, UPPER, LOWER. Bare identifiers that aren't function names are treated as\n * field lookups on the current row.\n *\n * Error values: '#ERROR!', '#DIV/0!', '#REF!', '#CIRCULAR!', '#NAME?'.\n * A formula that directly/transitively references its own cell yields\n * '#CIRCULAR!'.\n */\n\ntype ASTNode =\n | { kind: 'number'; value: number }\n | { kind: 'string'; value: string }\n | { kind: 'field'; name: string }\n | { kind: 'call'; fn: string; args: ASTNode[] }\n | {\n kind: 'binary';\n op: '+' | '-' | '*' | '/' | '==' | '!=' | '<' | '<=' | '>' | '>=';\n left: ASTNode;\n right: ASTNode;\n }\n | { kind: 'unary'; op: '-'; operand: ASTNode };\n\nclass Parser {\n private _src: string;\n private _pos = 0;\n\n constructor(src: string) {\n this._src = src.trim();\n }\n\n parse(): ASTNode {\n const node = this._parseExpr();\n this._skipWS();\n if (this._pos < this._src.length) {\n throw new Error(`Unexpected character at position ${this._pos}: '${this._src[this._pos]}'`);\n }\n return node;\n }\n\n private _skipWS(): void {\n while (this._pos < this._src.length && /\\s/.test(this._src[this._pos])) {\n this._pos++;\n }\n }\n\n private _consume(ch: string): void {\n this._skipWS();\n if (this._src[this._pos] !== ch) {\n throw new Error(`Expected '${ch}' at position ${this._pos}`);\n }\n this._pos++;\n }\n\n private _parseExpr(): ASTNode {\n return this._parseComparison();\n }\n\n private _parseComparison(): ASTNode {\n let left = this._parseAddSub();\n this._skipWS();\n while (this._pos < this._src.length) {\n const ch = this._src[this._pos];\n const ch2 = this._src.slice(this._pos, this._pos + 2);\n if (ch2 === '==' || ch2 === '!=' || ch2 === '<=' || ch2 === '>=') {\n this._pos += 2;\n const right = this._parseAddSub();\n left = { kind: 'binary', op: ch2, left, right };\n } else if (ch === '<' || ch === '>') {\n this._pos++;\n const right = this._parseAddSub();\n left = { kind: 'binary', op: ch, left, right };\n } else {\n break;\n }\n this._skipWS();\n }\n return left;\n }\n\n private _parseAddSub(): ASTNode {\n let left = this._parseMulDiv();\n this._skipWS();\n while (\n this._pos < this._src.length &&\n (this._src[this._pos] === '+' || this._src[this._pos] === '-')\n ) {\n const op = this._src[this._pos++] as '+' | '-';\n const right = this._parseMulDiv();\n left = { kind: 'binary', op, left, right };\n this._skipWS();\n }\n return left;\n }\n\n private _parseMulDiv(): ASTNode {\n let left = this._parseUnary();\n this._skipWS();\n while (\n this._pos < this._src.length &&\n (this._src[this._pos] === '*' || this._src[this._pos] === '/')\n ) {\n const op = this._src[this._pos++] as '*' | '/';\n const right = this._parseUnary();\n left = { kind: 'binary', op, left, right };\n this._skipWS();\n }\n return left;\n }\n\n private _parseUnary(): ASTNode {\n this._skipWS();\n if (this._src[this._pos] === '-') {\n this._pos++;\n return { kind: 'unary', op: '-', operand: this._parseUnary() };\n }\n return this._parsePrimary();\n }\n\n private _parsePrimary(): ASTNode {\n this._skipWS();\n const ch = this._src[this._pos];\n\n if (ch === undefined) {\n throw new Error('Unexpected end of expression');\n }\n\n if (ch === '(') {\n this._pos++;\n const node = this._parseExpr();\n this._consume(')');\n return node;\n }\n\n if (ch === '\"' || ch === \"'\") {\n return this._parseString(ch);\n }\n\n if (ch === '.' || (ch >= '0' && ch <= '9')) {\n return this._parseNumber();\n }\n\n if (/[A-Za-z_]/.test(ch)) {\n return this._parseIdentifier();\n }\n\n throw new Error(`Unexpected token at position ${this._pos}: '${ch}'`);\n }\n\n private _parseString(quote: string): ASTNode {\n this._pos++; // skip opening quote\n let s = '';\n while (this._pos < this._src.length && this._src[this._pos] !== quote) {\n s += this._src[this._pos++];\n }\n this._pos++; // skip closing quote\n return { kind: 'string', value: s };\n }\n\n private _parseNumber(): ASTNode {\n let s = '';\n while (this._pos < this._src.length && /[\\d.]/.test(this._src[this._pos])) {\n s += this._src[this._pos++];\n }\n if (this._src[this._pos] === 'e' || this._src[this._pos] === 'E') {\n s += this._src[this._pos++];\n if (this._src[this._pos] === '+' || this._src[this._pos] === '-') {\n s += this._src[this._pos++];\n }\n while (this._pos < this._src.length && /\\d/.test(this._src[this._pos])) {\n s += this._src[this._pos++];\n }\n }\n return { kind: 'number', value: Number(s) };\n }\n\n private _parseIdentifier(): ASTNode {\n let name = '';\n while (this._pos < this._src.length && /[\\w]/.test(this._src[this._pos])) {\n name += this._src[this._pos++];\n }\n this._skipWS();\n if (this._src[this._pos] === '(') {\n this._pos++;\n const args: ASTNode[] = [];\n this._skipWS();\n if (this._src[this._pos] !== ')') {\n args.push(this._parseExpr());\n this._skipWS();\n while (this._src[this._pos] === ',') {\n this._pos++;\n args.push(this._parseExpr());\n this._skipWS();\n }\n }\n this._consume(')');\n return { kind: 'call', fn: name.toUpperCase(), args };\n }\n return { kind: 'field', name };\n }\n}\n\ntype Row = Record<string, unknown>;\n\nconst FUNCTIONS: Record<string, (args: unknown[]) => unknown> = {\n SUM: (args) => args.reduce<number>((acc, v) => acc + (Number(v) || 0), 0),\n AVG: (args) =>\n args.length === 0 ? 0 : args.reduce<number>((acc, v) => acc + (Number(v) || 0), 0) / args.length,\n MIN: (args) => Math.min(...args.map(Number)),\n MAX: (args) => Math.max(...args.map(Number)),\n COUNT: (args) => args.filter((v) => !isNaN(Number(v)) && v !== '' && v != null).length,\n CONCAT: (args) => args.join(''),\n ROUND: ([n, d]) => Number(Number(n).toFixed(Number(d ?? 0))),\n ABS: ([n]) => Math.abs(Number(n)),\n FLOOR: ([n]) => Math.floor(Number(n)),\n CEIL: ([n]) => Math.ceil(Number(n)),\n LEN: ([s]) => String(s ?? '').length,\n UPPER: ([s]) => String(s ?? '').toUpperCase(),\n LOWER: ([s]) => String(s ?? '').toLowerCase(),\n IF: ([cond, t, f]) => (cond ? t : f),\n};\n\nfunction evalBinary(op: Extract<ASTNode, { kind: 'binary' }>['op'], l: unknown, r: unknown): unknown {\n switch (op) {\n case '+':\n return typeof l === 'string' || typeof r === 'string'\n ? String(l) + String(r)\n : Number(l) + Number(r);\n case '-':\n return Number(l) - Number(r);\n case '*':\n return Number(l) * Number(r);\n case '/': {\n const divisor = Number(r);\n return divisor === 0 ? '#DIV/0!' : Number(l) / divisor;\n }\n case '==':\n return l == r;\n case '!=':\n return l != r;\n case '<':\n return Number(l) < Number(r);\n case '<=':\n return Number(l) <= Number(r);\n case '>':\n return Number(l) > Number(r);\n case '>=':\n return Number(l) >= Number(r);\n default:\n return '#ERROR!';\n }\n}\n\nfunction evaluate(node: ASTNode, row: Row, visiting: Set<string>): unknown {\n switch (node.kind) {\n case 'number':\n return node.value;\n case 'string':\n return node.value;\n\n case 'field': {\n const key = node.name;\n if (visiting.has(key)) return '#CIRCULAR!';\n const raw = row[key];\n if (typeof raw === 'string' && raw.startsWith('=')) {\n visiting.add(key);\n try {\n const ast = new Parser(raw.slice(1)).parse();\n return evaluate(ast, row, visiting);\n } finally {\n visiting.delete(key);\n }\n }\n if (raw === undefined) return '#REF!';\n return raw;\n }\n\n case 'unary': {\n const v = evaluate(node.operand, row, visiting);\n if (typeof v === 'string' && v.startsWith('#')) return v;\n return -Number(v);\n }\n\n case 'binary': {\n const l = evaluate(node.left, row, visiting);\n const r = evaluate(node.right, row, visiting);\n if (typeof l === 'string' && l.startsWith('#')) return l;\n if (typeof r === 'string' && r.startsWith('#')) return r;\n return evalBinary(node.op, l, r);\n }\n\n case 'call': {\n const fn = FUNCTIONS[node.fn];\n if (!fn) return '#NAME?';\n const args = node.args.map((a) => evaluate(a, row, visiting));\n const err = args.find((a) => typeof a === 'string' && a.startsWith('#'));\n if (err) return err;\n return fn(args);\n }\n }\n}\n\nexport interface FormulaEngineOptions {\n /**\n * Fields that contain formula definitions. Key = field name, value = formula\n * string (e.g. '=SUM(price, tax)'). The row's field value is replaced by the\n * evaluation result.\n */\n formulaFields: Record<string, string>;\n}\n\nexport class FormulaEngine {\n private readonly _formulaFields: Record<string, string>;\n\n constructor(options: FormulaEngineOptions) {\n this._formulaFields = options.formulaFields;\n }\n\n /** Evaluate all formula fields for a row, returning a new (unmutated) row. */\n evaluateRow(row: Row): Row {\n const result: Row = { ...row };\n for (const [field, formula] of Object.entries(this._formulaFields)) {\n result[field] = this.evaluateFormula(formula, row, field);\n }\n return result;\n }\n\n /** Evaluate a single formula string against a row. */\n evaluateFormula(formula: string, row: Row, selfField?: string): unknown {\n const expr = formula.startsWith('=') ? formula.slice(1) : formula;\n try {\n const ast = new Parser(expr).parse();\n const visiting = selfField ? new Set([selfField]) : new Set<string>();\n return evaluate(ast, row, visiting);\n } catch {\n return '#ERROR!';\n }\n }\n\n /** Whether a formula string is parseable (no evaluation). */\n isValidFormula(formula: string): boolean {\n const expr = formula.startsWith('=') ? formula.slice(1) : formula;\n try {\n new Parser(expr).parse();\n return true;\n } catch {\n return false;\n }\n }\n}\n","/*\n * Public API Surface of @gridengine/angular-datagrid-enterprise\n *\n * Re-exports the open-source base grid so consumers need a single import, then\n * adds the license-gated Pro surface on top.\n */\n\n// ── Base grid (full re-export) ──────────────────────────────────────────────\nexport * from '@gridengine/angular-datagrid';\n\n// ── Pro component ───────────────────────────────────────────────────────────\nexport { DataGridPro } from './lib/data-grid-pro';\nexport { GridLicenseWatermark } from './lib/license-watermark';\n\n// ── License ─────────────────────────────────────────────────────────────────\nexport { LicenseManager, TIER_FEATURES } from './lib/license-manager';\nexport type {\n LicensePayload,\n LicenseTier,\n SupportLevel,\n LicenseStatus,\n LicenseValidationResult,\n} from './lib/license-manager';\nexport { provideGridEngineLicense } from './lib/provide-license';\nexport { PRODUCT_ID, PURCHASE_URL } from './lib/keyring';\n\n// ── Spreadsheet feature engines (framework-agnostic, usable standalone) ──────\nexport type { CellRange } from './lib/features/cell-range';\nexport { RangeSelectionEngine } from './lib/features/range-selection';\nexport type { RangeSelectionEngineOptions } from './lib/features/range-selection';\nexport { ClipboardEngine, parseTSV } from './lib/features/clipboard';\nexport type { ClipboardEngineOptions } from './lib/features/clipboard';\nexport { FillHandleEngine, toNumber, toTimestamp } from './lib/features/fill-handle';\nexport type {\n FillDirection,\n FillCell,\n FillResult,\n FillHandleEngineOptions,\n} from './lib/features/fill-handle';\nexport { UndoRedoManager } from './lib/features/undo-redo';\nexport type {\n UndoRedoCommand,\n CellEditCommand,\n PasteCommand,\n FillCommand,\n DeleteCommand,\n UndoRedoManagerOptions,\n} from './lib/features/undo-redo';\nexport { FormulaEngine } from './lib/features/formula';\nexport type { FormulaEngineOptions } from './lib/features/formula';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["coreResolveFeatures"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -276,5 +276,37 @@ declare class UndoRedoManager {
|
|
|
276
276
|
private _notifyChange;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
-
|
|
280
|
-
|
|
279
|
+
/**
|
|
280
|
+
* FormulaEngine — evaluates Excel-like formula strings against row data.
|
|
281
|
+
* Formulas start with '=' and reference other columns by field name.
|
|
282
|
+
*
|
|
283
|
+
* Functions: SUM, AVG, MIN, MAX, COUNT, IF, CONCAT, ROUND, ABS, FLOOR, CEIL,
|
|
284
|
+
* LEN, UPPER, LOWER. Bare identifiers that aren't function names are treated as
|
|
285
|
+
* field lookups on the current row.
|
|
286
|
+
*
|
|
287
|
+
* Error values: '#ERROR!', '#DIV/0!', '#REF!', '#CIRCULAR!', '#NAME?'.
|
|
288
|
+
* A formula that directly/transitively references its own cell yields
|
|
289
|
+
* '#CIRCULAR!'.
|
|
290
|
+
*/
|
|
291
|
+
type Row = Record<string, unknown>;
|
|
292
|
+
interface FormulaEngineOptions {
|
|
293
|
+
/**
|
|
294
|
+
* Fields that contain formula definitions. Key = field name, value = formula
|
|
295
|
+
* string (e.g. '=SUM(price, tax)'). The row's field value is replaced by the
|
|
296
|
+
* evaluation result.
|
|
297
|
+
*/
|
|
298
|
+
formulaFields: Record<string, string>;
|
|
299
|
+
}
|
|
300
|
+
declare class FormulaEngine {
|
|
301
|
+
private readonly _formulaFields;
|
|
302
|
+
constructor(options: FormulaEngineOptions);
|
|
303
|
+
/** Evaluate all formula fields for a row, returning a new (unmutated) row. */
|
|
304
|
+
evaluateRow(row: Row): Row;
|
|
305
|
+
/** Evaluate a single formula string against a row. */
|
|
306
|
+
evaluateFormula(formula: string, row: Row, selfField?: string): unknown;
|
|
307
|
+
/** Whether a formula string is parseable (no evaluation). */
|
|
308
|
+
isValidFormula(formula: string): boolean;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export { ClipboardEngine, DataGridPro, FillHandleEngine, FormulaEngine, GridLicenseWatermark, LicenseManager, PRODUCT_ID, PURCHASE_URL, RangeSelectionEngine, UndoRedoManager, parseTSV, provideGridEngineLicense, toNumber, toTimestamp };
|
|
312
|
+
export type { CellEditCommand, CellRange, ClipboardEngineOptions, DeleteCommand, FillCell, FillCommand, FillDirection, FillHandleEngineOptions, FillResult, FormulaEngineOptions, PasteCommand, RangeSelectionEngineOptions, UndoRedoCommand, UndoRedoManagerOptions };
|