diff --git a/dist/js/basis/basis.d.ts b/dist/js/basis/basis.d.ts index 6b36ea59a..ad628ff06 100644 --- a/dist/js/basis/basis.d.ts +++ b/dist/js/basis/basis.d.ts @@ -1,5 +1,5 @@ import { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; -import { BasisSchema, Coordinate3DSchema, Vector3DSchema } from "@mat3ra/esse/dist/js/types"; +import { BaseInMemoryEntitySchema, BasisSchema, Coordinate3DSchema, Vector3DSchema } from "@mat3ra/esse/dist/js/types"; import { Cell } from "../cell/cell"; import { AtomicCoordinateValue, Coordinates } from "./coordinates"; import { AtomicElementValue, Elements } from "./elements"; @@ -30,7 +30,8 @@ export interface ElementsAndCoordinatesConfig { units?: BasisSchema["units"]; cell?: Cell; } -export declare class Basis extends InMemoryEntity implements BasisSchema { +type BasisEntitySchema = BasisConfig & BaseInMemoryEntitySchema; +export declare class Basis extends InMemoryEntity implements BasisSchema { static defaultConfig: BasisSchema; units: BasisSchema["units"]; cell: Cell; @@ -46,8 +47,8 @@ export declare class Basis extends InMemoryEntity implements BasisSchema { set coordinates(coordinates: BasisSchema["coordinates"]); get labels(): BasisSchema["labels"]; set labels(labels: BasisSchema["labels"]); - toJSON(exclude?: string[]): BasisSchema; - clone(): Basis; + toJSON(exclude?: (keyof BasisConfig)[]): BasisSchema; + clone(): this; removeAllAtoms(): void; get cellRounded(): import("@mat3ra/esse/dist/js/types").Matrix3X3Schema; get elementsArray(): object[]; @@ -55,8 +56,8 @@ export declare class Basis extends InMemoryEntity implements BasisSchema { get coordinatesAsArray(): Coordinate3DSchema[]; get isInCartesianUnits(): boolean; get isInCrystalUnits(): boolean; - toCartesian(): void; - toCrystal(): void; + toCartesian(): this; + toCrystal(): this; getElementByIndex(idx: number): AtomicElementValue; getElementById(id: number): AtomicElementValue; getCoordinateValueByIndex(idx: number): AtomicCoordinateValue; diff --git a/dist/js/basis/basis.js b/dist/js/basis/basis.js index 92b01386e..4f47aa009 100644 --- a/dist/js/basis/basis.js +++ b/dist/js/basis/basis.js @@ -84,8 +84,6 @@ class Basis extends entity_1.InMemoryEntity { set labels(labels) { this._labels = labels_1.Labels.fromObjects(labels || []); } - // TODO: figure out how to override toJSON in the parent class with generic classes - // @ts-ignore toJSON(exclude = ["cell"]) { var _a; return { @@ -96,7 +94,6 @@ class Basis extends entity_1.InMemoryEntity { ...(((_a = this.labels) === null || _a === void 0 ? void 0 : _a.length) ? { labels: this.labels } : {}), }; } - // @ts-ignore clone() { const instance = super.clone(); instance.cell = this.cell.clone(); @@ -127,15 +124,17 @@ class Basis extends entity_1.InMemoryEntity { } toCartesian() { if (this.isInCartesianUnits) - return; + return this; this._coordinates.mapArrayInPlace((point) => this.cell.convertPointToCartesian(point)); this.units = constants_1.ATOMIC_COORD_UNITS.cartesian; + return this; } toCrystal() { if (this.isInCrystalUnits) - return; + return this; this._coordinates.mapArrayInPlace((point) => this.cell.convertPointToCrystal(point)); this.units = constants_1.ATOMIC_COORD_UNITS.crystal; + return this; } getElementByIndex(idx) { return this._elements.getElementValueByIndex(idx); diff --git a/dist/js/basis/constrained_basis.d.ts b/dist/js/basis/constrained_basis.d.ts index ea3e0441a..b075d7a68 100644 --- a/dist/js/basis/constrained_basis.d.ts +++ b/dist/js/basis/constrained_basis.d.ts @@ -15,7 +15,7 @@ export interface ElementsCoordinatesAndConstraintsConfig extends ElementsAndCoor * @extends Basis */ export declare class ConstrainedBasis extends Basis { - _constraints: AtomicConstraints; + private _constraints; constructor(config: ConstrainedBasisConfig); static fromElementsCoordinatesAndConstraints(config: ElementsCoordinatesAndConstraintsConfig): ConstrainedBasis; get constraints(): AtomicConstraintsSchema; diff --git a/dist/js/basis/constrained_basis.js b/dist/js/basis/constrained_basis.js index ce25b469a..88e6a0b08 100644 --- a/dist/js/basis/constrained_basis.js +++ b/dist/js/basis/constrained_basis.js @@ -12,8 +12,7 @@ const helpers_1 = require("./helpers"); class ConstrainedBasis extends basis_1.Basis { constructor(config) { super(config); - const { constraints } = config; - this._constraints = constraints_1.AtomicConstraints.fromObjects(constraints || []); // `constraints` is an Array with ids + this._constraints = constraints_1.AtomicConstraints.fromObjects(config.constraints); // `constraints` is an Array with ids } static fromElementsCoordinatesAndConstraints(config) { const basisConfig = this._convertValuesToConfig(config); diff --git a/dist/js/generated/MaterialSchemaMixin.d.ts b/dist/js/generated/MaterialSchemaMixin.d.ts new file mode 100644 index 000000000..aff45f703 --- /dev/null +++ b/dist/js/generated/MaterialSchemaMixin.d.ts @@ -0,0 +1,5 @@ +import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; +import type { MaterialPropertiesSchema } from "@mat3ra/esse/dist/js/types"; +export type MaterialSchemaMixin = MaterialPropertiesSchema; +export type MaterialInMemoryEntity = InMemoryEntity & MaterialSchemaMixin; +export declare function materialSchemaMixin(item: InMemoryEntity): asserts item is T & MaterialSchemaMixin; diff --git a/dist/js/generated/MaterialSchemaMixin.js b/dist/js/generated/MaterialSchemaMixin.js new file mode 100644 index 000000000..8329b0211 --- /dev/null +++ b/dist/js/generated/MaterialSchemaMixin.js @@ -0,0 +1,76 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.materialSchemaMixin = void 0; +function materialSchemaMixin(item) { + // @ts-expect-error + const properties = { + get formula() { + return this.prop("formula"); + }, + set formula(value) { + this.setProp("formula", value); + }, + get unitCellFormula() { + return this.prop("unitCellFormula"); + }, + set unitCellFormula(value) { + this.setProp("unitCellFormula", value); + }, + get basis() { + return this.requiredProp("basis"); + }, + set basis(value) { + this.setProp("basis", value); + }, + get lattice() { + return this.requiredProp("lattice"); + }, + set lattice(value) { + this.setProp("lattice", value); + }, + get derivedProperties() { + return this.prop("derivedProperties"); + }, + set derivedProperties(value) { + this.setProp("derivedProperties", value); + }, + get external() { + return this.prop("external"); + }, + set external(value) { + this.setProp("external", value); + }, + get src() { + return this.prop("src"); + }, + set src(value) { + this.setProp("src", value); + }, + get scaledHash() { + return this.prop("scaledHash"); + }, + set scaledHash(value) { + this.setProp("scaledHash", value); + }, + get icsdId() { + return this.prop("icsdId"); + }, + set icsdId(value) { + this.setProp("icsdId", value); + }, + get isNonPeriodic() { + return this.prop("isNonPeriodic"); + }, + set isNonPeriodic(value) { + this.setProp("isNonPeriodic", value); + }, + get consistencyChecks() { + return this.prop("consistencyChecks"); + }, + set consistencyChecks(value) { + this.setProp("consistencyChecks", value); + }, + }; + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} +exports.materialSchemaMixin = materialSchemaMixin; diff --git a/dist/js/lattice/lattice.d.ts b/dist/js/lattice/lattice.d.ts index 4ce327782..7b98e0d02 100644 --- a/dist/js/lattice/lattice.d.ts +++ b/dist/js/lattice/lattice.d.ts @@ -1,5 +1,5 @@ import { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; -import { LatticeSchema, LatticeTypeEnum, LatticeTypeExtendedEnum, LatticeVectorsSchema, Matrix3X3Schema } from "@mat3ra/esse/dist/js/types"; +import { BaseInMemoryEntitySchema, LatticeSchema, LatticeTypeEnum, LatticeTypeExtendedEnum, LatticeVectorsSchema, Matrix3X3Schema } from "@mat3ra/esse/dist/js/types"; import { Cell } from "../cell/cell"; import { UnitCell } from "./unit_cell"; /** @@ -10,7 +10,8 @@ export { defaultNonPeriodicMinimumLatticeSize, diatomicLatticePaddingFactor, mol export declare class LatticeVectors extends Cell implements LatticeVectorsSchema { } export type { LatticeVectorsSchema }; -export declare class Lattice extends InMemoryEntity implements LatticeSchema { +type LatticeEntitySchema = LatticeSchema & BaseInMemoryEntitySchema; +export declare class Lattice extends InMemoryEntity implements LatticeSchema { static defaultConfig: LatticeSchema; a: LatticeSchema["a"]; b: LatticeSchema["b"]; @@ -63,5 +64,5 @@ export declare class Lattice extends InMemoryEntity implements LatticeSchema { * @example {a: true, b: false, c: false, alpha: true, beta: false, gamma: false} */ get editables(): {}; - toJSON(exclude?: string[]): LatticeSchema; + toJSON(exclude?: (keyof LatticeSchema)[]): LatticeSchema; } diff --git a/dist/js/lattice/lattice.js b/dist/js/lattice/lattice.js index 6c442b23f..14612a5f4 100644 --- a/dist/js/lattice/lattice.js +++ b/dist/js/lattice/lattice.js @@ -246,8 +246,7 @@ class Lattice extends entity_1.InMemoryEntity { } return object; } - // @ts-ignore - toJSON(exclude) { + toJSON(exclude = []) { return { ...super.toJSON(exclude), vectors: this.vectors.toJSON(), diff --git a/dist/js/made.d.ts b/dist/js/made.d.ts index 9d77155d2..cd8061b7b 100644 --- a/dist/js/made.d.ts +++ b/dist/js/made.d.ts @@ -33,7 +33,7 @@ export declare const Made: { cartesian: string; }; Material: typeof Material; - defaultMaterialConfig: import("@mat3ra/esse/dist/js/types").MaterialSchema; + defaultMaterialConfig: import("./material").MaterialConfig; Lattice: typeof Lattice; Cell: typeof Cell; UnitCell: typeof UnitCell; diff --git a/dist/js/material.d.ts b/dist/js/material.d.ts index e9c84d04f..f387bca81 100644 --- a/dist/js/material.d.ts +++ b/dist/js/material.d.ts @@ -1,38 +1,28 @@ -import { type DefaultableInMemoryEntity, InMemoryEntity } from "@mat3ra/code/dist/js/entity"; -import { type HasConsistencyChecks } from "@mat3ra/code/dist/js/entity/mixins/HasConsistencyChecksMixin"; +import { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; +import { type Defaultable } from "@mat3ra/code/dist/js/entity/mixins/DefaultableMixin"; +import { type HashedEntity } from "@mat3ra/code/dist/js/entity/mixins/HashedEntityMixin"; import { type HasMetadata } from "@mat3ra/code/dist/js/entity/mixins/HasMetadataMixin"; -import type { AnyObject } from "@mat3ra/esse/dist/js/esse/types"; -import type { AtomicConstraintsSchema, ConsistencyCheck, DerivedPropertiesSchema, FileSourceSchema, LatticeSchema, MaterialSchema } from "@mat3ra/esse/dist/js/types"; +import { type NamedEntity } from "@mat3ra/code/dist/js/entity/mixins/NamedEntityMixin"; +import type { AtomicConstraintsSchema, BasisSchema, ConsistencyCheck, DerivedPropertiesSchema, FileSourceSchema, LatticeSchema, MaterialSchema } from "@mat3ra/esse/dist/js/types"; import type { BasisConfig } from "./basis/basis"; -import { type ConstrainedBasisConfig, ConstrainedBasis } from "./basis/constrained_basis"; -import { Constraint } from "./constraints/constraints"; +import { ConstrainedBasis } from "./basis/constrained_basis"; +import { type MaterialSchemaMixin } from "./generated/MaterialSchemaMixin"; import { Lattice } from "./lattice/lattice"; -interface Material extends HasConsistencyChecks, DefaultableInMemoryEntity, Required> { +export type PartialBy = Omit & Partial>; +export type MaterialConfig = PartialBy; +export declare const defaultMaterialConfig: MaterialConfig; +interface BaseMaterial extends MaterialSchemaMixin, NamedEntity, Defaultable, HashedEntity, Required> { } -type MaterialSchemaWithConsistencyChecksAsString = Omit & { - consistencyChecks?: ConsistencyCheck[]; -}; -type OptionallyConstrainedBasisConfig = BasisConfig & Partial>; -type Schema = MaterialSchemaWithConsistencyChecksAsString; -export declare const defaultMaterialConfig: MaterialSchema; -declare class Material extends InMemoryEntity implements Schema { +declare class BaseMaterial extends InMemoryEntity { +} +declare class Material extends BaseMaterial implements MaterialSchema { static createDefault: () => Material; - static get defaultConfig(): MaterialSchema; + static get defaultConfig(): MaterialConfig; static constructMaterialFileSource(fileName: string, fileContent: string, fileExtension: string): FileSourceSchema; - get name(): string; - set name(name: string); - get src(): FileSourceSchema | undefined; - set src(src: FileSourceSchema | undefined); + private constraints; + constructor(config: MaterialConfig, constraints?: AtomicConstraintsSchema); updateFormula(): void; - /** - * Gets Bolean value for whether or not a material is non-periodic vs periodic. - * False = periodic, True = non-periodic - */ - get isNonPeriodic(): boolean; - /** - * @summary Sets the value of isNonPeriodic based on Boolean value passed as an argument. - */ - set isNonPeriodic(bool: boolean); + updateHash(): void; /** * @summary Returns the specific derived property (as specified by name) for a material. */ @@ -71,29 +61,16 @@ declare class Material extends InMemoryEntity implements Schema { * @summary Returns the derived properties array for a material. */ getDerivedProperties(): DerivedPropertiesSchema; - /** - * Gets material's formula - */ - get formula(): string; - get unitCellFormula(): string; unsetFileProps(): void; - /** - * @param textOrObject Basis text or JSON object. - * @param format Format (xyz, etc.) - * @param unitz crystal/cartesian - */ - setBasis(textOrObject: string | BasisConfig, format?: string, unitz?: string): void; - setBasisConstraints(constraints: Constraint[]): void; - setBasisConstraintsFromArrayOfObjects(constraints: AtomicConstraintsSchema): void; - get basis(): OptionallyConstrainedBasisConfig; - get Basis(): ConstrainedBasis; + setBasis(basis: BasisConfig): void; + setBasis(basis: string, format: "xyz", unitz?: BasisSchema["units"]): void; + getBasis(constraints?: AtomicConstraintsSchema): ConstrainedBasis; + setLattice(lattice: LatticeSchema): void; + getLattice(): Lattice; /** * High-level access to unique elements from material instead of basis. */ get uniqueElements(): ("H" | "He" | "Li" | "Be" | "B" | "C" | "N" | "O" | "F" | "Ne" | "Na" | "Mg" | "Al" | "Si" | "P" | "S" | "Cl" | "Ar" | "K" | "Ca" | "Sc" | "Ti" | "V" | "Cr" | "Mn" | "Fe" | "Co" | "Ni" | "Cu" | "Zn" | "Ga" | "Ge" | "As" | "Se" | "Br" | "Kr" | "Rb" | "Sr" | "Y" | "Zr" | "Nb" | "Mo" | "Tc" | "Ru" | "Rh" | "Pd" | "Ag" | "Cd" | "In" | "Sn" | "Sb" | "Te" | "I" | "Xe" | "Cs" | "Ba" | "La" | "Ce" | "Pr" | "Nd" | "Pm" | "Sm" | "Eu" | "Gd" | "Tb" | "Dy" | "Ho" | "Er" | "Tm" | "Yb" | "Lu" | "Hf" | "Ta" | "W" | "Re" | "Os" | "Ir" | "Pt" | "Au" | "Hg" | "Tl" | "Pb" | "Bi" | "Po" | "At" | "Rn" | "Fr" | "Ra" | "Ac" | "Th" | "Pa" | "U" | "Np" | "Pu" | "Am" | "Cm" | "Bk" | "Cf" | "Es" | "Fm" | "Md" | "No" | "Lr" | "Rf" | "Db" | "Sg" | "Bh" | "Hs" | "Mt" | "Ds" | "Rg" | "Cn" | "Nh" | "Fl" | "Mc" | "Lv" | "Ts" | "Og" | "X" | "Vac")[]; - get lattice(): LatticeSchema; - set lattice(config: LatticeSchema); - get Lattice(): Lattice; /** * Returns the inchi string from the derivedProperties for a non-periodic material, or throws an error if the * inchi cannot be found. @@ -111,23 +88,15 @@ declare class Material extends InMemoryEntity implements Schema { * @param isScaled Whether to scale the lattice parameter 'a' to 1. */ calculateHash(salt?: string, isScaled?: boolean, bypassNonPeriodicCheck?: boolean): string; - set hash(hash: string); - get hash(): string; - /** - * Calculates hash from basis and lattice as above + scales lattice properties to make lattice.a = 1 - */ - get scaledHash(): string; - get external(): MaterialSchema["external"]; - set external(external: MaterialSchema["external"]); /** * Converts basis to crystal/fractional coordinates. */ - toCrystal(): void; + toCrystal(constraints?: AtomicConstraintsSchema): void; /** * Converts current material's basis coordinates to cartesian. * No changes if coordinates already cartesian. */ - toCartesian(): void; + toCartesian(constraints?: AtomicConstraintsSchema): void; /** * Returns material's basis in XYZ format. */ @@ -164,6 +133,6 @@ declare class Material extends InMemoryEntity implements Schema { * @returns Array of checks results */ getBasisConsistencyChecks(): ConsistencyCheck[]; - toJSON(): MaterialSchema & AnyObject; + toJSON(): MaterialSchema; } export { Material }; diff --git a/dist/js/material.js b/dist/js/material.js index 9952d317b..e3e8ba2b2 100644 --- a/dist/js/material.js +++ b/dist/js/material.js @@ -6,15 +6,25 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.Material = exports.defaultMaterialConfig = void 0; const entity_1 = require("@mat3ra/code/dist/js/entity"); const DefaultableMixin_1 = require("@mat3ra/code/dist/js/entity/mixins/DefaultableMixin"); -const HasConsistencyChecksMixin_1 = require("@mat3ra/code/dist/js/entity/mixins/HasConsistencyChecksMixin"); +const HashedEntityMixin_1 = require("@mat3ra/code/dist/js/entity/mixins/HashedEntityMixin"); const HasMetadataMixin_1 = require("@mat3ra/code/dist/js/entity/mixins/HasMetadataMixin"); +const NamedEntityMixin_1 = require("@mat3ra/code/dist/js/entity/mixins/NamedEntityMixin"); const crypto_js_1 = __importDefault(require("crypto-js")); const constrained_basis_1 = require("./basis/constrained_basis"); const conventional_cell_1 = require("./cell/conventional_cell"); -const constraints_1 = require("./constraints/constraints"); +const MaterialSchemaMixin_1 = require("./generated/MaterialSchemaMixin"); const lattice_1 = require("./lattice/lattice"); const parsers_1 = __importDefault(require("./parsers/parsers")); const supercell_1 = __importDefault(require("./tools/supercell")); +function parseBasis(textOrObject, format, unitz) { + if (typeof textOrObject === "string") { + if (format !== "xyz") { + throw new Error("Invalid format"); + } + return parsers_1.default.xyz.toBasisConfig(textOrObject, unitz); + } + return { constraints: [], ...textOrObject }; +} exports.defaultMaterialConfig = { name: "Silicon FCC", basis: { @@ -56,7 +66,14 @@ exports.defaultMaterialConfig = { }, metadata: {}, }; -class Material extends entity_1.InMemoryEntity { +class BaseMaterial extends entity_1.InMemoryEntity { +} +(0, MaterialSchemaMixin_1.materialSchemaMixin)(BaseMaterial.prototype); +(0, NamedEntityMixin_1.namedEntityMixin)(BaseMaterial.prototype); +(0, DefaultableMixin_1.defaultableEntityMixin)(BaseMaterial); +(0, HasMetadataMixin_1.hasMetadataMixin)(BaseMaterial.prototype); +(0, HashedEntityMixin_1.hashedEntityMixin)(BaseMaterial.prototype); +class Material extends BaseMaterial { static get defaultConfig() { return exports.defaultMaterialConfig; } @@ -68,35 +85,28 @@ class Material extends entity_1.InMemoryEntity { hash: crypto_js_1.default.MD5(fileContent).toString(), }; } - get name() { - var _a; - return (_a = this.prop("name")) !== null && _a !== void 0 ? _a : this.formula; // if name is not set, use formula, but keep empty string - } - set name(name) { - this.setProp("name", name); - } - get src() { - return this.prop("src"); - } - set src(src) { - this.setProp("src", src); + constructor(config, constraints = []) { + var _a, _b, _c, _d, _e, _f; + super({ + ...config, + formula: (_a = config.formula) !== null && _a !== void 0 ? _a : "", + name: (_c = (_b = config.name) !== null && _b !== void 0 ? _b : config.formula) !== null && _c !== void 0 ? _c : "", + metadata: (_d = config.metadata) !== null && _d !== void 0 ? _d : {}, + hash: (_e = config.hash) !== null && _e !== void 0 ? _e : "", + }); + this.constraints = []; + this.formula = config.formula || this.getBasis().formula; + this.name = this.name || this.formula; + this.constraints = constraints; + this.hash = (_f = config.hash) !== null && _f !== void 0 ? _f : this.calculateHash("", false, this.isNonPeriodic); } updateFormula() { - this.setProp("formula", this.Basis.formula); - this.setProp("unitCellFormula", this.Basis.unitCellFormula); - } - /** - * Gets Bolean value for whether or not a material is non-periodic vs periodic. - * False = periodic, True = non-periodic - */ - get isNonPeriodic() { - return this.prop("isNonPeriodic", false); + const basis = this.getBasis(); + this.formula = basis.formula; + this.unitCellFormula = basis.unitCellFormula; } - /** - * @summary Sets the value of isNonPeriodic based on Boolean value passed as an argument. - */ - set isNonPeriodic(bool) { - this.setProp("isNonPeriodic", bool); + updateHash() { + this.hash = this.calculateHash("", false, this.isNonPeriodic); } /** * @summary Returns the specific derived property (as specified by name) for a material. @@ -108,90 +118,52 @@ class Material extends entity_1.InMemoryEntity { * @summary Returns the derived properties array for a material. */ getDerivedProperties() { - return this.prop("derivedProperties", []); - } - /** - * Gets material's formula - */ - get formula() { - return this.prop("formula") || this.Basis.formula; - } - get unitCellFormula() { - return this.prop("unitCellFormula") || this.Basis.unitCellFormula; + var _a; + return (_a = this.derivedProperties) !== null && _a !== void 0 ? _a : []; } unsetFileProps() { this.unsetProp("src"); this.unsetProp("icsdId"); this.unsetProp("external"); } - /** - * @param textOrObject Basis text or JSON object. - * @param format Format (xyz, etc.) - * @param unitz crystal/cartesian - */ setBasis(textOrObject, format, unitz) { - let basis; - if (typeof textOrObject === "string" && format === "xyz") { - basis = parsers_1.default.xyz.toBasisConfig(textOrObject, unitz); - } - else { - basis = textOrObject; - } - this.setProp("basis", basis); + const { constraints, ...basis } = parseBasis(textOrObject, format, unitz); + this.basis = basis; + this.constraints = constraints; this.unsetFileProps(); this.updateFormula(); + this.updateHash(); } - setBasisConstraints(constraints) { - const basisWithConstraints = { - ...this.basis, - constraints: constraints.map((c) => c.toJSON()), - }; - this.setBasis(basisWithConstraints); - } - setBasisConstraintsFromArrayOfObjects(constraints) { - const constraintsInstances = constraints.map((c) => { - return constraints_1.Constraint.fromValueAndId(c.value, c.id); - }); - this.setBasisConstraints(constraintsInstances); - } - get basis() { - return this.requiredProp("basis"); - } - // returns the instance of {ConstrainedBasis} class - get Basis() { + getBasis(constraints) { const basisData = this.basis; return new constrained_basis_1.ConstrainedBasis({ ...basisData, - cell: this.Lattice.vectors, - constraints: basisData.constraints || [], + cell: this.getLattice().vectors, + constraints: constraints !== null && constraints !== void 0 ? constraints : this.constraints, }); } - /** - * High-level access to unique elements from material instead of basis. - */ - get uniqueElements() { - return this.Basis.uniqueElements; - } - get lattice() { - return this.prop("lattice"); - } - set lattice(config) { - const originalIsInCrystalUnits = this.Basis.isInCrystalUnits; - const basis = this.Basis; + setLattice(lattice) { + const basis = this.getBasis(); + const originalIsInCrystalUnits = basis.isInCrystalUnits; basis.toCartesian(); - const newLattice = new lattice_1.Lattice(config); - basis.cell = newLattice.vectors; - if (originalIsInCrystalUnits) + basis.cell = new lattice_1.Lattice(lattice).vectors; + if (originalIsInCrystalUnits) { basis.toCrystal(); - // Preserve all properties from the original basis to ensure constraints are included - const newBasisConfig = basis.toJSON(); - this.setProp("basis", newBasisConfig); - this.setProp("lattice", config); + } + this.basis = basis.toJSON(); + this.lattice = lattice; this.unsetFileProps(); + this.updateHash(); } - get Lattice() { + getLattice() { return new lattice_1.Lattice(this.lattice); } + /** + * High-level access to unique elements from material instead of basis. + */ + get uniqueElements() { + return this.getBasis().uniqueElements; + } /** * Returns the inchi string from the derivedProperties for a non-periodic material, or throws an error if the * inchi cannot be found. @@ -218,47 +190,31 @@ class Material extends entity_1.InMemoryEntity { let message; if (!this.isNonPeriodic || bypassNonPeriodicCheck) { message = - this.Basis.hashString + "#" + this.Lattice.getHashString(isScaled) + "#" + salt; + this.getBasis().hashString + + "#" + + this.getLattice().getHashString(isScaled) + + "#" + + salt; } else { message = this.getInchiStringForHash(); } return crypto_js_1.default.MD5(message).toString(); } - set hash(hash) { - this.setProp("hash", hash); - } - get hash() { - return this.prop("hash"); - } - /** - * Calculates hash from basis and lattice as above + scales lattice properties to make lattice.a = 1 - */ - get scaledHash() { - return this.calculateHash("", true); - } - get external() { - return this.prop("external"); - } - set external(external) { - this.setProp("external", external); - } /** * Converts basis to crystal/fractional coordinates. */ - toCrystal() { - const basis = this.Basis; - basis.toCrystal(); - this.setProp("basis", basis.toJSON()); + toCrystal(constraints = []) { + this.basis = this.getBasis(constraints).toCrystal().toJSON(); + this.updateHash(); } /** * Converts current material's basis coordinates to cartesian. * No changes if coordinates already cartesian. */ - toCartesian() { - const basis = this.Basis; - basis.toCartesian(); - this.setProp("basis", basis.toJSON()); + toCartesian(constraints = []) { + this.basis = this.getBasis(constraints).toCartesian().toJSON(); + this.updateHash(); } /** * Returns material's basis in XYZ format. @@ -298,12 +254,13 @@ class Material extends entity_1.InMemoryEntity { */ getACopyWithConventionalCell() { const material = this.clone(); + const lattice = this.getLattice(); // if conventional and primitive cells are the same => return a copy. - if ((0, conventional_cell_1.isConventionalCellSameAsPrimitiveForLatticeType)(this.Lattice.type)) { + if ((0, conventional_cell_1.isConventionalCellSameAsPrimitiveForLatticeType)(lattice.type)) { return material; } - const conventionalSupercellMatrix = conventional_cell_1.PRIMITIVE_TO_CONVENTIONAL_CELL_MULTIPLIERS[this.Lattice.type]; - const conventionalLatticeType = conventional_cell_1.PRIMITIVE_TO_CONVENTIONAL_CELL_LATTICE_TYPES[this.Lattice.type]; + const conventionalSupercellMatrix = conventional_cell_1.PRIMITIVE_TO_CONVENTIONAL_CELL_MULTIPLIERS[lattice.type]; + const conventionalLatticeType = conventional_cell_1.PRIMITIVE_TO_CONVENTIONAL_CELL_LATTICE_TYPES[lattice.type]; const config = supercell_1.default.generateConfig(this, conventionalSupercellMatrix); config.lattice.type = conventionalLatticeType; config.name = `${this.name} - conventional cell`; @@ -326,8 +283,8 @@ class Material extends entity_1.InMemoryEntity { getBasisConsistencyChecks() { const checks = []; const limit = 1000; - const basis = this.Basis; - if (this.Basis.elements.length < limit) { + const basis = this.getBasis(); + if (basis.elements.length < limit) { const overlappingAtomsGroups = basis.getOverlappingAtoms(); overlappingAtomsGroups.forEach(({ id1, id2, element1, element2 }) => { checks.push({ @@ -346,17 +303,14 @@ class Material extends entity_1.InMemoryEntity { return checks; } toJSON() { - // validation intoJSON() method will fail if name is not set in _json - this.name = this.name || this.formula; + const lattice = this.getLattice(); + const basis = this.getBasis(); return { ...super.toJSON(), - lattice: this.Lattice.toJSON(), - basis: this.Basis.toJSON(), + lattice: lattice.toJSON(), + basis: basis.toJSON(), isNonPeriodic: this.isNonPeriodic, }; } } exports.Material = Material; -(0, DefaultableMixin_1.defaultableEntityMixin)(Material); -(0, HasConsistencyChecksMixin_1.hasConsistencyChecksMixin)(Material.prototype); -(0, HasMetadataMixin_1.hasMetadataMixin)(Material.prototype); diff --git a/dist/js/tools/material.js b/dist/js/tools/material.js index 1d5dba6b9..037113fe3 100644 --- a/dist/js/tools/material.js +++ b/dist/js/tools/material.js @@ -15,7 +15,7 @@ function scaleOneLatticeVector(material, key = "a", factor = 1.0) { throw new Error("Lattice vectors are undefined"); } lattice.vectors[key] = lattice.vectors[key].map((v) => v * factor); - material.lattice = lattice_1.Lattice.fromVectors(lattice.vectors).toJSON(); + material.setLattice(lattice_1.Lattice.fromVectors(lattice.vectors).toJSON()); } /** * Updates the size of a materials lattice using the minimumLatticeSize function. @@ -23,10 +23,10 @@ function scaleOneLatticeVector(material, key = "a", factor = 1.0) { * @param material {Material} */ function scaleLatticeToMakeNonPeriodic(material) { - material.lattice = lattice_1.Lattice.fromConfigPartial({ - a: material.Basis.getMinimumLatticeSize(), + material.setLattice(lattice_1.Lattice.fromConfigPartial({ + a: material.getBasis().getMinimumLatticeSize(), type: "CUB", - }).toJSON(); + }).toJSON()); } /** * Updates the basis of a material by translating the coordinates @@ -34,11 +34,12 @@ function scaleLatticeToMakeNonPeriodic(material) { * @param material {Material} * */ function translateAtomsToCenter(material) { - const originalUnits = material.Basis.units; + const basis = material.getBasis(); + const originalUnits = basis.units; material.toCartesian(); - const updatedBasis = material.Basis; + const updatedBasis = basis.toCartesian(); const centerOfCoordinates = updatedBasis.centerOfCoordinatesPoint; - const centerOfLattice = math_1.math.multiply(0.5, material.Lattice.vectorArrays.reduce((a, b) => math_1.math.add(a, b))); + const centerOfLattice = math_1.math.multiply(0.5, material.getLattice().vectorArrays.reduce((a, b) => math_1.math.add(a, b))); const translationVector = math_1.math.subtract(centerOfLattice, centerOfCoordinates); updatedBasis.translateByVector(translationVector); material.setBasis(updatedBasis.toJSON()); diff --git a/dist/js/tools/supercell.d.ts b/dist/js/tools/supercell.d.ts index 0afac6c78..60e3f021a 100644 --- a/dist/js/tools/supercell.d.ts +++ b/dist/js/tools/supercell.d.ts @@ -9,8 +9,6 @@ import type { Material } from "../material"; declare function generateNewBasisWithinSupercell(basis: Basis | ConstrainedBasis, cell: Cell, supercell: Cell, supercellMatrix: Matrix3X3Schema): Basis; /** * @summary Generates supercell config for the specified material. - * @param material - * @param supercellMatrix {Number[][]} */ declare function generateConfig(material: Material, supercellMatrix: Matrix3X3Schema): { name: string; diff --git a/dist/js/tools/supercell.js b/dist/js/tools/supercell.js index ac4105b3b..5a699e02d 100644 --- a/dist/js/tools/supercell.js +++ b/dist/js/tools/supercell.js @@ -35,17 +35,15 @@ function generateNewBasisWithinSupercell(basis, cell, supercell, supercellMatrix } /** * @summary Generates supercell config for the specified material. - * @param material - * @param supercellMatrix {Number[][]} */ function generateConfig(material, supercellMatrix) { const det = math_1.math.det(supercellMatrix); if (det === 0) { throw new Error("Scaling matrix is degenerate."); } - const cell = material.Lattice.vectors; + const cell = material.getLattice().vectors; const supercell = cell.cloneAndScaleByMatrix(supercellMatrix); - const newBasis = generateNewBasisWithinSupercell(material.Basis, cell, supercell, supercellMatrix); + const newBasis = generateNewBasisWithinSupercell(material.getBasis(), cell, supercell, supercellMatrix); const newLattice = lattice_1.Lattice.fromVectors({ a: supercell.a, b: supercell.b, diff --git a/dist/js/tools/surface.d.ts b/dist/js/tools/surface.d.ts index 56e4ad1ad..553721333 100644 --- a/dist/js/tools/surface.d.ts +++ b/dist/js/tools/surface.d.ts @@ -1,6 +1,6 @@ -import { Coordinate3DSchema, MaterialSchema } from "@mat3ra/esse/dist/js/types"; -import { Material } from "../material"; -export type SlabConfigSchema = MaterialSchema & { +import { Coordinate3DSchema } from "@mat3ra/esse/dist/js/types"; +import { type MaterialConfig, Material } from "../material"; +export type SlabConfigSchema = MaterialConfig & { outOfPlaneAxisIndex: number; }; declare function generateConfig(material: Material, millerIndices: Coordinate3DSchema, numberOfLayers?: number, vx?: number, vy?: number): SlabConfigSchema; diff --git a/dist/js/tools/surface.js b/dist/js/tools/surface.js index 57a0c115f..582ec8bdf 100644 --- a/dist/js/tools/surface.js +++ b/dist/js/tools/surface.js @@ -133,7 +133,7 @@ function getDimensionsScalingMatrix(outOfPlaneAxisIndex, thickness, vx, vy) { function generateConfig(material, millerIndices, numberOfLayers = 1, vx = 1, vy = 1) { if (numberOfLayers < 1) throw new Error("Made.tools.surface.generateConfig: number of layers < 1."); - const cell = material.Lattice.vectors; + const cell = material.getLattice().vectors; const millerScalingMatrix = getMillerScalingMatrix(cell, millerIndices); const millerSupercell = cell.cloneAndScaleByMatrix(millerScalingMatrix); const millerPlanePseudoNormal = cell.convertPointToCartesian(millerIndices); @@ -141,7 +141,7 @@ function generateConfig(material, millerIndices, numberOfLayers = 1, vx = 1, vy const dimensionsScalingMatrix = getDimensionsScalingMatrix(outOfPlaneAxisIndex, numberOfLayers, vx, vy); const supercellMatrix = MULT(dimensionsScalingMatrix, millerScalingMatrix); const supercell = millerSupercell.cloneAndScaleByMatrix(dimensionsScalingMatrix); - const tempBasis = material.Basis.clone(); + const tempBasis = material.getBasis().clone(); const newBasis = supercell_1.default.generateNewBasisWithinSupercell(tempBasis, cell, supercell, supercellMatrix); const newLattice = lattice_1.Lattice.fromVectors({ a: supercell.vectorArrays[0], diff --git a/package-lock.json b/package-lock.json index 621209e4b..ad45cac82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,8 +31,8 @@ "@babel/register": "^7.22.15", "@babel/runtime-corejs3": "^7.16.8", "@exabyte-io/eslint-config": "2025.5.13-0", - "@mat3ra/code": "2026.5.27-0", - "@mat3ra/esse": "2026.5.27-0", + "@mat3ra/code": "https://github.com/Exabyte-io/code/archive/e5f03b02102f51a5792e0b8c4fedac3860aaf7ed.tar.gz", + "@mat3ra/esse": "https://github.com/mat3ra/esse/tarball/c6c4d84b1eedda012c968fd570b08b0faecde6c2", "@mat3ra/tsconfig": "2024.6.3-0", "@mat3ra/utils": "^2026.6.11-0", "@types/crypto-js": "^4.2.2", @@ -72,6 +72,7 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -588,6 +589,7 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -2389,6 +2391,7 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -2408,6 +2411,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2423,6 +2427,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -2431,6 +2436,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2445,6 +2451,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, "engines": { "node": ">= 4" } @@ -2453,6 +2460,7 @@ "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -2464,12 +2472,14 @@ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/@eslint/eslintrc/node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "node_modules/@exabyte-io/eslint-config": { "version": "2025.5.13-0", @@ -2835,6 +2845,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "deprecated": "Use @eslint/config-array instead", + "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -2848,7 +2859,8 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "deprecated": "Use @eslint/object-schema instead" + "deprecated": "Use @eslint/object-schema instead", + "dev": true }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -3020,9 +3032,9 @@ "license": "MIT" }, "node_modules/@mat3ra/code": { - "version": "2026.5.27-0", - "resolved": "https://registry.npmjs.org/@mat3ra/code/-/code-2026.5.27-0.tgz", - "integrity": "sha512-uPlUgleg2pRTzCZREnNQrsOjevoePE/wdJ43Eux+3CP4HMrwyA05c2uG/7flLCNQ/fe746j1FcZOeKB6+xECSA==", + "version": "0.0.0", + "resolved": "https://github.com/Exabyte-io/code/archive/e5f03b02102f51a5792e0b8c4fedac3860aaf7ed.tar.gz", + "integrity": "sha512-d50ie+SFn2jZIpIdGzdcx8olP35+zV+PMablDj1yTQcHho/A+9vOXibp405PGjcYCMr53TvzOm4IlrGWveQEMg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3114,9 +3126,9 @@ } }, "node_modules/@mat3ra/esse": { - "version": "2026.5.27-0", - "resolved": "https://registry.npmjs.org/@mat3ra/esse/-/esse-2026.5.27-0.tgz", - "integrity": "sha512-0/z6ORG+hNK64g/5S6JOZbgSUlTJDK4weMkkK4OIqYO4W26GQWRhvtRg4ydK38kV+IUHnwNYlEl3Z0b6XOwqTg==", + "version": "0.0.0", + "resolved": "https://github.com/mat3ra/esse/tarball/c6c4d84b1eedda012c968fd570b08b0faecde6c2", + "integrity": "sha512-2Zfm/ywV58tU8kWpK8U1KQDcfA1xSHYfcyb2JJBvSlZH/I58S3vUYr1w18L5Nqp1x6zB0z8CM9oB+5S5JSBYNw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4064,20 +4076,6 @@ "node": ">= 8" } }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -4460,6 +4458,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -4489,6 +4488,7 @@ "version": "8.20.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -4532,6 +4532,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, "engines": { "node": ">=6" } @@ -4567,6 +4568,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -4575,6 +4577,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -4797,6 +4800,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, "engines": { "node": ">=8" } @@ -5040,6 +5044,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { "node": ">=6" } @@ -5129,6 +5134,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -5350,6 +5356,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -5357,7 +5364,8 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/colorette": { "version": "2.0.20", @@ -5474,6 +5482,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5559,7 +5568,8 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/default-require-extensions": { "version": "3.0.1", @@ -5633,17 +5643,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -5660,6 +5659,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -5682,12 +5682,14 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -5844,6 +5846,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -5853,6 +5856,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -5905,37 +5909,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-compat-utils": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", - "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-compat-utils/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-config-airbnb": { "version": "19.0.4", "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", @@ -6043,29 +6016,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-json-compat-utils": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.3.tgz", - "integrity": "sha512-RbBmDFyu7FqnjE8F0ZxPNzx5UaptdeS9Uu50r7A+D7s/+FCX+ybiyViYEgFUaFIFqSWJgZRTpL5d8Kanxxl2lQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "esquery": "^1.6.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": "*", - "jsonc-eslint-parser": "^2.4.0 || ^3.0.0" - }, - "peerDependenciesMeta": { - "@eslint/json": { - "optional": true - } - } - }, "node_modules/eslint-module-utils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", @@ -6220,67 +6170,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/eslint-plugin-jsonc": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.21.1.tgz", - "integrity": "sha512-dbNR5iEnQeORwsK2WZzr3QaMtFCY3kKJVMRHPzUpKzMhmVy2zIpVgFDpX8MNoIdoqz6KCpCfOJavhfiSbZbN+w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.5.1", - "diff-sequences": "^27.5.1", - "eslint-compat-utils": "^0.6.4", - "eslint-json-compat-utils": "^0.2.1", - "espree": "^9.6.1 || ^10.3.0", - "graphemer": "^1.4.0", - "jsonc-eslint-parser": "^2.4.0", - "natural-compare": "^1.4.0", - "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-plugin-jsonc/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-jsonc/node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", @@ -6392,20 +6281,6 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -6478,6 +6353,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -6492,6 +6368,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, "engines": { "node": ">=4" } @@ -6508,6 +6385,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "dependencies": { "@babel/highlight": "^7.10.4" } @@ -6516,6 +6394,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6531,6 +6410,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -6545,6 +6425,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -6553,6 +6434,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6568,6 +6450,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -6578,12 +6461,14 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "engines": { "node": ">=10" }, @@ -6595,6 +6480,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -6609,6 +6495,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { "node": ">=8" } @@ -6617,6 +6504,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, "engines": { "node": ">= 4" } @@ -6625,6 +6513,7 @@ "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -6636,12 +6525,14 @@ "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/eslint/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -6653,6 +6544,7 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -6666,12 +6558,14 @@ "node_modules/eslint/node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -6682,12 +6576,14 @@ "node_modules/eslint/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -6701,6 +6597,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -6712,6 +6609,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, "engines": { "node": ">=4" } @@ -6720,6 +6618,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -6732,6 +6631,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -6744,6 +6644,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { "node": ">=4.0" } @@ -6809,7 +6710,8 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-diff": { "version": "1.3.0", @@ -6836,17 +6738,20 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fast-uri": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, "funding": [ { "type": "github", @@ -6871,6 +6776,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -6927,6 +6833,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -6939,7 +6846,8 @@ "node_modules/flatted": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.0.tgz", - "integrity": "sha512-noqGuLw158+DuD9UPRKHpJ2hGxpFyDlYYrfM0mWt4XhT4n0lwzTLh70Tkdyy4kyTmyTT9Bv7bWAJqw7cgkEXDg==" + "integrity": "sha512-noqGuLw158+DuD9UPRKHpJ2hGxpFyDlYYrfM0mWt4XhT4n0lwzTLh70Tkdyy4kyTmyTT9Bv7bWAJqw7cgkEXDg==", + "dev": true }, "node_modules/for-each": { "version": "0.3.3", @@ -7050,7 +6958,8 @@ "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true }, "node_modules/functions-have-names": { "version": "1.2.3", @@ -7163,6 +7072,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -7269,6 +7179,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { "node": ">=4" } @@ -7404,6 +7315,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7419,6 +7331,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, "engines": { "node": ">=0.8.19" } @@ -7582,6 +7495,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -7602,6 +7516,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -7625,6 +7540,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -7906,7 +7822,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/isobject": { "version": "3.0.1", @@ -8159,7 +8076,8 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "node_modules/json-schema": { "version": "0.4.0", @@ -8253,12 +8171,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/json5": { "version": "2.2.3", @@ -8271,73 +8191,6 @@ "node": ">=6" } }, - "node_modules/jsonc-eslint-parser": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.2.tgz", - "integrity": "sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "acorn": "^8.5.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -8357,6 +8210,7 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -8388,6 +8242,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -8579,12 +8434,14 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", @@ -9101,7 +8958,8 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/natural-compare-lite": { "version": "1.4.0", @@ -9611,6 +9469,7 @@ "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -9690,6 +9549,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -9717,6 +9577,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -9804,6 +9665,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, "engines": { "node": ">= 0.8.0" } @@ -9851,6 +9713,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, "engines": { "node": ">=0.4.0" } @@ -9870,6 +9733,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -9986,6 +9850,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, "engines": { "node": ">=8" }, @@ -10062,6 +9927,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -10106,6 +9972,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "engines": { "node": ">=4" } @@ -10153,6 +10020,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -10326,6 +10194,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -10337,6 +10206,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -10373,6 +10243,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -10389,6 +10260,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -10403,6 +10275,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -10413,7 +10286,8 @@ "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/source-map": { "version": "0.6.1", @@ -10513,6 +10387,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10591,6 +10466,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -10620,6 +10496,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, "engines": { "node": ">=8" }, @@ -10631,6 +10508,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -10649,27 +10527,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/synckit": { - "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -10698,7 +10560,8 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/through": { "version": "2.3.8", @@ -10879,6 +10742,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -10899,6 +10763,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, "engines": { "node": ">=10" }, @@ -11114,6 +10979,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -11135,7 +11001,8 @@ "node_modules/v8-compile-cache": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==" + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", + "dev": true }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", @@ -11189,6 +11056,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, diff --git a/package.json b/package.json index 12b104644..552a697dc 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,8 @@ "@babel/register": "^7.22.15", "@babel/runtime-corejs3": "^7.16.8", "@exabyte-io/eslint-config": "2025.5.13-0", - "@mat3ra/code": "2026.5.27-0", - "@mat3ra/esse": "2026.5.27-0", + "@mat3ra/code": "https://github.com/Exabyte-io/code/archive/e5f03b02102f51a5792e0b8c4fedac3860aaf7ed.tar.gz", + "@mat3ra/esse": "https://github.com/mat3ra/esse/tarball/c6c4d84b1eedda012c968fd570b08b0faecde6c2", "@mat3ra/tsconfig": "2024.6.3-0", "@mat3ra/utils": "^2026.6.11-0", "@types/crypto-js": "^4.2.2", diff --git a/scripts/generate-mixins.ts b/scripts/generate-mixins.ts new file mode 100644 index 000000000..2b64d7a86 --- /dev/null +++ b/scripts/generate-mixins.ts @@ -0,0 +1,28 @@ +#!/usr/bin/env node + +/** + * Script to generate mixin properties from JSON schema. + * + * Usage: + * npm run generate-mixins + */ + +import generateSchemaMixin from "@mat3ra/code/dist/js/generateSchemaMixin"; +import allSchemas from "@mat3ra/esse/dist/js/schemas.json"; +import type { JSONSchema7 } from "json-schema"; + +const SKIP_FIELDS: string[] = []; + +const OUTPUT_PATHS = { + "material/material-properties": "src/js/generated/MaterialSchemaMixin.ts", +}; + +function main() { + const result = generateSchemaMixin(allSchemas as JSONSchema7[], OUTPUT_PATHS, SKIP_FIELDS); + + if (result.errorCount > 0) { + process.exit(1); + } +} + +main(); diff --git a/src/js/basis/basis.ts b/src/js/basis/basis.ts index bbbb9860f..3d559d8fb 100644 --- a/src/js/basis/basis.ts +++ b/src/js/basis/basis.ts @@ -2,7 +2,12 @@ import { getElectronegativity, getElementAtomicRadius } from "@exabyte-io/periodic-table.js"; import { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; import { math } from "@mat3ra/code/dist/js/math"; -import { BasisSchema, Coordinate3DSchema, Vector3DSchema } from "@mat3ra/esse/dist/js/types"; +import { + BaseInMemoryEntitySchema, + BasisSchema, + Coordinate3DSchema, + Vector3DSchema, +} from "@mat3ra/esse/dist/js/types"; import { chain, toPairs, uniq, values } from "lodash"; import { Cell } from "../cell/cell"; @@ -71,7 +76,9 @@ const DEFAULT_BASIS_CONFIG = { units: "crystal", }; -export class Basis extends InMemoryEntity implements BasisSchema { +type BasisEntitySchema = BasisConfig & BaseInMemoryEntitySchema; + +export class Basis extends InMemoryEntity implements BasisSchema { static defaultConfig: BasisSchema = DEFAULT_BASIS_CONFIG as BasisSchema; units: BasisSchema["units"]; @@ -155,9 +162,7 @@ export class Basis extends InMemoryEntity implements BasisSchema { this._labels = Labels.fromObjects(labels || []); } - // TODO: figure out how to override toJSON in the parent class with generic classes - // @ts-ignore - toJSON(exclude: string[] = ["cell"]): BasisSchema { + toJSON(exclude: (keyof BasisConfig)[] = ["cell"]): BasisSchema { return { ...super.toJSON(exclude), elements: this.elements, @@ -167,8 +172,7 @@ export class Basis extends InMemoryEntity implements BasisSchema { }; } - // @ts-ignore - override clone(): Basis { + override clone(): this { const instance = super.clone(); instance.cell = this.cell.clone(); return instance; @@ -204,16 +208,18 @@ export class Basis extends InMemoryEntity implements BasisSchema { return this.units === ATOMIC_COORD_UNITS.crystal; } - toCartesian(): void { - if (this.isInCartesianUnits) return; + toCartesian() { + if (this.isInCartesianUnits) return this; this._coordinates.mapArrayInPlace((point) => this.cell.convertPointToCartesian(point)); this.units = ATOMIC_COORD_UNITS.cartesian as BasisSchema["units"]; + return this; } - toCrystal(): void { - if (this.isInCrystalUnits) return; + toCrystal() { + if (this.isInCrystalUnits) return this; this._coordinates.mapArrayInPlace((point) => this.cell.convertPointToCrystal(point)); this.units = ATOMIC_COORD_UNITS.crystal as BasisSchema["units"]; + return this; } getElementByIndex(idx: number): AtomicElementValue { diff --git a/src/js/basis/constrained_basis.ts b/src/js/basis/constrained_basis.ts index 4945cd9df..e401ac087 100644 --- a/src/js/basis/constrained_basis.ts +++ b/src/js/basis/constrained_basis.ts @@ -20,12 +20,11 @@ export interface ElementsCoordinatesAndConstraintsConfig extends ElementsAndCoor * @extends Basis */ export class ConstrainedBasis extends Basis { - _constraints: AtomicConstraints; + private _constraints: AtomicConstraints; constructor(config: ConstrainedBasisConfig) { super(config); - const { constraints } = config; - this._constraints = AtomicConstraints.fromObjects(constraints || []); // `constraints` is an Array with ids + this._constraints = AtomicConstraints.fromObjects(config.constraints); // `constraints` is an Array with ids } static fromElementsCoordinatesAndConstraints( diff --git a/src/js/generated/MaterialSchemaMixin.ts b/src/js/generated/MaterialSchemaMixin.ts new file mode 100644 index 000000000..cd0f43a11 --- /dev/null +++ b/src/js/generated/MaterialSchemaMixin.ts @@ -0,0 +1,82 @@ +import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; +import type { MaterialPropertiesSchema } from "@mat3ra/esse/dist/js/types"; + +export type MaterialSchemaMixin = MaterialPropertiesSchema; + +export type MaterialInMemoryEntity = InMemoryEntity & MaterialSchemaMixin; + +export function materialSchemaMixin( + item: InMemoryEntity, +): asserts item is T & MaterialSchemaMixin { + // @ts-expect-error + const properties: InMemoryEntity & MaterialSchemaMixin = { + get formula() { + return this.prop("formula"); + }, + set formula(value: MaterialPropertiesSchema["formula"]) { + this.setProp("formula", value); + }, + get unitCellFormula() { + return this.prop("unitCellFormula"); + }, + set unitCellFormula(value: MaterialPropertiesSchema["unitCellFormula"]) { + this.setProp("unitCellFormula", value); + }, + get basis() { + return this.requiredProp("basis"); + }, + set basis(value: MaterialPropertiesSchema["basis"]) { + this.setProp("basis", value); + }, + get lattice() { + return this.requiredProp("lattice"); + }, + set lattice(value: MaterialPropertiesSchema["lattice"]) { + this.setProp("lattice", value); + }, + get derivedProperties() { + return this.prop("derivedProperties"); + }, + set derivedProperties(value: MaterialPropertiesSchema["derivedProperties"]) { + this.setProp("derivedProperties", value); + }, + get external() { + return this.prop("external"); + }, + set external(value: MaterialPropertiesSchema["external"]) { + this.setProp("external", value); + }, + get src() { + return this.prop("src"); + }, + set src(value: MaterialPropertiesSchema["src"]) { + this.setProp("src", value); + }, + get scaledHash() { + return this.prop("scaledHash"); + }, + set scaledHash(value: MaterialPropertiesSchema["scaledHash"]) { + this.setProp("scaledHash", value); + }, + get icsdId() { + return this.prop("icsdId"); + }, + set icsdId(value: MaterialPropertiesSchema["icsdId"]) { + this.setProp("icsdId", value); + }, + get isNonPeriodic() { + return this.prop("isNonPeriodic"); + }, + set isNonPeriodic(value: MaterialPropertiesSchema["isNonPeriodic"]) { + this.setProp("isNonPeriodic", value); + }, + get consistencyChecks() { + return this.prop("consistencyChecks"); + }, + set consistencyChecks(value: MaterialPropertiesSchema["consistencyChecks"]) { + this.setProp("consistencyChecks", value); + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/js/lattice/lattice.ts b/src/js/lattice/lattice.ts index 55e6d4c79..8b1c9965e 100644 --- a/src/js/lattice/lattice.ts +++ b/src/js/lattice/lattice.ts @@ -2,6 +2,7 @@ import { HASH_TOLERANCE } from "@mat3ra/code/dist/js/constants"; import { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; import { math } from "@mat3ra/code/dist/js/math"; import { + BaseInMemoryEntitySchema, Coordinate3DSchema, LatticeSchema, LatticeTypeEnum, @@ -30,7 +31,9 @@ export class LatticeVectors extends Cell implements LatticeVectorsSchema {} export type { LatticeVectorsSchema }; -export class Lattice extends InMemoryEntity implements LatticeSchema { +type LatticeEntitySchema = LatticeSchema & BaseInMemoryEntitySchema; + +export class Lattice extends InMemoryEntity implements LatticeSchema { static defaultConfig: LatticeSchema = { a: 1, b: 1, @@ -294,11 +297,10 @@ export class Lattice extends InMemoryEntity implements LatticeSchema { return object; } - // @ts-ignore - toJSON(exclude?: string[]): LatticeSchema { + toJSON(exclude: (keyof LatticeSchema)[] = []): LatticeSchema { return { ...super.toJSON(exclude), vectors: this.vectors.toJSON(), - } as LatticeSchema; + }; } } diff --git a/src/js/material.ts b/src/js/material.ts index 6abac3d22..272b21c01 100644 --- a/src/js/material.ts +++ b/src/js/material.ts @@ -1,16 +1,23 @@ -import { type DefaultableInMemoryEntity, InMemoryEntity } from "@mat3ra/code/dist/js/entity"; -import { defaultableEntityMixin } from "@mat3ra/code/dist/js/entity/mixins/DefaultableMixin"; +import { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; import { - type HasConsistencyChecks, - hasConsistencyChecksMixin, -} from "@mat3ra/code/dist/js/entity/mixins/HasConsistencyChecksMixin"; + type Defaultable, + defaultableEntityMixin, +} from "@mat3ra/code/dist/js/entity/mixins/DefaultableMixin"; +import { + type HashedEntity, + hashedEntityMixin, +} from "@mat3ra/code/dist/js/entity/mixins/HashedEntityMixin"; import { type HasMetadata, hasMetadataMixin, } from "@mat3ra/code/dist/js/entity/mixins/HasMetadataMixin"; -import type { AnyObject } from "@mat3ra/esse/dist/js/esse/types"; +import { + type NamedEntity, + namedEntityMixin, +} from "@mat3ra/code/dist/js/entity/mixins/NamedEntityMixin"; import type { AtomicConstraintsSchema, + BasisSchema, ConsistencyCheck, DerivedPropertiesSchema, FileSourceSchema, @@ -27,27 +34,30 @@ import { PRIMITIVE_TO_CONVENTIONAL_CELL_LATTICE_TYPES, PRIMITIVE_TO_CONVENTIONAL_CELL_MULTIPLIERS, } from "./cell/conventional_cell"; -import { Constraint } from "./constraints/constraints"; +import { type MaterialSchemaMixin, materialSchemaMixin } from "./generated/MaterialSchemaMixin"; import { Lattice } from "./lattice/lattice"; import parsers from "./parsers/parsers"; import supercellTools from "./tools/supercell"; -interface Material - extends HasConsistencyChecks, - DefaultableInMemoryEntity, - Required> {} - -// TODO: remove in-line type creation -type MaterialSchemaWithConsistencyChecksAsString = Omit & { - consistencyChecks?: ConsistencyCheck[]; -}; +function parseBasis( + textOrObject: string | BasisConfig, + format?: "xyz", + unitz?: BasisSchema["units"], +): ConstrainedBasisConfig { + if (typeof textOrObject === "string") { + if (format !== "xyz") { + throw new Error("Invalid format"); + } + return parsers.xyz.toBasisConfig(textOrObject, unitz); + } + return { constraints: [], ...textOrObject }; +} -type OptionallyConstrainedBasisConfig = BasisConfig & - Partial>; +export type PartialBy = Omit & Partial>; -type Schema = MaterialSchemaWithConsistencyChecksAsString; +export type MaterialConfig = PartialBy; -export const defaultMaterialConfig: MaterialSchema = { +export const defaultMaterialConfig: MaterialConfig = { name: "Silicon FCC", basis: { elements: [ @@ -89,10 +99,25 @@ export const defaultMaterialConfig: MaterialSchema = { metadata: {}, }; -class Material extends InMemoryEntity implements Schema { +interface BaseMaterial + extends MaterialSchemaMixin, + NamedEntity, + Defaultable, + HashedEntity, + Required> {} + +class BaseMaterial extends InMemoryEntity {} + +materialSchemaMixin(BaseMaterial.prototype); +namedEntityMixin(BaseMaterial.prototype); +defaultableEntityMixin(BaseMaterial); +hasMetadataMixin(BaseMaterial.prototype); +hashedEntityMixin(BaseMaterial.prototype); + +class Material extends BaseMaterial implements MaterialSchema { declare static createDefault: () => Material; - static get defaultConfig() { + static get defaultConfig(): MaterialConfig { return defaultMaterialConfig; } @@ -109,40 +134,31 @@ class Material extends InMemoryEntity implements Schema { }; } - get name() { - return this.prop("name") ?? this.formula; // if name is not set, use formula, but keep empty string - } - - set name(name: string) { - this.setProp("name", name); - } + private constraints: AtomicConstraintsSchema = []; - get src() { - return this.prop("src"); - } + constructor(config: MaterialConfig, constraints: AtomicConstraintsSchema = []) { + super({ + ...config, + formula: config.formula ?? "", + name: config.name ?? config.formula ?? "", + metadata: config.metadata ?? {}, + hash: config.hash ?? "", + }); - set src(src: FileSourceSchema | undefined) { - this.setProp("src", src); + this.formula = config.formula || this.getBasis().formula; + this.name = this.name || this.formula; + this.constraints = constraints; + this.hash = config.hash ?? this.calculateHash("", false, this.isNonPeriodic); } updateFormula() { - this.setProp("formula", this.Basis.formula); - this.setProp("unitCellFormula", this.Basis.unitCellFormula); + const basis = this.getBasis(); + this.formula = basis.formula; + this.unitCellFormula = basis.unitCellFormula; } - /** - * Gets Bolean value for whether or not a material is non-periodic vs periodic. - * False = periodic, True = non-periodic - */ - get isNonPeriodic(): boolean { - return this.prop("isNonPeriodic", false); - } - - /** - * @summary Sets the value of isNonPeriodic based on Boolean value passed as an argument. - */ - set isNonPeriodic(bool: boolean) { - this.setProp("isNonPeriodic", bool); + updateHash() { + this.hash = this.calculateHash("", false, this.isNonPeriodic); } /** @@ -156,18 +172,7 @@ class Material extends InMemoryEntity implements Schema { * @summary Returns the derived properties array for a material. */ getDerivedProperties(): DerivedPropertiesSchema { - return this.prop("derivedProperties", []); - } - - /** - * Gets material's formula - */ - get formula(): string { - return this.prop("formula") || this.Basis.formula; - } - - get unitCellFormula(): string { - return this.prop("unitCellFormula") || this.Basis.unitCellFormula; + return this.derivedProperties ?? []; } unsetFileProps() { @@ -176,85 +181,59 @@ class Material extends InMemoryEntity implements Schema { this.unsetProp("external"); } - /** - * @param textOrObject Basis text or JSON object. - * @param format Format (xyz, etc.) - * @param unitz crystal/cartesian - */ - setBasis(textOrObject: string | BasisConfig, format?: string, unitz?: string) { - let basis: BasisConfig | undefined; - if (typeof textOrObject === "string" && format === "xyz") { - basis = parsers.xyz.toBasisConfig(textOrObject, unitz); - } else { - basis = textOrObject as BasisConfig; - } - this.setProp("basis", basis); - this.unsetFileProps(); - this.updateFormula(); - } + setBasis(basis: BasisConfig): void; - setBasisConstraints(constraints: Constraint[]) { - const basisWithConstraints = { - ...this.basis, - constraints: constraints.map((c) => c.toJSON()), - }; - this.setBasis(basisWithConstraints); - } + setBasis(basis: string, format: "xyz", unitz?: BasisSchema["units"]): void; - setBasisConstraintsFromArrayOfObjects(constraints: AtomicConstraintsSchema) { - const constraintsInstances = constraints.map((c) => { - return Constraint.fromValueAndId(c.value, c.id); - }); - this.setBasisConstraints(constraintsInstances); - } + setBasis(textOrObject: string | BasisConfig, format?: "xyz", unitz?: BasisSchema["units"]) { + const { constraints, ...basis } = parseBasis(textOrObject, format, unitz); - get basis() { - return this.requiredProp("basis"); + this.basis = basis; + this.constraints = constraints; + this.unsetFileProps(); + this.updateFormula(); + this.updateHash(); } - // returns the instance of {ConstrainedBasis} class - get Basis() { + getBasis(constraints?: AtomicConstraintsSchema) { const basisData = this.basis; return new ConstrainedBasis({ ...basisData, - cell: this.Lattice.vectors, - constraints: basisData.constraints || [], + cell: this.getLattice().vectors, + constraints: constraints ?? this.constraints, }); } - /** - * High-level access to unique elements from material instead of basis. - */ - get uniqueElements() { - return this.Basis.uniqueElements; - } - - get lattice(): LatticeSchema { - return this.prop("lattice") as LatticeSchema; - } + setLattice(lattice: LatticeSchema) { + const basis = this.getBasis(); + const originalIsInCrystalUnits = basis.isInCrystalUnits; - set lattice(config: LatticeSchema) { - const originalIsInCrystalUnits = this.Basis.isInCrystalUnits; - const basis = this.Basis; basis.toCartesian(); + basis.cell = new Lattice(lattice).vectors; - const newLattice = new Lattice(config); - basis.cell = newLattice.vectors; - if (originalIsInCrystalUnits) basis.toCrystal(); + if (originalIsInCrystalUnits) { + basis.toCrystal(); + } - // Preserve all properties from the original basis to ensure constraints are included - const newBasisConfig = basis.toJSON(); - this.setProp("basis", newBasisConfig); - this.setProp("lattice", config); + this.basis = basis.toJSON(); + this.lattice = lattice; this.unsetFileProps(); + this.updateHash(); } - get Lattice(): Lattice { + getLattice() { return new Lattice(this.lattice); } + /** + * High-level access to unique elements from material instead of basis. + */ + get uniqueElements() { + return this.getBasis().uniqueElements; + } + /** * Returns the inchi string from the derivedProperties for a non-periodic material, or throws an error if the * inchi cannot be found. @@ -282,53 +261,32 @@ class Material extends InMemoryEntity implements Schema { let message; if (!this.isNonPeriodic || bypassNonPeriodicCheck) { message = - this.Basis.hashString + "#" + this.Lattice.getHashString(isScaled) + "#" + salt; + this.getBasis().hashString + + "#" + + this.getLattice().getHashString(isScaled) + + "#" + + salt; } else { message = this.getInchiStringForHash(); } return CryptoJS.MD5(message).toString(); } - set hash(hash: string) { - this.setProp("hash", hash); - } - - get hash(): string { - return this.prop("hash") as string; - } - - /** - * Calculates hash from basis and lattice as above + scales lattice properties to make lattice.a = 1 - */ - get scaledHash(): string { - return this.calculateHash("", true); - } - - get external() { - return this.prop("external"); - } - - set external(external: MaterialSchema["external"]) { - this.setProp("external", external); - } - /** * Converts basis to crystal/fractional coordinates. */ - toCrystal() { - const basis = this.Basis; - basis.toCrystal(); - this.setProp("basis", basis.toJSON()); + toCrystal(constraints: AtomicConstraintsSchema = []) { + this.basis = this.getBasis(constraints).toCrystal().toJSON(); + this.updateHash(); } /** * Converts current material's basis coordinates to cartesian. * No changes if coordinates already cartesian. */ - toCartesian() { - const basis = this.Basis; - basis.toCartesian(); - this.setProp("basis", basis.toJSON()); + toCartesian(constraints: AtomicConstraintsSchema = []) { + this.basis = this.getBasis(constraints).toCartesian().toJSON(); + this.updateHash(); } /** @@ -372,15 +330,16 @@ class Material extends InMemoryEntity implements Schema { getACopyWithConventionalCell(): this { const material = this.clone(); + const lattice = this.getLattice(); + // if conventional and primitive cells are the same => return a copy. - if (isConventionalCellSameAsPrimitiveForLatticeType(this.Lattice.type)) { + if (isConventionalCellSameAsPrimitiveForLatticeType(lattice.type)) { return material; } const conventionalSupercellMatrix = - PRIMITIVE_TO_CONVENTIONAL_CELL_MULTIPLIERS[this.Lattice.type]; - const conventionalLatticeType = - PRIMITIVE_TO_CONVENTIONAL_CELL_LATTICE_TYPES[this.Lattice.type]; + PRIMITIVE_TO_CONVENTIONAL_CELL_MULTIPLIERS[lattice.type]; + const conventionalLatticeType = PRIMITIVE_TO_CONVENTIONAL_CELL_LATTICE_TYPES[lattice.type]; const config = supercellTools.generateConfig(this, conventionalSupercellMatrix); config.lattice.type = conventionalLatticeType; @@ -409,9 +368,9 @@ class Material extends InMemoryEntity implements Schema { getBasisConsistencyChecks(): ConsistencyCheck[] { const checks: ConsistencyCheck[] = []; const limit = 1000; - const basis = this.Basis; + const basis = this.getBasis(); - if (this.Basis.elements.length < limit) { + if (basis.elements.length < limit) { const overlappingAtomsGroups = basis.getOverlappingAtoms(); overlappingAtomsGroups.forEach(({ id1, id2, element1, element2 }) => { checks.push( @@ -438,21 +397,17 @@ class Material extends InMemoryEntity implements Schema { return checks; } - toJSON(): MaterialSchema & AnyObject { - // validation intoJSON() method will fail if name is not set in _json - this.name = this.name || this.formula; + toJSON(): MaterialSchema { + const lattice = this.getLattice(); + const basis = this.getBasis(); return { - ...(super.toJSON() as MaterialSchema & AnyObject), - lattice: this.Lattice.toJSON(), - basis: this.Basis.toJSON(), + ...super.toJSON(), + lattice: lattice.toJSON(), + basis: basis.toJSON(), isNonPeriodic: this.isNonPeriodic, - }; + } as MaterialSchema; } } -defaultableEntityMixin(Material); -hasConsistencyChecksMixin(Material.prototype); -hasMetadataMixin(Material.prototype); - export { Material }; diff --git a/src/js/tools/material.ts b/src/js/tools/material.ts index 76c4f2615..42fe7ff10 100644 --- a/src/js/tools/material.ts +++ b/src/js/tools/material.ts @@ -17,9 +17,9 @@ function scaleOneLatticeVector(material: Material, key: "a" | "b" | "c" = "a", f if (lattice.vectors === undefined) { throw new Error("Lattice vectors are undefined"); } - lattice.vectors[key] = lattice.vectors![key].map((v) => v * factor) as Vector3DSchema; + lattice.vectors[key] = lattice.vectors[key].map((v) => v * factor) as Vector3DSchema; - material.lattice = Lattice.fromVectors(lattice.vectors).toJSON(); + material.setLattice(Lattice.fromVectors(lattice.vectors).toJSON()); } /** @@ -28,10 +28,12 @@ function scaleOneLatticeVector(material: Material, key: "a" | "b" | "c" = "a", f * @param material {Material} */ function scaleLatticeToMakeNonPeriodic(material: Material) { - material.lattice = Lattice.fromConfigPartial({ - a: material.Basis.getMinimumLatticeSize(), - type: "CUB", - } as LatticeSchema).toJSON(); + material.setLattice( + Lattice.fromConfigPartial({ + a: material.getBasis().getMinimumLatticeSize(), + type: "CUB", + } as LatticeSchema).toJSON(), + ); } /** @@ -40,13 +42,14 @@ function scaleLatticeToMakeNonPeriodic(material: Material) { * @param material {Material} * */ function translateAtomsToCenter(material: Material) { - const originalUnits = material.Basis.units; + const basis = material.getBasis(); + const originalUnits = basis.units; material.toCartesian(); - const updatedBasis = material.Basis; + const updatedBasis = basis.toCartesian(); const centerOfCoordinates = updatedBasis.centerOfCoordinatesPoint; const centerOfLattice = math.multiply( 0.5, - material.Lattice.vectorArrays.reduce((a, b) => math.add(a, b) as Vector3DSchema), + material.getLattice().vectorArrays.reduce((a, b) => math.add(a, b) as Vector3DSchema), ); const translationVector = math.subtract(centerOfLattice, centerOfCoordinates); updatedBasis.translateByVector(translationVector as Vector3DSchema); diff --git a/src/js/tools/supercell.ts b/src/js/tools/supercell.ts index 0ebc03143..26276e7b2 100644 --- a/src/js/tools/supercell.ts +++ b/src/js/tools/supercell.ts @@ -52,18 +52,16 @@ function generateNewBasisWithinSupercell( /** * @summary Generates supercell config for the specified material. - * @param material - * @param supercellMatrix {Number[][]} */ function generateConfig(material: Material, supercellMatrix: Matrix3X3Schema) { const det = math.det(supercellMatrix); if (det === 0) { throw new Error("Scaling matrix is degenerate."); } - const cell = material.Lattice.vectors; + const cell = material.getLattice().vectors; const supercell = cell.cloneAndScaleByMatrix(supercellMatrix); const newBasis = generateNewBasisWithinSupercell( - material.Basis, + material.getBasis(), cell, supercell, supercellMatrix, diff --git a/src/js/tools/surface.ts b/src/js/tools/surface.ts index eb49d9a5d..97dd68a7c 100644 --- a/src/js/tools/surface.ts +++ b/src/js/tools/surface.ts @@ -1,14 +1,9 @@ import { math } from "@mat3ra/code/dist/js/math"; -import { - Coordinate3DSchema, - MaterialSchema, - Matrix3X3Schema, - Vector3DSchema, -} from "@mat3ra/esse/dist/js/types"; +import { Coordinate3DSchema, Matrix3X3Schema, Vector3DSchema } from "@mat3ra/esse/dist/js/types"; import { Cell } from "../cell/cell"; import { Lattice } from "../lattice/lattice"; -import { Material } from "../material"; +import { type MaterialConfig, Material } from "../material"; import SupercellTools from "./supercell"; const MULT = math.multiply; @@ -152,7 +147,7 @@ function getDimensionsScalingMatrix( return transformationMatrix as Matrix3X3Schema; } -export type SlabConfigSchema = MaterialSchema & { +export type SlabConfigSchema = MaterialConfig & { outOfPlaneAxisIndex: number; }; @@ -175,7 +170,7 @@ function generateConfig( if (numberOfLayers < 1) throw new Error("Made.tools.surface.generateConfig: number of layers < 1."); - const cell = material.Lattice.vectors; + const cell = material.getLattice().vectors; const millerScalingMatrix = getMillerScalingMatrix(cell, millerIndices); const millerSupercell = cell.cloneAndScaleByMatrix(millerScalingMatrix); const millerPlanePseudoNormal = cell.convertPointToCartesian(millerIndices); @@ -189,7 +184,7 @@ function generateConfig( ); const supercellMatrix = MULT(dimensionsScalingMatrix, millerScalingMatrix); const supercell = millerSupercell.cloneAndScaleByMatrix(dimensionsScalingMatrix); - const tempBasis = material.Basis.clone(); + const tempBasis = material.getBasis().clone(); const newBasis = SupercellTools.generateNewBasisWithinSupercell( tempBasis, cell, diff --git a/tests/js/basis/basis.ts b/tests/js/basis/basis.ts index 6c784b9f1..c9dd77f70 100644 --- a/tests/js/basis/basis.ts +++ b/tests/js/basis/basis.ts @@ -29,20 +29,20 @@ describe("Basis", () => { }); it("should return true when basis is compared to its clone", () => { - const basis1 = new Material(Na4Cl4).Basis; + const basis1 = new Material(Na4Cl4).getBasis(); const basis2 = basis1.clone(); expect(basis1.isEqualTo(basis2)).to.be.equal(true); expect(basis1.hasEquivalentCellTo(basis2)).to.be.equal(true); }); it("should return jsonified basis", () => { - const basis = new Material(Na4Cl4).Basis; + const basis = new Material(Na4Cl4).getBasis(); expect(basis.toJSON()).to.be.deep.almost.equal(Na4Cl4.basis); }); it("should return true if cells are equal", () => { - const basis1 = new Material(Na4Cl4).Basis; - const basis2 = new Material(Na4Cl4Cartesian).Basis; + const basis1 = new Material(Na4Cl4).getBasis(); + const basis2 = new Material(Na4Cl4Cartesian).getBasis(); expect(basis1.hasEquivalentCellTo(basis2)).to.be.equal(true); }); @@ -120,8 +120,7 @@ describe("Basis", () => { }); it("should convert crystal to cartesian", () => { - const basis = new Material(Na4Cl4).Basis; - basis.toCartesian(); + const basis = new Material(Na4Cl4).getBasis().toCartesian(); expect(basis.isInCartesianUnits).to.be.equal(true); expect(basis.coordinates).to.be.deep.almost.equal(Na4Cl4Cartesian.basis.coordinates); }); @@ -195,7 +194,7 @@ describe("Basis", () => { */ it("should return standard representation", () => { - const basis = new Material(Na4Cl4Cartesian).Basis; + const basis = new Material(Na4Cl4Cartesian).getBasis(); expect(basis.standardRepresentation).to.be.deep.almost.equal(Na4Cl4.basis); }); diff --git a/tests/js/material.test.ts b/tests/js/material.test.ts index f593784e1..e7e75e2cb 100644 --- a/tests/js/material.test.ts +++ b/tests/js/material.test.ts @@ -16,8 +16,8 @@ describe("Material", () => { it("should return cloned material", () => { const material = new Material(Silicon); const clonedMaterial = material.clone(); - clonedMaterial.setBasis(newBasisXYZ, "xyz", clonedMaterial.Basis.units); - expect(clonedMaterial.Basis.elements).to.have.lengthOf(2); + clonedMaterial.setBasis(newBasisXYZ, "xyz", clonedMaterial.getBasis().units); + expect(clonedMaterial.getBasis().elements).to.have.lengthOf(2); }); describe("calculateHash", () => { diff --git a/tests/js/parsers/poscar.ts b/tests/js/parsers/poscar.ts index 962c4bfc7..ae99b08ba 100644 --- a/tests/js/parsers/poscar.ts +++ b/tests/js/parsers/poscar.ts @@ -4,6 +4,15 @@ import { AtomicConstraints } from "../../../src/js/constraints/constraints"; import { Material } from "../../../src/js/material"; import parsers from "../../../src/js/parsers/parsers"; import { atomsCount } from "../../../src/js/parsers/poscar"; +import { + atomicConstraints, + H2OPoscar, + Na4Cl4, + Na4Cl4Poscar, + Silicon, + Zr1H23Zr1H1, + Zr1H23Zr1H1Poscar, +} from "../fixtures"; const O2_POSCAR_WITH_COMMENTS = `O2 molecule in a box 1.0 ! universal scaling parameters @@ -16,15 +25,6 @@ cart ! positions in cartesian coordinates 0 0 0 O 0 0 1.21 O `; -import { - atomicConstraints, - H2OPoscar, - Na4Cl4, - Na4Cl4Poscar, - Silicon, - Zr1H23Zr1H1, - Zr1H23Zr1H1Poscar, -} from "../fixtures"; describe("Parsers.POSCAR", () => { it("should return a valid poscar", () => { @@ -81,7 +81,7 @@ direct const material = new Material(Silicon); const clonedMaterial = material.clone(); - clonedMaterial.setBasis(newBasisXYZ, "xyz", clonedMaterial.Basis.units); + clonedMaterial.setBasis(newBasisXYZ, "xyz", clonedMaterial.getBasis().units); const poscar = clonedMaterial.getAsPOSCAR(true); expect(poscar).to.be.equal(poscarConstraints); diff --git a/tests/js/tools/supercell.ts b/tests/js/tools/supercell.ts index 57f54c6f4..c537b566b 100644 --- a/tests/js/tools/supercell.ts +++ b/tests/js/tools/supercell.ts @@ -44,7 +44,7 @@ direct 0.625000000 0.250000000 0.250000000 Ge`; const material = new Material(Silicon); const clonedMaterial = material.clone(); - clonedMaterial.setBasis(newBasisXYZ, "xyz", clonedMaterial.Basis.units); + clonedMaterial.setBasis(newBasisXYZ, "xyz", clonedMaterial.getBasis().units); const supercellConfig = Made.tools.supercell.generateConfig(clonedMaterial, [ [2, 0, 0], [0, 1, 0], diff --git a/tests/js/tools/surface.ts b/tests/js/tools/surface.ts index 941475f9d..7041db1b5 100644 --- a/tests/js/tools/surface.ts +++ b/tests/js/tools/surface.ts @@ -8,6 +8,11 @@ import { Silicon, SiSlab100, SiSlab111, SiSlab111NoVacuum } from "../fixtures"; const { assertDeepAlmostEqual } = Utils.assertion; +const toJSONWithoutHash = (material: Material) => { + const { hash: _, ...json } = material.toJSON(); + return json; +}; + const generateSlabWithVacuum = (slabConfig: SlabConfigSchema, vacuumRatio: number) => { const slabMaterial = new Material(slabConfig); const { outOfPlaneAxisIndex } = slabConfig; @@ -90,9 +95,10 @@ describe("Tools:Surface", () => { const vacuumRatio = 0.5; const slabMaterial = generateSlabWithVacuum(slabConfig, vacuumRatio); const expectedSlabMaterial = new Material(SiSlab111); - const expectedMaterialJSON = expectedSlabMaterial.toJSON(); - const slabMaterialJSON = slabMaterial.toJSON(); - assertDeepAlmostEqual(expectedMaterialJSON, slabMaterialJSON); + assertDeepAlmostEqual( + toJSONWithoutHash(expectedSlabMaterial), + toJSONWithoutHash(slabMaterial), + ); }); it("should return slab (111) with vacuum for gamma = 60.001", () => { @@ -108,8 +114,9 @@ describe("Tools:Surface", () => { const vacuumRatio = 0.5; const slabMaterial = generateSlabWithVacuum(slabConfig, vacuumRatio); const expectedSlabMaterial = new Material(SiSlab111); - const expectedMaterialJSON = expectedSlabMaterial.toJSON(); - const slabMaterialJSON = slabMaterial.toJSON(); - assertDeepAlmostEqual(expectedMaterialJSON, slabMaterialJSON); + assertDeepAlmostEqual( + toJSONWithoutHash(expectedSlabMaterial), + toJSONWithoutHash(slabMaterial), + ); }); });