Subversion Repositories wimsdev

Rev

Rev 17 | Rev 2876 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1365 bpr 1
/* Jmol 11.7 script library Jmol.js  15:32 06.12.2008 Bob Hanson
2
 
3
 checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm
4
 
5
    based on:
6
 *
7
 * Copyright (C) 2004-2005  Miguel, Jmol Development, www.jmol.org
8
 *
9
 * Contact: hansonr@stolaf.edu
10
 *
11
 *  This library is free software; you can redistribute it and/or
12
 *  modify it under the terms of the GNU Lesser General Public
13
 *  License as published by the Free Software Foundation; either
14
 *  version 2.1 of the License, or (at your option) any later version.
15
 *
16
 *  This library is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
 *  Lesser General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU Lesser General Public
22
 *  License along with this library; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24
 *  02111-1307  USA.
25
 */
26
 
27
// for documentation see www.jmol.org/jslibrary
28
 
29
try{if(typeof(_jmol)!="undefined")exit()
30
 
31
// place "?NOAPPLET" on your command line to check applet control action with a textarea
32
// place "?JMOLJAR=xxxxx" to use a specific jar file
33
 
34
// bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)
35
// bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007
36
// bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007
37
// bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007
38
// bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006
39
// bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006
40
// bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006
41
// bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006
42
// bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.
43
// bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006
44
// bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006
45
// bob hanson -- fix for iframes not available for finding applet
46
// bob hanson -- added applet fake ?NOAPPLET URL flag
47
// bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006
48
//                      used PRIOR to jmolApplet() or jmolAppletInline()
49
//               added 4th array element in jmolRadioGroup -- title
50
//               added <span> and id around link, checkbox, radio, menu
51
//               fixing AJAX loads for MSIE/Opera-Mozilla incompatibility
52
//            -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar
53
//               renamed Jmol.js for Jmol 11 distribution
54
//            -- modified jmolRestoreOrientation() to be immediate, no 1-second delay
55
// bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006
56
// bh         -- jmolCommandInput()
57
// bh         -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues
58
// bh         -- minor fixes suggested by Angel
59
// bh         -- adds jmolSetSyncId() and jmolGetSyncId()
60
// bh 3/2008  -- adds jmolAppendInlineScript() and jmolAppendInlineArray()
61
// bh 3/2008  -- fixes IE7 bug in relation to jmolLoadInlineArray()
62
// bh 6/2008  -- adds jmolSetAppletWindow()
63
// Angel H. 6/2008  -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]
64
// bh 7/2008  -- code fix "for(i..." not "for(var i..."
65
// bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)
66
// bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console
67
 
68
var defaultdir = "."
69
var defaultjar = "JmolApplet.jar"
70
 
71
 
72
// Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr@stolaf.edu:
73
 
74
// JMOLJAR=xxxxx.jar on the URL for this page will override
75
// the JAR file specified in the jmolInitialize() call.
76
 
77
// The idea is that it can be very useful to test a web page with different JAR files
78
// Or for an expert user to substitute a signed applet for an unsigned one
79
// so as to use a broader range of models or to create JPEG files, for example.
80
 
81
// If the JAR file is not in the current directory (has any sort of "/" in its name)
82
// then the user is presented with a warning and asked whether it is OK to change Jar files.
83
// The default action, if the user just presses "OK" is to NOT allow the change. 
84
// The user must type the word "yes" in the prompt box for the change to be approved.
85
 
86
// If you don't want people to be able to switch in their own JAR file on your page,
87
// simply set this next line to read "var allowJMOLJAR = false".
88
 
89
 
90
var allowJMOLJAR = true  
91
 
92
 
93
var undefined; // for IE 5 ... wherein undefined is undefined
94
 
95
////////////////////////////////////////////////////////////////
96
// Basic Scripting infrastruture
97
////////////////////////////////////////////////////////////////
98
 
99
function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {
100
  if (_jmol.initialized)
101
    return;
102
  _jmol.initialized = true;
103
  if(allowJMOLJAR && document.location.search.indexOf("JMOLJAR=")>=0) {
104
    var f = document.location.search.split("JMOLJAR=")[1].split("&")[0];
105
    if (f.indexOf("/") >= 0) {
106
      alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.")
107
      var ok = prompt("Do you want to use applet " + f + "? ","yes or no")
108
      if (ok == "yes") {
109
        codebaseDirectory = f.substring(0, f.lastIndexOf("/"));
110
        fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);
111
      } else {
112
        _jmolGetJarFilename(fileNameOrUseSignedApplet);
113
        alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');
114
      }
115
    } else {
116
      fileNameOrUseSignedApplet = f;
117
    }
118
  }
119
  _jmolSetCodebase(codebaseDirectory);
120
  _jmolGetJarFilename(fileNameOrUseSignedApplet);
121
  _jmolOnloadResetForms();
122
}
123
 
124
function jmolSetTranslation(TF) {
125
  _jmol.params.doTranslate = ''+TF;
126
}
127
 
128
function _jmolGetJarFilename(fileNameOrFlag) {
129
  _jmol.archivePath =
130
    (typeof(fileNameOrFlag) == "string"  ? fileNameOrFlag : (fileNameOrFlag ?  "JmolAppletSigned" : "JmolApplet") + "0.jar");
131
}
132
 
133
function jmolSetDocument(doc) {
134
  _jmol.currentDocument = doc;
135
}
136
 
137
function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {
138
  _jmolInitCheck();
139
  _jmol.params.boxbgcolor = boxbgcolor;
140
  if (boxfgcolor)
141
    _jmol.params.boxfgcolor = boxfgcolor
142
  else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")
143
    _jmol.params.boxfgcolor = "black";
144
  else
145
    _jmol.params.boxfgcolor = "white";
146
  if (progresscolor)
147
    _jmol.params.progresscolor = progresscolor;
148
  if (_jmol.debugAlert)
149
    alert(" boxbgcolor=" + _jmol.params.boxbgcolor +
150
          " boxfgcolor=" + _jmol.params.boxfgcolor +
151
          " progresscolor=" + _jmol.params.progresscolor);
152
}
153
 
154
function jmolSetAppletWindow(w) {
155
  _jmol.appletWindow = w;
156
}
157
 
158
function jmolApplet(size, script, nameSuffix) {
159
  _jmolInitCheck();
160
  return _jmolApplet(size, null, script, nameSuffix);
161
}
162
 
163
////////////////////////////////////////////////////////////////
164
// Basic controls
165
////////////////////////////////////////////////////////////////
166
 
