molstar
Version:
A comprehensive macromolecular library.
610 lines • 24.3 kB
JavaScript
"use strict";
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author David Sehnal <david.sehnal@gmail.com>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParamDefinition = void 0;
var tslib_1 = require("tslib");
var index_1 = require("./index");
var linear_algebra_1 = require("../mol-math/linear-algebra");
var object_1 = require("./object");
var string_1 = require("./string");
var lists_1 = require("./color/lists");
var assets_1 = require("./assets");
var ParamDefinition;
(function (ParamDefinition) {
ParamDefinition.Essential = { isEssential: true };
function setInfo(param, info) {
if (!info)
return param;
if (info.label)
param.label = info.label;
if (info.description)
param.description = info.description;
if (info.legend)
param.legend = info.legend;
if (info.fieldLabels)
param.fieldLabels = info.fieldLabels;
if (info.isHidden)
param.isHidden = info.isHidden;
if (info.shortLabel)
param.shortLabel = info.shortLabel;
if (info.twoColumns)
param.twoColumns = info.twoColumns;
if (info.isEssential)
param.isEssential = info.isEssential;
if (info.category)
param.category = info.category;
if (info.hideIf)
param.hideIf = info.hideIf;
if (info.help)
param.help = info.help;
return param;
}
function Optional(p) {
var ret = (0, tslib_1.__assign)({}, p);
ret.isOptional = true;
return ret;
}
ParamDefinition.Optional = Optional;
function Value(defaultValue, info) {
return setInfo({ type: 'value', defaultValue: defaultValue }, info);
}
ParamDefinition.Value = Value;
function Select(defaultValue, options, info) {
return setInfo({ type: 'select', defaultValue: checkDefaultKey(defaultValue, options), options: options, cycle: info === null || info === void 0 ? void 0 : info.cycle }, info);
}
ParamDefinition.Select = Select;
function MultiSelect(defaultValue, options, info) {
// TODO: check if default value is a subset of options?
var ret = setInfo({ type: 'multi-select', defaultValue: defaultValue, options: options }, info);
if (info === null || info === void 0 ? void 0 : info.emptyValue)
ret.emptyValue = info.emptyValue;
return ret;
}
ParamDefinition.MultiSelect = MultiSelect;
function Boolean(defaultValue, info) {
return setInfo({ type: 'boolean', defaultValue: defaultValue }, info);
}
ParamDefinition.Boolean = Boolean;
function Text(defaultValue, info) {
if (defaultValue === void 0) { defaultValue = ''; }
return setInfo({ type: 'text', defaultValue: defaultValue }, info);
}
ParamDefinition.Text = Text;
function Color(defaultValue, info) {
var ret = setInfo({ type: 'color', defaultValue: defaultValue }, info);
if (info === null || info === void 0 ? void 0 : info.isExpanded)
ret.isExpanded = info.isExpanded;
return ret;
}
ParamDefinition.Color = Color;
function ColorList(defaultValue, info) {
var def;
if (typeof defaultValue === 'string') {
var colors = (0, lists_1.getColorListFromName)(defaultValue);
def = { kind: colors.type !== 'qualitative' ? 'interpolate' : 'set', colors: colors.list };
}
else {
def = defaultValue;
}
return setInfo({ type: 'color-list', presetKind: (info === null || info === void 0 ? void 0 : info.presetKind) || 'all', defaultValue: def, offsets: !!(info === null || info === void 0 ? void 0 : info.offsets) }, info);
}
ParamDefinition.ColorList = ColorList;
function Vec3(defaultValue, range, info) {
return setInfo(setRange({ type: 'vec3', defaultValue: defaultValue }, range), info);
}
ParamDefinition.Vec3 = Vec3;
function Mat4(defaultValue, info) {
return setInfo({ type: 'mat4', defaultValue: defaultValue }, info);
}
ParamDefinition.Mat4 = Mat4;
function Url(url, info) {
var defaultValue = typeof url === 'string' ? assets_1.Asset.Url(url) : assets_1.Asset.Url(url.url, { body: url.body });
var ret = setInfo({ type: 'url', defaultValue: defaultValue }, info);
return ret;
}
ParamDefinition.Url = Url;
function File(info) {
var ret = setInfo({ type: 'file', defaultValue: null }, info);
if (info === null || info === void 0 ? void 0 : info.accept)
ret.accept = info.accept;
return ret;
}
ParamDefinition.File = File;
function FileList(info) {
var ret = setInfo({ type: 'file-list', defaultValue: null }, info);
if (info === null || info === void 0 ? void 0 : info.accept)
ret.accept = info.accept;
return ret;
}
ParamDefinition.FileList = FileList;
function setRange(p, range) {
if (!range)
return p;
if (typeof range.min !== 'undefined')
p.min = range.min;
if (typeof range.max !== 'undefined')
p.max = range.max;
if (typeof range.step !== 'undefined')
p.step = range.step;
return p;
}
function Numeric(defaultValue, range, info) {
var ret = setInfo(setRange({ type: 'number', defaultValue: defaultValue }, range), info);
if (info === null || info === void 0 ? void 0 : info.immediateUpdate)
ret.immediateUpdate = true;
return ret;
}
ParamDefinition.Numeric = Numeric;
function Interval(defaultValue, range, info) {
return setInfo(setRange({ type: 'interval', defaultValue: defaultValue }, range), info);
}
ParamDefinition.Interval = Interval;
function LineGraph(defaultValue, info) {
return setInfo({ type: 'line-graph', defaultValue: defaultValue }, info);
}
ParamDefinition.LineGraph = LineGraph;
function Group(params, info) {
var ret = setInfo({ type: 'group', defaultValue: (info === null || info === void 0 ? void 0 : info.customDefault) || getDefaultValues(params), params: params }, info);
if (info === null || info === void 0 ? void 0 : info.isExpanded)
ret.isExpanded = info.isExpanded;
if (info === null || info === void 0 ? void 0 : info.isFlat)
ret.isFlat = info.isFlat;
if (info === null || info === void 0 ? void 0 : info.pivot)
ret.pivot = info.pivot;
return ret;
}
ParamDefinition.Group = Group;
function EmptyGroup(info) {
return Group({}, info);
}
ParamDefinition.EmptyGroup = EmptyGroup;
function Mapped(defaultKey, names, map, info) {
var name = checkDefaultKey(defaultKey, names);
return setInfo({
type: 'mapped',
defaultValue: { name: name, params: map(name).defaultValue },
select: Select(name, names, info),
map: map
}, info);
}
ParamDefinition.Mapped = Mapped;
function MappedStatic(defaultKey, map, info) {
var options = (info === null || info === void 0 ? void 0 : info.options)
? info.options
: Object.keys(map).map(function (k) { return [k, map[k].label || (0, string_1.stringToWords)(k)]; });
var name = checkDefaultKey(defaultKey, options);
return setInfo({
type: 'mapped',
defaultValue: { name: name, params: map[name].defaultValue },
select: Select(name, options, info),
map: function (key) { return map[key]; }
}, info);
}
ParamDefinition.MappedStatic = MappedStatic;
function ObjectList(element, getLabel, info) {
return setInfo({ type: 'object-list', element: element, getLabel: getLabel, ctor: _defaultObjectListCtor, defaultValue: (info === null || info === void 0 ? void 0 : info.defaultValue) || [] }, info);
}
ParamDefinition.ObjectList = ObjectList;
function _defaultObjectListCtor() { return getDefaultValues(this.element); }
function unsetGetValue() {
throw new Error('getValue not set. Fix runtime.');
}
function ValueRef(getOptions, resolveRef, info) {
var _a;
return setInfo({ type: 'value-ref', defaultValue: { ref: (_a = info === null || info === void 0 ? void 0 : info.defaultRef) !== null && _a !== void 0 ? _a : '', getValue: unsetGetValue }, getOptions: getOptions, resolveRef: resolveRef }, info);
}
ParamDefinition.ValueRef = ValueRef;
function DataRef(info) {
var _a;
return setInfo({ type: 'data-ref', defaultValue: { ref: (_a = info === null || info === void 0 ? void 0 : info.defaultRef) !== null && _a !== void 0 ? _a : '', getValue: unsetGetValue } }, info);
}
ParamDefinition.DataRef = DataRef;
function Converted(fromValue, toValue, converted) {
return { type: 'converted', defaultValue: toValue(converted.defaultValue), converted: converted, fromValue: fromValue, toValue: toValue };
}
ParamDefinition.Converted = Converted;
function Conditioned(defaultValue, conditionParams, conditionForValue, conditionedValue, info) {
var options = Object.keys(conditionParams).map(function (k) { return [k, k]; });
return setInfo({ type: 'conditioned', select: Select(conditionForValue(defaultValue), options, info), defaultValue: defaultValue, conditionParams: conditionParams, conditionForValue: conditionForValue, conditionedValue: conditionedValue }, info);
}
ParamDefinition.Conditioned = Conditioned;
function Script(defaultValue, info) {
return setInfo({ type: 'script', defaultValue: defaultValue }, info);
}
ParamDefinition.Script = Script;
function For(params) {
return 0;
}
ParamDefinition.For = For;
function getDefaultValues(params) {
var d = {};
for (var _a = 0, _b = Object.keys(params); _a < _b.length; _a++) {
var k = _b[_a];
if (params[k].isOptional)
continue;
d[k] = params[k].defaultValue;
}
return d;
}
ParamDefinition.getDefaultValues = getDefaultValues;
function _resolveRef(resolve, ref) {
return function () { return resolve(ref); };
}
function resolveRefValue(p, value, getData) {
if (!value)
return;
if (p.type === 'value-ref') {
var v = value;
if (!v.ref)
v.getValue = function () { throw new Error('Unset ref in ValueRef value.'); };
else
v.getValue = _resolveRef(p.resolveRef, v.ref);
}
else if (p.type === 'data-ref') {
var v = value;
if (!v.ref)
v.getValue = function () { throw new Error('Unset ref in ValueRef value.'); };
else
v.getValue = _resolveRef(getData, v.ref);
}
else if (p.type === 'group') {
resolveRefs(p.params, value, getData);
}
else if (p.type === 'mapped') {
var v = value;
var param = p.map(v.name);
resolveRefValue(param, v.params, getData);
}
else if (p.type === 'object-list') {
if (!hasValueRef(p.element))
return;
for (var _a = 0, value_1 = value; _a < value_1.length; _a++) {
var e = value_1[_a];
resolveRefs(p.element, e, getData);
}
}
}
function hasParamValueRef(p) {
if (p.type === 'value-ref' || p.type === 'data-ref') {
return true;
}
else if (p.type === 'group') {
if (hasValueRef(p.params))
return true;
}
else if (p.type === 'mapped') {
for (var _a = 0, _b = p.select.options; _a < _b.length; _a++) {
var o = _b[_a][0];
if (hasParamValueRef(p.map(o)))
return true;
}
}
else if (p.type === 'object-list') {
return hasValueRef(p.element);
}
return false;
}
function hasValueRef(params) {
for (var _a = 0, _b = Object.keys(params); _a < _b.length; _a++) {
var n = _b[_a];
if (hasParamValueRef(params[n]))
return true;
}
return false;
}
function resolveRefs(params, values, getData) {
for (var _a = 0, _b = Object.keys(params); _a < _b.length; _a++) {
var n = _b[_a];
resolveRefValue(params[n], values === null || values === void 0 ? void 0 : values[n], getData);
}
}
ParamDefinition.resolveRefs = resolveRefs;
function setDefaultValues(params, defaultValues) {
for (var _a = 0, _b = Object.keys(params); _a < _b.length; _a++) {
var k = _b[_a];
if (params[k].isOptional)
continue;
params[k].defaultValue = defaultValues[k];
}
}
ParamDefinition.setDefaultValues = setDefaultValues;
function clone(params) {
return (0, object_1.deepClone)(params);
}
ParamDefinition.clone = clone;
function validate(params, values) {
// TODO
return void 0;
}
ParamDefinition.validate = validate;
function areEqual(params, a, b) {
if (a === b)
return true;
if (typeof a !== 'object' || typeof b !== 'object')
return false;
for (var _a = 0, _b = Object.keys(params); _a < _b.length; _a++) {
var k = _b[_a];
if (!isParamEqual(params[k], a[k], b[k]))
return false;
}
return true;
}
ParamDefinition.areEqual = areEqual;
function isParamEqual(p, a, b) {
if (a === b)
return true;
if (p.type === 'group') {
return areEqual(p.params, a, b);
}
else if (p.type === 'mapped') {
var u = a, v = b;
if (u.name !== v.name)
return false;
var map = p.map(u.name);
return isParamEqual(map, u.params, v.params);
}
else if (p.type === 'multi-select') {
var u = a, v = b;
if (u.length !== v.length)
return false;
if (u.length < 10) {
for (var i = 0, _i = u.length; i < _i; i++) {
if (u[i] === v[i])
continue;
if (v.indexOf(u[i]) < 0)
return false;
}
}
else {
// TODO: should the value of multiselect be a set?
var vSet = new Set(v);
for (var i = 0, _i = u.length; i < _i; i++) {
if (u[i] === v[i])
continue;
if (!vSet.has(u[i]))
return false;
}
}
return true;
}
else if (p.type === 'interval') {
return a[0] === b[0] && a[1] === b[1];
}
else if (p.type === 'line-graph') {
var u = a, v = b;
if (u.length !== v.length)
return false;
for (var i = 0, _i = u.length; i < _i; i++) {
if (!linear_algebra_1.Vec2.areEqual(u[i], v[i]))
return false;
}
return true;
}
else if (p.type === 'vec3') {
return linear_algebra_1.Vec3.equals(a, b);
}
else if (p.type === 'mat4') {
return linear_algebra_1.Mat4.areEqual(a, b, linear_algebra_1.EPSILON);
}
else if (p.type === 'script') {
var u = a, v = b;
return u.language === v.language && u.expression === v.expression;
}
else if (p.type === 'object-list') {
var u = a, v = b;
var l = u.length;
if (l !== v.length)
return false;
for (var i = 0; i < l; i++) {
if (!areEqual(p.element, u[i], v[i]))
return false;
}
return true;
}
else if (typeof a === 'object' && typeof b === 'object') {
return (0, index_1.shallowEqualObjects)(a, b);
}
// a === b was checked at the top.
return false;
}
ParamDefinition.isParamEqual = isParamEqual;
function merge(params, a, b) {
if (a === undefined)
return (0, tslib_1.__assign)({}, b);
if (b === undefined)
return (0, tslib_1.__assign)({}, a);
var o = Object.create(null);
for (var _a = 0, _b = Object.keys(params); _a < _b.length; _a++) {
var k = _b[_a];
o[k] = mergeParam(params[k], a[k], b[k]);
}
return o;
}
ParamDefinition.merge = merge;
function mergeParam(p, a, b) {
if (a === undefined)
return typeof b === 'object' && !Array.isArray(b) ? (0, tslib_1.__assign)({}, b) : b;
if (b === undefined)
return typeof a === 'object' && !Array.isArray(a) ? (0, tslib_1.__assign)({}, a) : a;
if (p.type === 'group') {
return merge(p.params, a, b);
}
else if (p.type === 'mapped') {
var u = a, v = b;
if (u.name !== v.name)
return (0, tslib_1.__assign)({}, v);
var map = p.map(v.name);
return {
name: v.name,
params: mergeParam(map, u.params, v.params)
};
}
else if (p.type === 'value') {
return b;
}
else if (typeof a === 'object' && typeof b === 'object') {
if (Array.isArray(b)) {
return b;
}
return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, a), b);
}
else {
return b;
}
}
ParamDefinition.mergeParam = mergeParam;
function selectHasOption(p, v) {
for (var _a = 0, _b = p.options; _a < _b.length; _a++) {
var o = _b[_a];
if (o[0] === v)
return true;
}
return false;
}
function normalizeParam(p, value, defaultIfUndefined) {
if (value === void 0 || value === null) {
return defaultIfUndefined ? p.defaultValue : void 0;
}
// TODO: is this a good idea and will work well?
// if (typeof p.defaultValue !== typeof value) {
// return p.defaultValue;
// }
if (p.type === 'value') {
return value;
}
else if (p.type === 'group') {
var ret = Object.create(null);
for (var _a = 0, _b = Object.keys(p.params); _a < _b.length; _a++) {
var key = _b[_a];
var param = p.params[key];
if (value[key] === void 0) {
if (defaultIfUndefined)
ret[key] = param.defaultValue;
}
else {
ret[key] = normalizeParam(param, value[key], defaultIfUndefined);
}
}
return ret;
}
else if (p.type === 'mapped') {
var v = value;
if (typeof v.name !== 'string') {
return p.defaultValue;
}
if (typeof v.params === 'undefined') {
return defaultIfUndefined ? p.defaultValue : void 0;
}
if (!selectHasOption(p.select, v.name)) {
return p.defaultValue;
}
var param = p.map(v.name);
return {
name: v.name,
params: normalizeParam(param, v.params, defaultIfUndefined)
};
}
else if (p.type === 'select') {
if (!selectHasOption(p, value))
return p.defaultValue;
return value;
}
else if (p.type === 'multi-select') {
if (!Array.isArray(value))
return p.defaultValue;
var ret = value.filter(function (v) { return selectHasOption(this, v); }, p);
if (value.length > 0 && ret.length === 0)
return p.defaultValue;
return ret;
}
else if (p.type === 'object-list') {
if (!Array.isArray(value))
return p.defaultValue;
return value.map(function (v) { return normalizeParams(p.element, v, defaultIfUndefined ? 'all' : 'skip'); });
}
// TODO: validate/normalize all param types "properly"??
return value;
}
function normalizeParams(p, value, defaultIfUndefined) {
if (typeof value !== 'object' || value === null) {
return defaultIfUndefined ? getDefaultValues(p) : value;
}
var ret = Object.create(null);
for (var _a = 0, _b = Object.keys(p); _a < _b.length; _a++) {
var key = _b[_a];
var param = p[key];
if (value[key] === void 0) {
if (defaultIfUndefined === 'all')
ret[key] = param.defaultValue;
}
else {
ret[key] = normalizeParam(param, value[key], defaultIfUndefined !== 'skip');
}
}
return ret;
}
ParamDefinition.normalizeParams = normalizeParams;
/**
* Map an object to a list of [K, string][] to be used as options, stringToWords for key used by default (or identity of null).
*
* if options is { [string]: string } and mapping is not provided, use the Value.
*/
function objectToOptions(options, f) {
var ret = [];
for (var _a = 0, _b = Object.keys(options); _a < _b.length; _a++) {
var k = _b[_a];
if (!f) {
if (typeof options[k] === 'string')
ret.push([k, options[k]]);
else
ret.push([k, f === null ? k : (0, string_1.stringToWords)(k)]);
}
else {
var o = f(k, options[k]);
ret.push(typeof o === 'string' ? [k, o] : [k, o[0], o[1]]);
}
}
return ret;
}
ParamDefinition.objectToOptions = objectToOptions;
/**
* Map array of options using stringToWords by default (or identity of null).
*/
function arrayToOptions(xs, f) {
var ret = [];
for (var _a = 0, xs_1 = xs; _a < xs_1.length; _a++) {
var x = xs_1[_a];
if (!f) {
ret.push([x, f === null ? x : (0, string_1.stringToWords)(x)]);
}
else {
ret.push([x, f(x)]);
}
}
return ret;
}
ParamDefinition.arrayToOptions = arrayToOptions;
function optionLabel(param, value) {
for (var _a = 0, _b = param.options; _a < _b.length; _a++) {
var o = _b[_a];
if (o[0] === value)
return o[1];
}
return '';
}
ParamDefinition.optionLabel = optionLabel;
function checkDefaultKey(k, options) {
for (var _a = 0, options_1 = options; _a < options_1.length; _a++) {
var o = options_1[_a];
if (o[0] === k)
return k;
}
return options.length > 0 ? options[0][0] : void 0;
}
})(ParamDefinition = exports.ParamDefinition || (exports.ParamDefinition = {}));
//# sourceMappingURL=param-definition.js.map