Skip to content
Snippets Groups Projects
Commit 4fb9af89 authored by David Sehnal's avatar David Sehnal
Browse files

tables

parent a81464dd
No related branches found
No related tags found
No related merge requests found
...@@ -69,6 +69,27 @@ describe('table', () => { ...@@ -69,6 +69,27 @@ describe('table', () => {
expect(t.n.toArray()).toEqual(['row1', 'row2']); expect(t.n.toArray()).toEqual(['row1', 'row2']);
}); });
it('ofArrays', () => {
const t = Table.ofArrays<typeof schema>(schema, {
x: [10, -1],
n: ['row1', 'row2'],
});
expect(t.x.toArray()).toEqual([10, -1]);
expect(t.n.toArray()).toEqual(['row1', 'row2']);
});
it('pickColumns', () => {
const t = Table.ofColumns<typeof schema>({
x: Column.ofArray({ array: [10, -1], type: Column.Type.int }),
n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }),
});
const s = { x: Column.Type.int };
const picked = Table.pickColumns(s, t);
expect(picked._columns).toEqual(['x']);
expect(picked._rowCount).toEqual(2);
expect(picked.x.toArray()).toEqual([10, -1]);
});
it('sort', () => { it('sort', () => {
const t = Table.ofColumns<typeof schema>({ const t = Table.ofColumns<typeof schema>({
x: Column.ofArray({ array: [10, -1], type: Column.Type.int }), x: Column.ofArray({ array: [10, -1], type: Column.Type.int }),
......
...@@ -17,18 +17,24 @@ interface Column<T> { ...@@ -17,18 +17,24 @@ interface Column<T> {
} }
namespace Column { namespace Column {
export type Type = typeof Type.str | typeof Type.int | typeof Type.float | Type.Vector | Type.Matrix export type Type<T = any> = Type.Str | Type.Int | Type.Float | Type.Vector | Type.Matrix | Type.Aliased<T>
export namespace Type { export namespace Type {
export const str = { T: '' as string, kind: 'str' as 'str' }; export type Str = { T: string, kind: 'str' }
export const int = { T: 0 as number, kind: 'int' as 'int' }; export type Int = { T: number, kind: 'int' }
export const float = { T: 0 as number, kind: 'float' as 'float' }; export type Float = { T: number, kind: 'float' }
export type Vector = { T: number[], dim: number, kind: 'vector' }; export type Vector = { T: number[], dim: number, kind: 'vector' };
export type Matrix = { T: number[][], rows: number, cols: number, kind: 'matrix' }; export type Matrix = { T: number[][], rows: number, cols: number, kind: 'matrix' };
export type Aliased<T> = { T: T } & { kind: 'str' | 'int' | 'float' }
export const str: Str = { T: '', kind: 'str' };
export const int: Int = { T: 0, kind: 'int' };
export const float: Float = { T: 0, kind: 'float' };
export function vector(dim: number): Vector { return { T: [] as number[], dim, kind: 'vector' }; } export function vector(dim: number): Vector { return { T: [] as number[], dim, kind: 'vector' }; }
export function matrix(rows: number, cols: number): Matrix { return { T: [] as number[][], rows, cols, kind: 'matrix' }; } export function matrix(rows: number, cols: number): Matrix { return { T: [] as number[][], rows, cols, kind: 'matrix' }; }
export function aliased<T>(t: Type): Aliased<T> { return t as any as Aliased<T>; }
} }
export interface ToArrayParams { export interface ToArrayParams {
......
...@@ -9,10 +9,21 @@ import { sortArray } from './sort' ...@@ -9,10 +9,21 @@ import { sortArray } from './sort'
type Table<Schema extends Table.Schema> = { readonly _rowCount: number, readonly _columns: ReadonlyArray<string> } & Table.Columns<Schema> type Table<Schema extends Table.Schema> = { readonly _rowCount: number, readonly _columns: ReadonlyArray<string> } & Table.Columns<Schema>
/** An immutable table */
namespace Table { namespace Table {
export type Schema = { [field: string]: Column.Type } export type Schema = { [field: string]: Column.Type }
export type Columns<S extends Schema> = { [C in keyof S]: Column<S[C]['T']> } export type Columns<S extends Schema> = { [C in keyof S]: Column<S[C]['T']> }
export type Row<S extends Schema> = { [C in keyof S]: S[C]['T'] } export type Row<S extends Schema> = { [C in keyof S]: S[C]['T'] }
export type Arrays<S extends Schema> = { [C in keyof S]: ArrayLike<S[C]['T']> }
export function pickColumns<S extends Schema, T extends S>(schema: S, table: Table<T>): Table<S> {
const ret = Object.create(null);
const keys = Object.keys(schema);
ret._rowCount = table._rowCount;
ret._columns = keys;
for (const k of keys) ret[k] = table[k];
return ret;
}
export function ofColumns<S extends Schema, R extends Table<S> = Table<S>>(columns: Columns<S>): R { export function ofColumns<S extends Schema, R extends Table<S> = Table<S>>(columns: Columns<S>): R {
const _columns = Object.keys(columns); const _columns = Object.keys(columns);
...@@ -26,7 +37,7 @@ namespace Table { ...@@ -26,7 +37,7 @@ namespace Table {
const columns = Object.keys(schema); const columns = Object.keys(schema);
ret._rowCount = rowCount; ret._rowCount = rowCount;
ret._columns = columns; ret._columns = columns;
for (const k of Object.keys(schema)) { for (const k of columns) {
(ret as any)[k] = Column.ofLambda({ (ret as any)[k] = Column.ofLambda({
rowCount, rowCount,
type: schema[k], type: schema[k],
...@@ -37,6 +48,17 @@ namespace Table { ...@@ -37,6 +48,17 @@ namespace Table {
return ret as R; return ret as R;
} }
export function ofArrays<S extends Schema, R extends Table<S> = Table<S>>(schema: Schema, arrays: Arrays<S>): R {
const ret = Object.create(null);
const columns = Object.keys(schema);
ret._rowCount = arrays[columns[0]].length;
ret._columns = columns;
for (const k of Object.keys(schema)) {
(ret as any)[k] = Column.ofArray({ array: arrays[k], type: schema[k] })
}
return ret as R;
}
/** Sort and return a new table */ /** Sort and return a new table */
export function sort<T extends Table<S>, S extends Schema>(table: T, cmp: (i: number, j: number) => number) { export function sort<T extends Table<S>, S extends Schema>(table: T, cmp: (i: number, j: number) => number) {
const indices = new Int32Array(table._rowCount); const indices = new Int32Array(table._rowCount);
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
*/ */
import Column from '../../../mol-base/collections/column' import Column from '../../../mol-base/collections/column'
import { Shape as mmCIF } from '../../../mol-io/reader/cif/schema/mmcif' import Table from '../../../mol-base/collections/table'
import { Schema as mmCIF } from '../../../mol-io/reader/cif/schema/mmcif'
export interface ElementSymbol extends String { '@type': 'element-symbol' } export interface ElementSymbol extends String { '@type': 'element-symbol' }
export function ElementSymbol(s: string): ElementSymbol { export function ElementSymbol(s: string): ElementSymbol {
...@@ -13,50 +14,55 @@ export function ElementSymbol(s: string): ElementSymbol { ...@@ -13,50 +14,55 @@ export function ElementSymbol(s: string): ElementSymbol {
return s.toUpperCase() as any; return s.toUpperCase() as any;
} }
type Key = { key: Column<number> } export const AtomsSchema = {
type_symbol: Column.Type.aliased<ElementSymbol>(mmCIF.atom_site.type_symbol),
type _Atoms = Pick<mmCIF['atom_site'], label_atom_id: mmCIF.atom_site.label_atom_id,
| 'type_symbol' auth_atom_id: mmCIF.atom_site.auth_atom_id,
| 'label_atom_id' label_alt_id: mmCIF.atom_site.label_alt_id,
| 'auth_atom_id' pdbx_formal_charge: mmCIF.atom_site.pdbx_formal_charge,
| 'label_alt_id' occupancy: mmCIF.atom_site.occupancy,
| 'pdbx_formal_charge' B_iso_or_equiv: mmCIF.atom_site.B_iso_or_equiv,
| 'occupancy'
| 'B_iso_or_equiv'> key: Column.Type.int,
& Key source_row: Column.Type.int,
export interface Atoms extends _Atoms { };
source_row: Column<number>
} export interface Atoms extends Table<typeof AtomsSchema> { }
export const ResiduesSchema = {
group_PDB: mmCIF.atom_site.group_PDB,
label_comp_id: mmCIF.atom_site.label_comp_id,
auth_comp_id: mmCIF.atom_site.auth_comp_id,
label_seq_id: mmCIF.atom_site.label_seq_id,
auth_seq_id: mmCIF.atom_site.auth_seq_id,
pdbx_PDB_ins_code: mmCIF.atom_site.pdbx_PDB_ins_code,
type _Residues = Pick<mmCIF['atom_site'], key: Column.Type.int
| 'group_PDB' };
| 'label_comp_id'
| 'auth_comp_id' export interface Residues extends Table<typeof AtomsSchema> { }
| 'label_seq_id'
| 'auth_seq_id' export const ChainsSchema = {
| 'pdbx_PDB_ins_code'> label_asym_id: mmCIF.atom_site.label_asym_id,
& Key auth_asym_id: mmCIF.atom_site.auth_asym_id,
export interface Residues extends _Residues { } auth_comp_id: mmCIF.atom_site.auth_comp_id,
label_entity_id: mmCIF.atom_site.label_entity_id,
type _Chains = Pick<mmCIF['atom_site'], pdbx_PDB_model_num: mmCIF.atom_site.pdbx_PDB_model_num,
| 'label_asym_id'
| 'auth_asym_id' key: Column.Type.int,
| 'auth_comp_id' entityIndex: Column.Type.int
| 'label_entity_id'
| 'pdbx_PDB_model_num'>
& Key
export interface Chains extends _Chains {
enityDataIndex: Column<number>
} }
type _EntityData = mmCIF['entity'] export interface Chains extends Table<typeof ChainsSchema> { }
export interface EntityData extends _EntityData { }
export const EntitySchema = mmCIF['entity']
export interface Entities extends Table<typeof EntitySchema> { }
export interface Macromolecule { export interface Macromolecule {
atoms: Atoms, atoms: Atoms,
residues: Residues, residues: Residues,
chains: Chains, chains: Chains,
entityData: EntityData entities: Entities
} }
export default Macromolecule export default Macromolecule
\ No newline at end of file
...@@ -21,7 +21,7 @@ const testBlock = Data.Block({ ...@@ -21,7 +21,7 @@ const testBlock = Data.Block({
}, 'test'); }, 'test');
namespace TestSchema { namespace TestSchema {
export const atoms = { x: Schema.Field.int(), name: Schema.Field.str() } export const atoms = { x: Schema.Types.int, name: Schema.Types.str }
export const schema = { atoms } export const schema = { atoms }
} }
......
...@@ -6,93 +6,56 @@ ...@@ -6,93 +6,56 @@
import * as Data from './data-model' import * as Data from './data-model'
import Column, { createAndFillArray } from '../../../mol-base/collections/column' import Column, { createAndFillArray } from '../../../mol-base/collections/column'
import Table from '../../../mol-base/collections/table'
/**
* A schema defines the shape of categories and fields.
*
* @example:
* const atom_site = {
* '@alias': '_atom_site',
* label_atom_id: Field.str(),
* Cartn_x: Field.float(),
* Cartn_y: Field.float(),
* Cartn_z: Field.float(),
* }
*
* const mmCIF = { atom_site };
*/
//////////////////////////////////////////////
export function toTypedFrame<Schema extends FrameSchema, Frame extends TypedFrame<Schema> = TypedFrame<Schema>>(schema: Schema, frame: Data.Frame): Frame { export function toTypedFrame<Schema extends FrameSchema, Frame extends TypedFrame<Schema> = TypedFrame<Schema>>(schema: Schema, frame: Data.Frame): Frame {
return createTypedFrame(schema, frame) as Frame; return createTypedFrame(schema, frame) as Frame;
} }
export function toTypedCategory<Schema extends CategorySchema>(schema: Schema, category: Data.Category): TypedCategory<Schema> { export function toTable<Schema extends Table.Schema, R extends Table<Schema> = Table<Schema>>(schema: Schema, category: Data.Category): R {
return new _TypedCategory(category, schema, true) as TypedCategory<any>; return new _TypedCategory(category, schema, true) as any;
} }
export type FrameSchema = { [category: string]: CategorySchema } export const Types = Column.Type
export type TypedFrameShape<Schema extends FrameSchema> = { [C in keyof Schema]: TypedCategoryShape<Schema[C]> }
export type FrameSchema = { [category: string]: Table.Schema }
export type TypedFrame<Schema extends FrameSchema> = { export type TypedFrame<Schema extends FrameSchema> = {
readonly _header?: string, readonly _header?: string,
readonly _frame: Data.Frame readonly _frame: Data.Frame
} & { [C in keyof Schema]: TypedCategory<Schema[C]> } } & { [C in keyof Schema]: Table<Schema[C]> }
export type CategorySchema = { [field: string]: Field.Schema<any> } type ColumnCtor = (field: Data.Field, category: Data.Category, key: string) => Column<any>
export type TypedCategoryShape<Schema extends CategorySchema> = { [F in keyof Schema]: Column<Schema[F]['T']> }
export type TypedCategory<Schema extends CategorySchema> = { function getColumnCtor(t: Column.Type): ColumnCtor {
readonly _rowCount: number, switch (t.kind) {
readonly _isDefined: boolean, case 'str': return (f, c, k) => createColumn(Column.Type.str, f, f.str, f.toStringArray);
readonly _category: Data.Category case 'int': return (f, c, k) => createColumn(Column.Type.int, f, f.int, f.toIntArray);
} & { [F in keyof Schema]: Column<Schema[F]['T']> } case 'float': return (f, c, k) => createColumn(Column.Type.float, f, f.float, f.toFloatArray);
case 'vector': return (f, c, k) => {
export namespace Field { const dim = t.dim;
export interface Schema<T> { T: T, ctor: (field: Data.Field, category: Data.Category, key: string) => Column<T>, undefinedField: (c: number) => Data.Field, alias?: string }; const value = (row: number) => Data.getVector(c, k, dim, row);
export interface Spec { undefinedField?: (c: number) => Data.Field, alias?: string } return createColumn(t, f, value, params => createAndFillArray(f.rowCount, value, params));
export function alias(name: string): Schema<any> { return { alias: name } as any; }
export function str(spec?: Spec) { return createSchema(spec, Str); }
export function int(spec?: Spec) { return createSchema(spec, Int); }
export function float(spec?: Spec) { return createSchema(spec, Float); }
export function vector(rows: number, spec?: Spec) { return createSchema(spec, Vector(rows)); }
export function matrix(rows: number, cols: number, spec?: Spec) { return createSchema(spec, Matrix(rows, cols)); }
function create<T>(type: Column.Type, field: Data.Field, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> {
return {
'@type': type,
'@array': field['@array'],
isDefined: field.isDefined,
rowCount: field.rowCount,
value,
valueKind: field.valueKind,
areValuesEqual: field.areValuesEqual,
toArray
};
}
function Str(field: Data.Field) { return create(Column.Type.str, field, field.str, field.toStringArray); }
function Int(field: Data.Field) { return create(Column.Type.int, field, field.int, field.toIntArray); }
function Float(field: Data.Field) { return create(Column.Type.float, field, field.float, field.toFloatArray); }
function Vector(rows: number) {
return function(field: Data.Field, category: Data.Category, key: string) {
const value = (row: number) => Data.getVector(category, key, rows, row);
return create(Column.Type.vector(rows), field, value, params => createAndFillArray(field.rowCount, value, params));
} }
} case 'matrix': return (f, c, k) => {
const rows = t.rows, cols = t.cols;
function Matrix(rows: number, cols: number) { const value = (row: number) => Data.getMatrix(c, k, rows, cols, row);
return function(field: Data.Field, category: Data.Category, key: string) { return createColumn(t, f, value, params => createAndFillArray(f.rowCount, value, params));
const value = (row: number) => Data.getMatrix(category, key, rows, cols, row);
return create(Column.Type.matrix(rows, cols), field, value, params => createAndFillArray(field.rowCount, value, params));
} }
} }
}
// spec argument is to allow for specialised implementation for undefined fields
function createSchema<T>(spec: Spec | undefined, ctor: (field: Data.Field, category: Data.Category, key: string) => Column<T>): Schema<T> { function createColumn<T>(type: Column.Type, field: Data.Field, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> {
return { T: 0 as any, ctor, undefinedField: (spec && spec.undefinedField) || Data.DefaultUndefinedField, alias: spec && spec.alias }; return {
} '@type': type,
'@array': field['@array'],
isDefined: field.isDefined,
rowCount: field.rowCount,
value,
valueKind: field.valueKind,
areValuesEqual: field.areValuesEqual,
toArray
};
} }
class _TypedFrame implements TypedFrame<any> { // tslint:disable-line:class-name class _TypedFrame implements TypedFrame<any> { // tslint:disable-line:class-name
...@@ -104,19 +67,21 @@ class _TypedFrame implements TypedFrame<any> { // tslint:disable-line:class-name ...@@ -104,19 +67,21 @@ class _TypedFrame implements TypedFrame<any> { // tslint:disable-line:class-name
} }
} }
class _TypedCategory implements TypedCategory<any> { // tslint:disable-line:class-name class _TypedCategory implements Table<any> { // tslint:disable-line:class-name
_rowCount = this._category.rowCount; _rowCount = this._category.rowCount;
constructor(public _category: Data.Category, schema: CategorySchema, public _isDefined: boolean) { _columns: ReadonlyArray<string>;
const fieldKeys = Object.keys(schema).filter(k => k !== '@alias'); constructor(public _category: Data.Category, schema: Table.Schema, public _isDefined: boolean) {
const fieldKeys = Object.keys(schema);
this._columns = fieldKeys;
const cache = Object.create(null); const cache = Object.create(null);
for (const k of fieldKeys) { for (const k of fieldKeys) {
const s = schema[k]; const cType = schema[k];
const ctor = getColumnCtor(cType);
Object.defineProperty(this, k, { Object.defineProperty(this, k, {
get: function() { get: function() {
if (cache[k]) return cache[k]; if (cache[k]) return cache[k];
const name = s.alias || k; const field = _category.getField(k);
const field = _category.getField(name) || s.undefinedField(_category.rowCount); cache[k] = !!field ? ctor(field, _category, k) : Column.Undefined(_category.rowCount, cType);
cache[k] = s.ctor(field, _category, name);
return cache[k]; return cache[k];
}, },
enumerable: true, enumerable: true,
...@@ -130,9 +95,7 @@ function createTypedFrame(schema: FrameSchema, frame: Data.Frame): any { ...@@ -130,9 +95,7 @@ function createTypedFrame(schema: FrameSchema, frame: Data.Frame): any {
return new _TypedFrame(frame, schema); return new _TypedFrame(frame, schema);
} }
function createTypedCategory(key: string, schema: CategorySchema, frame: Data.Frame) { function createTypedCategory(key: string, schema: Table.Schema, frame: Data.Frame) {
const alias = (schema['@alias'] && schema['@alias'].alias) || key; const cat = frame.categories[key[0] === '_' ? key : '_' + key];
const name = alias[0] === '_' ? alias : '_' + alias;
const cat = frame.categories[name];
return new _TypedCategory(cat || Data.Category.Empty, schema, !!cat); return new _TypedCategory(cat || Data.Category.Empty, schema, !!cat);
} }
\ No newline at end of file
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { Field, TypedFrame } from '../schema' import { Types, TypedFrame } from '../schema'
const str = Field.str() const str = Types.str
const float = Field.float() const float = Types.float
const datablock = { const datablock = {
id: str, id: str,
...@@ -58,7 +58,7 @@ const item_units_conversion = { ...@@ -58,7 +58,7 @@ const item_units_conversion = {
// TODO save frame dic schema // TODO save frame dic schema
const dic = { export const Schema = {
datablock, datablock,
dictionary, dictionary,
dictionary_history, dictionary_history,
...@@ -69,5 +69,7 @@ const dic = { ...@@ -69,5 +69,7 @@ const dic = {
item_units_conversion item_units_conversion
} }
type dic = TypedFrame<typeof dic> export interface Frame extends TypedFrame<typeof Schema> { }
export default dic
// type dic = TypedFrame<typeof dic>
//export default dic
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
*/ */
import { Field, TypedFrame, TypedFrameShape } from '../schema' import { Types, TypedFrame } from '../schema'
const str = Field.str(); const str = Types.str;
const int = Field.int(); const int = Types.int;
const float = Field.float(); const float = Types.float;
const entry = { const entry = {
id: str id: str
...@@ -18,7 +18,7 @@ type EntityType = 'polymer' | 'non-polymer' | 'water' ...@@ -18,7 +18,7 @@ type EntityType = 'polymer' | 'non-polymer' | 'water'
const entity = { const entity = {
id: str, id: str,
type: str as Field.Schema<EntityType>, type: Types.aliased<EntityType>(str),
src_method: str, src_method: str,
pdbx_description: str, pdbx_description: str,
formula_weight: float, formula_weight: float,
...@@ -48,8 +48,8 @@ const cell = { ...@@ -48,8 +48,8 @@ const cell = {
const symmetry = { const symmetry = {
entry_id: str, entry_id: str,
space_group_name_HM: Field.str({ alias: 'space_group_name_H-M' }), 'space_group_name_H-M': str,
pdbx_full_space_group_name_HM: Field.str({ alias: 'pdbx_full_space_group_name_H-M' }), 'pdbx_full_space_group_name_H': str,
cell_setting: str, cell_setting: str,
Int_Tables_number: int, Int_Tables_number: int,
space_group_name_Hall: str space_group_name_Hall: str
...@@ -117,7 +117,7 @@ type BondValueOrder = ...@@ -117,7 +117,7 @@ type BondValueOrder =
const struct_conn = { const struct_conn = {
id: str, id: str,
conn_type_id: str as Field.Schema<StructConnTypeId>, conn_type_id: Types.aliased<StructConnTypeId>(str),
pdbx_PDB_id: str, pdbx_PDB_id: str,
ptnr1_label_asym_id: str, ptnr1_label_asym_id: str,
ptnr1_label_comp_id: str, ptnr1_label_comp_id: str,
...@@ -148,11 +148,11 @@ const struct_conn = { ...@@ -148,11 +148,11 @@ const struct_conn = {
pdbx_ptnr3_PDB_ins_code: str, pdbx_ptnr3_PDB_ins_code: str,
details: str, details: str,
pdbx_dist_value: float, pdbx_dist_value: float,
pdbx_value_order: str as Field.Schema<BondValueOrder> pdbx_value_order: Types.aliased<BondValueOrder>(str)
} }
const struct_conn_type = { const struct_conn_type = {
id: str as Field.Schema<StructConnTypeId>, id: Types.aliased<StructConnTypeId>(str),
criteria: str, criteria: str,
reference: str reference: str
} }
...@@ -161,10 +161,10 @@ const chem_comp_bond = { ...@@ -161,10 +161,10 @@ const chem_comp_bond = {
comp_id: str, comp_id: str,
pdbx_stereo_config: str, pdbx_stereo_config: str,
pdbx_ordinal: int, pdbx_ordinal: int,
pdbx_aromatic_flag: str as Field.Schema<'Y' | 'N'>, pdbx_aromatic_flag: Types.aliased<'Y' | 'N'>(str),
atom_id_1: str, atom_id_1: str,
atom_id_2: str, atom_id_2: str,
value_order: str as Field.Schema<BondValueOrder> value_order: Types.aliased<BondValueOrder>(str)
} }
const pdbx_struct_assembly = { const pdbx_struct_assembly = {
...@@ -186,8 +186,8 @@ const pdbx_struct_oper_list = { ...@@ -186,8 +186,8 @@ const pdbx_struct_oper_list = {
type: str, type: str,
name: str, name: str,
symmetry_operation: str, symmetry_operation: str,
matrix: Field.matrix(3, 3), matrix: Types.matrix(3, 3),
vector: Field.vector(3) vector: Types.vector(3)
} }
const pdbx_struct_mod_residue = { const pdbx_struct_mod_residue = {
...@@ -245,5 +245,4 @@ export const Schema = { ...@@ -245,5 +245,4 @@ export const Schema = {
atom_site atom_site
}; };
export interface Frame extends TypedFrame<typeof Schema> { } export interface Frame extends TypedFrame<typeof Schema> { }
export interface Shape extends TypedFrameShape<typeof Schema> { } \ No newline at end of file
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment