UNPKG

drugflow-molstar

Version:
796 lines (795 loc) 207 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var mol_plugin_ui_1 = require("molstar/lib/mol-plugin-ui"); var transforms_1 = require("molstar/lib/mol-plugin-state/transforms"); var structure_representation_params_1 = require("molstar/lib/mol-plugin-state/helpers/structure-representation-params"); var commands_1 = require("molstar/lib/mol-plugin/commands"); var spec_1 = require("molstar/lib/mol-plugin-ui/spec"); var model_index_1 = require("molstar/lib/mol-plugin-state/animation/built-in/model-index"); var loci_1 = require("molstar/lib/mol-model/loci"); var helpers_1 = require("./helpers"); var rx_event_helper_1 = require("molstar/lib/mol-util/rx-event-helper"); var structure_1 = require("molstar/lib/mol-model/structure"); var builder_1 = require("molstar/lib/mol-script/language/builder"); var structure_selection_query_1 = require("molstar/lib/mol-plugin-state/helpers/structure-selection-query"); var mol_task_1 = require("molstar/lib/mol-task"); var color_1 = require("molstar/lib/mol-util/color/color"); var structure_2 = require("molstar/lib/mol-model/structure"); var mol_state_1 = require("molstar/lib/mol-state"); var representation_1 = require("molstar/lib/mol-repr/representation"); var representation_2 = require("molstar/lib/mol-repr/structure/representation"); var units_visual_1 = require("molstar/lib/mol-repr/structure/units-visual"); var param_definition_1 = require("molstar/lib/mol-util/param-definition"); var location_iterator_1 = require("molstar/lib/mol-geo/util/location-iterator"); var location_1 = require("molstar/lib/mol-model/location"); var loci_2 = require("molstar/lib/mol-model/loci"); var box_1 = require("molstar/lib/mol-geo/geometry/mesh/builder/box"); var mesh_builder_1 = require("molstar/lib/mol-geo/geometry/mesh/mesh-builder"); var linear_algebra_1 = require("molstar/lib/mol-math/linear-algebra"); var int_1 = require("molstar/lib/mol-data/int"); var names_1 = require("molstar/lib/mol-util/color/names"); var structure_contact3d_1 = require("./structure_contact3d"); var structure_transparency_1 = require("molstar/lib/mol-plugin-state/helpers/structure-transparency"); var interactions_1 = require("molstar/lib/mol-model-props/computed/interactions"); var common_1 = require("molstar/lib/mol-model-props/computed/interactions/common"); require('molstar/lib/mol-plugin-ui/skin/light.scss'); var DrugflowMolstarPlugin = /** @class */ (function () { function DrugflowMolstarPlugin() { var _this = this; this._ev = rx_event_helper_1.RxEventHelper.create(); this.events = { loadComplete: this._ev() }; this.assemblyRef = ''; this.granularity = 'residue'; this.selected_info = { "all": { "polymer": [], "ligand": [], "other": [] }, "prev": { "polymer": [], "ligand": [], "other": [] }, "now": { "polymer": [], "ligand": [], "other": [] } }; this.isHighlightColorUpdated = false; // 隐藏状态追踪器 this.hiddenState = { chains: new Set(), // 隐藏的链ID ligands: new Set(), // 隐藏的配体(格式: "chainId:resId" 或 "chainId:resName") residues: new Set() // 隐藏的残基(格式: "chainId:resId") }; this.canvas = { toggleControls: function (isVisible) { if (typeof isVisible === 'undefined') isVisible = !_this.plugin.layout.state.showControls; commands_1.PluginCommands.Layout.Update(_this.plugin, { state: { showControls: isVisible } }); }, toggleExpanded: function (isExpanded) { if (typeof isExpanded === 'undefined') isExpanded = !_this.plugin.layout.state.isExpanded; commands_1.PluginCommands.Layout.Update(_this.plugin, { state: { isExpanded: isExpanded } }); }, setBgColor: function (color) { if (!color) return; _this.canvas.applySettings({ color: color }); }, applySettings: function (settings) { if (!settings) return; var rendererParams = {}; if (settings.color) rendererParams['backgroundColor'] = color_1.Color.fromRgb(settings.color.r, settings.color.g, settings.color.b); if (settings.lighting) rendererParams['style'] = { name: settings.lighting }; var renderer = _this.plugin.canvas3d.props.renderer; commands_1.PluginCommands.Canvas3D.SetSettings(_this.plugin, { settings: { renderer: tslib_1.__assign(tslib_1.__assign({}, renderer), rendererParams) } }); }, toggleSelect: function (isSelect) { _this.plugin.selectionMode = !isSelect; }, }; this.measure = { add_distance: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: loci = this.plugin.managers.structure.selection.additionsHistory; if (loci.length < 2) { console.log('please select two atoms'); return [2 /*return*/]; } return [4 /*yield*/, this.plugin.managers.structure.measurement.addDistance(loci[0].loci, loci[1].loci)]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, add_angle: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: loci = this.plugin.managers.structure.selection.additionsHistory; if (loci.length < 3) { console.log('please select three atoms'); return [2 /*return*/]; } return [4 /*yield*/, this.plugin.managers.structure.measurement.addAngle(loci[0].loci, loci[1].loci, loci[2].loci)]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, add_dihedral: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: loci = this.plugin.managers.structure.selection.additionsHistory; if (loci.length < 4) { console.log('please select four atoms'); return [2 /*return*/]; } return [4 /*yield*/, this.plugin.managers.structure.measurement.addDihedral(loci[0].loci, loci[1].loci, loci[2].loci, loci[3].loci)]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, add_orientation: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var locis; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: locis = []; this.plugin.managers.structure.selection.entries.forEach(function (v) { locis.push(v.selection); }); return [4 /*yield*/, this.plugin.managers.structure.measurement.addOrientation(locis)]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, add_plane: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var locis; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: locis = []; this.plugin.managers.structure.selection.entries.forEach(function (v) { locis.push(v.selection); }); return [4 /*yield*/, this.plugin.managers.structure.measurement.addPlane(locis)]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, clean_all_measure: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var state, groupRef, builder; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: state = this.plugin.state.data; groupRef = mol_state_1.StateSelection.findTagInSubtree(state.tree, mol_state_1.StateTransform.RootRef, 'measurement-group'); builder = this.plugin.state.data.build(); if (!groupRef) return [3 /*break*/, 2]; builder.to(mol_state_1.StateTransform.RootRef).delete(groupRef); return [4 /*yield*/, this.applyState(builder)]; case 1: _b.sent(); return [3 /*break*/, 3]; case 2: console.log('no measurement group'); _b.label = 3; case 3: return [2 /*return*/]; } }); }); } }; this.visual = { select_all: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var all_query, data; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: all_query = structure_selection_query_1.StructureSelectionQueries.all; data = this.plugin.state.data.select(this.assemblyRef)[0].obj.data; return [4 /*yield*/, this.plugin.runTask(mol_task_1.Task.create('Structure Selection', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var selection, loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, all_query.getSelection(this.plugin, runtime, data)]; case 1: selection = _b.sent(); loci = structure_1.StructureSelection.toLociWithSourceUnits(selection); this.plugin.managers.interactivity.lociSelects.select({ loci: loci }); return [2 /*return*/]; } }); }); }))]; case 1: _b.sent(); this.add_selection_info(); return [2 /*return*/]; } }); }); }, select_none: function () { _this.plugin.managers.interactivity.lociSelects.deselectAll(); _this.add_selection_info(); }, expand_select: function (expand, type) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var whole_residues, surroundings_query, data; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: whole_residues = true; if (type) { if (type === 'atom') whole_residues = false; } surroundings_query = (0, structure_selection_query_1.StructureSelectionQuery)('Surrounding of Selection', builder_1.MolScriptBuilder.struct.modifier.union([ builder_1.MolScriptBuilder.struct.modifier.exceptBy({ 0: builder_1.MolScriptBuilder.struct.modifier.includeSurroundings({ 0: builder_1.MolScriptBuilder.internal.generator.current(), radius: expand, 'as-whole-residues': whole_residues }), by: builder_1.MolScriptBuilder.internal.generator.current() }) ]), { description: 'Select surrounding of the current selection.', category: structure_selection_query_1.StructureSelectionCategory.Manipulate, referencesCurrent: true }); data = this.plugin.state.data.select(this.assemblyRef)[0].obj.data; return [4 /*yield*/, this.plugin.runTask(mol_task_1.Task.create('Structure Selection', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var selection, loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, surroundings_query.getSelection(this.plugin, runtime, data)]; case 1: selection = _b.sent(); loci = structure_1.StructureSelection.toLociWithSourceUnits(selection); this.plugin.managers.interactivity.lociSelects.select({ loci: loci }); return [2 /*return*/]; } }); }); }))]; case 1: _b.sent(); this.add_selection_info(); return [2 /*return*/]; } }); }); }, deselect_current: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_query, data; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: current_query = structure_selection_query_1.StructureSelectionQueries.current; data = this.plugin.state.data.select(this.assemblyRef)[0].obj.data; return [4 /*yield*/, this.plugin.runTask(mol_task_1.Task.create('Structure Selection', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_selection, current_loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, current_query.getSelection(this.plugin, runtime, data)]; case 1: current_selection = _b.sent(); current_loci = structure_1.StructureSelection.toLociWithSourceUnits(current_selection); this.plugin.managers.interactivity.lociSelects.deselect({ loci: current_loci }); return [2 /*return*/]; } }); }); }))]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, inverse_select: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_query, inverse_query, data; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: current_query = structure_selection_query_1.StructureSelectionQueries.current; inverse_query = structure_selection_query_1.StructureSelectionQueries.complement; data = this.plugin.state.data.select(this.assemblyRef)[0].obj.data; return [4 /*yield*/, this.plugin.runTask(mol_task_1.Task.create('Structure Selection', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_selection, inverse_selection, current_loci, inverse_loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, current_query.getSelection(this.plugin, runtime, data)]; case 1: current_selection = _b.sent(); return [4 /*yield*/, inverse_query.getSelection(this.plugin, runtime, data)]; case 2: inverse_selection = _b.sent(); current_loci = structure_1.StructureSelection.toLociWithSourceUnits(current_selection); inverse_loci = structure_1.StructureSelection.toLociWithSourceUnits(inverse_selection); this.plugin.managers.interactivity.lociSelects.select({ loci: inverse_loci }); this.plugin.managers.interactivity.lociSelects.deselect({ loci: current_loci }); return [2 /*return*/]; } }); }); }))]; case 1: _b.sent(); this.add_selection_info(); return [2 /*return*/]; } }); }); }, hideSelect: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var sel, components, _i, sel_1, s; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: sel = this.plugin.managers.structure.hierarchy.getStructuresWithSelection(); components = []; for (_i = 0, sel_1 = sel; _i < sel_1.length; _i++) { s = sel_1[_i]; components.push.apply(components, s.components); } if (components.length === 0) return [2 /*return*/]; return [4 /*yield*/, this.plugin.managers.structure.component.modifyByCurrentSelection(components, 'subtract')]; case 1: _b.sent(); this.update_selected_info(); return [2 /*return*/]; } }); }); }, _showSelect: function () { var args_1 = []; for (var _b = 0; _b < arguments.length; _b++) { args_1[_b] = arguments[_b]; } return tslib_1.__awaiter(_this, tslib_1.__spreadArray([], tslib_1.__read(args_1), false), void 0, function (type) { var sel, components, _i, sel_1, s, _j, _a, c; if (type === void 0) { type = 'Polymer'; } return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: sel = this.plugin.managers.structure.hierarchy.getStructuresWithSelection(); if (sel.length === 0) { console.log('sel is empty, ok'); return [2 /*return*/, 0]; } components = []; for (_i = 0, sel_1 = sel; _i < sel_1.length; _i++) { s = sel_1[_i]; for (_j = 0, _a = s.components; _j < _a.length; _j++) { c = _a[_j]; if (c.key !== type) continue; components.push(c); } // if (s.components.key !== type) continue; // components.push.apply(components, s.components); } if (components.length === 0) { console.log('components is empty, need recreate'); return [2 /*return*/, -1]; } console.log('showSelect components', components); return [4 /*yield*/, this.plugin.managers.structure.component.modifyByCurrentSelection(components, 'union')]; case 1: _c.sent(); return [4 /*yield*/, this.visual.deselect_current()]; case 2: _c.sent(); this.add_selection_info(); return [2 /*return*/, 0]; } }); }); }, changeProps: function (val) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_b) { //todo 切换选中粒度 this.plugin.managers.interactivity.setProps({ granularity: val }); this.granularity = val; return [2 /*return*/]; }); }); }, toggleSpin: function (isSpinning, resetCamera) { if (!_this.plugin.canvas3d) return; var trackball = _this.plugin.canvas3d.props.trackball; var toggleSpinParam = trackball.animate.name === 'spin' ? { name: 'off', params: {} } : { name: 'spin', params: { speed: 1 } }; if (typeof isSpinning !== 'undefined') { toggleSpinParam = { name: 'off', params: {} }; if (isSpinning) toggleSpinParam = { name: 'spin', params: { speed: 1 } }; } commands_1.PluginCommands.Canvas3D.SetSettings(_this.plugin, { settings: { trackball: tslib_1.__assign(tslib_1.__assign({}, trackball), { animate: toggleSpinParam }) } }); if (resetCamera) commands_1.PluginCommands.Camera.Reset(_this.plugin, {}); }, focus: function (params, structureNumber, expand_num) { var loci = _this.getLociForParams(params, structureNumber); if (expand_num) { _this.plugin.managers.camera.focusLoci(loci, { extraRadius: expand_num }); } else { _this.plugin.managers.camera.focusLoci(loci); } }, get_current_loci: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_query, data, ret; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: current_query = structure_selection_query_1.StructureSelectionQueries.current; data = this.plugin.state.data.select(this.assemblyRef)[0].obj.data; ret = loci_1.EmptyLoci; return [4 /*yield*/, this.plugin.runTask(mol_task_1.Task.create('Structure Selection', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_selection; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, current_query.getSelection(this.plugin, runtime, data)]; case 1: current_selection = _b.sent(); ret = structure_1.StructureSelection.toLociWithSourceUnits(current_selection); return [2 /*return*/]; } }); }); }))]; case 1: _b.sent(); return [2 /*return*/, ret]; } }); }); }, focus_loci: function (loci) { _this.plugin.managers.camera.focusLoci(loci); }, focus_now: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_query, data; var _this = this; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: current_query = structure_selection_query_1.StructureSelectionQueries.current; data = this.plugin.state.data.select(this.assemblyRef)[0].obj.data; return [4 /*yield*/, this.plugin.runTask(mol_task_1.Task.create('Structure Selection', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var current_selection, current_loci; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, current_query.getSelection(this.plugin, runtime, data)]; case 1: current_selection = _b.sent(); current_loci = structure_1.StructureSelection.toLociWithSourceUnits(current_selection); this.plugin.managers.camera.focusLoci(current_loci); return [2 /*return*/]; } }); }); }))]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, select: function (params, deselect) { if (deselect === void 0) { deselect = false; } var loci = _this.getLociForParams(params); if (loci_1.Loci.isEmpty(loci)) return; if (deselect) { _this.plugin.managers.interactivity.lociSelects.deselect({ loci: loci }); } else { _this.plugin.managers.interactivity.lociSelects.select({ loci: loci }); } _this.add_selection_info(); }, camera_reset: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, commands_1.PluginCommands.Camera.Reset(this.plugin, { durationMs: 250 })]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }, /** * 应用所有隐藏状态(内部方法) */ _applyHiddenState: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var structures, components, structures_1, structures_1_1, s, chainArray, _loop_1, this_1, i, ligandArray, _loop_2, this_2, i, residuesByChain, _b, _c, residueKey, _d, chainId, resIdStr, resId, _loop_3, this_3, residuesByChain_1, residuesByChain_1_1, _e, chainId, residueIds, e_1_1; var e_2, _f, e_3, _g, e_1, _h; var _this = this; return tslib_1.__generator(this, function (_k) { switch (_k.label) { case 0: structures = this.plugin.managers.structure.hierarchy.current.structures; components = []; try { for (structures_1 = tslib_1.__values(structures), structures_1_1 = structures_1.next(); !structures_1_1.done; structures_1_1 = structures_1.next()) { s = structures_1_1.value; components.push.apply(components, tslib_1.__spreadArray([], tslib_1.__read(s.components), false)); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (structures_1_1 && !structures_1_1.done && (_f = structures_1.return)) _f.call(structures_1); } finally { if (e_2) throw e_2.error; } } if (components.length === 0) { return [2 /*return*/]; } // 先清除所有透明度 return [4 /*yield*/, (0, structure_transparency_1.clearStructureTransparency)(this.plugin, components)]; case 1: // 先清除所有透明度 _k.sent(); // 如果没有需要隐藏的,直接返回 if (this.hiddenState.chains.size === 0 && this.hiddenState.ligands.size === 0 && this.hiddenState.residues.size === 0) { return [2 /*return*/]; } chainArray = Array.from(this.hiddenState.chains); _loop_1 = function (i) { var chainId; return tslib_1.__generator(this, function (_l) { switch (_l.label) { case 0: chainId = chainArray[i]; return [4 /*yield*/, (0, structure_transparency_1.setStructureTransparency)(this_1.plugin, components, 1, function (structure) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var chainQuery; var _this = this; return tslib_1.__generator(this, function (_b) { chainQuery = (0, structure_selection_query_1.StructureSelectionQuery)("Chain_".concat(chainId), builder_1.MolScriptBuilder.struct.generator.atomGroups({ 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('auth_asym_id'), chainId]) }), { description: "Chain ".concat(chainId), category: structure_selection_query_1.StructureSelectionCategory.Manipulate }); return [2 /*return*/, this.plugin.runTask(mol_task_1.Task.create('Select Chain', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var selection; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, chainQuery.getSelection(this.plugin, runtime, structure)]; case 1: selection = _b.sent(); return [2 /*return*/, structure_1.StructureSelection.toLociWithSourceUnits(selection)]; } }); }); }))]; }); }); })]; case 1: _l.sent(); return [2 /*return*/]; } }); }; this_1 = this; i = 0; _k.label = 2; case 2: if (!(i < chainArray.length)) return [3 /*break*/, 5]; return [5 /*yield**/, _loop_1(i)]; case 3: _k.sent(); _k.label = 4; case 4: i++; return [3 /*break*/, 2]; case 5: ligandArray = Array.from(this.hiddenState.ligands); _loop_2 = function (i) { var ligandKey, parts, chainId, identifier, resId, resName, queryConditions; return tslib_1.__generator(this, function (_m) { switch (_m.label) { case 0: ligandKey = ligandArray[i]; parts = ligandKey.split(':'); chainId = parts[0]; identifier = parts[1]; resId = isNaN(Number(identifier)) ? undefined : Number(identifier); resName = isNaN(Number(identifier)) ? identifier : undefined; queryConditions = { 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('auth_asym_id'), chainId]) }; if (resName) { queryConditions['residue-test'] = builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('auth_comp_id'), resName.toUpperCase()]); } else if (resId !== undefined) { queryConditions['residue-test'] = builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('auth_seq_id'), resId]); } return [4 /*yield*/, (0, structure_transparency_1.setStructureTransparency)(this_2.plugin, components, 1, function (structure) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var ligandQuery; var _this = this; return tslib_1.__generator(this, function (_b) { ligandQuery = (0, structure_selection_query_1.StructureSelectionQuery)("Ligand_".concat(ligandKey), builder_1.MolScriptBuilder.struct.generator.atomGroups(queryConditions), { description: "Ligand at ".concat(ligandKey), category: structure_selection_query_1.StructureSelectionCategory.Manipulate }); return [2 /*return*/, this.plugin.runTask(mol_task_1.Task.create('Select Ligand', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var selection; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, ligandQuery.getSelection(this.plugin, runtime, structure)]; case 1: selection = _b.sent(); return [2 /*return*/, structure_1.StructureSelection.toLociWithSourceUnits(selection)]; } }); }); }))]; }); }); })]; case 1: _m.sent(); return [2 /*return*/]; } }); }; this_2 = this; i = 0; _k.label = 6; case 6: if (!(i < ligandArray.length)) return [3 /*break*/, 9]; return [5 /*yield**/, _loop_2(i)]; case 7: _k.sent(); _k.label = 8; case 8: i++; return [3 /*break*/, 6]; case 9: residuesByChain = new Map(); try { for (_b = tslib_1.__values(this.hiddenState.residues), _c = _b.next(); !_c.done; _c = _b.next()) { residueKey = _c.value; _d = tslib_1.__read(residueKey.split(':'), 2), chainId = _d[0], resIdStr = _d[1]; resId = Number(resIdStr); if (!residuesByChain.has(chainId)) { residuesByChain.set(chainId, []); } residuesByChain.get(chainId).push(resId); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_c && !_c.done && (_g = _b.return)) _g.call(_b); } finally { if (e_3) throw e_3.error; } } _loop_3 = function (chainId, residueIds) { return tslib_1.__generator(this, function (_o) { switch (_o.label) { case 0: return [4 /*yield*/, (0, structure_transparency_1.setStructureTransparency)(this_3.plugin, components, 1, function (structure) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var residueQuery; var _this = this; return tslib_1.__generator(this, function (_b) { residueQuery = (0, structure_selection_query_1.StructureSelectionQuery)("Residues_".concat(chainId), builder_1.MolScriptBuilder.struct.generator.atomGroups({ 'chain-test': builder_1.MolScriptBuilder.core.rel.eq([builder_1.MolScriptBuilder.ammp('auth_asym_id'), chainId]), 'residue-test': builder_1.MolScriptBuilder.core.set.has([ builder_1.MolScriptBuilder.set.apply(builder_1.MolScriptBuilder, tslib_1.__spreadArray([], tslib_1.__read(residueIds), false)), builder_1.MolScriptBuilder.ammp('auth_seq_id') ]) }), { description: "Residues in chain ".concat(chainId), category: structure_selection_query_1.StructureSelectionCategory.Manipulate }); return [2 /*return*/, this.plugin.runTask(mol_task_1.Task.create('Select Residues', function (runtime) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var selection; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, residueQuery.getSelection(this.plugin, runtime, structure)]; case 1: selection = _b.sent(); return [2 /*return*/, structure_1.StructureSelection.toLociWithSourceUnits(selection)]; } }); }); }))]; }); }); })]; case 1: _o.sent(); return [2 /*return*/]; } }); }; this_3 = this; _k.label = 10; case 10: _k.trys.push([10, 15, 16, 17]); residuesByChain_1 = tslib_1.__values(residuesByChain), residuesByChain_1_1 = residuesByChain_1.next(); _k.label = 11; case 11: if (!!residuesByChain_1_1.done) return [3 /*break*/, 14]; _e = tslib_1.__read(residuesByChain_1_1.value, 2), chainId = _e[0], residueIds = _e[1]; return [5 /*yield**/, _loop_3(chainId, residueIds)]; case 12: _k.sent(); _k.label = 13; case 13: residuesByChain_1_1 = residuesByChain_1.next(); return [3 /*break*/, 11]; case 14: return [3 /*break*/, 17]; case 15: e_1_1 = _k.sent(); e_1 = { error: e_1_1 }; return [3 /*break*/, 17]; case 16: try { if (residuesByChain_1_1 && !residuesByChain_1_1.done && (_h = residuesByChain_1.return)) _h.call(residuesByChain_1); } finally { if (e_1) throw e_1.error; } return [7 /*endfinally*/]; case 17: return [2 /*return*/]; } }); }); }, /** * 使用透明度隐藏指定的链 * @param chainId 链ID,例如 'A', 'B' */ hideChain: function (chainId) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: // 添加到隐藏状态 this.hiddenState.chains.add(chainId); // 重新应用所有隐藏状态 return [4 /*yield*/, this.visual._applyHiddenState()]; case 1: // 重新应用所有隐藏状态 _b.sent(); console.log("\u2705 Chain ".concat(chainId, " hidden")); return [2 /*return*/]; } }); }); }, /** * 清除指定链的透明度来显示 * @param chainId 链ID,例如 'A', 'B' */ showChain: function (chainId) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: // 从隐藏状态中移除 this.hiddenState.chains.delete(chainId); // 重新应用所有隐藏状态 return [4 /*yield*/, this.visual._applyHiddenState()]; case 1: // 重新应用所有隐藏状态 _b.sent(); console.log("\u2705 Chain ".concat(chainId, " shown")); return [2 /*return*/]; } }); }); }, /** * 使用透明度隐藏指定链中的残基 * @param chainId 链ID,例如 'A', 'B' * @param residueIds 残基序号数组,例如 [10, 15, 20] 或范围 { start: 10, end: 20 } */ hideResidues: function (chainId, residueIds) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var ids, ids_1, ids_1_1, resId; var e_4, _b; return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: