icn3d 3.41.0 → 3.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/icn3d.module.js CHANGED
@@ -2532,7 +2532,6 @@ THREE.TrackballControls = function ( object, domElement, icn3d ) {
2532
2532
  _this._panStart.add( mouseChange.subVectors( _this._panEnd, _this._panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
2533
2533
 
2534
2534
  }
2535
-
2536
2535
  }
2537
2536
  }
2538
2537
 
@@ -3569,6 +3568,103 @@ THREE.OrthographicTrackballControls = function ( object, domElement, icn3d ) { v
3569
3568
  THREE.OrthographicTrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
3570
3569
  THREE.OrthographicTrackballControls.prototype.constructor = THREE.OrthographicTrackballControls;
3571
3570
 
3571
+ /**
3572
+ * @author alteredq / http://alteredqualia.com/
3573
+ * @authod mrdoob / http://mrdoob.com/
3574
+ * @authod arodic / http://aleksandarrodic.com/
3575
+ * modified by Jiyao Wang
3576
+ */
3577
+
3578
+ THREE.StereoEffect = function ( renderer ) {
3579
+ var _this = this;
3580
+ // API
3581
+
3582
+ _this.separation = 3; // 1;
3583
+
3584
+ // internals
3585
+
3586
+ // _this._width, _this._height;
3587
+
3588
+ _this._position = new THREE.Vector3();
3589
+ _this._quaternion = new THREE.Quaternion();
3590
+ _this._scale = new THREE.Vector3();
3591
+
3592
+ _this._cameraL = new THREE.PerspectiveCamera();
3593
+ _this._cameraR = new THREE.PerspectiveCamera();
3594
+
3595
+ // initialization
3596
+
3597
+ renderer.autoClear = false;
3598
+
3599
+ _this.setSize = function ( width, height ) {
3600
+
3601
+ _this._width = width / 2;
3602
+ _this._height = height;
3603
+
3604
+ renderer.setSize( width, height );
3605
+
3606
+ };
3607
+
3608
+ _this.render = function ( scene, camera ) {
3609
+
3610
+ scene.updateMatrixWorld();
3611
+
3612
+ if ( camera.parent === undefined ) camera.updateMatrixWorld();
3613
+
3614
+ camera.matrixWorld.decompose( _this._position, _this._quaternion, _this._scale );
3615
+
3616
+ // left
3617
+ _this._cameraL.copy(camera);
3618
+ _this._cameraL.aspect = 0.5 * camera.aspect;
3619
+ _this._cameraL.updateProjectionMatrix();
3620
+
3621
+ /*
3622
+ _this._cameraL.fov = camera.fov;
3623
+ _this._cameraL.aspect = 0.5 * camera.aspect;
3624
+ _this._cameraL.near = camera.near;
3625
+ _this._cameraL.far = camera.far;
3626
+ _this._cameraL.updateProjectionMatrix();
3627
+
3628
+ _this._cameraL.position.copy( _this._position );
3629
+ // _this._cameraL.quaternion.copy( _this._quaternion );
3630
+ */
3631
+ _this._cameraL.translateX( - _this.separation );
3632
+
3633
+ // right
3634
+ _this._cameraR.copy(camera);
3635
+ _this._cameraR.aspect = 0.5 * camera.aspect;
3636
+ _this._cameraR.updateProjectionMatrix();
3637
+
3638
+ /*
3639
+ _this._cameraR.fov = camera.fov;
3640
+ _this._cameraR.aspect = 0.5 * camera.aspect;
3641
+ _this._cameraR.near = camera.near;
3642
+ _this._cameraR.far = camera.far;
3643
+ // _this._cameraR.projectionMatrix = _this._cameraL.projectionMatrix;
3644
+ _this._cameraR.updateProjectionMatrix();
3645
+
3646
+ _this._cameraR.position.copy( _this._position );
3647
+ // _this._cameraR.quaternion.copy( _this._quaternion );
3648
+ */
3649
+
3650
+ _this._cameraR.translateX( _this.separation );
3651
+
3652
+ //
3653
+
3654
+ renderer.setViewport( 0, 0, _this._width * 2, _this._height );
3655
+ renderer.clear();
3656
+
3657
+ renderer.setViewport( 0, 0, _this._width, _this._height );
3658
+ renderer.render( scene, _this._cameraL );
3659
+
3660
+ renderer.setViewport( _this._width, 0, _this._width, _this._height );
3661
+ renderer.render( scene, _this._cameraR );
3662
+
3663
+ };
3664
+
3665
+ };
3666
+
3667
+
3572
3668
 
3573
3669
  // ; var __CIFTools = function () {
3574
3670
  // 'use strict';
@@ -9706,6 +9802,7 @@ class ClickMenu {
9706
9802
 
9707
9803
  applyShownMenus(bNoSave) { let me = this.icn3dui; me.icn3d;
9708
9804
  let idArray = [];
9805
+
9709
9806
  for(let id in me.htmlCls.allMenus) {
9710
9807
  if(me.htmlCls.shownMenus.hasOwnProperty(id)) {
9711
9808
  $("#" + me.pre + id).parent().show();
@@ -9936,6 +10033,14 @@ class ClickMenu {
9936
10033
  me.htmlCls.dialogCls.openDlg('dl_urlfile', 'Load data by URL');
9937
10034
  });
9938
10035
 
10036
+ me.myEventCls.onIds("#" + me.pre + "mn1_clustalwfile", "click", function(e) { me.icn3d; //e.preventDefault();
10037
+ me.htmlCls.dialogCls.openDlg('dl_clustalwfile', 'Please input CLUSTALW MSA File');
10038
+ });
10039
+
10040
+ me.myEventCls.onIds("#" + me.pre + "mn1_fastafile", "click", function(e) { me.icn3d; //e.preventDefault();
10041
+ me.htmlCls.dialogCls.openDlg('dl_fastafile', 'Please input FASTA MSA File');
10042
+ });
10043
+
9939
10044
  me.myEventCls.onIds("#" + me.pre + "mn1_fixedversion", "click", function(e) { me.icn3d; //e.preventDefault();
9940
10045
  me.htmlCls.dialogCls.openDlg('dl_fixedversion', 'Open Share Link URL in the archived version of iCn3D');
9941
10046
  });
@@ -10037,6 +10142,11 @@ class ClickMenu {
10037
10142
  ic.saveFileCls.saveFile(file_pref + '_statefile.txt', 'command');
10038
10143
  });
10039
10144
 
10145
+ me.myEventCls.onIds("#" + me.pre + "mn1_exportVideo", "click", function(e) { me.icn3d; //e.preventDefault();
10146
+ thisClass.setLogCmd("export video", false);
10147
+ me.htmlCls.dialogCls.openDlg('dl_video', 'Save canvas changes in a video');
10148
+ });
10149
+
10040
10150
 
10041
10151
  me.myEventCls.onIds("#" + me.pre + "mn1_exportPdbRes", "click", function(e) { me.icn3d; //e.preventDefault();
10042
10152
  me.htmlCls.setHtmlCls.exportPdb();
@@ -11729,6 +11839,18 @@ class ClickMenu {
11729
11839
  //}
11730
11840
  });
11731
11841
 
11842
+ me.myEventCls.onIds("#" + me.pre + "mn6_stereoYes", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
11843
+ ic.opts['effect'] = 'stereo';
11844
+ ic.drawCls.draw();
11845
+ thisClass.setLogCmd('stereo on', true);
11846
+ });
11847
+
11848
+ me.myEventCls.onIds("#" + me.pre + "mn6_stereoNo", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
11849
+ ic.opts['effect'] = 'none';
11850
+ ic.drawCls.draw();
11851
+ thisClass.setLogCmd('stereo off', true);
11852
+ });
11853
+
11732
11854
  $(document).on("click", "#" + me.pre + "mn2_translate", function(e) { me.icn3d; //e.preventDefault();
11733
11855
  me.htmlCls.dialogCls.openDlg('dl_translate', 'Translate the X,Y,Z coordinates of the structure');
11734
11856
  });
@@ -12742,9 +12864,19 @@ class SetMenu {
12742
12864
  html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
12743
12865
  html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
12744
12866
  html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
12867
+
12868
+ html += this.getMenuSep();
12869
+
12870
+ html += this.getMenuText('mn1_msawrap', 'Multiple Seq. Alignment', undefined, undefined, 2);
12871
+ html += "<ul>";
12872
+ html += this.getLink('mn1_clustalwfile', 'CLUSTALW Format', undefined, 3);
12873
+ html += this.getLink('mn1_fastafile', 'FASTA Format', undefined, 3);
12874
+ html += "</ul>";
12875
+
12745
12876
  html += this.getLink('mn1_afmapfile', 'AlphaFold PAE File', undefined, 2);
12746
12877
 
12747
12878
  html += this.getLink('mn1_urlfile', 'URL(CORS) ' + me.htmlCls.wifiStr, undefined, 2);
12879
+
12748
12880
  html += this.getMenuSep();
12749
12881
  html += this.getLink('mn1_pngimage', 'iCn3D PNG (appendable)', 1, 2);
12750
12882
  html += this.getLink('mn1_state', 'State/Script File', undefined, 2);
@@ -12851,6 +12983,7 @@ class SetMenu {
12851
12983
  html += "</ul>";
12852
12984
  html += "</li>";
12853
12985
 
12986
+ html += this.getLink('mn1_exportVideo', 'Video', undefined, 2);
12854
12987
  html += this.getLink('mn1_exportState', 'State File', undefined, 2);
12855
12988
  html += this.getLink('mn1_exportSelections', 'Selection File', undefined, 2);
12856
12989
  html += this.getLink('mn1_exportSelDetails', 'Selection Details', undefined, 2);
@@ -13068,6 +13201,13 @@ class SetMenu {
13068
13201
  html += "</ul>";
13069
13202
  html += "</li>";
13070
13203
 
13204
+ html += this.getMenuText('mn6_stereoWrapper', 'Stereo View', undefined, undefined, 1);
13205
+ html += "<ul>";
13206
+ html += this.getRadio('mn6_stereo', 'mn6_stereoYes', 'On', undefined, undefined, 2);
13207
+ html += this.getRadio('mn6_stereo', 'mn6_stereoNo', 'Off', true, undefined, 2);
13208
+ html += "</ul>";
13209
+ html += "</li>";
13210
+
13071
13211
  html += this.getLink('mn6_sidebyside', 'Side by Side', undefined, 1);
13072
13212
 
13073
13213
  html += this.getMenuText('mn2_rotate', 'Rotate', undefined, 1, 1);
@@ -15097,6 +15237,19 @@ class SetDialog {
15097
15237
  html += me.htmlCls.buttonStr + "reload_xyzfile'>Load</button>";
15098
15238
  html += "</div>";
15099
15239
 
15240
+ html += me.htmlCls.divStr + "dl_clustalwfile' class='" + dialogClass + "' style='max-width:500px'>";
15241
+ html += this.addNotebookTitle('dl_clustalwfile', 'Please input a CLUSTALW MSA file');
15242
+ html += "Note the sequence names are either UniProt ID (e.g., A4D1S0 or A4D1S0_A), RefSeq ID (e.g., NP_001743), or PDB chain ID (e.g., 1HHO_A).<br><br>";
15243
+ html += "CLUSTALW File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "clustalwfile' size=8> ";
15244
+ html += me.htmlCls.buttonStr + "reload_clustalwfile'>Load</button><br>";
15245
+ html += "</div>";
15246
+ html += me.htmlCls.divStr + "dl_fastafile' class='" + dialogClass + "' style='max-width:500px'>";
15247
+ html += this.addNotebookTitle('dl_fastafile', 'Please input a FASTA file');
15248
+ html += "Note the sequence IDs following the symbol \">\" contain either UniProt ID (e.g., sp| or tr|), RefSeq ID (e.g., ref|), PDB chain ID (e.g., pdb|1HHO|A), or iCn3D chain ID (e.g., A4D1S0_A, 1HHO_A).<br><br>";
15249
+ html += "FASTA File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "fastafile' size=8> ";
15250
+ html += me.htmlCls.buttonStr + "reload_fastafile'>Load</button><br>";
15251
+ html += "</div>";
15252
+
15100
15253
  html += me.htmlCls.divStr + "dl_afmapfile' class='" + dialogClass + "'>";
15101
15254
  html += this.addNotebookTitle('dl_afmapfile', 'Please input an AlphaFold PAE file');
15102
15255
  html += "AlphaFold PAE File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "afmapfile' size=8> <br><br>";
@@ -15216,6 +15369,13 @@ class SetDialog {
15216
15369
  html += me.htmlCls.buttonStr + "reload_state' style='margin-top: 6px;'>Load</button>";
15217
15370
  html += "</div>";
15218
15371
 
15372
+ html += me.htmlCls.divStr + "dl_video' class='" + dialogClass + "'>";
15373
+ html += this.addNotebookTitle('dl_video', 'Save canvas changes in a video');
15374
+ html += "State file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "state'><br/>";
15375
+ html += me.htmlCls.buttonStr + "video_start' style='margin-top: 6px;'>Video Start</button>";
15376
+ html += me.htmlCls.buttonStr + "video_end' style='margin: 6px 0px 0px 30px;'>Video End</button>";
15377
+ html += "</div>";
15378
+
15219
15379
  html += me.htmlCls.divStr + "dl_fixedversion' style='max-width:500px' class='" + dialogClass + "'>";
15220
15380
  html += this.addNotebookTitle('dl_fixedversion', 'Use fixed version of iCn3D');
15221
15381
  html += "Since January 6, 2021, you can show the original view with the archived version of iCn3D by pasting your URL below and click \"Show Originial View\". Note the version in the parameter \"v\" was used to replace \"full.html\" with \"full_[v].html\" in the URL.<br><br>";
@@ -16575,17 +16735,10 @@ class Events {
16575
16735
  }
16576
16736
  }
16577
16737
 
16578
- async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d;
16738
+ async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
16579
16739
  //me = ic.setIcn3dui(this.id);
16580
16740
  ic.bInitial = true;
16581
- if(!me.cfg.notebook) dialog.dialog( "close" );
16582
- //close all dialog
16583
- if(!me.cfg.notebook) {
16584
- $(".ui-dialog-content").dialog("close");
16585
- }
16586
- else {
16587
- ic.resizeCanvasCls.closeDialogs();
16588
- }
16741
+ thisClass.iniFileLoad();
16589
16742
  let files = $("#" + me.pre + fileId)[0].files;
16590
16743
  if(!files[0]) {
16591
16744
  alert("Please select a file before clicking 'Load'");
@@ -16631,11 +16784,22 @@ class Events {
16631
16784
 
16632
16785
  exportMsa(type) { let me = this.icn3dui, ic = me.icn3d;
16633
16786
  let text = ic.msa[type].join('\n\n');
16634
- let fileType = (type == 'fasta') ? '.fasta' : (type == 'clustal') ? '.aln' : '.txt';
16787
+ let fileType = (type == 'fasta') ? '.fasta' : (type == 'clustalw') ? '.aln' : '.txt';
16635
16788
 
16636
16789
  ic.saveFileCls.saveFile(ic.inputid + '_align' + fileType, 'text', [text]);
16637
16790
  }
16638
16791
 
16792
+ iniFileLoad() { let me = this.icn3dui, ic = me.icn3d;
16793
+ if(!me.cfg.notebook) dialog.dialog( "close" );
16794
+ //close all dialog
16795
+ if(!me.cfg.notebook) {
16796
+ $(".ui-dialog-content").dialog("close");
16797
+ }
16798
+ else {
16799
+ ic.resizeCanvasCls.closeDialogs();
16800
+ }
16801
+ }
16802
+
16639
16803
  async launchMmdb(ids, bBiounit, hostUrl, bAppend) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
16640
16804
  if(!me.cfg.notebook) dialog.dialog( "close" );
16641
16805
 
@@ -17731,16 +17895,40 @@ class Events {
17731
17895
 
17732
17896
  me.htmlCls.setHtmlCls.clickReload_pngimage();
17733
17897
 
17898
+ me.myEventCls.onIds("#" + me.pre + "video_start", "click", function(e) { let ic = me.icn3d;
17899
+ e.preventDefault();
17900
+
17901
+ const canvas = document.getElementById(ic.pre + "canvas");
17902
+ ic.videoRecorder = new MediaRecorder(canvas.captureStream());
17903
+ const recordedChunks = [];
17904
+
17905
+ // Collect data chunks
17906
+ ic.videoRecorder.ondataavailable = event => {
17907
+ recordedChunks.push(event.data);
17908
+ };
17909
+
17910
+ ic.videoRecorder.onstop = event => {
17911
+ // Code to save the recordedChunks as a video file
17912
+ const blob = new Blob(recordedChunks, {type: ic.videoRecorder.mimeType});
17913
+ let fileName = ic.inputid + '_video';
17914
+ saveAs(blob, fileName);
17915
+ };
17916
+
17917
+ // Start recording
17918
+ ic.videoRecorder.start();
17919
+ thisClass.setLogCmd('Video revording started', false);
17920
+ });
17921
+
17922
+ me.myEventCls.onIds("#" + me.pre + "video_end", "click", function(e) { let ic = me.icn3d;
17923
+ e.preventDefault();
17924
+
17925
+ ic.videoRecorder.stop();
17926
+ thisClass.setLogCmd('Video revording ended', false);
17927
+ });
17928
+
17734
17929
  me.myEventCls.onIds("#" + me.pre + "reload_state", "click", function(e) { let ic = me.icn3d;
17735
17930
  e.preventDefault();
17736
- if(!me.cfg.notebook) dialog.dialog( "close" );
17737
- //close all dialog
17738
- if(!me.cfg.notebook) {
17739
- $(".ui-dialog-content").dialog("close");
17740
- }
17741
- else {
17742
- ic.resizeCanvasCls.closeDialogs();
17743
- }
17931
+ thisClass.iniFileLoad();
17744
17932
  // initialize icn3dui
17745
17933
  //Do NOT clear data if iCn3D loads a pdb or other data file and then load a state file
17746
17934
  if(!ic.bInputfile) {
@@ -17792,12 +17980,7 @@ class Events {
17792
17980
  if (!file) {
17793
17981
  alert("Please select a file before clicking 'Load'");
17794
17982
  } else {
17795
- if (!me.cfg.notebook) dialog.dialog("close");
17796
- if (!me.cfg.notebook) {
17797
- $(".ui-dialog-content").dialog("close");
17798
- } else {
17799
- ic.resizeCanvasCls.closeDialogs();
17800
- }
17983
+ thisClass.iniFileLoad();
17801
17984
 
17802
17985
  ic.dAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
17803
17986
  ic.hAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
@@ -18352,14 +18535,7 @@ class Events {
18352
18535
  me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
18353
18536
  e.preventDefault();
18354
18537
  ic.bInitial = true;
18355
- if(!me.cfg.notebook) dialog.dialog( "close" );
18356
- //close all dialog
18357
- if(!me.cfg.notebook) {
18358
- $(".ui-dialog-content").dialog("close");
18359
- }
18360
- else {
18361
- ic.resizeCanvasCls.closeDialogs();
18362
- }
18538
+ thisClass.iniFileLoad();
18363
18539
  let file = $("#" + me.pre + "mol2file")[0].files[0];
18364
18540
  if(!file) {
18365
18541
  alert("Please select a file before clicking 'Load'");
@@ -18386,14 +18562,7 @@ class Events {
18386
18562
  me.myEventCls.onIds("#" + me.pre + "reload_sdffile", "click", function(e) { let ic = me.icn3d;
18387
18563
  e.preventDefault();
18388
18564
  ic.bInitial = true;
18389
- if(!me.cfg.notebook) dialog.dialog( "close" );
18390
- //close all dialog
18391
- if(!me.cfg.notebook) {
18392
- $(".ui-dialog-content").dialog("close");
18393
- }
18394
- else {
18395
- ic.resizeCanvasCls.closeDialogs();
18396
- }
18565
+ thisClass.iniFileLoad();
18397
18566
  let file = $("#" + me.pre + "sdffile")[0].files[0];
18398
18567
  if(!file) {
18399
18568
  alert("Please select a file before clicking 'Load'");
@@ -18420,14 +18589,7 @@ class Events {
18420
18589
  me.myEventCls.onIds("#" + me.pre + "reload_xyzfile", "click", function(e) { let ic = me.icn3d;
18421
18590
  e.preventDefault();
18422
18591
  ic.bInitial = true;
18423
- if(!me.cfg.notebook) dialog.dialog( "close" );
18424
- //close all dialog
18425
- if(!me.cfg.notebook) {
18426
- $(".ui-dialog-content").dialog("close");
18427
- }
18428
- else {
18429
- ic.resizeCanvasCls.closeDialogs();
18430
- }
18592
+ thisClass.iniFileLoad();
18431
18593
  let file = $("#" + me.pre + "xyzfile")[0].files[0];
18432
18594
  if(!file) {
18433
18595
  alert("Please select a file before clicking 'Load'");
@@ -18451,17 +18613,64 @@ class Events {
18451
18613
  }
18452
18614
  });
18453
18615
 
18454
- me.myEventCls.onIds("#" + me.pre + "reload_afmapfile", "click", function(e) { let ic = me.icn3d;
18616
+ me.myEventCls.onIds("#" + me.pre + "reload_clustalwfile", "click", function(e) { let ic = me.icn3d;
18455
18617
  e.preventDefault();
18456
18618
  ic.bInitial = true;
18457
- if(!me.cfg.notebook) dialog.dialog( "close" );
18458
- //close all dialog
18459
- if(!me.cfg.notebook) {
18460
- $(".ui-dialog-content").dialog("close");
18619
+ thisClass.iniFileLoad();
18620
+
18621
+ let file = $("#" + me.pre + "clustalwfile")[0].files[0];
18622
+ if(!file) {
18623
+ alert("Please select a file before clicking 'Load'");
18461
18624
  }
18462
18625
  else {
18463
- ic.resizeCanvasCls.closeDialogs();
18626
+ me.htmlCls.setHtmlCls.fileSupport();
18627
+ let reader = new FileReader();
18628
+ reader.onload = async function(e) {
18629
+ let dataStr = e.target.result; // or = reader.result;
18630
+ thisClass.setLogCmd('load CLUSTALW file ' + $("#" + me.pre + "clustalwfile").val(), false);
18631
+ ic.molTitle = "";
18632
+ ic.inputid = undefined;
18633
+ //ic.initUI();
18634
+ ic.init();
18635
+ ic.bInputfile = false; //true;
18636
+ ic.InputfileType = 'clustalw';
18637
+ await ic.msaParserCls.loadMsaData(dataStr, 'clustalw');
18638
+ };
18639
+ reader.readAsText(file);
18640
+ }
18641
+ });
18642
+
18643
+ me.myEventCls.onIds("#" + me.pre + "reload_fastafile", "click", function(e) { let ic = me.icn3d;
18644
+ e.preventDefault();
18645
+ ic.bInitial = true;
18646
+ thisClass.iniFileLoad();
18647
+
18648
+ let file = $("#" + me.pre + "fastafile")[0].files[0];
18649
+ if(!file) {
18650
+ alert("Please select a file before clicking 'Load'");
18651
+ }
18652
+ else {
18653
+ me.htmlCls.setHtmlCls.fileSupport();
18654
+ let reader = new FileReader();
18655
+ reader.onload = async function(e) {
18656
+ let dataStr = e.target.result; // or = reader.result;
18657
+ thisClass.setLogCmd('load FASTA file ' + $("#" + me.pre + "fastafile").val(), false);
18658
+ ic.molTitle = "";
18659
+ ic.inputid = undefined;
18660
+ //ic.initUI();
18661
+ ic.init();
18662
+ ic.bInputfile = false; //true;
18663
+ ic.InputfileType = 'fasta';
18664
+ await ic.msaParserCls.loadMsaData(dataStr, 'fasta');
18665
+ };
18666
+ reader.readAsText(file);
18464
18667
  }
18668
+ });
18669
+
18670
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfile", "click", function(e) { let ic = me.icn3d;
18671
+ e.preventDefault();
18672
+ ic.bInitial = true;
18673
+ thisClass.iniFileLoad();
18465
18674
  let file = $("#" + me.pre + "afmapfile")[0].files[0];
18466
18675
  if(!file) {
18467
18676
  alert("Please select a file before clicking 'Load'");
@@ -18483,14 +18692,7 @@ class Events {
18483
18692
  me.myEventCls.onIds("#" + me.pre + "reload_afmapfilefull", "click", function(e) { let ic = me.icn3d;
18484
18693
  e.preventDefault();
18485
18694
  ic.bInitial = true;
18486
- if(!me.cfg.notebook) dialog.dialog( "close" );
18487
- //close all dialog
18488
- if(!me.cfg.notebook) {
18489
- $(".ui-dialog-content").dialog("close");
18490
- }
18491
- else {
18492
- ic.resizeCanvasCls.closeDialogs();
18493
- }
18695
+ thisClass.iniFileLoad();
18494
18696
  let file = $("#" + me.pre + "afmapfile")[0].files[0];
18495
18697
  if(!file) {
18496
18698
  alert("Please select a file before clicking 'Load'");
@@ -18512,14 +18714,7 @@ class Events {
18512
18714
  me.myEventCls.onIds("#" + me.pre + "reload_urlfile", "click", async function(e) { let ic = me.icn3d;
18513
18715
  e.preventDefault();
18514
18716
  ic.bInitial = true;
18515
- if(!me.cfg.notebook) dialog.dialog( "close" );
18516
- //close all dialog
18517
- if(!me.cfg.notebook) {
18518
- $(".ui-dialog-content").dialog("close");
18519
- }
18520
- else {
18521
- ic.resizeCanvasCls.closeDialogs();
18522
- }
18717
+ thisClass.iniFileLoad();
18523
18718
  let type = $("#" + me.pre + "filetype").val();
18524
18719
  let url = $("#" + me.pre + "urlfile").val();
18525
18720
  ic.inputurl = 'type=' + type + '&url=' + encodeURIComponent(url);
@@ -19394,8 +19589,8 @@ class Events {
19394
19589
 
19395
19590
  me.myEventCls.onIds("#" + me.pre + "saveClustal", "click", function(e) { me.icn3d;
19396
19591
  e.stopImmediatePropagation();
19397
- thisClass.exportMsa('clustal');
19398
- thisClass.setLogCmd('Save alignment in CLUSTALW format', false);
19592
+ thisClass.exportMsa('clustalw');
19593
+ thisClass.setLogCmd('Save alignment in CLUSTALWW format', false);
19399
19594
  });
19400
19595
 
19401
19596
  me.myEventCls.onIds("#" + me.pre + "saveResbyres", "click", function(e) { me.icn3d;
@@ -20265,7 +20460,7 @@ class SetHtml {
20265
20460
 
20266
20461
  sequencesHtml += "<div style='min-width:200px; display:inline-block;'><b>Selection:</b> Name: " + me.htmlCls.inputTextStr + "id='" + me.pre + "alignseq_command_name' value='alseq_" + index + "' size='10'> " + me.htmlCls.space2 + "<button style='white-space:nowrap;' id='" + me.pre + "alignseq_saveselection'>Save</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "alignseq_clearselection'>Clear</button></div><br/>";
20267
20462
 
20268
- sequencesHtml += "<div style='min-width:200px; display:inline-block; margin-top:3px'><b>Save Alignment</b>: " + "<button style='white-space:nowrap;' id='" + me.pre + "saveFasta'>FASTA</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "saveClustal'>CLUSTAL</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "saveResbyres'>Residue by Residue</button></div><br/>";
20463
+ sequencesHtml += "<div style='min-width:200px; display:inline-block; margin-top:3px'><b>Save Alignment</b>: " + "<button style='white-space:nowrap;' id='" + me.pre + "saveFasta'>FASTA</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "saveClustal'>CLUSTALW</button> <button style='white-space:nowrap; margin-left:20px;' id='" + me.pre + "saveResbyres'>Residue by Residue</button></div><br/>";
20269
20464
 
20270
20465
  sequencesHtml += me.htmlCls.divStr + "alignseqguide" + suffix + "' style='display:none; white-space:normal;' class='icn3d-box'>";
20271
20466
 
@@ -20958,9 +21153,9 @@ class Html {
20958
21153
  this.MENU_WIDTH = 750;
20959
21154
  //The width (in px) that was left empty by the 3D viewer. The default is 20px.
20960
21155
  this.LESSWIDTH = 20;
20961
- this.LESSWIDTH_RESIZE = 20;
21156
+ this.LESSWIDTH_RESIZE = 30; //20;
20962
21157
  //The height (in px) that was left empty by the 3D viewer. The default is 20px.
20963
- this.LESSHEIGHT = 20;
21158
+ this.LESSHEIGHT = (me.cfg.showlogo) ? 60 : 20; //20; // NCBI log is 40px high
20964
21159
 
20965
21160
  // size of 2D cartoons
20966
21161
  this.width2d = 200;
@@ -27521,7 +27716,12 @@ class Scene {
27521
27716
  ic.cams = {
27522
27717
  perspective: ic.perspectiveCamera,
27523
27718
  orthographic: ic.orthographicCamera,
27524
- };
27719
+ };
27720
+
27721
+ if(!me.bNode && ic.opts['effect'] == 'stereo' && !window.icn3duiHash) {
27722
+ ic.effect = ic.effects[options.effect];
27723
+ ic.effect.setSize(ic.container.width(), ic.container.height());
27724
+ }
27525
27725
  };
27526
27726
 
27527
27727
  setVrAr() { let ic = this.icn3d; ic.icn3dui;
@@ -31243,8 +31443,9 @@ class Strand {
31243
31443
  }
31244
31444
  }
31245
31445
 
31246
- // add one extra residue for coils between strands/helix
31247
- if(!isNaN(firstAtom.resi) && ic.pk === 3 && bHighlight === 1 && firstAtom.ss === 'coil') {
31446
+ // add one extra residue for coils between strands/helix if the style is NOT stick, ball and stick, lines, sphere, and dot
31447
+ // if(!isNaN(firstAtom.resi) && ic.pk === 3 && bHighlight === 1 && firstAtom.ss === 'coil') {
31448
+ if(!isNaN(firstAtom.resi) && ic.pk === 3 && bHighlight === 1 && firstAtom.ss === 'coil' && firstAtom.style != 'stick' && firstAtom.style != 'ball and stick' && firstAtom.style != 'lines' && firstAtom.style != 'sphere' && firstAtom.style != 'dot') {
31248
31449
  let residueid = firstAtom.structure + '_' + firstAtom.chain + '_' + (parseInt(firstAtom.resi) - 1).toString();
31249
31450
  if(ic.residues.hasOwnProperty(residueid)) {
31250
31451
  atomsAdjust = me.hashUtilsCls.unionHash(atomsAdjust, me.hashUtilsCls.hash2Atoms(ic.residues[residueid],
@@ -31279,8 +31480,8 @@ class Strand {
31279
31480
  }
31280
31481
  }
31281
31482
 
31282
- // add one extra residue for coils between strands/helix
31283
- if(ic.pk === 3 && bHighlight === 1 && lastAtom.ss === 'coil') {
31483
+ // add one extra residue for coils between strands/helix if the style is NOT stick, ball and stick, lines, sphere, and dot
31484
+ if(ic.pk === 3 && bHighlight === 1 && lastAtom.ss === 'coil' && firstAtom.style != 'stick' && firstAtom.style != 'ball and stick' && firstAtom.style != 'lines' && firstAtom.style != 'sphere' && firstAtom.style != 'dot') {
31284
31485
  let residueid = lastAtom.structure + '_' + lastAtom.chain + '_' + (parseInt(lastAtom.resi) + 1).toString();
31285
31486
  if(ic.residues.hasOwnProperty(residueid)) {
31286
31487
  atomsAdjust = me.hashUtilsCls.unionHash(atomsAdjust, me.hashUtilsCls.hash2Atoms(ic.residues[residueid],
@@ -34130,6 +34331,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
34130
34331
  }
34131
34332
  else {
34132
34333
  // let index2ori = {};
34334
+ let maxdist = this.maxdist;
34133
34335
  for(let serial in atomlist) {
34134
34336
  let atom = atoms[atomlist[serial]];
34135
34337
 
@@ -34146,11 +34348,11 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
34146
34348
  }
34147
34349
 
34148
34350
  // show map near the structure
34149
- for(i = Math.floor(r.x) - this.maxdist, il = Math.ceil(r.x) + this.maxdist; i <= il; ++i) {
34351
+ for(i = Math.floor(r.x) - maxdist, il = Math.ceil(r.x) + maxdist; i <= il; ++i) {
34150
34352
  if(i < 0 || i > this.header.xExtent*this.scaleFactor - 1) continue;
34151
- for(j = Math.floor(r.y) - this.maxdist, jl = Math.ceil(r.y) + this.maxdist; j<= jl; ++j) {
34353
+ for(j = Math.floor(r.y) - maxdist, jl = Math.ceil(r.y) + maxdist; j<= jl; ++j) {
34152
34354
  if(j < 0 || j > this.header.yExtent*this.scaleFactor - 1) continue;
34153
- for(k = Math.floor(r.z) - this.maxdist, kl = Math.ceil(r.z) + this.maxdist; k<= kl; ++k) {
34355
+ for(k = Math.floor(r.z) - maxdist, kl = Math.ceil(r.z) + maxdist; k<= kl; ++k) {
34154
34356
  if(k < 0 || k > this.header.zExtent*this.scaleFactor - 1) continue;
34155
34357
  let index = i * widthHeight + j * height + k;
34156
34358
  indexArray.push(index);
@@ -34159,6 +34361,16 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
34159
34361
  }
34160
34362
  }
34161
34363
 
34364
+ // show all
34365
+ // for(i = 0; i < this.pLength; ++i) {
34366
+ // for(j = 0; j < this.pWidth; ++j) {
34367
+ // for(k = 0; k < this.pHeight; ++k) {
34368
+ // let index = i * widthHeight + j * height + k;
34369
+ // indexArray.push(index);
34370
+ // }
34371
+ // }
34372
+ // }
34373
+
34162
34374
  for(i = 0, il = indexArray.length; i < il; ++i) {
34163
34375
  let index = indexArray[i];
34164
34376
 
@@ -35420,6 +35632,7 @@ class ApplyDisplay {
35420
35632
  for(let residueid in singletonResidueHash) {
35421
35633
  // get calpha
35422
35634
  let calpha = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residueid]);
35635
+ let sideAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.selectionCls.getSideAtoms(ic.residues[residueid]));
35423
35636
  let atom = calpha;
35424
35637
 
35425
35638
  let prevResidueid = atom.structure + '_' + atom.chain + '_' + (parseInt(atom.resi) - 1).toString();
@@ -35436,7 +35649,7 @@ class ApplyDisplay {
35436
35649
  }
35437
35650
  else if( (atom.style === 'ribbon' && atom.ss === 'coil') || (atom.style === 'strand' && atom.ss === 'coil') || atom.style === 'o3 trace' || atom.style === 'schematic' || atom.style === 'c alpha trace' || atom.style === 'b factor tube' || (atom.style === 'cylinder and plate' && atom.ss !== 'helix') ) {
35438
35651
  // do not add extra residue if the side chain is shown
35439
- if(calpha !== undefined && calpha.style2 !== undefined && calpha.style2 !== 'nothing') continue;
35652
+ if(sideAtom !== undefined && sideAtom.style2 !== undefined && sideAtom.style2 !== 'nothing') continue;
35440
35653
 
35441
35654
  let bAddResidue = false;
35442
35655
  // add the next residue with same style
@@ -35471,7 +35684,7 @@ class ApplyDisplay {
35471
35684
  }
35472
35685
  else if( (atom.style === 'ribbon' && atom.ss !== 'coil' && atom.ssend) || (atom.style === 'strand' && atom.ss !== 'coil' && atom.ssend)) {
35473
35686
  // do not add extra residue if the side chain is shown
35474
- if(calpha !== undefined && calpha.style2 !== undefined && calpha.style2 !== 'nothing') continue;
35687
+ if(sideAtom !== undefined && sideAtom.style2 !== undefined && sideAtom.style2 !== 'nothing') continue;
35475
35688
 
35476
35689
  let bAddResidue = false;
35477
35690
  // add the next residue with same style
@@ -38356,11 +38569,18 @@ class Alternate {
38356
38569
  }
38357
38570
 
38358
38571
  if(ic.scene) {
38572
+ ic.renderer.clear();
38573
+
38359
38574
  // https://github.com/gkjohnson/three-gpu-pathtracer/blob/main/example/basic.js
38360
38575
  ic.renderer.outputEncoding = THREE.sRGBEncoding;
38361
38576
  //ic.renderer.outputEncoding = THREE.LinearEncoding
38362
38577
 
38363
- ic.renderer.render(ic.scene, cam);
38578
+ if(ic.opts['effect'] == 'stereo' && !window.icn3duiHash) {
38579
+ ic.effect.render(ic.scene, cam);
38580
+ }
38581
+ else {
38582
+ ic.renderer.render(ic.scene, cam);
38583
+ }
38364
38584
  }
38365
38585
  }
38366
38586
 
@@ -52737,13 +52957,20 @@ class ShowInter {
52737
52957
  }
52738
52958
  // do not change the set of displaying atoms
52739
52959
  //ic.dAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
52740
- let commandname, commanddesc;
52960
+ let commandname, commanddesc, commandname2;
52741
52961
  let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atomlistTarget);
52962
+
52742
52963
  if(firstAtom !== undefined) {
52743
52964
  commandname = "sphere." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + radius + "A";
52744
- if(bInteraction) commandname = "interactions." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + $("#" + ic.pre + "contactthreshold").val() + "A";
52965
+ //sometimes firstAtom.resi changed, thus we add a general name
52966
+ commandname2 = "sphere-" + radius + "A";
52967
+ if(bInteraction) {
52968
+ commandname = "interactions." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + $("#" + ic.pre + "contactthreshold").val() + "A";
52969
+ commandname2 = "interactions-" + $("#" + ic.pre + "contactthreshold").val() + "A";
52970
+ }
52745
52971
  commanddesc = commandname;
52746
52972
  ic.selectionCls.addCustomSelection(residueArray, commandname, commanddesc, select, true);
52973
+ ic.selectionCls.addCustomSelection(residueArray, commandname2, commanddesc, select, true);
52747
52974
  }
52748
52975
  ic.selectionCls.saveSelectionIfSelected();
52749
52976
  ic.drawCls.draw();
@@ -54921,6 +55148,7 @@ class ChainalignParser {
54921
55148
 
54922
55149
  ajaxArray.push(alignAjax);
54923
55150
  indexArray.push(index - 1);
55151
+ mmdbid_q = chainidArray[index].substr(0, chainidArray[index].indexOf('_'));
54924
55152
  struArray.push(mmdbid_q);
54925
55153
  }
54926
55154
 
@@ -54949,7 +55177,8 @@ class ChainalignParser {
54949
55177
  let mmdbid_q = struArray[i];
54950
55178
  let index = indexArray[i];
54951
55179
 
54952
- let bEqualMmdbid = (mmdbid_q == mmdbid_t);
55180
+ // let bEqualMmdbid = (mmdbid_q == mmdbid_t);
55181
+ let bEqualMmdbid = (mmdbid_q.substr(0,4) == mmdbid_t.substr(0,4));
54953
55182
  let bEqualChain = false;
54954
55183
 
54955
55184
  let queryData = {}; // check whether undefined
@@ -55199,7 +55428,7 @@ class ChainalignParser {
55199
55428
 
55200
55429
  transformStructure(mmdbid, index, alignType, bForce) { let ic = this.icn3d, me = ic.icn3dui;
55201
55430
  let chainidArray = ic.structures[mmdbid];
55202
-
55431
+
55203
55432
  for(let i = 0, il = chainidArray.length; i < il; ++i) {
55204
55433
  for(let serial in ic.chains[chainidArray[i]]) {
55205
55434
  let atm = ic.atoms[serial];
@@ -55331,6 +55560,26 @@ class ChainalignParser {
55331
55560
  return chainidArray;
55332
55561
  }
55333
55562
 
55563
+ addPostfixForStructureids(structArray) { let ic = this.icn3d; ic.icn3dui;
55564
+ let struct2cnt = {};
55565
+ for(let i = 0, il = structArray.length; i < il; ++i) {
55566
+ let struct = structArray[i].toUpperCase();
55567
+
55568
+ if(!struct2cnt.hasOwnProperty(struct)) {
55569
+ struct2cnt[struct] = 1;
55570
+ }
55571
+ else {
55572
+ ++struct2cnt[struct];
55573
+ }
55574
+
55575
+ struct = (struct2cnt[struct] == 1) ? struct : struct + struct2cnt[struct];
55576
+
55577
+ structArray[i] = struct;
55578
+ }
55579
+
55580
+ return structArray;
55581
+ }
55582
+
55334
55583
  async downloadChainalignment(chainalign) { let ic = this.icn3d, me = ic.icn3dui;
55335
55584
  let thisClass = this;
55336
55585
 
@@ -55372,6 +55621,7 @@ class ChainalignParser {
55372
55621
 
55373
55622
  ic.afChainIndexHash = {};
55374
55623
  ic.pdbChainIndexHash = {};
55624
+
55375
55625
  for(let index = 1, indexLen = alignArray.length; index < indexLen; ++index) {
55376
55626
  let pos2 = alignArray[index].indexOf('_');
55377
55627
  let mmdbid_q_tmp = alignArray[index].substr(0, pos2).toUpperCase();
@@ -55479,7 +55729,8 @@ class ChainalignParser {
55479
55729
 
55480
55730
  if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
55481
55731
  ) {
55482
- ic.mmdbidArray.push(mmdbid_q);
55732
+ // ic.mmdbidArray.push(mmdbid_q);
55733
+ ic.mmdbidArray.push(mmdbid_q.substr(0,4));
55483
55734
  queryDataArray.push(queryData);
55484
55735
  }
55485
55736
  else {
@@ -55518,7 +55769,8 @@ class ChainalignParser {
55518
55769
  // let align = (me.bNode) ? dataArray[index2 - missedChainCnt] : dataArray[index2 - missedChainCnt].value;//[0];
55519
55770
  let align = dataArray[index2 - missedChainCnt].value;//[0];
55520
55771
 
55521
- let bEqualMmdbid = (mmdbid_q == mmdbid_t);
55772
+ // let bEqualMmdbid = (mmdbid_q == mmdbid_t);
55773
+ let bEqualMmdbid = (mmdbid_q.substr(0,4) == mmdbid_t.substr(0,4));
55522
55774
  let bEqualChain = (chain_q == chain_t);
55523
55775
 
55524
55776
  me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
@@ -55689,15 +55941,14 @@ class ChainalignParser {
55689
55941
 
55690
55942
  let structArray = [];
55691
55943
 
55692
- for(let i = 0, il = structArrayTmp.length; i < il; ++i) {
55693
- let id = structArrayTmp[i].toUpperCase();
55694
- // sometimes we want to load same structure multiple times
55695
- if(!ic.structures.hasOwnProperty(id) && structArray.indexOf(id) == -1) {
55696
- structArray.push(structArrayTmp[i]);
55697
- }
55698
- else {
55699
- // only when bNoDuplicate is undefined/false, it's allowed to load multiple copies of the same structure
55700
- if(!bNoDuplicate) structArray.push(structArrayTmp[i] + me.htmlCls.postfix);
55944
+ // only when bNoDuplicate is undefined/false, it's allowed to load multiple copies of the same structure
55945
+ if(!bNoDuplicate) {
55946
+ structArray = this.addPostfixForStructureids(structArrayTmp);
55947
+ }
55948
+ else {
55949
+ for(let i = 0, il = structArrayTmp.length; i < il; ++i) {
55950
+ let id = structArrayTmp[i].toUpperCase();
55951
+ if(!ic.structures.hasOwnProperty(id)) structArray.push(structArrayTmp[i]);
55701
55952
  }
55702
55953
  }
55703
55954
 
@@ -59692,6 +59943,283 @@ class XyzParser {
59692
59943
  }
59693
59944
  }
59694
59945
 
59946
+ /**
59947
+ * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
59948
+ */
59949
+
59950
+ class MsaParser {
59951
+ constructor(icn3d) {
59952
+ this.icn3d = icn3d;
59953
+ }
59954
+
59955
+ async loadMsaData(data, type) { let ic = this.icn3d, me = ic.icn3dui;
59956
+ let bResult = await this.loadMsaSeqData(data, type);
59957
+
59958
+ if(me.cfg.align === undefined && Object.keys(ic.structures).length == 1) {
59959
+ $("#" + ic.pre + "alternateWrapper").hide();
59960
+ }
59961
+
59962
+ let typeStr = type.toUpperCase();
59963
+
59964
+ if(!bResult) {
59965
+ alert('The ' + typeStr + ' file has the wrong format...');
59966
+ }
59967
+ else {
59968
+ // retrieve the structures
59969
+ me.cfg.bu = 0; // show all chains
59970
+ await ic.chainalignParserCls.downloadMmdbAf(ic.struArray.join(','));
59971
+ me.htmlCls.clickMenuCls.setLogCmd('load mmdbaf0 ' + ic.struArray.join(','), true);
59972
+
59973
+ // get the position of the first MSA residue in the full sequence
59974
+ let startPosArray = [];
59975
+ for(let i = 0, il = ic.inputChainidArray.length; i < il; ++i) {
59976
+ let chainid = ic.inputChainidArray[i];
59977
+ let inputSeqNoGap = ic.inputSeqArray[i].replace(/-/g, '');
59978
+
59979
+ // get the full seq
59980
+ let fullSeq = '';
59981
+ for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
59982
+ fullSeq += ic.chainsSeq[chainid][j].name;
59983
+ }
59984
+
59985
+ // find the starting position of "inputSeq" in "fullSeq"
59986
+ let pos = fullSeq.toUpperCase().indexOf(inputSeqNoGap.substr(0, 20).toUpperCase());
59987
+ if(pos == -1) {
59988
+ console.log("The sequence of the aligned chain " + chainid + " (" + inputSeqNoGap.toUpperCase() + ") is different from the sequence from the structure (" + fullSeq.toUpperCase() + "), and is thus not aligned correctly...");
59989
+ pos = 0;
59990
+ }
59991
+ startPosArray.push(pos);
59992
+ }
59993
+
59994
+ // define residue mapping
59995
+ // The format is ": "-separated pairs: "1,5,10-50 | 1,5,10-50: 2,6,11-51 | 1,5,10-50"
59996
+ let predefinedres = '';
59997
+
59998
+ let chainid1 = ic.inputChainidArray[0], inputSeq1 = ic.inputSeqArray[0], pos1 = startPosArray[0];
59999
+ // loop through 2nd and forward
60000
+ for(let i = 1, il = ic.inputChainidArray.length; i < il; ++i) {
60001
+ let chainid2 = ic.inputChainidArray[i];
60002
+ let inputSeq2 = ic.inputSeqArray[i];
60003
+ let pos2 = startPosArray[i];
60004
+
60005
+ let index1 = pos1, index2 = pos2;
60006
+ let resiArray1 = [], resiArray2 = [];
60007
+ for(let j = 0, jl = inputSeq2.length; j < jl; ++j) {
60008
+ if(inputSeq1[j] != '-' && inputSeq2[j] != '-' && ic.chainsSeq[chainid1][index1] && ic.chainsSeq[chainid2][index2]) {
60009
+ let resi1 = ic.chainsSeq[chainid1][index1].resi;
60010
+ let resi2 = ic.chainsSeq[chainid2][index2].resi;
60011
+ if(ic.residues[chainid1 + '_' + resi1] && ic.residues[chainid2 + '_' + resi2]) {
60012
+ resiArray1.push(ic.chainsSeq[chainid1][index1].resi);
60013
+ resiArray2.push(ic.chainsSeq[chainid2][index2].resi);
60014
+ }
60015
+ }
60016
+
60017
+ if(inputSeq1[j] != '-') ++index1;
60018
+ if(inputSeq2[j] != '-') ++index2;
60019
+ }
60020
+ let resiRangeStr1 = ic.resid2specCls.resi2range(resiArray1, true);
60021
+ let resiRangeStr2 = ic.resid2specCls.resi2range(resiArray2, true);
60022
+
60023
+ predefinedres += resiRangeStr1 + ' | ' + resiRangeStr2;
60024
+ if(i < il -1) predefinedres += ': ';
60025
+ }
60026
+
60027
+ // realign based on residue by residue
60028
+ let alignment_final = ic.inputChainidArray.join(',');
60029
+
60030
+ if(predefinedres && (alignment_final.split(',').length - 1) != predefinedres.split(': ').length) {
60031
+ alert("Please make sure the number of chains and the lines of predefined residues are the same...");
60032
+ return;
60033
+ }
60034
+
60035
+ me.cfg.resdef = predefinedres.replace(/:/gi, ';');
60036
+
60037
+ let bRealign = true, bPredefined = true;
60038
+ let chainidArray = alignment_final.split(',');
60039
+ await ic.realignParserCls.realignChainOnSeqAlign(undefined, chainidArray, bRealign, bPredefined);
60040
+
60041
+ me.htmlCls.clickMenuCls.setLogCmd("realign predefined " + alignment_final + " " + predefinedres, true);
60042
+
60043
+
60044
+ ic.opts['color'] = 'identity';
60045
+ ic.setColorCls.setColorByOptions(ic.opts, ic.hAtoms);
60046
+ me.htmlCls.clickMenuCls.setLogCmd("color identity", true);
60047
+
60048
+ // show selection
60049
+ ic.selectionCls.showSelection();
60050
+ me.htmlCls.clickMenuCls.setLogCmd("show selection", true);
60051
+ }
60052
+ }
60053
+
60054
+ async loadMsaSeqData(data, type) { let ic = this.icn3d; ic.icn3dui;
60055
+ let lines = data.split(/\r?\n|\r/);
60056
+ if(lines.length < 2) return false;
60057
+
60058
+ ic.init();
60059
+
60060
+ ic.molTitle = "";
60061
+
60062
+ let seqHash = {};
60063
+
60064
+ let bStart = false, bSecBlock = false, chainid = '', seq = '', bFound = false;
60065
+
60066
+ if(type == 'clustalw' && lines[0].substr(0,7) != 'CLUSTAL') { // CLUSTAL W or CLUSTALW
60067
+ return false;
60068
+ }
60069
+
60070
+ let startLineNum = (type == 'clustalw') ? 1 : 0;
60071
+
60072
+ // 1. parse input msa
60073
+ for(let i = startLineNum, il = lines.length; i < il; ++i) {
60074
+ let line = lines[i].trim();
60075
+ if(line === '') {
60076
+ if(bStart) bSecBlock = true;
60077
+ bStart = false;
60078
+ continue;
60079
+ }
60080
+
60081
+ if(!bStart) { // first line
60082
+ if(type == 'fasta' && line.substr(0,1) != '>') {
60083
+ return false;
60084
+ }
60085
+ bStart = true;
60086
+ }
60087
+
60088
+ if(type == 'clustalw') {
60089
+ if(line.substr(0, 1) != ' ' && line.substr(0, 1) != '\t') {
60090
+ let chainid_seq = line.split(/\s+/);
60091
+ let idArray = chainid_seq[0].split('|');
60092
+ let result = this.getChainid(idArray, bStart && !bSecBlock);
60093
+ bFound = result.bFound;
60094
+ chainid = result.chainid;
60095
+
60096
+ if(bFound) {
60097
+ if(!seqHash.hasOwnProperty(chainid)) {
60098
+ seqHash[chainid] = chainid_seq[1];
60099
+ }
60100
+ else {
60101
+ seqHash[chainid] += chainid_seq[1];
60102
+ }
60103
+ }
60104
+ }
60105
+ }
60106
+ else if(type == 'fasta') {
60107
+ if(line.substr(0,1) == ">") {
60108
+ // add the previous seq
60109
+ if(chainid && seq && bFound) seqHash[chainid] = seq;
60110
+ chainid = '';
60111
+ seq = '';
60112
+
60113
+ let pos = line.indexOf(' ');
60114
+ let idArray = line.substr(1, pos).split('|');
60115
+
60116
+ if(idArray.length == 1) {
60117
+ chainid = idArray[0];
60118
+ }
60119
+ else {
60120
+ let result = this.getChainid(idArray, true);
60121
+ bFound = result.bFound;
60122
+ chainid = result.chainid;
60123
+ }
60124
+ }
60125
+ else {
60126
+ seq += line;
60127
+ }
60128
+ }
60129
+ }
60130
+
60131
+ // add the last seq
60132
+ if(type == 'fasta' && chainid && seq && bFound) seqHash[chainid] = seq;
60133
+
60134
+ // 2. get the PDB ID or RefSeqID or AlphaFold ID
60135
+ ic.inputChainidArray = [];
60136
+ ic.inputSeqArray = [];
60137
+ ic.struArray = [];
60138
+
60139
+ // find the tempate where the first residue is not gap
60140
+ let template = '';
60141
+ for(let chainid in seqHash) {
60142
+ let seq = seqHash[chainid];
60143
+ if(seq.substr(0,1) != '-') {
60144
+ template = chainid;
60145
+ await this.processOneChain(chainid, seqHash);
60146
+ break;
60147
+ }
60148
+ }
60149
+ if(!template) template = Object.keys(seqHash)[0];
60150
+
60151
+ for(let chainid in seqHash) {
60152
+ if(chainid != template) await this.processOneChain(chainid, seqHash);
60153
+ }
60154
+
60155
+ return true;
60156
+ }
60157
+
60158
+ async processOneChain(chainid, seqHash) { let ic = this.icn3d, me = ic.icn3dui;
60159
+ ic.inputSeqArray.push(seqHash[chainid]);
60160
+ // ic.inputSeqArray.push(seqHash[chainid].replace(/-/g, '')); // remove the gaps in seq
60161
+
60162
+ if(chainid.lastIndexOf('_') == 2) { // refseq ID
60163
+ // convert refseq to uniprot id
60164
+ let url = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi?refseq2uniprot=" + chainid;
60165
+
60166
+ let data = await me.getAjaxPromise(url, 'jsonp', false, 'The protein accession ' + chainid + ' can not be mapped to AlphaFold UniProt ID...');
60167
+ if(data && data.uniprot) {
60168
+ if(!ic.uniprot2acc) ic.uniprot2acc = {};
60169
+ let uniprot = data.uniprot;
60170
+ ic.uniprot2acc[uniprot] = chainid;
60171
+ ic.struArray.push(uniprot);
60172
+ ic.inputChainidArray.push(uniprot + '_A');
60173
+ }
60174
+ else {
60175
+ console.log('The accession ' + refseqid + ' can not be mapped to AlphaFold UniProt ID. It will be treated as a UniProt ID instead.');
60176
+ ic.struArray.push(chainid);
60177
+ ic.inputChainidArray.push(chainid + '_A');
60178
+ }
60179
+ }
60180
+ else if(chainid.indexOf('_') != -1) { // PDB ID
60181
+ let stru = chainid.substr(0, chainid.indexOf('_')).substr(0, 4);
60182
+ ic.struArray.push(stru);
60183
+ ic.inputChainidArray.push(chainid);
60184
+ }
60185
+ else if(chainid.length > 5) { // UniProt ID
60186
+ ic.struArray.push(chainid);
60187
+ ic.inputChainidArray.push(chainid + '_A');
60188
+ }
60189
+ }
60190
+
60191
+ getChainid(idArray, bWarning) { let ic = this.icn3d; ic.icn3dui;
60192
+ let bFound = false;
60193
+ let chainid = idArray[0];
60194
+
60195
+ for(let j = 0, jl = idArray.length; j < jl; ++j) {
60196
+ if(idArray[j] == 'pdb') {
60197
+ chainid = idArray[j+1] + '_' + idArray[j+2];
60198
+ bFound = true;
60199
+ break;
60200
+ }
60201
+ else if(idArray[j] == 'ref') { // refseq
60202
+ let refseq = idArray[j+1].split('.')[0];
60203
+ chainid = refseq; // + '_A';
60204
+ bFound = true;
60205
+ break;
60206
+ }
60207
+ else if(idArray[j] == 'sp' || idArray[j] == 'tr') { // uniprot
60208
+ let uniprot = idArray[j+1];
60209
+ chainid = uniprot;
60210
+ bFound = true;
60211
+ break;
60212
+ }
60213
+ }
60214
+
60215
+ if(!bFound && bWarning) {
60216
+ alert("The sequence ID " + idArray.join('|') + " does not have the correctly formatted PDB, UniProt or RefSeq ID...");
60217
+ }
60218
+
60219
+ return {chainid: chainid, bFound: bFound};
60220
+ }
60221
+ }
60222
+
59695
60223
  /**
59696
60224
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
59697
60225
  */
@@ -59833,7 +60361,7 @@ class RealignParser {
59833
60361
  // If rmsd from vastsrv is too large, realign the chains
59834
60362
  //if(me.cfg.chainalign && !me.cfg.usepdbnum && me.cfg.resdef && rmsd > 5) {
59835
60363
  // redo algnment only for VAST serv page
59836
- if(!me.cfg.usepdbnum && me.cfg.resdef && rmsd > 5) {
60364
+ if(!me.cfg.usepdbnum && me.cfg.resdef && rmsd > 5 && me.cfg.chainalign) {
59837
60365
  console.log("RMSD from VAST is larger than 5. Realign the chains with TM-align.");
59838
60366
  //let nameArray = me.cfg.chainalign.split(',');
59839
60367
  let nameArray = Object.keys(chainidHash);
@@ -60289,7 +60817,8 @@ let resRangeArray = (me.cfg.resrange) ? decodeURIComponent(me.cfg.resrange).spli
60289
60817
  let predefinedResArray, predefinedResPair;
60290
60818
 
60291
60819
  if(bPredefined) {
60292
- predefinedResArray = decodeURIComponent(me.cfg.resdef).trim().replace(/\+/gi, ' ').split(': ');
60820
+ // predefinedResArray = decodeURIComponent(me.cfg.resdef).trim().replace(/\+/gi, ' ').split(': ');
60821
+ predefinedResArray = decodeURIComponent(me.cfg.resdef).trim().replace(/\+/gi, ' ').split('; ');
60293
60822
 
60294
60823
  if(predefinedResArray.length != chainidArray.length - 1) {
60295
60824
  alert("Please make sure the number of chains and the lines of predefined residues are the same...");
@@ -60566,7 +61095,7 @@ class DensityCifParser {
60566
61095
  let thisClass = this;
60567
61096
 
60568
61097
  let url;
60569
- let detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 2 : 4; //0 : 4;
61098
+ let detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 0 : 4; // max 6
60570
61099
 
60571
61100
  //https://www.ebi.ac.uk/pdbe/densities/doc.html
60572
61101
  if(type == '2fofc' || type == 'fofc') {
@@ -60577,6 +61106,7 @@ class DensityCifParser {
60577
61106
  url = "https://www.ebi.ac.uk/pdbe/volume-server/x-ray/" + pdbid.toLowerCase() + "/box/" + min_max[0][0] + "," + min_max[0][1] + "," + min_max[0][2] + "/" + min_max[1][0] + "," + min_max[1][1] + "," + min_max[1][2] + "?detail=" + detail;
60578
61107
  }
60579
61108
  else if(type == 'em') {
61109
+ detail = (me.utilsCls.isMobile() || me.cfg.notebook) ? 0: 5; // max 6
60580
61110
  url = "https://www.ebi.ac.uk/pdbe/densities/emd/" + emd.toLowerCase() + "/cell?detail=" + detail;
60581
61111
  }
60582
61112
 
@@ -61936,7 +62466,8 @@ class ParserUtils {
61936
62466
  ic.rmsd_supr = me.rmsdSuprCls.getRmsdSuprCls(coordsFrom, coordsTo, n);
61937
62467
 
61938
62468
  // apply matrix for each atom
61939
- if(ic.rmsd_supr.rot !== undefined && ic.rmsd_supr.rmsd < 0.1) {
62469
+ // if(ic.rmsd_supr.rot !== undefined && ic.rmsd_supr.rmsd < 0.1) {
62470
+ if(ic.rmsd_supr.rot !== undefined && ic.rmsd_supr.rmsd < 1) { // 6M17 has some coordinates change and rmsd is 0.3
61940
62471
  let rot = ic.rmsd_supr.rot;
61941
62472
  let centerFrom = ic.rmsd_supr.trans1;
61942
62473
  let centerTo = ic.rmsd_supr.trans2;
@@ -62150,11 +62681,12 @@ class ParserUtils {
62150
62681
 
62151
62682
  // set defined sets before loadScript
62152
62683
  if(ic.bInitial) {
62153
- if(me.cfg.mobilemenu) {
62154
- me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
62155
- let bNoSave = true;
62156
- me.htmlCls.clickMenuCls.applyShownMenus(bNoSave);
62157
- }
62684
+ // if(me.cfg.mobilemenu) {
62685
+ // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.simpleMenus);
62686
+ // let bNoSave = true;
62687
+ // me.htmlCls.clickMenuCls.applyShownMenus(bNoSave);
62688
+ // }
62689
+
62158
62690
  // else {
62159
62691
  // me.htmlCls.shownMenus = me.hashUtilsCls.cloneHash(me.htmlCls.allMenus);
62160
62692
  // me.htmlCls.clickMenuCls.applyShownMenus();
@@ -62211,6 +62743,10 @@ class ParserUtils {
62211
62743
  if(me.cfg.closepopup || me.cfg.imageonly) {
62212
62744
  ic.resizeCanvasCls.closeDialogs();
62213
62745
  }
62746
+
62747
+ if(!me.cfg.showlogo) {
62748
+ $("#ncbi_logo").hide();
62749
+ }
62214
62750
  }
62215
62751
  else {
62216
62752
  ic.hlUpdateCls.updateHlAll();
@@ -64626,7 +65162,7 @@ class SetSeqAlign {
64626
65162
 
64627
65163
  setMsaFormat(chainidArray) { let ic = this.icn3d; ic.icn3dui;
64628
65164
  //set MSA
64629
- let fastaFormat = '', clustalFormat = 'CLUSTALW\n\n', resbyresFormat = '';
65165
+ let fastaFormat = '', clustalwFormat = 'CLUSTALWW\n\n', resbyresFormat = '';
64630
65166
  let chainArrayClustal = [];
64631
65167
 
64632
65168
  let consArray = [], resiArrayTemplate = [];
@@ -64635,8 +65171,8 @@ class SetSeqAlign {
64635
65171
  let chainid = chainidArray[i];
64636
65172
  fastaFormat += '>' + chainid + '\n';
64637
65173
 
64638
- let clustalArray = [];
64639
- let clustalLine = chainid.padEnd(20, ' ');
65174
+ let clustalwArray = [];
65175
+ let clustalwLine = chainid.padEnd(20, ' ');
64640
65176
  let consLine = ''.padEnd(20, ' ');
64641
65177
 
64642
65178
  let resiArrayTarget = [], resiArrayQuery = [];
@@ -64645,7 +65181,7 @@ class SetSeqAlign {
64645
65181
  for(let j = 0, jl = ic.alnChainsSeq[chainid].length; j < jl; ++j) {
64646
65182
  let resn = ic.alnChainsSeq[chainid][j].resn;
64647
65183
  fastaFormat += resn;
64648
- clustalLine += resn;
65184
+ clustalwLine += resn;
64649
65185
  if(i == il - 1) {
64650
65186
  let alignedClass = ic.alnChainsSeq[chainid][j].class;
64651
65187
  if(alignedClass == 'icn3d-cons') {
@@ -64664,7 +65200,8 @@ class SetSeqAlign {
64664
65200
  resiArrayTemplate.push(ic.alnChainsSeq[chainid][j].resi);
64665
65201
  }
64666
65202
  else {
64667
- if(ic.alnChainsSeq[chainid][j].aligned) {
65203
+ // if(ic.alnChainsSeq[chainid][j].aligned) {
65204
+ if(ic.alnChainsSeq[chainid][j].aligned && ic.alnChainsSeq[chainidTemplate][j] && ic.alnChainsSeq[chainid][j]) {
64668
65205
  resiArrayTarget.push(ic.alnChainsSeq[chainidTemplate][j].resi);
64669
65206
  resiArrayQuery.push(ic.alnChainsSeq[chainid][j].resi);
64670
65207
  }
@@ -64674,9 +65211,9 @@ class SetSeqAlign {
64674
65211
 
64675
65212
  if(cnt % 60 == 0) {
64676
65213
  fastaFormat += '\n';
64677
- clustalLine += ' ' + String(parseInt(cnt / 60) * 60);
64678
- clustalArray.push(clustalLine);
64679
- clustalLine = chainid.padEnd(20, ' ');
65214
+ clustalwLine += ' ' + String(parseInt(cnt / 60) * 60);
65215
+ clustalwArray.push(clustalwLine);
65216
+ clustalwLine = chainid.padEnd(20, ' ');
64680
65217
 
64681
65218
  if(i == il - 1) {
64682
65219
  consArray.push(consLine);
@@ -64687,7 +65224,7 @@ class SetSeqAlign {
64687
65224
 
64688
65225
  // add last line
64689
65226
  if(cnt % 60 != 0) {
64690
- clustalArray.push(clustalLine);
65227
+ clustalwArray.push(clustalwLine);
64691
65228
  if(i == il - 1) {
64692
65229
  consArray.push(consLine);
64693
65230
  }
@@ -64695,7 +65232,7 @@ class SetSeqAlign {
64695
65232
 
64696
65233
  fastaFormat += '\n';
64697
65234
 
64698
- chainArrayClustal.push(clustalArray);
65235
+ chainArrayClustal.push(clustalwArray);
64699
65236
  if(i == il - 1) chainArrayClustal.push(consArray);
64700
65237
 
64701
65238
  // residue by residue
@@ -64705,23 +65242,23 @@ class SetSeqAlign {
64705
65242
  if(i > 0) resbyresFormat += resiRangeStr1 + ' | ' + resiRangeStr2 + '\n';
64706
65243
  }
64707
65244
 
64708
- // CLUSTALW
65245
+ // CLUSTALWW
64709
65246
  for(let j = 0, jl = chainArrayClustal[0].length; j < jl; ++j) {
64710
65247
  for(let i = 0, il = chainArrayClustal.length; i < il; ++i) {
64711
- clustalFormat += chainArrayClustal[i][j] + '\n';
65248
+ clustalwFormat += chainArrayClustal[i][j] + '\n';
64712
65249
  }
64713
- clustalFormat += '\n';
65250
+ clustalwFormat += '\n';
64714
65251
  }
64715
65252
 
64716
65253
  // seq MSA
64717
65254
  if(!ic.msa) ic.msa = {};
64718
65255
 
64719
65256
  if(!ic.msa['fasta']) ic.msa['fasta'] = [];
64720
- if(!ic.msa['clustal']) ic.msa['clustal'] = [];
65257
+ if(!ic.msa['clustalw']) ic.msa['clustalw'] = [];
64721
65258
  if(!ic.msa['resbyres']) ic.msa['resbyres'] = [];
64722
65259
 
64723
65260
  ic.msa['fasta'].push(fastaFormat);
64724
- ic.msa['clustal'].push(clustalFormat);
65261
+ ic.msa['clustalw'].push(clustalwFormat);
64725
65262
  ic.msa['resbyres'].push(resbyresFormat);
64726
65263
  }
64727
65264
  }
@@ -67477,6 +68014,12 @@ class ApplyCommand {
67477
68014
  else if(command == 'set slab off') {
67478
68015
  ic.opts['slab'] = 'no';
67479
68016
  }
68017
+ else if(command == 'stereo on') {
68018
+ ic.opts['effect'] = 'stereo';
68019
+ }
68020
+ else if(command == 'stereo off') {
68021
+ ic.opts['effect'] = 'none';
68022
+ }
67480
68023
  else if(command == 'set assembly on') {
67481
68024
  ic.bAssembly = true;
67482
68025
  }
@@ -69550,16 +70093,26 @@ class DefinedSets {
69550
70093
  } // outer for
69551
70094
  }
69552
70095
 
69553
- setHAtomsFromSets(nameArray, type) { let ic = this.icn3d, me = ic.icn3dui;
70096
+ setHAtomsFromSets(nameArray, type) { let ic = this.icn3d; ic.icn3dui;
69554
70097
  for(let i = 0; i < nameArray.length; ++i) {
69555
70098
  let selectedSet = nameArray[i];
69556
70099
 
69557
- if((ic.defNames2Atoms === undefined || !ic.defNames2Atoms.hasOwnProperty(selectedSet)) &&(ic.defNames2Residues === undefined || !ic.defNames2Residues.hasOwnProperty(selectedSet)) ) continue;
70100
+ this.setHAtomsFromSets_base(selectedSet, type);
69558
70101
 
70102
+ // sometimes the "resi" changed and thus the name changed
70103
+ //"sphere." + firstAtom.chain + ":" + me.utilsCls.residueName2Abbr(firstAtom.resn.substr(0, 3)).trim() + firstAtom.resi + "-" + radius + "A";
70104
+ if(Object.keys(ic.hAtoms).length == 0 && (selectedSet.split('.')[0] == 'sphere' || selectedSet.split('.')[0] == 'interactions')) {
70105
+ let pos = selectedSet.lastIndexOf('-');
70106
+ selectedSet = selectedSet.split('.')[0] + selectedSet.substr(pos);
70107
+ this.setHAtomsFromSets_base(selectedSet, type);
70108
+ }
70109
+ } // outer for
70110
+ }
70111
+
70112
+ setHAtomsFromSets_base(selectedSet, type) { let ic = this.icn3d, me = ic.icn3dui;
69559
70113
  if(ic.defNames2Atoms !== undefined && ic.defNames2Atoms.hasOwnProperty(selectedSet)) {
69560
70114
 
69561
70115
  let atomArray = ic.defNames2Atoms[selectedSet];
69562
-
69563
70116
  if(type === 'or') {
69564
70117
  for(let j = 0, jl = atomArray.length; j < jl; ++j) {
69565
70118
  ic.hAtoms[atomArray[j]] = 1;
@@ -69605,7 +70158,6 @@ class DefinedSets {
69605
70158
  ic.hAtoms = me.hashUtilsCls.exclHash(ic.hAtoms, atomHash);
69606
70159
  }
69607
70160
  }
69608
- } // outer for
69609
70161
  }
69610
70162
 
69611
70163
  updateAdvancedCommands(nameArray, type) { let ic = this.icn3d; ic.icn3dui;
@@ -69628,6 +70180,7 @@ class DefinedSets {
69628
70180
 
69629
70181
  combineSets(orArray, andArray, notArray, commandname) { let ic = this.icn3d, me = ic.icn3dui;
69630
70182
  ic.hAtoms = {};
70183
+
69631
70184
  this.setHAtomsFromSets(orArray, 'or');
69632
70185
 
69633
70186
  if(Object.keys(ic.hAtoms).length == 0) {
@@ -71066,6 +71619,10 @@ class LoadScript {
71066
71619
  ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH, me.htmlCls.HEIGHT, true);
71067
71620
  }
71068
71621
 
71622
+ if(!me.cfg.showlogo) {
71623
+ $("#ncbi_logo").hide();
71624
+ }
71625
+
71069
71626
  // an extra render to remove artifacts in transparent surface
71070
71627
  if(ic.bTransparentSurface && ic.bRender) ic.drawCls.render();
71071
71628
 
@@ -71723,19 +72280,22 @@ class Selection {
71723
72280
  selectSideChains() { let ic = this.icn3d, me = ic.icn3dui;
71724
72281
  let currHAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
71725
72282
 
71726
- //let nuclMainArray = ["C1'", "C1*", "C2'", "C2*", "C3'", "C3*", "C4'", "C4*", "C5'", "C5*", "O3'", "O3*", "O4'", "O4*", "O5'", "O5*", "P", "OP1", "O1P", "OP2", "O2P"];
72283
+ ic.hAtoms = this.getSideAtoms(currHAtoms);
72284
+ ic.hlUpdateCls.showHighlight();
72285
+ }
71727
72286
 
71728
- ic.hAtoms = {};
71729
- for(let i in currHAtoms) {
72287
+ getSideAtoms(atoms) { let ic = this.icn3d, me = ic.icn3dui;
72288
+ let sideAtoms = {};
72289
+ for(let i in atoms) {
71730
72290
  if((ic.proteins.hasOwnProperty(i) && ic.atoms[i].name !== "N" && ic.atoms[i].name !== "H"
71731
72291
  && ic.atoms[i].name !== "C" && ic.atoms[i].name !== "O"
71732
72292
  && !(ic.atoms[i].name === "CA" && ic.atoms[i].elem === "C") && ic.atoms[i].name !== "HA")
71733
72293
  ||(ic.nucleotides.hasOwnProperty(i) && me.parasCls.nuclMainArray.indexOf(ic.atoms[i].name) === -1) ) {
71734
- ic.hAtoms[i] = 1;
72294
+ sideAtoms[i] = 1;
71735
72295
  }
71736
72296
  }
71737
72297
 
71738
- ic.hlUpdateCls.showHighlight();
72298
+ return sideAtoms;
71739
72299
  }
71740
72300
 
71741
72301
  selectMainSideChains() { let ic = this.icn3d, me = ic.icn3dui;
@@ -72351,9 +72911,12 @@ class Resid2spec {
72351
72911
  resi2range(resiArray, bString) {var ic = this.icn3d; ic.icn3dui;
72352
72912
  let range = [], rangeStr = '';
72353
72913
 
72354
- let resiArraySorted = resiArray.sort(function(a, b) {
72355
- return parseInt(a) - parseInt(b);
72356
- });
72914
+ // some chains such as 3SN6_R start with residues with high residue numbers, then end with residues with low residue numbers
72915
+ // let resiArraySorted = resiArray.sort(function(a, b) {
72916
+ // return parseInt(a) - parseInt(b);
72917
+ // });
72918
+
72919
+ let resiArraySorted = resiArray;
72357
72920
 
72358
72921
  let startResi = resiArraySorted[0];
72359
72922
  let prevResi, resi;
@@ -73638,18 +74201,29 @@ class Dssp {
73638
74201
 
73639
74202
  ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
73640
74203
 
73641
- let bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template);
73642
74204
  let numRound = 0;
74205
+ let bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, undefined, numRound);
74206
+ ++numRound;
73643
74207
 
73644
74208
  //while(!bNoMoreIg) {
73645
74209
  while(!bNoMoreIg && numRound < 15) {
73646
74210
  let bRerun = true;
73647
- bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun);
74211
+ bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun, numRound);
73648
74212
  ++numRound;
73649
74213
  }
73650
74214
  }
73651
74215
  else {
73652
- await thisClass.parseRefPdbData(undefined, template);
74216
+ await thisClass.parseRefPdbData(undefined, template, undefined, numRound);
74217
+ }
74218
+
74219
+ // refnum should be adjusted after all Ig are detected since sometimes the sheet extension may affect another Ig domain
74220
+ if(!ic.chainid2igtrack) ic.chainid2igtrack = {};
74221
+ for(let chainid in ic.chains) {
74222
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]);
74223
+ if(ic.proteins.hasOwnProperty(atom.serial)) {
74224
+ let giSeq = ic.showSeqCls.getSeq(chainid);
74225
+ ic.chainid2igtrack[chainid] = this.ajdustRefnum(giSeq, chainid);
74226
+ }
73653
74227
  }
73654
74228
  // }
73655
74229
  // catch(err) {
@@ -73658,7 +74232,7 @@ class Dssp {
73658
74232
  // }
73659
74233
  }
73660
74234
 
73661
- async parseRefPdbData(dataArray, template, bRerun) { let ic = this.icn3d, me = ic.icn3dui;
74235
+ async parseRefPdbData(dataArray, template, bRerun, numRound) { let ic = this.icn3d, me = ic.icn3dui;
73662
74236
  let thisClass = this;
73663
74237
 
73664
74238
  let struArray = Object.keys(ic.structures);
@@ -73752,7 +74326,7 @@ class Dssp {
73752
74326
  dataArray2 = await this.promiseWithFixedJobs(ajaxArray);
73753
74327
 
73754
74328
  let bRound1 = true;
73755
- bNoMoreIg = await thisClass.parseAlignData(dataArray2, domainidpairArray, bRound1);
74329
+ bNoMoreIg = await thisClass.parseAlignData(dataArray2, domainidpairArray, bRound1, numRound);
73756
74330
 
73757
74331
  /// if(ic.deferredRefnum !== undefined) ic.deferredRefnum.resolve();
73758
74332
  }
@@ -73798,7 +74372,7 @@ class Dssp {
73798
74372
 
73799
74373
  dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
73800
74374
 
73801
- bNoMoreIg = await thisClass.parseAlignData(dataArray3, domainidpairArray3);
74375
+ bNoMoreIg = await thisClass.parseAlignData(dataArray3, domainidpairArray3, undefined, numRound);
73802
74376
  }
73803
74377
 
73804
74378
  return bNoMoreIg;
@@ -74026,7 +74600,7 @@ class Dssp {
74026
74600
  delete ic.domainid2refpdbname[domainid];
74027
74601
  delete ic.domainid2score[domainid];
74028
74602
  }
74029
- continue;
74603
+ continue;
74030
74604
  }
74031
74605
  // }
74032
74606
  }
@@ -74090,7 +74664,7 @@ class Dssp {
74090
74664
  return domainid2segs; // only used in round 2
74091
74665
  }
74092
74666
 
74093
- async parseAlignData(dataArray, domainidpairArray, bRound1) { let ic = this.icn3d, me = ic.icn3dui;
74667
+ async parseAlignData(dataArray, domainidpairArray, bRound1, numRound) { let ic = this.icn3d, me = ic.icn3dui;
74094
74668
  let bNoMoreIg = false;
74095
74669
 
74096
74670
  let domainid2segs = this.parseAlignData_part1(dataArray, domainidpairArray, bRound1);
@@ -74115,7 +74689,8 @@ class Dssp {
74115
74689
  //let pdbid = domainid.substr(0, domainid.indexOf('_'));
74116
74690
  let chainid = domainid.substr(0, domainid.indexOf(','));
74117
74691
 
74118
- if(ic.refpdbHash.hasOwnProperty(chainid)) {
74692
+ // Adjusted refpdbname in the first try
74693
+ if(ic.refpdbHash.hasOwnProperty(chainid) && numRound == 0) {
74119
74694
  refpdbnameList = [chainid];
74120
74695
 
74121
74696
  if(!me.bNode) console.log("Adjusted refpdbname for domainid " + domainid + ": " + chainid);
@@ -74168,7 +74743,7 @@ class Dssp {
74168
74743
 
74169
74744
  dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
74170
74745
 
74171
- bNoMoreIg = await this.parseAlignData(dataArray3, domainidpairArray3, false);
74746
+ bNoMoreIg = await this.parseAlignData(dataArray3, domainidpairArray3, false, numRound);
74172
74747
 
74173
74748
  // end of round 2
74174
74749
  return bNoMoreIg;
@@ -74413,6 +74988,8 @@ class Dssp {
74413
74988
  }
74414
74989
  }
74415
74990
 
74991
+ // refnum should be adjusted after all Ig are detected since sometimes the sheet extension may affect another Ig domain
74992
+ /*
74416
74993
  if(!ic.chainid2igtrack) ic.chainid2igtrack = {};
74417
74994
  for(let chainid in ic.chains) {
74418
74995
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]);
@@ -74421,6 +74998,7 @@ class Dssp {
74421
74998
  ic.chainid2igtrack[chainid] = this.ajdustRefnum(giSeq, chainid);
74422
74999
  }
74423
75000
  }
75001
+ */
74424
75002
  }
74425
75003
 
74426
75004
  getStrandFromRefnum(oriRefnum, finalStrand) { let ic = this.icn3d; ic.icn3dui;
@@ -79353,7 +79931,7 @@ class ResizeCanvas {
79353
79931
  //let itemArray = ['dl_selectannotations', 'dl_alignment', 'dl_2ddgm', 'dl_definedsets', 'dl_graph',
79354
79932
  // 'dl_linegraph', 'dl_scatterplot', 'dl_contactmap', 'dl_allinteraction', 'dl_copyurl',
79355
79933
  // 'dl_symmetry', 'dl_symd', 'dl_rmsd', 'dl_legend', 'dl_disttable'];
79356
- let itemArray = ['dl_2ddgm', 'dl_2dctn', 'dl_alignment', 'dl_sequence2', 'dl_definedsets', 'dl_setsmenu', 'dl_command', 'dl_setoperations', 'dl_vast', 'dl_foldseek', 'dl_mmtfid', 'dl_pdbid', 'dl_afid', 'dl_opmid', 'dl_pdbfile', 'dl_pdbfile_app', 'dl_rescolorfile', 'dl_customcolor', 'dl_align', 'dl_alignaf', 'dl_chainalign', 'dl_chainalign2', 'dl_chainalign3', 'dl_mutation', 'dl_mol2file', 'dl_sdffile', 'dl_xyzfile', 'dl_afmapfile', 'dl_urlfile', 'dl_mmciffile', 'dl_mmcifid', 'dl_mmdbid', 'dl_mmdbafid', 'dl_blast_rep_id', 'dl_yournote', 'dl_proteinname', 'dl_refseqid', 'dl_cid', 'dl_pngimage', 'dl_state', 'dl_fixedversion', 'dl_selection', 'dl_dsn6', 'dl_dsn6url', 'dl_clr', 'dl_symmetry', 'dl_symd', 'dl_contact', 'dl_hbonds', 'dl_realign', 'dl_realignbystruct', 'dl_allinteracton', 'dl_interactionsorted', 'dl_linegraph', 'dl_linegraphcolor', 'dl_scatterplot', 'dl_scatterploitcolor', 'dl_contactmap', 'dl_alignerrormap', 'dl_elecmap2fofc', 'dl_elecmapfofc', 'dl_emmap', 'dl_aroundsphere', 'dl_adjustmem', 'dl_selectplane', 'dl_addlabel', 'dl_addlabelselection', 'dl_labelColor', 'dl_distance', 'dl_stabilizer', 'dl_disttwosets', 'dl_distmanysets', 'dl_stabilizer_rm', 'dl_thickness', 'dl_thickness2', 'dl_addtrack', 'dl_addtrack_tabs', 'dl_saveselection', 'dl_copyurl', 'dl_selectannotations', 'dl_annotations_tabs', 'dl_anno_view_tabs', 'dl_annotations', 'dl_graph', 'dl_svgcolor', 'dl_area', 'dl_colorbyarea', 'dl_rmsd', 'dl_buriedarea', 'dl_propbypercentout', 'dl_propbybfactor', 'dl_legend', 'dl_disttable', 'dl_translate'];
79934
+ let itemArray = ['dl_2ddgm', 'dl_2dctn', 'dl_alignment', 'dl_sequence2', 'dl_definedsets', 'dl_setsmenu', 'dl_command', 'dl_setoperations', 'dl_vast', 'dl_foldseek', 'dl_mmtfid', 'dl_pdbid', 'dl_afid', 'dl_opmid', 'dl_pdbfile', 'dl_pdbfile_app', 'dl_rescolorfile', 'dl_customcolor', 'dl_align', 'dl_alignaf', 'dl_chainalign', 'dl_chainalign2', 'dl_chainalign3', 'dl_mutation', 'dl_mol2file', 'dl_sdffile', 'dl_xyzfile', 'dl_clustalwfile', 'dl_fastafile', 'dl_afmapfile', 'dl_urlfile', 'dl_mmciffile', 'dl_mmcifid', 'dl_mmdbid', 'dl_mmdbafid', 'dl_blast_rep_id', 'dl_yournote', 'dl_proteinname', 'dl_refseqid', 'dl_cid', 'dl_pngimage', 'dl_state', 'dl_fixedversion', 'dl_selection', 'dl_dsn6', 'dl_dsn6url', 'dl_clr', 'dl_symmetry', 'dl_symd', 'dl_contact', 'dl_hbonds', 'dl_realign', 'dl_realignbystruct', 'dl_allinteracton', 'dl_interactionsorted', 'dl_linegraph', 'dl_linegraphcolor', 'dl_scatterplot', 'dl_scatterploitcolor', 'dl_contactmap', 'dl_alignerrormap', 'dl_elecmap2fofc', 'dl_elecmapfofc', 'dl_emmap', 'dl_aroundsphere', 'dl_adjustmem', 'dl_selectplane', 'dl_addlabel', 'dl_addlabelselection', 'dl_labelColor', 'dl_distance', 'dl_stabilizer', 'dl_disttwosets', 'dl_distmanysets', 'dl_stabilizer_rm', 'dl_thickness', 'dl_thickness2', 'dl_addtrack', 'dl_addtrack_tabs', 'dl_saveselection', 'dl_copyurl', 'dl_selectannotations', 'dl_annotations_tabs', 'dl_anno_view_tabs', 'dl_annotations', 'dl_graph', 'dl_svgcolor', 'dl_area', 'dl_colorbyarea', 'dl_rmsd', 'dl_buriedarea', 'dl_propbypercentout', 'dl_propbybfactor', 'dl_legend', 'dl_disttable', 'dl_translate'];
79357
79935
 
79358
79936
  for(let i in itemArray) {
79359
79937
  let item = itemArray[i];
@@ -80099,9 +80677,10 @@ class SaveFile {
80099
80677
  ssObj.resn = atom.resn;
80100
80678
  ssObj.resi = atom.resi;
80101
80679
 
80102
- if(parseInt(atom.resi) > parseInt(prevResi) + 1) {
80103
- ssObj.ss = ' ';
80104
- ssArray.push(ssObj);
80680
+ if(parseInt(atom.resi) > parseInt(prevResi) + 1 || atom.ssbegin) {
80681
+ let ssObj2 = me.hashUtilsCls.cloneHash(ssObj);
80682
+ ssObj2.ss = ' ';
80683
+ ssArray.push(ssObj2);
80105
80684
  }
80106
80685
 
80107
80686
  if(atom.ss == 'helix') {
@@ -80112,13 +80691,13 @@ class SaveFile {
80112
80691
  ssObj.ss = 'S';
80113
80692
  ssArray.push(ssObj);
80114
80693
  }
80115
-
80694
+ /*
80116
80695
  if(atom.ssend) {
80117
80696
  let ssObj2 = me.hashUtilsCls.cloneHash(ssObj);
80118
80697
  ssObj2.ss = ' ';
80119
80698
  ssArray.push(ssObj2);
80120
80699
  }
80121
-
80700
+ */
80122
80701
  prevResi = atom.resi;
80123
80702
  }
80124
80703
 
@@ -80126,9 +80705,9 @@ class SaveFile {
80126
80705
  for(let i = 0, il = ssArray.length; i < il; ++i) {
80127
80706
  let ssObj = ssArray[i];
80128
80707
 
80129
- if(ssObj.ss != prevSs || ssObj.ssbegin) {
80708
+ if(ssObj.ss != prevSs) {
80130
80709
  // print prev
80131
- stru2header[stru] += this.printPrevSecondary(bHelix, bSheet, prevRealSsObj, ssCnt);
80710
+ if(prevSs !== ' ') stru2header[stru] += this.printPrevSecondary(bHelix, bSheet, prevRealSsObj, ssCnt);
80132
80711
 
80133
80712
  // print current
80134
80713
  ssCnt = 0;
@@ -80136,7 +80715,7 @@ class SaveFile {
80136
80715
  bSheet = false;
80137
80716
  prevRealSsObj = undefined;
80138
80717
 
80139
- if(ssObj.ss != ' ') {
80718
+ if(ssObj.ss !== ' ') {
80140
80719
  if(ssObj.ss == 'H') {
80141
80720
  bHelix = true;
80142
80721
  prevRealSsObj = ssObj;
@@ -80152,7 +80731,7 @@ class SaveFile {
80152
80731
  }
80153
80732
  }
80154
80733
 
80155
- if(ssObj.ss != ' ') {
80734
+ if(ssObj.ss !== ' ') {
80156
80735
  ++ssCnt;
80157
80736
  prevRealSsObj = ssObj;
80158
80737
  }
@@ -80800,7 +81379,7 @@ class ShareLink {
80800
81379
  let shortName = strArray[strArray.length - 1];
80801
81380
  ic.saveFileCls.saveFile(inputid + '-' + shortName + '.png', 'png');
80802
81381
  let text = '<div style="float:left; border: solid 1px #0000ff; padding: 5px; margin: 10px; text-align:center;">';
80803
- text += '<a href="https://www.ncbi.nlm.nih.gov/Structure/icn3d/share.html?' + shortName + '" target="_blank">';
81382
+ text += '<a href="https://www.ncbi.nlm.nih.gov/Structure/icn3d/share2.html?' + shortName + '" target="_blank">';
80804
81383
  text += '<img style="height:300px" src ="' + inputid + '-' + shortName + '.png"><br>\n';
80805
81384
  text += '<!--Start of your comments==================-->\n';
80806
81385
  let yournote =(ic.yournote) ? ': ' + ic.yournote.replace(/\n/g, "<br>").replace(/; /g, ", ") : '';
@@ -80815,13 +81394,14 @@ class ShareLink {
80815
81394
  if(bPngHtml && data.shortLink === undefined) {
80816
81395
  ic.saveFileCls.saveFile(inputid + '_icn3d_loadable.png', 'png');
80817
81396
  }
80818
-
81397
+ /*
80819
81398
  //shorturl: https://icn3d.page.link/NvbAh1Vmiwc4bgX87
80820
81399
  let urlArray = shorturl.split('page.link/');
80821
- //if(urlArray.length == 2) shorturl = me.htmlCls.baseUrl + 'icn3d/share.html?' + urlArray[1];
80822
81400
  // When the baseURL is structure.ncbi.nlm.nih.gov, mmcifparser.cgi has a problem to pass posted data in Mac/iphone
80823
81401
  // So the base URL is still www.ncbi.nlm.nih.gov/Structure,just use short URL here
80824
81402
  if(urlArray.length == 2) shorturl = 'https://www.ncbi.nlm.nih.gov/Structure/icn3d/share.html?' + urlArray[1];
81403
+ */
81404
+ shorturl = 'https://www.ncbi.nlm.nih.gov/Structure/icn3d/share2.html?' + shorturl;
80825
81405
 
80826
81406
  $("#" + ic.pre + "short_url").val(shorturl);
80827
81407
  $("#" + ic.pre + "short_url_title").val(shorturl + '&t=' + ic.yournote);
@@ -80840,6 +81420,7 @@ class ShareLink {
80840
81420
  }
80841
81421
 
80842
81422
  getShareLinkPrms(url, bPngHtml) { let ic = this.icn3d, me = ic.icn3dui;
81423
+ /*
80843
81424
  //https://firebase.google.com/docs/dynamic-links/rest
80844
81425
  //Web API Key: AIzaSyBxl9CgM0dY5lagHL4UOhEpLWE1fuwdnvc
80845
81426
  let fdlUrl = "https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=AIzaSyBxl9CgM0dY5lagHL4UOhEpLWE1fuwdnvc";
@@ -80863,6 +81444,26 @@ class ShareLink {
80863
81444
  }
80864
81445
  });
80865
81446
  });
81447
+ */
81448
+
81449
+ let serviceUrl = "https://icn3d.link/?longurl=" + encodeURIComponent(url);
81450
+ return new Promise(function(resolve, reject) {
81451
+ $.ajax({
81452
+ url: serviceUrl,
81453
+ dataType: 'json',
81454
+ cache: true,
81455
+ success: function(data) {
81456
+ resolve(data);
81457
+ },
81458
+ error : function(xhr, textStatus, errorThrown ) {
81459
+ let shorturl = 'Problem in getting shortened URL';
81460
+ $("#" + ic.pre + "ori_url").val(url);
81461
+ $("#" + ic.pre + "short_url").val(shorturl);
81462
+ $("#" + ic.pre + "short_url_title").val(shorturl + '&t=' + ic.yournote);
81463
+ if(!bPngHtml) me.htmlCls.dialogCls.openDlg('dl_copyurl', 'Copy a Share Link URL');
81464
+ }
81465
+ });
81466
+ });
80866
81467
  }
80867
81468
 
80868
81469
  shareLinkUrl(bAllCommands, bOutputCmd, bStatefile) { let ic = this.icn3d, me = ic.icn3dui;
@@ -80889,6 +81490,7 @@ class ShareLink {
80889
81490
  if(key === 'height' && value === '100%') continue;
80890
81491
 
80891
81492
  if(key === 'resize' && value === true) continue;
81493
+ if(key === 'showlogo' && value === true) continue;
80892
81494
  if(key === 'showmenu' && value === true) continue;
80893
81495
  if(key === 'showtitle' && value === true) continue;
80894
81496
  if(key === 'showcommand' && value === true) continue;
@@ -82001,8 +82603,10 @@ class Ray {
82001
82603
  this.icn3d = icn3d;
82002
82604
  }
82003
82605
 
82004
- rayCaster(e, bClick) {
82606
+ rayCaster(e, bClick) { let ic = this.icn3d; ic.icn3dui;
82607
+ if(!ic.opts || ic.opts['effect'] == 'none') {
82005
82608
  this.rayCasterBase(e, bClick);
82609
+ }
82006
82610
  }
82007
82611
 
82008
82612
  rayCasterBase(e, bClick) { let ic = this.icn3d; ic.icn3dui;
@@ -83323,6 +83927,14 @@ class iCn3D {
83323
83927
  });
83324
83928
  }
83325
83929
 
83930
+ this.effects = {
83931
+ //'anaglyph': new THREE.AnaglyphEffect(this.renderer),
83932
+ //'parallax barrier': new THREE.ParallaxBarrierEffect(this.renderer),
83933
+ //'oculus rift': new THREE.OculusRiftEffect(this.renderer),
83934
+ 'stereo': new THREE.StereoEffect(this.renderer),
83935
+ 'none': this.renderer
83936
+ };
83937
+
83326
83938
  this.overdraw = 0;
83327
83939
  }
83328
83940
  else {
@@ -83469,14 +84081,6 @@ class iCn3D {
83469
84081
 
83470
84082
  this.bExtrude = true;
83471
84083
 
83472
- this.effects = {
83473
- //'anaglyph': new THREE.AnaglyphEffect(this.renderer),
83474
- //'parallax barrier': new THREE.ParallaxBarrierEffect(this.renderer),
83475
- //'oculus rift': new THREE.OculusRiftEffect(this.renderer),
83476
- //'stereo': new THREE.StereoEffect(this.renderer),
83477
- 'none': this.renderer
83478
- };
83479
-
83480
84084
  this.maxD = 500; // size of the molecule
83481
84085
  this.oriMaxD = this.maxD; // size of the molecule
83482
84086
  //this.cam_z = -150;
@@ -83529,6 +84133,7 @@ class iCn3D {
83529
84133
  //The default display options
83530
84134
  this.optsOri = {};
83531
84135
  this.optsOri['camera'] = 'perspective'; //perspective, orthographic
84136
+ this.optsOri['effect'] = 'none'; //stereo, none
83532
84137
  this.optsOri['background'] = 'black'; //transparent, black, grey, white
83533
84138
  this.optsOri['color'] = 'chain'; //spectrum, secondary structure, charge, hydrophobic, conserved, chain, residue, atom, b factor, red, green, blue, magenta, yellow, cyan, white, grey, custom, ig strand
83534
84139
  this.optsOri['proteins'] = 'ribbon'; //ribbon, strand, cylinder and plate, schematic, c alpha trace, backbone, b factor tube, lines, stick, ball and stick, sphere, nothing
@@ -83722,6 +84327,7 @@ class iCn3D {
83722
84327
  this.pdbParserCls = new PdbParser(this);
83723
84328
  this.sdfParserCls = new SdfParser(this);
83724
84329
  this.xyzParserCls = new XyzParser(this);
84330
+ this.msaParserCls = new MsaParser(this);
83725
84331
  this.realignParserCls = new RealignParser(this);
83726
84332
  this.densityCifParserCls = new DensityCifParser(this);
83727
84333
  this.ParserUtilsCls = new ParserUtils(this);
@@ -83978,7 +84584,7 @@ class iCn3DUI {
83978
84584
  //even when multiple iCn3D viewers are shown together.
83979
84585
  this.pre = this.cfg.divid + "_";
83980
84586
 
83981
- this.REVISION = '3.41.0';
84587
+ this.REVISION = '3.43.0';
83982
84588
 
83983
84589
  // In nodejs, iCn3D defines "window = {navigator: {}}"
83984
84590
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -83987,6 +84593,7 @@ class iCn3DUI {
83987
84593
  if(this.cfg.width === undefined) this.cfg.width = '100%';
83988
84594
  if(this.cfg.height === undefined) this.cfg.height = '100%';
83989
84595
  if(this.cfg.resize === undefined) this.cfg.resize = true;
84596
+ if(this.cfg.showlogo === undefined) this.cfg.showlogo = true;
83990
84597
  if(this.cfg.showmenu === undefined) this.cfg.showmenu = true;
83991
84598
  if(this.cfg.showtitle === undefined) this.cfg.showtitle = true;
83992
84599
  if(this.cfg.showcommand === undefined) this.cfg.showcommand = true;
@@ -84407,8 +85014,12 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
84407
85014
  }
84408
85015
  else if(me.cfg.align !== undefined) {
84409
85016
  // ic.bNCBI = true;
84410
-
85017
+ if(me.cfg.align.indexOf('185055,') != -1) {
85018
+ me.cfg.align = me.cfg.align.replace('185055,', '199731,'); //the mmdbid of PDB 6M17 was changed from 185055 to 199731
85019
+ }
85020
+
84411
85021
  let alignArray = me.cfg.align.split(','); // e.g., 6 IDs: 103701,1,4,68563,1,167 [mmdbid1,biounit,molecule,mmdbid2,biounit,molecule], or 2IDs: 103701,68563 [mmdbid1,mmdbid2]
85022
+
84412
85023
  if(alignArray.length === 6) {
84413
85024
  ic.inputid = alignArray[0] + "_" + alignArray[3];
84414
85025
  }
@@ -84729,4 +85340,4 @@ class printMsg {
84729
85340
  }
84730
85341
  }
84731
85342
 
84732
- export { ARButton, AddTrack, AlignParser, AlignSW, AlignSeq, Alternate, Analysis, AnnoCddSite, AnnoContact, AnnoCrossLink, AnnoDomain, AnnoSnpClinVar, AnnoSsbond, AnnoTransMem, Annotation, ApplyCenter, ApplyClbonds, ApplyCommand, ApplyDisplay, ApplyMap, ApplyOther, ApplySsbonds, ApplySymd, Axes, Box, Brick, Camera, CartoonNucl, ChainalignParser, ClickMenu, Contact, Control, ConvertTypeCls, Curve, CurveStripArrow, Cylinder, DefinedSets, Delphi, DensityCifParser, Diagram2d, Dialog, Domain3d, Draw, DrawGraph, Dsn6Parser, Dssp, ElectronMap, Events, Export3D, FirstAtomObj, Fog, GetGraph, Glycan, HBond, HashUtilsCls, HlObjects, HlSeq, HlUpdate, Html, Impostor, Instancing, Label, Line$1 as Line, LineGraph, LoadAtomData, LoadCIF, LoadPDB, LoadScript, MarchingCube, MmcifParser, MmdbParser, Mol2Parser, MyEventCls, OpmParser, ParasCls, ParserUtils, PdbParser, PiHalogen, Picking, ProteinSurface, Ray, RealignParser, Refnum, ReprSub, Resid2spec, ResidueLabels, ResizeCanvas, RmsdSuprCls, Saltbridge, SaveFile, Scap, Scene, SdfParser, SelectByCommand, Selection, SetColor, SetDialog, SetHtml, SetMenu, SetOption, SetSeqAlign, SetStyle, ShareLink, ShowAnno, ShowInter, ShowSeq, Sphere$1 as Sphere, Stick, Strand, Strip, SubdivideCls, Surface, Symd, ThreeDPrint, Transform, Tube, UtilsCls, VRButton, Vastplus, ViewInterPairs, XyzParser, iCn3D, iCn3DUI, printMsg };
85343
+ export { ARButton, AddTrack, AlignParser, AlignSW, AlignSeq, Alternate, Analysis, AnnoCddSite, AnnoContact, AnnoCrossLink, AnnoDomain, AnnoSnpClinVar, AnnoSsbond, AnnoTransMem, Annotation, ApplyCenter, ApplyClbonds, ApplyCommand, ApplyDisplay, ApplyMap, ApplyOther, ApplySsbonds, ApplySymd, Axes, Box, Brick, Camera, CartoonNucl, ChainalignParser, ClickMenu, Contact, Control, ConvertTypeCls, Curve, CurveStripArrow, Cylinder, DefinedSets, Delphi, DensityCifParser, Diagram2d, Dialog, Domain3d, Draw, DrawGraph, Dsn6Parser, Dssp, ElectronMap, Events, Export3D, FirstAtomObj, Fog, GetGraph, Glycan, HBond, HashUtilsCls, HlObjects, HlSeq, HlUpdate, Html, Impostor, Instancing, Label, Line$1 as Line, LineGraph, LoadAtomData, LoadCIF, LoadPDB, LoadScript, MarchingCube, MmcifParser, MmdbParser, Mol2Parser, MsaParser, MyEventCls, OpmParser, ParasCls, ParserUtils, PdbParser, PiHalogen, Picking, ProteinSurface, Ray, RealignParser, Refnum, ReprSub, Resid2spec, ResidueLabels, ResizeCanvas, RmsdSuprCls, Saltbridge, SaveFile, Scap, Scene, SdfParser, SelectByCommand, Selection, SetColor, SetDialog, SetHtml, SetMenu, SetOption, SetSeqAlign, SetStyle, ShareLink, ShowAnno, ShowInter, ShowSeq, Sphere$1 as Sphere, Stick, Strand, Strip, SubdivideCls, Surface, Symd, ThreeDPrint, Transform, Tube, UtilsCls, VRButton, Vastplus, ViewInterPairs, XyzParser, iCn3D, iCn3DUI, printMsg };