167
function jmolButton(script, label, id, title) {
168
  _jmolInitCheck();
169
  if (id == undefined || id == null)
170
    id = "jmolButton" + _jmol.buttonCount;
171
  if (label == undefined || label == null)
172
    label = script.substring(0, 32);
173
  ++_jmol.buttonCount;
174
  var scriptIndex = _jmolAddScript(script);
175
  var t = "<span id=\"span_"+id+"\""+(title ? " title =\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +
176
          "' value='" + label +
177
          "' onClick='_jmolClick(" + scriptIndex + _jmol.targetText +
178
          ")' onMouseover='_jmolMouseOver(" + scriptIndex +
179
          ");return true' onMouseout='_jmolMouseOut()' " +
180
          _jmol.buttonCssText + "/></span>";
181
  if (_jmol.debugAlert)
182
    alert(t);
183
  return _jmolDocumentWrite(t);
184
}
185
 
186
function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,
187
                      labelHtml, isChecked, id, title) {
188
  _jmolInitCheck();
189
  if (id == undefined || id == null)
190
    id = "jmolCheckbox" + _jmol.checkboxCount;
191
  ++_jmol.checkboxCount;
192
  if (scriptWhenChecked == undefined || scriptWhenChecked == null ||
193
      scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {
194
    alert("jmolCheckbox requires two scripts");
195
    return;
196
  }
197
  if (labelHtml == undefined || labelHtml == null) {
198
    alert("jmolCheckbox requires a label");
199
    return;
200
  }
201
  var indexChecked = _jmolAddScript(scriptWhenChecked);
202
  var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);
203
  var eospan = "</span>"
204
  var t = "<span id=\"span_"+id+"\""+(title ? " title =\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +
205
          "' onClick='_jmolCbClick(this," +
206
          indexChecked + "," + indexUnchecked + _jmol.targetText +
207
          ")' onMouseover='_jmolCbOver(this," + indexChecked + "," +
208
          indexUnchecked +
209
          ");return true' onMouseout='_jmolMouseOut()' " +
210
          (isChecked ? "checked " : "") + _jmol.checkboxCssText + "/>"
211
  if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
212
        t += eospan
213
        eospan = "";
214
  }
215
  t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;
216
  if (_jmol.debugAlert)
217
    alert(t);
218
  return _jmolDocumentWrite(t);
219
}
220
 
221
function jmolStartNewRadioGroup() {
222
  ++_jmol.radioGroupCount;
223
}
224
 
225
function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {
226
  /*
227
 
228
    array: [radio1,radio2,radio3...]
229
    where radioN = ["script","label",isSelected,"id","title"]
230
 
231
  */
232
 
233
  _jmolInitCheck();
234
  var type = typeof arrayOfRadioButtons;
235
  if (type != "object" || type == null || ! arrayOfRadioButtons.length) {
236
    alert("invalid arrayOfRadioButtons");
237
    return;
238
  }
239
  if (separatorHtml == undefined || separatorHtml == null)
240
    separatorHtml = "&nbsp; ";
241
  var len = arrayOfRadioButtons.length;
242
  jmolStartNewRadioGroup();
243
  if (!groupName)
244
    groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1);
245
  var t = "<span id='"+(id ? id : groupName)+"'>";
246
  for (var i = 0; i < len; ++i) {
247
    if (i == len - 1)
248
      separatorHtml = "";
249
    var radio = arrayOfRadioButtons[i];
250
    type = typeof radio;
251
    if (type == "object") {
252
      t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);
253
    } else {
254
      t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);
255
    }
256
  }
257
  t+="</span>"
258
  if (_jmol.debugAlert)
259
    alert(t);
260
  return _jmolDocumentWrite(t);
261
}
262
 
263
 
264
function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
265
  _jmolInitCheck();
266
  if (_jmol.radioGroupCount == 0)
267
    ++_jmol.radioGroupCount;
268
  var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);
269
  if (_jmol.debugAlert)
270
    alert(t);
271
  return _jmolDocumentWrite(t);
272
}
273
 
274
function jmolLink(script, label, id, title) {
275
  _jmolInitCheck();
276
  if (id == undefined || id == null)
277
    id = "jmolLink" + _jmol.linkCount;
278
  if (label == undefined || label == null)
279
    label = script.substring(0, 32);
280
  ++_jmol.linkCount;
281
  var scriptIndex = _jmolAddScript(script);
282
  var t = "<span id=\"span_"+id+"\""+(title ? " title =\"" + title + "\"":"")+"><a name='" + id + "' id='" + id +
283
          "' href='javascript:_jmolClick(" + scriptIndex + _jmol.targetText + ");' onMouseover='_jmolMouseOver(" + scriptIndex +
284
          ");return true;' onMouseout='_jmolMouseOut()' " +
285
          _jmol.linkCssText + ">" + label + "</a></span>";
286
  if (_jmol.debugAlert)
287
    alert(t);
288
  return _jmolDocumentWrite(t);
289
}
290
 
291
function jmolCommandInput(label, size, id, title) {
292
  _jmolInitCheck();
293
  if (id == undefined || id == null)
294
    id = "jmolCmd" + _jmol.cmdCount;
295
  if (label == undefined || label == null)
296
    label = "Execute";
297
  if (size == undefined || isNaN(size))
298
    size = 60;
299
  ++_jmol.cmdCount;
300
  var t = "<span id=\"span_"+id+"\""+(title ? " title =\"" + title + "\"":"")+"><input name='" + id + "' id='" + id +
301
          "' size='"+size+"'><input type=button value = '"+label+"' onClick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")'/></span>";
302
  if (_jmol.debugAlert)
303
    alert(t);
304
  return _jmolDocumentWrite(t);
305
}
306
 
307
function jmolMenu(arrayOfMenuItems, size, id, title) {
308
  _jmolInitCheck();
309
  if (id == undefined || id == null)
310
    id = "jmolMenu" + _jmol.menuCount;
311
  ++_jmol.menuCount;
312
  var type = typeof arrayOfMenuItems;
313
  if (type != null && type == "object" && arrayOfMenuItems.length) {
314
    var len = arrayOfMenuItems.length;
315
    if (typeof size != "number" || size == 1)
316
      size = null;
317
    else if (size < 0)
318
      size = len;
319
    var sizeText = size ? " size='" + size + "' " : "";
320
    var t = "<span id=\"span_"+id+"\""+(title ? " title =\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +
321
            "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +
322
            sizeText + _jmol.menuCssText + ">";
323
    for (var i = 0; i < len; ++i) {
324
      var menuItem = arrayOfMenuItems[i];
325
      type = typeof menuItem;
326
      var script, text;
327
      var isSelected = undefined;
328
      if (type == "object" && menuItem != null) {
329
        script = menuItem[0];
330
        text = menuItem[1];
331
        isSelected = menuItem[2];
332
      } else {
333
        script = text = menuItem;
334
      }
335
      if (text == undefined || text == null)
336
        text = script;         
337
          if (script=="#optgroup") {
338
        t += "<optgroup label='" + text + "'>";  
339
          } else if (script=="#optgroupEnd") {
340
        t += "</optgroup>";      
341
          } else {             
342
        var scriptIndex = _jmolAddScript(script);
343
        var selectedText = isSelected ? "' selected>" : "'>";
344
        t += "<option value='" + scriptIndex + selectedText + text + "</option>";
345
          }
346
    }
347
    t += "</select></span>";
348
    if (_jmol.debugAlert)
349
      alert(t);
350
    return _jmolDocumentWrite(t);
351
  }
352
}
353
 
354
function jmolHtml(html) {
355
  return _jmolDocumentWrite(html);
356
}
357
 
358
function jmolBr() {
359
  return _jmolDocumentWrite("<br />");
360
}
361
 
362
////////////////////////////////////////////////////////////////
363
// advanced scripting functions
364
////////////////////////////////////////////////////////////////
365
 
366
function jmolDebugAlert(enableAlerts) {
367
  _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)
368
}
369
 
370
function jmolAppletInline(size, inlineModel, script, nameSuffix) {
371
  _jmolInitCheck();
372
  return _jmolApplet(size, _jmolSterilizeInline(inlineModel),
373
                     script, nameSuffix);
374
}
375
 
376
function jmolSetTarget(targetSuffix) {
377
  _jmol.targetSuffix = targetSuffix;
378
  _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : "";
379
}
380
 
381
function jmolScript(script, targetSuffix) {
382
  if (script) {
383
    _jmolCheckBrowser();
384
    if (targetSuffix == "all") {
385
      with (_jmol) {
386
        for (var i = 0; i < appletSuffixes.length; ++i) {
387
          var applet = _jmolGetApplet(appletSuffixes[i]);
388
          if (applet) applet.script(script);
389
        }
390
      }
391
    } else {
392
      var applet=_jmolGetApplet(targetSuffix);
393
      if (applet) applet.script(script);
394
    }
395
  }
396
}
397
 
398
function jmolLoadInline(model, targetSuffix) {
399
  if (!model)return "ERROR: NO MODEL"
400
  var applet=_jmolGetApplet(targetSuffix);
401
  if (!applet)return "ERROR: NO APPLET"
402
  if (typeof(model) == "string")
403
    return applet.loadInlineString(model, "", false);
404
  else
405
    return applet.loadInlineArray(model, "", false);
406
}
407
 
408
 
409
function jmolLoadInlineScript(model, script, targetSuffix) {
410
  if (!model)return "ERROR: NO MODEL"
411
  var applet=_jmolGetApplet(targetSuffix);
412
  if (!applet)return "ERROR: NO APPLET"
413
  return applet.loadInlineString(model, script, false);
414
}
415
 
416
 
417
function jmolLoadInlineArray(ModelArray, script, targetSuffix) {
418
  if (!model)return "ERROR: NO MODEL"
419
  if (!script)script=""
420
  var applet=_jmolGetApplet(targetSuffix);
421
  if (!applet)return "ERROR: NO APPLET"
422
  try {
423
    return applet.loadInlineArray(ModelArray, script, false);
424
  } catch (err) {
425
    //IE 7 bug
426
    return applet.loadInlineString(ModelArray.join("\n"), script, false);
427
  }
428
}
429
 
430
function jmolAppendInlineArray(ModelArray, script, targetSuffix) {
431
  if (!model)return "ERROR: NO MODEL"
432
  if (!script)script=""
433
  var applet=_jmolGetApplet(targetSuffix);
434
  if (!applet)return "ERROR: NO APPLET"
435
  try {
436
    return applet.loadInlineArray(ModelArray, script, true);
437
  } catch (err) {
438
    //IE 7 bug
439
    return applet.loadInlineString(ModelArray.join("\n"), script, true);
440
  }
441
}
442
 
443
function jmolAppendInlineScript(model, script, targetSuffix) {
444
  if (!model)return "ERROR: NO MODEL"
445
  var applet=_jmolGetApplet(targetSuffix);
446
  if (!applet)return "ERROR: NO APPLET"
447
  return applet.loadInlineString(model, script, true);
448
}
449
 
450
function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {
451
  if (typeof action == "string") {
452
    action = action.toLowerCase();
453
    if (action != "alert" && action != "redirect" && action != "popup")
454
      action = null;
455
  }
456
  if (typeof action != "string")
457
    alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
458
          "action must be 'alert', 'redirect', or 'popup'");
459
  else {
460
    if (typeof urlOrMessage != "string")
461
      alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
462
            "urlOrMessage must be a string");
463
    else {
464
      _jmol.checkBrowserAction = action;
465
      _jmol.checkBrowserUrlOrMessage = urlOrMessage;
466
    }
467
  }
468
  if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")
469
    _jmolCheckBrowser();
470
}
471
 
472
////////////////////////////////////////////////////////////////
473
// Cascading Style Sheet Class support
474
////////////////////////////////////////////////////////////////
475
 
476
function jmolSetAppletCssClass(appletCssClass) {
477
  if (_jmol.hasGetElementById) {
478
    _jmol.appletCssClass = appletCssClass;
479
    _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";
480
  }
481
}
482
 
483
function jmolSetButtonCssClass(buttonCssClass) {
484
  if (_jmol.hasGetElementById) {
485
    _jmol.buttonCssClass = buttonCssClass;
486
    _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";
487
  }
488
}
489
 
490
function jmolSetCheckboxCssClass(checkboxCssClass) {
491
  if (_jmol.hasGetElementById) {
492
    _jmol.checkboxCssClass = checkboxCssClass;
493
    _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";
494
  }
495
}
496
 
497
function jmolSetRadioCssClass(radioCssClass) {
498
  if (_jmol.hasGetElementById) {
499
    _jmol.radioCssClass = radioCssClass;
500
    _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";
501
  }
502
}
503
 
504
function jmolSetLinkCssClass(linkCssClass) {
505
  if (_jmol.hasGetElementById) {
506
    _jmol.linkCssClass = linkCssClass;
507
    _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";
508
  }
509
}
510
 
511
function jmolSetMenuCssClass(menuCssClass) {
512
  if (_jmol.hasGetElementById) {
513
    _jmol.menuCssClass = menuCssClass;
514
    _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";
515
  }
516
}
517
 
518
////////////////////////////////////////////////////////////////
519
// functions for INTERNAL USE ONLY which are subject to change
520
// use at your own risk ... you have been WARNED!
521
////////////////////////////////////////////////////////////////
522
var _jmol = {
523
  currentDocument: document,
524
 
525
  debugAlert: false,
526
 
527
  codebase: "",
528
  modelbase: ".",
529
 
530
  appletCount: 0,
531
  appletSuffixes: [],
532
  appletWindow: null,
533
 
534
  buttonCount: 0,
535
  checkboxCount: 0,
536
  linkCount: 0,
537
  cmdCount: 0,
538
  menuCount: 0,
539
  radioCount: 0,
540
  radioGroupCount: 0,
541
 
542
  appletCssClass: null,
543
  appletCssText: "",
544
  buttonCssClass: null,
545
  buttonCssText: "",
546
  checkboxCssClass: null,
547
  checkboxCssText: "",
548
  radioCssClass: null,
549
  radioCssText: "",
550
  linkCssClass: null,
551
  linkCssText: "",
552
  menuCssClass: null,
553
  menuCssText: "",
554
 
555
  targetSuffix: 0,
556
  targetText: "",
557
  scripts: [""],
558
  params: {
559
        syncId: ("" + Math.random()).substring(3),
560
        progressbar: "true",
561
        progresscolor: "blue",
562
        boxbgcolor: "black",
563
        boxfgcolor: "white",
564
        boxmessage: "Downloading JmolApplet ..."
565
  },
566
  ua: navigator.userAgent.toLowerCase(),
567
  uaVersion: parseFloat(navigator.appVersion),
568
 
569
  os: "unknown",
570
  browser: "unknown",
571
  browserVersion: 0,
572
  hasGetElementById: !!document.getElementById,
573
  isJavaEnabled: navigator.javaEnabled(),
574
  isNetscape47Win: false,
575
  isIEWin: false,
576
  useIEObject: false,
577
  useHtml4Object: false,
578
 
579
  windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",
580
  windowsCabUrl:
581
   "http://java.sun.com/update/1.5.0/jinstall-1_5_0_05-windows-i586.cab",
582
 
583
  isBrowserCompliant: false,
584
  isJavaCompliant: false,
585
  isFullyCompliant: false,
586
 
587
  initialized: false,
588
  initChecked: false,
589
 
590
  browserChecked: false,
591
  checkBrowserAction: "alert",
592
  checkBrowserUrlOrMessage: null,
593
 
594
  archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar
595
 
596
  previousOnloadHandler: null,
597
  ready: {}
598
}
599
 
600
with (_jmol) {
601
  function _jmolTestUA(candidate) {
602
    var ua = _jmol.ua;
603
    var index = ua.indexOf(candidate);
604
    if (index < 0)
605
      return false;
606
    _jmol.browser = candidate;
607
    _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));
608
    return true;
609
  }
610
 
611
  function _jmolTestOS(candidate) {
612
    if (_jmol.ua.indexOf(candidate) < 0)
613
      return false;
614
    _jmol.os = candidate;
615
    return true;
616
  }
617
 
618
  _jmolTestUA("konqueror") ||
619
  _jmolTestUA("safari") ||
620
  _jmolTestUA("omniweb") ||
621
  _jmolTestUA("opera") ||
622
  _jmolTestUA("webtv") ||
623
  _jmolTestUA("icab") ||
624
  _jmolTestUA("msie") ||
625
  (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla"));
626
 
627
  _jmolTestOS("linux") ||
628
  _jmolTestOS("unix") ||
629
  _jmolTestOS("mac") ||
630
  _jmolTestOS("win");
631
 
632
  isNetscape47Win = (os == "win" && browser == "mozilla" &&
633
                     browserVersion >= 4.78 && browserVersion <= 4.8);
634
 
635
  if (os == "win") {
636
    isBrowserCompliant = hasGetElementById;
637
  } else if (os == "mac") { // mac is the problem child :-(
638
    if (browser == "mozilla" && browserVersion >= 5) {
639
      // miguel 2004 11 17
640
      // checking the plugins array does not work because
641
      // Netscape 7.2 OS X still has Java 1.3.1 listed even though
642
      // javaplugin.sf.net is installed to upgrade to 1.4.2
643
      eval("try {var v = java.lang.System.getProperty('java.version');" +
644
           " _jmol.isBrowserCompliant = v >= '1.4.2';" +
645
           " } catch (e) { }");
646
    } else if (browser == "opera" && browserVersion <= 7.54) {
647
      isBrowserCompliant = false;
648
    } else {
649
      isBrowserCompliant = hasGetElementById &&
650
        !((browser == "msie") ||
651
          (browser == "safari" && browserVersion < 125.12));
652
    }
653
  } else if (os == "linux" || os == "unix") {
654
    if (browser == "konqueror" && browserVersion <= 3.3)
655
      isBrowserCompliant = false;
656
    else
657
      isBrowserCompliant = hasGetElementById;
658
  } else { // other OS
659
    isBrowserCompliant = hasGetElementById;
660
  }
661
 
662
  // possibly more checks in the future for this
663
  isJavaCompliant = isJavaEnabled;
664
 
665
  isFullyCompliant = isBrowserCompliant && isJavaCompliant;
666
 
667
  // IE5.5 works just fine ... but let's push them to Sun Java
668
  isIEWin = (os == "win" && browser == "msie" && browserVersion >= 5.5);
669
  useIEObject = isIEWin;
670
  useHtml4Object =
671
   (os != "mac" && browser == "mozilla" && browserVersion >= 5) ||
672
   (os == "win" && browser == "opera" && browserVersion >= 8) ||
673
   (os == "mac" && browser == "safari" && browserVersion >= 412.2);
674
 
675
 doTranslate = true;
676
 haveSetTranslate = false;
677
}
678
 
679
 
680
function jmolSetCallback(callbackName,funcName) {
681
  _jmol.params[callbackName] = funcName
682
}
683
 
684
function jmolSetSyncId(n) {
685
  return _jmol.params["syncId"] = n
686
}
687
 
688
function jmolGetSyncId() {
689
  return _jmol.params["syncId"]
690
}
691
 
692
function jmolSetLogLevel(n) {
693
  _jmol.params.logLevel = ''+n;
694
}
695
 
696
        /*  AngelH, mar2007:
697
                By (re)setting these variables in the webpage before calling jmolApplet(),
698
                a custom message can be provided (e.g. localized for user's language) when no Java is installed.
699
        */
700
if (noJavaMsg==undefined) var noJavaMsg =
701
        "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +
702
        "Check the warning message from your browser and/or enable Java applets in<br />\n" +
703
        "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";
704
if (noJavaMsg2==undefined) var noJavaMsg2 =
705
        "You do not have the<br />\n" +
706
        "Java Runtime Environment<br />\n" +
707
        "installed for applet support.<br />\n" +
708
        "Visit <a href='http://www.java.com'>www.java.com</a>";
709
function _jmolApplet(size, inlineModel, script, nameSuffix) {
710
        /*  AngelH, mar2007
711
                Fixed percent / pixel business, to avoid browser errors:
712
                put "px" where needed, avoid where not.        
713
        */
714
  with (_jmol) {
715
    if (! nameSuffix)
716
      nameSuffix = appletCount;
717
    appletSuffixes.push(nameSuffix);
718
    ++appletCount;
719
    if (! script)
720
      script = "select *";
721
    var sz = _jmolGetAppletSize(size);
722
    var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";
723
    var tHeader, tFooter;
724
    if (!codebase)
725
        jmolInitialize(".");
726
    if (useIEObject || useHtml4Object) {
727
      params.name = 'jmolApplet' + nameSuffix;
728
      params.archive = archivePath;
729
      params.mayscript = 'true';
730
      params.codebase = codebase;
731
    }
732
    if (useIEObject) { // use MSFT IE6 object tag with .cab file reference
733
      winCodebase = (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "");
734
      params.code = 'JmolApplet';
735
      tHeader =
736
        "<object name='jmolApplet" + nameSuffix +
737
        "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
738
        " classid='" + windowsClassId + "'\n" + winCodebase + widthAndHeight + ">\n";
739
      tFooter = "</object>";
740
    } else if (useHtml4Object) { // use HTML4 object tag
741
      tHeader =
742
        "<object name='jmolApplet" + nameSuffix +
743
        "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
744
        " classid='java:JmolApplet'\n" +
745
        " type='application/x-java-applet'\n" +
746
        widthAndHeight + ">\n";
747
      tFooter = "</object>";
748
    } else { // use applet tag
749
      tHeader =
750
        "<applet name='jmolApplet" + nameSuffix +
751
        "' id='jmolApplet" + nameSuffix +
752
        "' " + appletCssText +
753
        " code='JmolApplet'" +
754
        " archive='" + archivePath + "' codebase='" + codebase + "'\n" +
755
                widthAndHeight +
756
        " mayscript='true'>\n";
757
      tFooter = "</applet>";
758
    }
759
    var visitJava;
760
    if (isIEWin || useHtml4Object) {
761
                var szX = "width:" + sz[0]
762
                if ( szX.indexOf("%")==-1 ) szX+="px"
763
                var szY = "height:" + sz[1]
764
                if ( szY.indexOf("%")==-1 ) szY+="px"
765
      visitJava =
766
        "<p style='background-color:yellow; color:black; " +
767
                szX + ";" + szY + ";" +
768
        // why doesn't this vertical-align work?
769
        "text-align:center;vertical-align:middle;'>\n" +
770
                noJavaMsg +
771
        "</p>";
772
    } else {
773
      visitJava =
774
        "<table bgcolor='yellow'><tr>" +
775
        "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +
776
                noJavaMsg2 +
777
        "</font></td></tr></table>";
778
    }
779
    params.loadInline = (inlineModel ? inlineModel : "");
780
    params.script = (script ? _jmolSterilizeScript(script) : "");
781
    var t = tHeader + _jmolParams() + visitJava + tFooter;
782
    jmolSetTarget(nameSuffix);
783
    ready["jmolApplet" + nameSuffix] = false;
784
    if (_jmol.debugAlert)
785
      alert(t);
786
    return _jmolDocumentWrite(t);
787
  }
788
}
789
 
790
function _jmolParams() {
791
 var t = "";
792
 for (i in _jmol.params)
793
        if(_jmol.params[i]!="")
794
                 t+="  <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";
795
 return t
796
}
797
 
798
function _jmolInitCheck() {
799
  if (_jmol.initChecked)
800
    return;
801
  _jmol.initChecked = true;
802
  jmolInitialize(defaultdir, defaultjar)
803
}
804
 
805
function _jmolCheckBrowser() {
806
  with (_jmol) {
807
    if (browserChecked)
808
      return;
809
    browserChecked = true;
810
 
811
    if (isFullyCompliant)
812
      return true;
813
 
814
    if (checkBrowserAction == "redirect")
815
      location.href = checkBrowserUrlOrMessage;
816
    else if (checkBrowserAction == "popup")
817
      _jmolPopup(checkBrowserUrlOrMessage);
818
    else {
819
      var msg = checkBrowserUrlOrMessage;
820
      if (msg == null)
821
        msg = "Your web browser is not fully compatible with Jmol\n\n" +
822
              "browser: " + browser +
823
              "   version: " + browserVersion +
824
              "   os: " + os +
825
              "\n\n" + ua;
826
      alert(msg);
827
    }
828
  }
829
  return false;
830
}
831
 
832
function _jmolDocumentWrite(text) {
833
  if (_jmol.currentDocument)
834
    _jmol.currentDocument.write(text);
835
  return text;
836
}
837
 
838
function _jmolPopup(url) {
839
  var popup = window.open(url, "JmolPopup",
840
                          "left=150,top=150,height=400,width=600," +
841
                          "directories=yes,location=yes,menubar=yes," +
842
                          "toolbar=yes," +
843
                          "resizable=yes,scrollbars=yes,status=yes");
844
  if (popup.focus)
845
    poup.focus();
846
}
847
 
848
function _jmolReadyCallback(name) {
849
  if (_jmol.debugAlert)
850
    alert(name + " is ready");
851
  _jmol.ready["" + name] = true;
852
}
853
 
854
function _jmolSterilizeScript(script) {
855
  var inlineScript = script.replace(/'/g, "&#39;");
856
  if (_jmol.debugAlert)
857
    alert("script:\n" + inlineScript);
858
  return inlineScript;
859
}
860
 
861
function _jmolSterilizeInline(model) {
862
  var inlineModel =
863
    model.replace(/\r|\n|\r\n/g, "|").replace(/'/g, "&#39;");
864
  if (_jmol.debugAlert)
865
    alert("inline model:\n" + inlineModel);
866
  return inlineModel;
867
}
868
 
869
        /*  AngelH, mar2007:
870
                By (re)setting this variable in the webpage before calling jmolApplet(), limits for applet size can be overriden.
871
        */
872
 
873
        /* hansonr, jun2007:
874
                2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)
875
        */
876
 
877
if (allowedJmolSize==undefined) var allowedJmolSize = [1, 2048, 300]   // min, max, default (pixels)
878
function _jmolGetAppletSize(size) {
879
        /*  AngelH, mar2007
880
                Accepts single number or 2-value array, each one can be either:
881
           percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)
882
           Size is now returned as string or number, no "px".
883
        */
884
  var width, height;
885
  if ( (typeof size) == "object" && size != null ) {
886
    width = size[0]; height = size[1];
887
  } else {
888
    width = height = size;
889
  }
890
  // if percent, leave it as it is:
891
  if ( width.toString().charAt(width.toString().length-1) != "%" ) {
892
    width = parseFloat(width);  // convert to nr., or strip text, or make zero
893
        if ( width <= 1 && width > 0 ) { width = (width*100)+"%" }      // decimal: convert to percent and quit
894
        else if ( width >= allowedJmolSize[0] && width <= allowedJmolSize[1] ) { width = parseInt(width) }      // accept only that range (pixels)
895
        else { width = allowedJmolSize[2] }     // default size 300 pixels
896
  }
897
  if ( height.toString().charAt(height.toString().length-1) != "%" ) {
898
    height = parseFloat(height);
899
        if ( height <= 1 && height > 0 ) { height = (height*100)+"%" }
900
        else if ( height >= allowedJmolSize[0] && height <= allowedJmolSize[1] ) { height = parseInt(height) }
901
        else { height = allowedJmolSize[2] }
902
  }
903
  return [width, height];
904
}
905
 
906
function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
907
  ++_jmol.radioCount;
908
  if (groupName == undefined || groupName == null)
909
    groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1);
910
  if (!script)
911
    return "";
912
  if (labelHtml == undefined || labelHtml == null)
913
    labelHtml = script.substring(0, 32);
914
  if (! separatorHtml)
915
    separatorHtml = "";
916
  var scriptIndex = _jmolAddScript(script);
917
  var eospan = "</span>"
918
  var t = "<span id=\"span_"+id+"\""+(title ? " title =\"" + title + "\"":"")+"><input name='"
919
        + groupName + "' id='"+id+"' type='radio' onClick='_jmolClick(" +
920
         scriptIndex + _jmol.targetText + ");return true;' onMouseover='_jmolMouseOver(" +
921
         scriptIndex + ");return true;' onMouseout='_jmolMouseOut()' " +
922
         (isChecked ? "checked " : "") + _jmol.radioCssText + "/>"
923
  if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
924
        t += eospan
925
        eospan = "";
926
  }
927
  t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;
928
 
929
  return t;
930
}
931
 
932
function _jmolFindApplet(target) {
933
  // first look for the target in the current window
934
  var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);
935
  // THEN look for the target in child frames
936
  if (applet == undefined)
937
    applet = _jmolSearchFrames(window, target);
938
  // FINALLY look for the target in sibling frames
939
  if (applet == undefined)
940
    applet = _jmolSearchFrames(top, target); // look starting in top frame
941
  return applet;
942
}
943
 
944
function _jmolGetApplet(targetSuffix){
945
 var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
946
 var applet = _jmolFindApplet(target);
947
 if (applet) return applet
948
 if(!_jmol.alerted)alert("could not find applet " + target);
949
 _jmol.alerted = true;
950
 return null
951
}
952
 
953
function _jmolSearchFrames(win, target) {
954
  var applet;
955
  var frames = win.frames;
956
  if (frames && frames.length) { // look in all the frames below this window
957
   try{
958
    for (var i = 0; i < frames.length; ++i) {
959
      applet = _jmolSearchFrames(frames[i], target);
960
      if (applet)
961
        return applet;
962
    }
963
   }catch(e) {
964
        if (_jmol.debugAlert)
965
                alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()")
966
   }
967
  }
968
  return applet = _jmolFindAppletInWindow(win, target)
969
}
970
 
971
function _jmolFindAppletInWindow(win, target) {
972
    var doc = win.document;
973
    // getElementById fails on MacOSX Safari & Mozilla  
974
    if (_jmol.useHtml4Object || _jmol.useIEObject)
975
      return doc.getElementById(target);
976
    else if (doc.applets)
977
      return doc.applets[target];
978
    else
979
      return doc[target];
980
}
981
 
982
function _jmolAddScript(script) {
983
  if (! script)
984
    return 0;
985
  var index = _jmol.scripts.length;
986
  _jmol.scripts[index] = script;
987
  return index;
988
}
989
 
990
function _jmolClick(scriptIndex, targetSuffix, elementClicked) {
991
  _jmol.element = elementClicked;
992
  jmolScript(_jmol.scripts[scriptIndex], targetSuffix);
993
}
994
 
995
function _jmolMenuSelected(menuObject, targetSuffix) {
996
  var scriptIndex = menuObject.value;
997
  if (scriptIndex != undefined) {
998
    jmolScript(_jmol.scripts[scriptIndex], targetSuffix);
999
    return;
1000
  }
1001
  var len = menuObject.length;
1002
  if (typeof len == "number") {
1003
    for (var i = 0; i < len; ++i) {
1004
      if (menuObject[i].selected) {
1005
        _jmolClick(menuObject[i].value, targetSuffix);
1006
        return;
1007
      }
1008
    }
1009
  }
1010
  alert("?Que? menu selected bug #8734");
1011
}
1012
 
1013
 
1014
_jmol.checkboxMasters = {};
1015
_jmol.checkboxItems = {};
1016
 
1017
function jmolSetCheckboxGroup(chkMaster,chkBox) {
1018
        var id = chkMaster;
1019
        if(typeof(id)=="number")id = "jmolCheckbox" + id;
1020
        chkMaster = document.getElementById(id);
1021
        if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);
1022
        var m = _jmol.checkboxMasters[id] = {};
1023
        m.chkMaster = chkMaster;
1024
        m.chkGroup = {};
1025
        for (var i = 1; i < arguments.length; i++){
1026
                var id = arguments[i];
1027
                if(typeof(id)=="number")id = "jmolCheckbox" + id;
1028
                checkboxItem = document.getElementById(id);
1029
                if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);
1030
                m.chkGroup[id] = checkboxItem;
1031
                _jmol.checkboxItems[id] = m;
1032
        }
1033
}
1034
 
1035
function _jmolNotifyMaster(m){
1036
        //called when a group item is checked
1037
        var allOn = true;
1038
        var allOff = true;
1039
        for (var chkBox in m.chkGroup){
1040
                if(m.chkGroup[chkBox].checked)
1041
                        allOff = false;
1042
                else
1043
                        allOn = false;
1044
        }
1045
        if (allOn)m.chkMaster.checked = true;  
1046
        if (allOff)m.chkMaster.checked = false;
1047
        if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])
1048
                _jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])
1049
}
1050
 
1051
function _jmolNotifyGroup(m, isOn){
1052
        //called when a master item is checked
1053
        for (var chkBox in m.chkGroup){
1054
                var item = m.chkGroup[chkBox]
1055
                item.checked = isOn;
1056
                if (_jmol.checkboxMasters[item.id])
1057
                        _jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)
1058
        }
1059
}
1060
 
1061
function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {
1062
  _jmol.control = ckbox
1063
  _jmolClick(ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);
1064
  if(_jmol.checkboxMasters[ckbox.id])
1065
        _jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)
1066
  if(_jmol.checkboxItems[ckbox.id])
1067
        _jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])
1068
}
1069
 
1070
function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {
1071
  window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];
1072
}
1073
 
1074
function _jmolMouseOver(scriptIndex) {
1075
  window.status = _jmol.scripts[scriptIndex];
1076
}
1077
 
1078
function _jmolMouseOut() {
1079
  window.status = " ";
1080
  return true;
1081
}
1082
 
1083
function _jmolSetCodebase(codebase) {
1084
  _jmol.codebase = codebase ? codebase : ".";
1085
  if (_jmol.debugAlert)
1086
    alert("jmolCodebase=" + _jmol.codebase);
1087
}
1088
 
1089
function _jmolOnloadResetForms() {
1090
  // must be evaluated ONLY once
1091
  _jmol.previousOnloadHandler = window.onload;
1092
  window.onload =
1093
  function() {
1094
    with (_jmol) {
1095
      if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {
1096
        var forms = document.forms;
1097
        for (var i = forms.length; --i >= 0; )
1098
          forms[i].reset();
1099
      }
1100
      if (previousOnloadHandler)
1101
        previousOnloadHandler();
1102
    }
1103
  }
1104
}
1105
 
1106
////////////////////////////////////
1107
/////extensions for getProperty/////
1108
////////////////////////////////////
1109
 
1110
 
1111
function _jmolEvalJSON(s,key){
1112
 s=s+""
1113
 if(!s)return []
1114
 if(s.charAt(0)!="{"){
1115
        if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")
1116
        return s
1117
 }
1118
 var A = eval("("+s+")")
1119
 if(!A)return
1120
 if(key && A[key])A=A[key]
1121
 return A
1122
}
1123
 
1124
function _jmolEnumerateObject(A,key){
1125
 var sout=""
1126
 if(typeof(A) == "string" && A!="null"){
1127
        sout+="\n"+key+"=\""+A+"\""
1128
 }else if(!isNaN(A)||A==null){
1129
        sout+="\n"+key+"="+(A+""==""?"null":A)
1130
 }else if(A.length){
1131
    sout+=key+"=[]"
1132
    for(var i=0;i<A.length;i++){
1133
        sout+="\n"
1134
        if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
1135
                sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")
1136
        }else{
1137
                sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
1138
        }
1139
    }
1140
 }else{
1141
    if(key != ""){
1142
        sout+=key+"={}"
1143
        key+="."
1144
    }
1145
 
1146
    for(var i in A){
1147
        sout+="\n"
1148
        if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
1149
                sout+=_jmolEnumerateObject(A[i],key+i)
1150
        }else{
1151
                sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
1152
        }
1153
    }
1154
 }
1155
 return sout
1156
}
1157
 
1158
 
1159
function _jmolSortKey0(a,b){
1160
 return (a[0]<b[0]?1:a[0]>b[0]?-1:0)
1161
}
1162
 
1163
function _jmolSortMessages(A){
1164
 if(!A || typeof(A)!="object")return []
1165
 var B = []
1166
 for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]
1167
 if(B.length == 0) return
1168
 B=B.sort(_jmolSortKey0)
1169
 return B
1170
}
1171
 
1172
/////////additional extensions //////////
1173
 
1174
 
1175
function _jmolDomScriptLoad(URL){
1176
 //open(URL) //to debug
1177
 _jmol.servercall=URL
1178
 var node = document.getElementById("_jmolScriptNode")
1179
 if (node && _jmol.browser!="msie"){
1180
    document.getElementsByTagName("HEAD")[0].removeChild(node)
1181
    node=null
1182
 }
1183
 if (node) {
1184
   node.setAttribute("src",URL)
1185
 } else {
1186
   node=document.createElement("script")
1187
   node.setAttribute("id","_jmolScriptNode")
1188
   node.setAttribute("type","text/javascript")
1189
   node.setAttribute("src",URL)
1190
   document.getElementsByTagName("HEAD")[0].appendChild(node)
1191
 }
1192
}
1193
 
1194
 
1195
function _jmolExtractPostData(url){
1196
 S=url.split("&POST:")
1197
 var s=""
1198
 for(var i=1;i<S.length;i++){
1199
        KV=S[i].split("=")
1200
        s+="&POSTKEY"+i+"="+KV[0]
1201
        s+="&POSTVALUE"+i+"="+KV[1]
1202
 }
1203
 return "&url="+escape(S[0])+s
1204
}
1205
 
1206
function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){
1207
 //called by server, but in client
1208
 //overload this function to customize return
1209
 _jmol.remoteURL=remoteURL
1210
 if(isError)alert(errorMessage)
1211
 jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)
1212
}
1213
 
1214
//////////user property/status functions/////////
1215
 
1216
function jmolGetStatus(strStatus,targetSuffix){
1217
 return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))
1218
}
1219
 
1220
function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {
1221
 return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)
1222
}
1223
 
1224
function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {
1225
 var applet = _jmolGetApplet(targetSuffix);
1226
 if(!sValue)sValue=""
1227
 return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")
1228
}
1229
 
1230
function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {
1231
 if(!sValue)sValue = ""
1232
 var applet = _jmolGetApplet(targetSuffix);
1233
 try {
1234
  return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")
1235
 } catch(e) {
1236
  return ""
1237
 }
1238
}
1239
 
1240
function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {
1241
 if(!sValue)sValue = ""
1242
 var applet = _jmolGetApplet(targetSuffix);
1243
 return (applet ? applet.getProperty(sKey,sValue) : null)
1244
}
1245
 
1246
 
1247
function jmolDecodeJSON(s) {
1248
 return _jmolEnumerateObject(_jmolEvalJSON(s),"")
1249
}
1250
 
1251
 
1252
///////// synchronous scripting ////////
1253
 
1254
function jmolScriptWait(script, targetSuffix) {
1255
  if(!targetSuffix)targetSuffix="0"
1256
  var Ret=jmolScriptWaitAsArray(script, targetSuffix)
1257
  var s = ""
1258
  for(var i=Ret.length;--i>=0;)
1259
  for(var j=0;j< Ret[i].length;j++)
1260
        s+=Ret[i][j]+"\n"
1261
  return s
1262
}
1263
 
1264
function jmolScriptWaitOutput(script, targetSuffix) {
1265
  if(!targetSuffix)targetSuffix="0"
1266
  var ret = ""
1267
  try{
1268
   if (script) {
1269
    _jmolCheckBrowser();
1270
    var applet=_jmolGetApplet(targetSuffix);
1271
    if (applet) ret += applet.scriptWaitOutput(script);
1272
   }
1273
  }catch(e){
1274
  }
1275
 return ret;
1276
}
1277
 
1278
function jmolEvaluate(molecularMath, targetSuffix) {
1279
 
1280
  //carries out molecular math on a model
1281
 
1282
  if(!targetSuffix)targetSuffix="0"
1283
  var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);
1284
  var s = result.replace(/\-*\d+/,"")
1285
  if (s == "" && !isNaN(parseInt(result)))return parseInt(result);
1286
  var s = result.replace(/\-*\d*\.\d*/,"")
1287
  if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);
1288
  return result;
1289
}
1290
 
1291
function jmolScriptEcho(script, targetSuffix) {
1292
  // returns a newline-separated list of all echos from a script
1293
  if(!targetSuffix)targetSuffix="0"
1294
  var Ret=jmolScriptWaitAsArray(script, targetSuffix)
1295
  var s = ""
1296
  for(var i=Ret.length;--i>=0;)
1297
  for(var j=Ret[i].length;--j>=0;)
1298
        if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"
1299
  return s.replace(/ \| /g, "\n")
1300
}
1301
 
1302
 
1303
function jmolScriptMessage(script, targetSuffix) {
1304
  // returns a newline-separated list of all messages from a script, ending with "script completed\n"
1305
  if(!targetSuffix)targetSuffix="0"
1306
  var Ret=jmolScriptWaitAsArray(script, targetSuffix)
1307
  var s = ""
1308
  for(var i=Ret.length;--i>=0;)
1309
  for(var j=Ret[i].length;--j>=0;)
1310
        if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"
1311
  return s.replace(/ \| /g, "\n")
1312
}
1313
 
1314
 
1315
function jmolScriptWaitAsArray(script, targetSuffix) {
1316
 var ret = ""
1317
 try{
1318
  jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)
1319
  if (script) {
1320
    _jmolCheckBrowser();
1321
    var applet=_jmolGetApplet(targetSuffix);
1322
    if (applet) ret += applet.scriptWait(script);
1323
    ret = _jmolEvalJSON(ret,"jmolStatus")
1324
    if(typeof ret == "object")
1325
        return ret
1326
  }
1327
 }catch(e){
1328
 }
1329
  return [[ret]]
1330
}
1331
 
1332
 
1333
 
1334
////////////   save/restore orientation   /////////////
1335
 
1336
function jmolSaveOrientation(id, targetSuffix) {  
1337
 if(!targetSuffix)targetSuffix="0"
1338
  return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo
1339
}
1340
 
1341
function jmolRestoreOrientation(id, targetSuffix) {
1342
 if(!targetSuffix)targetSuffix="0"
1343
 var s=_jmol["savedOrientation"+id]
1344
 if (!s || s == "")return
1345
 s=s.replace(/1\.0/,"0")
1346
 return jmolScriptWait(s,targetSuffix)
1347
}
1348
 
1349
function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {
1350
 if(arguments.length < 2)delay=1;
1351
 if(!targetSuffix)targetSuffix="0"
1352
 var s=_jmol["savedOrientation"+id]
1353
 if (!s || s == "")return
1354
 s=s.replace(/1\.0/,delay)
1355
 return jmolScriptWait(s,targetSuffix)
1356
}
1357
 
1358
////////////  add parameter /////////////
1359
/*
1360
 * for adding callbacks or other parameters. Use:
1361
 
1362
   jmolSetDocument(0)
1363
   var s= jmolApplet(....)
1364
   s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")
1365
   document.write(s)
1366
   jmolSetDocument(document) // if you want to then write buttons and such normally
1367
 
1368
 */
1369
 
1370
function jmolAppletAddParam(appletCode,name,value){
1371
  if(value == "")return appletCode
1372
  return appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param")
1373
}
1374
 
1375
///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////
1376
 
1377
function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){
1378
 
1379
 if(!_jmol.thismodel)_jmol.thismodel = "1crn"
1380
 if(!_jmol.serverURL)_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"
1381
 if(!_jmol.RCSBserver)_jmol.RCSBserver="http://www.rcsb.org"
1382
 if(!_jmol.defaultURL_RCSB)_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF"
1383
 if(!fileformat)fileformat="PDB"
1384
 if(!pdbid)pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel)
1385
 if(!pdbid || pdbid.length != 4)return ""
1386
 if(!targetSuffix)targetSuffix="0"
1387
 if(!optionalscript)optionalscript=""
1388
 var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())
1389
 if(fileformat!="CIF")url=url.replace(/CIF/,fileformat)
1390
 _jmol.optionalscript=optionalscript
1391
 _jmol.thismodel=pdbid
1392
 _jmol.thistargetsuffix=targetSuffix
1393
 _jmol.thisurl=url
1394
 _jmol.modelArray = []
1395
 url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
1396
 _jmolDomScriptLoad(url)
1397
 return url
1398
}
1399
 
1400
/////////////// St. Olaf College AJAX server -- ANY URL ///////////
1401
 
1402
function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){
1403
 _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"
1404
 if(!_jmol.thisurlANY)_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol"
1405
 if(!url)url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY)
1406
 if(!userid)userid="0"
1407
 if(!targetSuffix)targetSuffix="0"
1408
 if(!optionalscript)optionalscript=""
1409
 _jmol.optionalscript=optionalscript
1410
 _jmol.thistargetsuffix=targetSuffix
1411
 _jmol.modelArray = []
1412
 _jmol.thisurl = url
1413
 url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
1414
 _jmolDomScriptLoad(url)
1415
}
1416
 
1417
 
1418
/////////////// Mineralogical Society of America (MSA) data /////////
1419
 
1420
function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){
1421
 
1422
 if(!_jmol.thiskeyMSA)_jmol.thiskeyMSA = "mineral"
1423
 if(!_jmol.thismodelMSA)_jmol.thismodelMSA = "quartz"
1424
 if(!_jmol.ajaxURL_MSA)_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs"
1425
 if(!key)key=prompt("Enter a field:", _jmol.thiskeyMSA)
1426
 if(!key)return ""
1427
 if(!value)value=prompt("Enter a "+key+":", _jmol.thismodelMSA)
1428
 if(!value)return ""
1429
 if(!targetSuffix)targetSuffix="0"
1430
 if(!optionalscript)optionalscript=""
1431
 if(optionalscript == 1)optionalscript='load "" {1 1 1}'
1432
 var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)
1433
 _jmol.optionalscript=optionalscript
1434
 _jmol.thiskeyMSA=key
1435
 _jmol.thismodelMSA=value
1436
 _jmol.thistargetsuffix=targetSuffix
1437
 _jmol.thisurl=url
1438
 _jmol.modelArray = []
1439
 loadModel=_jmolLoadModel
1440
 _jmolDomScriptLoad(url)
1441
 return url
1442
}
1443
 
1444
 
1445
 
1446
function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){
1447
 if(!userid)userid="0"
1448
 if(!targetSuffix)targetSuffix="0"
1449
 if(!optionalscript)optionalscript=""
1450
 _jmol.optionalscript=optionalscript
1451
 _jmol.thismodel=userid
1452
 _jmol.thistargetsuffix=targetSuffix
1453
 _jmol.modelArray = []
1454
 _jmol.thisurl = url
1455
 url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix
1456
 _jmolDomScriptLoad(url)
1457
}
1458
 
1459
 
1460
//// in case Jmol library has already been loaded:
1461
 
1462
}catch(e){}
1463
 
1464
///////////////moving atoms //////////////
1465
 
1466
// HIGHLY experimental!!
1467
 
1468
function jmolSetAtomCoord(i,x,y,z,targetSuffix){
1469
    _jmolCheckBrowser();
1470
      var applet=_jmolGetApplet(targetSuffix);
1471
      if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)
1472
}
1473
 
1474
function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){
1475
    _jmolCheckBrowser();
1476
      var applet=_jmolGetApplet(targetSuffix);
1477
      if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)
1478
}
1479
 
1480
 
1481
///////////////applet fake for testing buttons/////////////
1482
 
1483
 
1484
if(document.location.search.indexOf("NOAPPLET")>=0){
1485
        jmolApplet = function(w){
1486
                var s="<table style='background-color:black' width="+w+"><tr height="+w+">"
1487
                +"<td align=center valign=center style='background-color:white'>"
1488
                +"Applet would be here"
1489
                +"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"
1490
                +"</td></tr></table>"
1491
                return _jmolDocumentWrite(s)
1492
        }
1493
 
1494
        _jmolFindApplet = function(){return jmolApplet0}
1495
 
1496
        jmolApplet0 = {
1497
         script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}
1498
        ,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script}
1499
        ,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}
1500
        }
1501
}
1502
 
1503
 
1504
///////////////////////////////////////////
1505
 
1506
//new 9:49 AM 3/6/2007:
1507
 
1508
//both w and h are optional. 
1509
//if either is between 0 and 1, then it is taken as percent/100.
1510
//if either is greater than 1, then it is taken as a size. 
1511
function jmolResize(w,h) {
1512
 _jmol.alerted = true;
1513
 var percentW = (!w ? 100 : w <= 1  && w > 0 ? w * 100 : 0)
1514
 var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0)
1515
 if (_jmol.browser=="msie") {
1516
   var width=document.body.clientWidth;
1517
   var height=document.body.clientHeight;
1518
 } else {
1519
   var netscapeScrollWidth=15;
1520
   var width=window.innerWidth - netscapeScrollWidth;
1521
   var height=window.innerHeight-netscapeScrollWidth;
1522
 }
1523
 var applet = _jmolGetApplet(0);
1524
 if(!applet)return;
1525
 applet.style.width = (percentW ? width * percentW/100 : w)+"px"
1526
 applet.style.height = (percentH ? height * percentH/100 : h)+"px"
1527
 title=width +  " " + height + " " + (new Date())
1528
}
1529