otsdaq_utilities  v2_05_02_indev
JSRootCore.js
1 
6 
7 (function( factory ) {
8  if ( typeof define === "function" && define.amd ) {
9 
10  var jsroot = factory({});
11 
12  var dir = jsroot.source_dir + "scripts/", ext = jsroot.source_min ? ".min" : "";
13 
14  var paths = {
15  'd3' : dir+'d3.v3.min',
16  'jquery' : dir+'jquery.min',
17  'jquery-ui' : dir+'jquery-ui.min',
18  'jqueryui-mousewheel' : dir+'jquery.mousewheel'+ext,
19  'jqueryui-touch-punch' : dir+'touch-punch.min',
20  'rawinflate' : dir+'rawinflate'+ext,
21  'MathJax' : 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG&delayStartupUntil=configured',
22  'saveSvgAsPng' : dir+'saveSvgAsPng'+ext,
23  'threejs' : dir+'three'+ext,
24  'threejs_all' : dir+'three.extra'+ext,
25 // 'JSRootCore' : dir+'JSRootCore'+ext,
26  'JSRootMath' : dir+'JSRootMath'+ext,
27  'JSRootInterface' : dir+'JSRootInterface'+ext,
28  'JSRootIOEvolution' : dir+'JSRootIOEvolution'+ext,
29  'JSRootPainter' : dir+'JSRootPainter'+ext,
30  'JSRootPainter.more' : dir+'JSRootPainter.more'+ext,
31  'JSRootPainter.jquery' : dir+'JSRootPainter.jquery'+ext,
32  'JSRoot3DPainter' : dir+'JSRoot3DPainter'+ext,
33  'ThreeCSG' : dir+'ThreeCSG'+ext,
34  'JSRootGeoPainter' : dir+'JSRootGeoPainter'+ext
35  };
36 
37  var cfg_paths;
38  if ((requirejs.s!==undefined) && (requirejs.s.contexts !== undefined) && ((requirejs.s.contexts._!==undefined) &&
39  requirejs.s.contexts._.config!==undefined)) cfg_paths = requirejs.s.contexts._.config.paths;
40  else console.warn("Require.js paths changed - please contact JSROOT developers");
41 
42  // check if modules are already loaded
43  for (var module in paths)
44  if (requirejs.defined(module) || (cfg_paths && (module in cfg_paths)))
45  delete paths[module];
46 
47  // configure all dependencies
48  requirejs.config({
49  paths: paths,
50  shim: {
51  'jqueryui-mousewheel': { deps: ['jquery-ui'] },
52  'jqueryui-touch-punch': { deps: ['jquery-ui'] },
53  'threejs_all': { deps: [ 'threejs'] },
54  'MathJax': {
55  exports: 'MathJax',
56  init: function () {
57  MathJax.Hub.Config({ TeX: { extensions: ["color.js"] }});
58  MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
59  var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;
60  VARIANT["normal"].fonts.unshift("MathJax_SansSerif");
61  VARIANT["bold"].fonts.unshift("MathJax_SansSerif-bold");
62  VARIANT["italic"].fonts.unshift("MathJax_SansSerif");
63  VARIANT["-tex-mathit"].fonts.unshift("MathJax_SansSerif");
64  });
65  MathJax.Hub.Startup.onload();
66  return MathJax;
67  }
68  }
69  }
70  });
71 
72  // AMD. Register as an anonymous module.
73  define( jsroot );
74 
75  if (!require.specified("JSRootCore"))
76  define('JSRootCore', [], jsroot);
77 
78  if (!require.specified("jsroot"))
79  define('jsroot', [], jsroot);
80 
81  } else {
82 
83  if (typeof JSROOT != 'undefined')
84  throw new Error("JSROOT is already defined", "JSRootCore.js");
85 
86  JSROOT = {};
87 
88  factory(JSROOT);
89  }
90 } (function(JSROOT) {
91 
92  JSROOT.version = "4.5.0 25/04/2016";
93 
94  JSROOT.source_dir = "";
95  JSROOT.source_min = false;
96  JSROOT.source_fullpath = ""; // full name of source script
97  JSROOT.bower_dir = ""; // when specified, use standard libs from bower location
98 
99  JSROOT.id_counter = 0;
100 
101  JSROOT.touches = false;
102  JSROOT.browser = { isOpera:false, isFirefox:true, isSafari:false, isChrome:false, isIE:false };
103 
104  if ((typeof document !== "undefined") && (typeof window !== "undefined")) {
105  var scripts = document.getElementsByTagName('script');
106  for (var n = 0; n < scripts.length; ++n) {
107  var src = scripts[n].src;
108  if ((src===undefined) || (typeof src !== 'string')) continue;
109 
110  var pos = src.indexOf("scripts/JSRootCore.");
111  if (pos<0) continue;
112 
113  JSROOT.source_dir = src.substr(0, pos);
114  JSROOT.source_min = src.indexOf("scripts/JSRootCore.min.js") >= 0;
115 
116  JSROOT.source_fullpath = src;
117 
118  if ((console!==undefined) && (typeof console.log == 'function'))
119  console.log("Set JSROOT.source_dir to " + JSROOT.source_dir + ", " + JSROOT.version);
120  break;
121  }
122 
123  JSROOT.touches = ('ontouchend' in document); // identify if touch events are supported
124  JSROOT.browser.isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
125  JSROOT.browser.isFirefox = typeof InstallTrigger !== 'undefined';
126  JSROOT.browser.isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
127  JSROOT.browser.isChrome = !!window.chrome && !JSROOT.browser.isOpera;
128  JSROOT.browser.isIE = false || !!document.documentMode;
129  }
130 
131  JSROOT.browser.isWebKit = JSROOT.browser.isChrome || JSROOT.browser.isSafari;
132 
133  // default draw styles, can be changed after loading of JSRootCore.js
134  JSROOT.gStyle = {
135  Tooltip : 1, // 0 - off, 1 - on
136  ContextMenu : true,
137  Zooming : true,
138  MoveResize : true, // enable move and resize of elements like statbox, title, pave, colz
139  DragAndDrop : true, // enables drag and drop functionality
140  ToolBar : true, // show additional tool buttons on the canvas
141  OptimizeDraw : 1, // drawing optimization: 0 - disabled, 1 - only for large (>5000 1d bins, >50 2d bins) histograms, 2 - always
142  AutoStat : true,
143  OptStat : 1111,
144  OptFit : 0,
145  FrameNDC : { fX1NDC: 0.07, fY1NDC: 0.12, fX2NDC: 0.95, fY2NDC: 0.88 },
146  StatNDC : { fX1NDC: 0.78, fY1NDC: 0.75, fX2NDC: 0.98, fY2NDC: 0.91 },
147  StatText : { fTextAngle: 0, fTextSize: 9, fTextAlign: 12, fTextColor: 1, fTextFont: 42 },
148  StatFill : { fFillColor: 0, fFillStyle: 1001 },
149  TimeOffset : 788918400000, // UTC time at 01/01/95
150  StatFormat : "6.4g",
151  FitFormat : "5.4g",
152  Palette : 57,
153  MathJax : 0, // 0 - never, 1 - only for complex cases, 2 - always
154  ProgressBox : true, // show progress box
155  Embed3DinSVG : 2, // 0 - no embed, only 3D plot, 1 - overlay over SVG (IE/WebKit), 2 - embed into SVG (only Firefox)
156  NoWebGL : false, // if true, WebGL will be disabled,
157  EndErrorSize : 2 // size in pixels of end error for E1 draw options
158  };
159 
160  JSROOT.BIT = function(n) { return 1 << (n); }
161 
162  // TH1 status bits
163  JSROOT.TH1StatusBits = {
164  kNoStats : JSROOT.BIT(9), // don't draw stats box
165  kUserContour : JSROOT.BIT(10), // user specified contour levels
166  kCanRebin : JSROOT.BIT(11), // can rebin axis
167  kLogX : JSROOT.BIT(15), // X-axis in log scale
168  kIsZoomed : JSROOT.BIT(16), // bit set when zooming on Y axis
169  kNoTitle : JSROOT.BIT(17), // don't draw the histogram title
170  kIsAverage : JSROOT.BIT(18) // Bin contents are average (used by Add)
171  };
172 
173  JSROOT.EAxisBits = {
174  kTickPlus : JSROOT.BIT(9),
175  kTickMinus : JSROOT.BIT(10),
176  kAxisRange : JSROOT.BIT(11),
177  kCenterTitle : JSROOT.BIT(12),
178  kCenterLabels : JSROOT.BIT(14),
179  kRotateTitle : JSROOT.BIT(15),
180  kPalette : JSROOT.BIT(16),
181  kNoExponent : JSROOT.BIT(17),
182  kLabelsHori : JSROOT.BIT(18),
183  kLabelsVert : JSROOT.BIT(19),
184  kLabelsDown : JSROOT.BIT(20),
185  kLabelsUp : JSROOT.BIT(21),
186  kIsInteger : JSROOT.BIT(22),
187  kMoreLogLabels : JSROOT.BIT(23),
188  kDecimals : JSROOT.BIT(11)
189  };
190 
191  // wrapper for console.log, avoids missing console in IE
192  // if divid specified, provide output to the HTML element
193  JSROOT.console = function(value, divid) {
194  if ((divid!=null) && (typeof divid=='string') && ((typeof document.getElementById(divid))!='undefined'))
195  document.getElementById(divid).innerHTML = value;
196  else
197  if ((typeof console != 'undefined') && (typeof console.log == 'function'))
198  console.log(value);
199  }
200 
201  // This is part of the JSON-R code, found on
202  // https://github.com/graniteds/jsonr
203  // Only unref part was used, arrays are not accounted as objects
204  // Should be used to reintroduce objects references, produced by TBufferJSON
205  JSROOT.JSONR_unref = function(value, dy) {
206  var c, i, k, ks;
207  if (!dy) dy = [];
208 
209  switch (typeof value) {
210  case 'string':
211  if ((value.length > 5) && (value.substr(0, 5) == "$ref:")) {
212  c = parseInt(value.substr(5));
213  if (!isNaN(c) && (c < dy.length)) {
214  value = dy[c];
215  }
216  }
217  break;
218 
219  case 'object':
220  if (value !== null) {
221 
222  if (Object.prototype.toString.apply(value) === '[object Array]') {
223  for (i = 0; i < value.length; ++i) {
224  value[i] = this.JSONR_unref(value[i], dy);
225  }
226  } else {
227 
228  // account only objects in ref table
229  if (dy.indexOf(value) === -1) {
230  dy.push(value);
231  }
232 
233  // add methods to all objects, where _typename is specified
234  if ('_typename' in value) this.addMethods(value);
235 
236  ks = Object.keys(value);
237  for (i = 0; i < ks.length; ++i) {
238  k = ks[i];
239  value[k] = this.JSONR_unref(value[k], dy);
240  }
241  }
242  }
243  break;
244  }
245 
246  return value;
247  }
248 
249  JSROOT.debug = 0;
250 
251  // This is simple replacement of jQuery.extend method
252  // Just copy (not clone) all fields from source to the target object
253  JSROOT.extend = function(tgt, src, map, deep_copy) {
254  if ((src === null) || (typeof src !== 'object')) return src;
255  if ((tgt === null) || (typeof tgt !== 'object')) tgt = {};
256 
257  for (var k in src)
258  tgt[k] = src[k];
259 
260  return tgt;
261  }
262 
263  // Make deep clone of the object, including all sub-objects
264  JSROOT.clone = function(src, map) {
265  if (src === null) return null;
266 
267  if (!map) {
268  map = { obj:[], clones:[] };
269  } else {
270  var i = map.obj.indexOf(src);
271  if (i>=0) return map.clones[i];
272  }
273 
274  var proto = Object.prototype.toString.apply(src);
275 
276  // process normal array
277  if (proto === '[object Array]') {
278  var tgt = [];
279  map.obj.push(src);
280  map.clones.push(tgt);
281  for (var i = 0; i < src.length; ++i)
282  tgt.push(JSROOT.clone(src[i], map));
283 
284  return tgt;
285  }
286 
287  // process typed array
288  if ((proto.indexOf('[object ') == 0) && (proto.indexOf('Array]') == proto.length-6)) {
289  var tgt = [];
290  map.obj.push(src);
291  map.clones.push(tgt);
292  for (var i = 0; i < src.length; ++i)
293  tgt.push(src[i]);
294 
295  return tgt;
296  }
297 
298  var tgt = {};
299  map.obj.push(src);
300  map.clones.push(tgt);
301 
302  for (var k in src) {
303  if (typeof src[k] === 'object')
304  tgt[k] = JSROOT.clone(src[k], map);
305  else
306  tgt[k] = src[k];
307  }
308 
309  return tgt;
310  }
311 
312  // method can be used to delete all functions from objects
313  // only such objects can be cloned when transfer to Worker
314  JSROOT.clear_func = function(src, map) {
315  if (src === null) return;
316 
317  var proto = Object.prototype.toString.apply(src);
318 
319  if (proto === '[object Array]') {
320  for (var n=0;n<src.length;n++)
321  if (typeof src[n] === 'object')
322  JSROOT.clear_func(src[n], map);
323  return;
324  }
325 
326  if ((proto.indexOf('[object ') == 0) && (proto.indexOf('Array]') == proto.length-6)) return;
327 
328  if (!map) map = [];
329  var nomap = (map.length == 0);
330  if ('__clean_func__' in src) return;
331 
332  map.push(src);
333  src['__clean_func__'] = true;
334 
335  for (var k in src) {
336  if (typeof src[k] === 'object')
337  JSROOT.clear_func(src[k], map);
338  else
339  if (typeof src[k] === 'function') delete src[k];
340  }
341 
342  if (nomap)
343  for (var n=0;n<map.length;++n)
344  delete map[n]['__clean_func__'];
345  }
346 
347 
348  JSROOT.parse = function(arg) {
349  if ((arg==null) || (arg=="")) return null;
350  var obj = JSON.parse(arg);
351  if (obj!=null) obj = this.JSONR_unref(obj);
352  return obj;
353  }
354 
355  JSROOT.GetUrlOption = function(opt, url, dflt) {
356  // analyzes document.URL and extracts options after '?' mark
357  // following options supported ?opt1&opt2=3
358  // In case of opt1 empty string will be returned, in case of opt2 '3'
359  // If option not found, null is returned (or provided default value)
360 
361  if (arguments.length < 3) dflt = null;
362  if ((opt==null) || (typeof opt != 'string') || (opt.length==0)) return dflt;
363 
364  if (!url) {
365  if (typeof document === 'undefined') return dflt;
366  url = document.URL;
367  }
368 
369  var pos = url.indexOf("?");
370  if (pos<0) return dflt;
371  url = url.slice(pos+1);
372 
373  while (url.length>0) {
374 
375  if (url==opt) return "";
376 
377  pos = url.indexOf("&");
378  if (pos < 0) pos = url.length;
379 
380  if (url.indexOf(opt) == 0) {
381  if (url.charAt(opt.length)=="&") return "";
382 
383  // replace several symbols which are known to make a problem
384  if (url.charAt(opt.length)=="=")
385  return url.slice(opt.length+1, pos).replace(/%27/g, "'").replace(/%22/g, '"').replace(/%20/g, ' ').replace(/%3C/g, '<').replace(/%3E/g, '>').replace(/%5B/g, '[').replace(/%5D/g, ']');
386  }
387 
388  url = url.slice(pos+1);
389  }
390  return dflt;
391  }
392 
393  JSROOT.ParseAsArray = function(val) {
394  // parse string value as array.
395  // It could be just simple string: "value"
396  // or array with or without string quotes: [element], ['eleme1',elem2]
397 
398  var res = [];
399 
400  if (typeof val != 'string') return res;
401 
402  val = val.trim();
403  if (val=="") return res;
404 
405  // return as array with single element
406  if ((val.length<2) || (val[0]!='[') || (val[val.length-1]!=']')) {
407  res.push(val); return res;
408  }
409 
410  // try to parse ourself
411  var arr = val.substr(1, val.length-2).split(","); // remove brackets
412 
413  for (var i = 0; i < arr.length; ++i) {
414  var sub = arr[i].trim();
415  if ((sub.length>1) && (sub[0]==sub[sub.length-1]) && ((sub[0]=='"') || (sub[0]=="'")))
416  sub = sub.substr(1, sub.length-2);
417  res.push(sub);
418  }
419  return res;
420  }
421 
422  JSROOT.GetUrlOptionAsArray = function(opt, url) {
423  // special handling of URL options to produce array
424  // if normal option is specified ...?opt=abc, than array with single element will be created
425  // one could specify normal JSON array ...?opt=['item1','item2']
426  // but also one could skip quotes ...?opt=[item1,item2]
427  // one could collect values from several options, specifying
428  // options names via semicolon like opt='item;items'
429 
430  var res = [];
431 
432  while (opt.length>0) {
433  var separ = opt.indexOf(";");
434  var part = separ>0 ? opt.substr(0, separ) : opt;
435  if (separ>0) opt = opt.substr(separ+1); else opt = "";
436 
437  var val = this.GetUrlOption(part, url, null);
438  res = res.concat(JSROOT.ParseAsArray(val));
439  }
440  return res;
441  }
442 
443  JSROOT.findFunction = function(name) {
444  if (typeof name === 'function') return name;
445  var func = window[name];
446  if (typeof func == 'function') return func;
447  var separ = name.lastIndexOf(".");
448  if (separ<0) return null;
449  var namespace = name.slice(0, separ);
450  name = name.slice(separ+1);
451  if (namespace=="JSROOT") func = this[name]; else
452  if (namespace=="JSROOT.Painter") { if ('Painter' in this) func = this['Painter'][name]; } else
453  if (window[namespace]) func = window[namespace][name];
454  return (typeof func == 'function') ? func : null;
455  }
456 
457  JSROOT.CallBack = function(func, arg1, arg2) {
458  // generic method to invoke callback function
459  // func either normal function or container like
460  // { obj: object_pointer, func: name of method to call }
461  // arg1, arg2 are optional arguments of the callback
462 
463  if (typeof func == 'string') func = JSROOT.findFunction(func);
464 
465  if (func == null) return;
466 
467  if (typeof func == 'function') return func(arg1,arg2);
468 
469  if (typeof func != 'object') return;
470 
471  if (('obj' in func) && ('func' in func) &&
472  (typeof func.obj == 'object') && (typeof func.func == 'string') &&
473  (typeof func.obj[func.func] == 'function')) {
474  alert('Old-style call-back, change code for ' + func.func);
475  return func.obj[func.func](arg1, arg2);
476  }
477  }
478 
479  JSROOT.NewHttpRequest = function(url, kind, user_call_back) {
480  // Create asynchronous XMLHttpRequest object.
481  // One should call req.send() to submit request
482  // kind of the request can be:
483  // "bin" - abstract binary data, result as string (default)
484  // "buf" - abstract binary data, result as BufferArray (if supported)
485  // "text" - returns req.responseText
486  // "object" - returns JSROOT.parse(req.responseText)
487  // "xml" - returns res.responseXML
488  // "head" - returns request itself, uses "HEAD" method
489  // Result will be returned to the callback functions
490  // Request will be set as this pointer in the callback
491  // If failed, request returns null
492 
493  var xhr = new XMLHttpRequest();
494 
495  function callback(res) {
496  // we set pointer on request when calling callback
497  if (typeof user_call_back == 'function') user_call_back.call(xhr, res);
498  }
499 
500  var pthis = this;
501 
502  if (window.ActiveXObject) {
503 
504  xhr.onreadystatechange = function() {
505  if (xhr.readyState != 4) return;
506 
507  if (xhr.status != 200 && xhr.status != 206) {
508  // error
509  return callback(null);
510  }
511 
512  if (kind == "xml") return callback(xhr.responseXML);
513  if (kind == "text") return callback(xhr.responseText);
514  if (kind == "object") return callback(pthis.parse(xhr.responseText));
515  if (kind == "head") return callback(xhr);
516 
517  if ((kind == "buf") && ('responseType' in xhr) &&
518  (xhr.responseType == 'arraybuffer') && ('response' in xhr))
519  return callback(xhr.response);
520 
521  var filecontent = new String("");
522  var array = new VBArray(xhr.responseBody).toArray();
523  for (var i = 0; i < array.length; ++i)
524  filecontent = filecontent + String.fromCharCode(array[i]);
525  delete array;
526  callback(filecontent);
527  }
528 
529  xhr.open(kind == 'head' ? 'HEAD' : 'GET', url, true);
530 
531  if (kind=="buf") {
532  if (('Uint8Array' in window) && ('responseType' in xhr))
533  xhr.responseType = 'arraybuffer';
534  }
535 
536  } else {
537 
538  xhr.onreadystatechange = function() {
539  if (xhr.readyState != 4) return;
540 
541  if (xhr.status != 200 && xhr.status != 206) {
542  return callback(null);
543  }
544 
545  if (kind == "xml") return callback(xhr.responseXML);
546  if (kind == "text") return callback(xhr.responseText);
547  if (kind == "object") return callback(pthis.parse(xhr.responseText));
548  if (kind == "head") return callback(xhr);
549 
550  // if no response type is supported, return as text (most probably, will fail)
551  if (! ('responseType' in xhr))
552  return callback(xhr.responseText);
553 
554  if ((kind=="bin") && ('Uint8Array' in window) && ('byteLength' in xhr.response)) {
555  // if string representation in requested - provide it
556  var filecontent = "";
557  var u8Arr = new Uint8Array(xhr.response, 0, xhr.response.byteLength);
558  for (var i = 0; i < u8Arr.length; ++i)
559  filecontent = filecontent + String.fromCharCode(u8Arr[i]);
560  delete u8Arr;
561 
562  return callback(filecontent);
563  }
564 
565  callback(xhr.response);
566  }
567 
568  xhr.open(kind == 'head' ? 'HEAD' : 'GET', url, true);
569 
570  if ((kind == "bin") || (kind == "buf")) {
571  if (('Uint8Array' in window) && ('responseType' in xhr)) {
572  xhr.responseType = 'arraybuffer';
573  } else {
574  //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
575  xhr.overrideMimeType("text/plain; charset=x-user-defined");
576  }
577  }
578 
579  }
580  return xhr;
581  }
582 
583  JSROOT.loadScript = function(urllist, callback, debugout) {
584  // dynamic script loader using callback
585  // (as loading scripts may be asynchronous)
586  // one could specify list of scripts or style files, separated by semicolon ';'
587  // one can prepend file name with '$$$' - than file will be loaded from JSROOT location
588  // This location can be set by JSROOT.source_dir or it will be detected automatically
589  // by the position of JSRootCore.js file, which must be loaded by normal methods:
590  // <script type="text/javascript" src="scripts/JSRootCore.js"></script>
591 
592  function completeLoad() {
593  if (debugout)
594  document.getElementById(debugout).innerHTML = "";
595  else
596  JSROOT.progress();
597 
598  if ((urllist!=null) && (urllist.length>0))
599  return JSROOT.loadScript(urllist, callback, debugout);
600 
601  JSROOT.CallBack(callback);
602  }
603 
604  if ((urllist==null) || (urllist.length==0))
605  return completeLoad();
606 
607  var filename = urllist;
608  var separ = filename.indexOf(";");
609  if (separ>0) {
610  filename = filename.substr(0, separ);
611  urllist = urllist.slice(separ+1);
612  } else {
613  urllist = "";
614  }
615 
616  var isrootjs = false, isbower = false;
617  if (filename.indexOf("$$$")===0) {
618  isrootjs = true;
619  filename = filename.slice(3);
620  if ((filename.indexOf("style/")==0) && JSROOT.source_min &&
621  (filename.lastIndexOf('.css')==filename.length-3) &&
622  (filename.indexOf('.min.css')<0))
623  filename = filename.slice(0, filename.length-4) + '.min.css';
624  } else
625  if (filename.indexOf("###")===0) {
626  isbower = true;
627  filename = filename.slice(3);
628  }
629  var isstyle = filename.indexOf('.css') > 0;
630 
631  if (isstyle) {
632  var styles = document.getElementsByTagName('link');
633  for (var n = 0; n < styles.length; ++n) {
634  if ((styles[n].type != 'text/css') || (styles[n].rel !== 'stylesheet')) continue;
635 
636  var href = styles[n].href;
637  if ((href == null) || (href.length == 0)) continue;
638 
639  if (href.indexOf(filename)>=0) return completeLoad();
640  }
641 
642  } else {
643  var scripts = document.getElementsByTagName('script');
644 
645  for (var n = 0; n < scripts.length; ++n) {
646  // if (scripts[n].type != 'text/javascript') continue;
647 
648  var src = scripts[n].src;
649  if ((src == null) || (src.length == 0)) continue;
650 
651  if ((src.indexOf(filename)>=0) && (src.indexOf("load=")<0)) {
652  // avoid wrong decision when script name is specified as more argument
653  return completeLoad();
654  }
655  }
656  }
657 
658  if (isrootjs && (JSROOT.source_dir!=null)) filename = JSROOT.source_dir + filename; else
659  if (isbower && (JSROOT.bower_dir.length>0)) filename = JSROOT.bower_dir + filename;
660 
661  var element = null;
662 
663  if (debugout)
664  document.getElementById(debugout).innerHTML = "loading " + filename + " ...";
665  else
666  JSROOT.progress("loading " + filename + " ...");
667 
668  if (isstyle) {
669  element = document.createElement("link");
670  element.setAttribute("rel", "stylesheet");
671  element.setAttribute("type", "text/css");
672  element.setAttribute("href", filename);
673  } else {
674  element = document.createElement("script");
675  element.setAttribute('type', "text/javascript");
676  element.setAttribute('src', filename);
677  }
678 
679  if (element.readyState) { // Internet Explorer specific
680  element.onreadystatechange = function() {
681  if (element.readyState == "loaded" || element.readyState == "complete") {
682  element.onreadystatechange = null;
683  completeLoad();
684  }
685  }
686  } else { // Other browsers
687  element.onload = function() {
688  element.onload = null;
689  completeLoad();
690  }
691  }
692 
693  document.getElementsByTagName("head")[0].appendChild(element);
694  }
695 
696  JSROOT.AssertPrerequisites = function(kind, callback, debugout) {
697  // one could specify kind of requirements
698  // 'io' for I/O functionality (default)
699  // '2d' for 2d graphic
700  // 'jq' jQuery and jQuery-ui
701  // 'jq2d' jQuery-dependend part of 2d graphic
702  // '3d' for 3d graphic
703  // 'simple' for basic user interface
704  // 'load:' list of user-specific scripts at the end of kind string
705 
706  var jsroot = JSROOT;
707 
708  if (!('doing_assert' in jsroot)) jsroot.doing_assert = [];
709 
710  if ((typeof kind !== 'string') || (kind == ''))
711  return jsroot.CallBack(callback);
712 
713  if (kind=='__next__') {
714  if (jsroot.doing_assert.length==0) return;
715  var req = jsroot.doing_assert[0];
716  if ('running' in req) return;
717  kind = req._kind;
718  callback = req._callback;
719  debugout = req._debug;
720  } else {
721  jsroot.doing_assert.push({_kind:kind, _callback:callback, _debug: debugout});
722  if (jsroot.doing_assert.length > 1) return;
723  }
724 
725  jsroot.doing_assert[0]['running'] = true;
726 
727  if (kind.charAt(kind.length-1)!=";") kind+=";";
728 
729  var ext = jsroot.source_min ? ".min" : "";
730 
731  var need_jquery = false, use_bower = (JSROOT.bower_dir.length>0);
732 
733  // file names should be separated with ';'
734  var mainfiles = "", extrafiles = ""; // scripts for direct loadin
735  var modules = []; // modules used for require.js
736 
737  if (kind.indexOf('io;')>=0) {
738  mainfiles += "$$$scripts/rawinflate" + ext + ".js;" +
739  "$$$scripts/JSRootIOEvolution" + ext + ".js;";
740  modules.push('JSRootIOEvolution');
741  }
742 
743  if (kind.indexOf('2d;')>=0) {
744  if (!('_test_d3_' in jsroot)) {
745  if (typeof d3 != 'undefined') {
746  jsroot.console('Reuse existing d3.js ' + d3.version + ", required 3.4.10", debugout);
747  jsroot['_test_d3_'] = 1;
748  } else {
749  mainfiles += use_bower ? '###d3/d3.min.js;' : '$$$scripts/d3.v3.min.js;';
750  jsroot['_test_d3_'] = 2;
751  }
752  }
753  modules.push('JSRootPainter');
754  mainfiles += '$$$scripts/JSRootPainter' + ext + ".js;";
755  extrafiles += '$$$style/JSRootPainter' + ext + '.css;';
756  }
757 
758  if (kind.indexOf('savepng;')>=0) {
759  modules.push('saveSvgAsPng');
760  mainfiles += '$$$scripts/saveSvgAsPng' + ext + ".js;";
761  }
762 
763  if (kind.indexOf('jq;')>=0) need_jquery = true;
764 
765  if (kind.indexOf('math;')>=0) {
766  mainfiles += '$$$scripts/JSRootMath' + ext + ".js;";
767  modules.push('JSRootMath');
768  }
769 
770  if (kind.indexOf('more2d;')>=0) {
771  mainfiles += '$$$scripts/JSRootPainter.more' + ext + ".js;";
772  modules.push('JSRootPainter.more');
773  }
774 
775  if (kind.indexOf('jq2d;')>=0) {
776  mainfiles += '$$$scripts/JSRootPainter.jquery' + ext + ".js;";
777  modules.push('JSRootPainter.jquery');
778  need_jquery = true;
779  }
780 
781  if ((kind.indexOf("3d;")>=0) || (kind.indexOf("geom;")>=0)) {
782  if (use_bower)
783  mainfiles += "###threejs/build/three.min.js;" +
784  "###threejs/examples/js/utils/FontUtils.js;" +
785  "###threejs/examples/js/renderers/Projector.js;" +
786  "###threejs/examples/js/renderers/CanvasRenderer.js;" +
787  "###threejs/examples/js/geometries/TextGeometry.js;" +
788  "###threejs/examples/js/controls/OrbitControls.js;" +
789  "###threejs/examples/js/controls/TransformControls.js;" +
790  "###threejs/examples/fonts/helvetiker_regular.typeface.js";
791  else
792  mainfiles += "$$$scripts/three" + ext + ".js;" +
793  "$$$scripts/three.extra" + ext + ".js;";
794  modules.push("threejs_all");
795  mainfiles += "$$$scripts/JSRoot3DPainter" + ext + ".js;";
796  modules.push('JSRoot3DPainter');
797  }
798 
799  if (kind.indexOf("geom;")>=0) {
800  mainfiles += "$$$scripts/ThreeCSG" + ext + ".js;" +
801  "$$$scripts/JSRootGeoPainter" + ext + ".js;";
802  extrafiles += "$$$style/JSRootGeoPainter" + ext + ".css;";
803  modules.push('ThreeCSG', 'JSRootGeoPainter');
804  }
805 
806  if (kind.indexOf("mathjax;")>=0) {
807  if (typeof MathJax == 'undefined') {
808  mainfiles += (use_bower ? "###MathJax/MathJax.js" : "https://cdn.mathjax.org/mathjax/latest/MathJax.js") +
809  "?config=TeX-AMS-MML_SVG," + jsroot.source_dir + "scripts/mathjax_config.js;";
810  }
811  if (JSROOT.gStyle.MathJax == 0) JSROOT.gStyle.MathJax = 1;
812  modules.push('MathJax');
813  }
814 
815  if (kind.indexOf("simple;")>=0) {
816  need_jquery = true;
817  mainfiles += '$$$scripts/JSRootInterface' + ext + ".js;";
818  extrafiles += '$$$style/JSRootInterface' + ext + '.css;';
819  modules.push('JSRootInterface');
820  }
821 
822  if (need_jquery && (JSROOT.load_jquery==null)) {
823  var has_jq = (typeof jQuery != 'undefined'), lst_jq = "";
824 
825  if (has_jq)
826  jsroot.console('Reuse existing jQuery ' + jQuery.fn.jquery + ", required 2.1.4", debugout);
827  else
828  lst_jq += (use_bower ? "###jquery/dist" : "$$$scripts") + "/jquery.min.js;";
829  if (has_jq && typeof $.ui != 'undefined')
830  jsroot.console('Reuse existing jQuery-ui ' + $.ui.version + ", required 1.11.4", debugout);
831  else {
832  lst_jq += (use_bower ? "###jquery-ui" : "$$$scripts") + '/jquery-ui.min.js;';
833  extrafiles += '$$$style/jquery-ui' + ext + '.css;';
834  }
835 
836  if (JSROOT.touches) {
837  lst_jq += use_bower ? '###jqueryui-touch-punch/jquery.ui.touch-punch.min.js;' : '$$$scripts/touch-punch.min.js;';
838  modules.push('jqueryui-touch-punch');
839  }
840 
841  modules.splice(0,0, 'jquery', 'jquery-ui', 'jqueryui-mousewheel');
842  mainfiles = lst_jq + mainfiles;
843 
844  jsroot.load_jquery = true;
845  }
846 
847  var pos = kind.indexOf("user:");
848  if (pos<0) pos = kind.indexOf("load:");
849  if (pos>=0) extrafiles += kind.slice(pos+5);
850 
851  function load_callback() {
852  var req = jsroot.doing_assert.shift();
853  jsroot.CallBack(req._callback);
854  jsroot.AssertPrerequisites('__next__');
855  }
856 
857  if ((typeof define === "function") && define.amd && (modules.length>0)) {
858  jsroot.console("loading " + JSON.stringify(modules) + " with require.js", debugout);
859  require(modules, function() {
860  jsroot.loadScript(extrafiles, load_callback, debugout);
861  });
862  } else {
863  jsroot.loadScript(mainfiles + extrafiles, load_callback, debugout);
864  }
865  }
866 
867  // function can be used to open ROOT file, I/O functionality will be loaded when missing
868  JSROOT.OpenFile = function(filename, callback) {
869  JSROOT.AssertPrerequisites("io", function() {
870  new JSROOT.TFile(filename, callback);
871  });
872  }
873 
874  // function can be used to draw supported ROOT classes,
875  // required functionality will be loaded automatically
876  // if painter pointer required, one should load '2d' functionlity itself
877  JSROOT.draw = function(divid, obj, opt) {
878  JSROOT.AssertPrerequisites("2d", function() {
879  JSROOT.draw(divid, obj, opt);
880  });
881  }
882 
883  JSROOT.redraw = function(divid, obj, opt) {
884  JSROOT.AssertPrerequisites("2d", function() {
885  JSROOT.redraw(divid, obj, opt);
886  });
887  }
888 
889  JSROOT.BuildSimpleGUI = function(user_scripts, andThen) {
890  if (typeof user_scripts == 'function') {
891  andThen = user_scripts;
892  user_scripts = null;
893  }
894 
895  var debugout = null;
896  var nobrowser = JSROOT.GetUrlOption('nobrowser')!=null;
897  var requirements = "io;2d;";
898 
899  if (document.getElementById('simpleGUI')) {
900  debugout = 'simpleGUI';
901  if ((JSROOT.GetUrlOption('json')!=null) &&
902  (JSROOT.GetUrlOption('file')==null) &&
903  (JSROOT.GetUrlOption('files')==null)) requirements = "2d;";
904  } else
905  if (document.getElementById('onlineGUI')) { debugout = 'onlineGUI'; requirements = "2d;"; } else
906  if (document.getElementById('drawGUI')) { debugout = 'drawGUI'; requirements = "2d;"; nobrowser = true; }
907 
908  if (user_scripts == 'check_existing_elements') {
909  user_scripts = null;
910  if (debugout == null) return;
911  }
912 
913  if (!nobrowser) requirements += 'jq2d;simple;';
914 
915  if (user_scripts == null) user_scripts = JSROOT.GetUrlOption("autoload");
916  if (user_scripts == null) user_scripts = JSROOT.GetUrlOption("load");
917 
918  if (user_scripts != null)
919  requirements += "load:" + user_scripts + ";";
920 
921  JSROOT.AssertPrerequisites(requirements, function() {
922  JSROOT.CallBack(JSROOT.findFunction(nobrowser ? 'JSROOT.BuildNobrowserGUI' : 'BuildSimpleGUI'));
923  JSROOT.CallBack(andThen);
924  }, debugout);
925  };
926 
927  JSROOT.Create = function(typename, target) {
928  var obj = target;
929  if (obj == null) obj = { _typename: typename };
930 
931  switch (typename) {
932  case 'TObject':
933  JSROOT.extend(obj, { fUniqueID: 0, fBits: 0x3000008 });
934  break;
935  case 'TNamed':
936  JSROOT.extend(obj, { fUniqueID: 0, fBits: 0x3000008, fName: "", fTitle: "" });
937  break;
938  case 'TList':
939  case 'THashList':
940  JSROOT.extend(obj, { name: typename, arr : [], opt : [] });
941  break;
942  case 'TAttAxis':
943  JSROOT.extend(obj, { fNdivisions: 510, fAxisColor: 1,
944  fLabelColor: 1, fLabelFont: 42, fLabelOffset: 0.005, fLabelSize: 0.035, fTickLength: 0.03,
945  fTitleOffset: 1, fTitleSize: 0.035, fTitleColor: 1, fTitleFont : 42 });
946  break;
947  case 'TAxis':
948  JSROOT.Create("TNamed", obj);
949  JSROOT.Create("TAttAxis", obj);
950  JSROOT.extend(obj, { fNbins: 0, fXmin: 0, fXmax: 0, fXbins : [], fFirst: 0, fLast: 0,
951  fBits2: 0, fTimeDisplay: false, fTimeFormat: "", fLabels: null });
952  break;
953  case 'TAttLine':
954  JSROOT.extend(obj, { fLineColor: 1, fLineStyle : 1, fLineWidth : 1 });
955  break;
956  case 'TAttFill':
957  JSROOT.extend(obj, { fFillColor: 0, fFillStyle : 0 } );
958  break;
959  case 'TAttMarker':
960  JSROOT.extend(obj, { fMarkerColor: 1, fMarkerStyle : 1, fMarkerSize : 1. });
961  break;
962  case 'TLine':
963  JSROOT.Create("TObject", obj);
964  JSROOT.Create("TAttLine", obj);
965  JSROOT.extend(obj, { fX1: 0, fX2: 1, fY1: 0, fY2: 1 });
966  break;
967  case 'TBox':
968  JSROOT.Create("TObject", obj);
969  JSROOT.Create("TAttLine", obj);
970  JSROOT.Create("TAttFill", obj);
971  JSROOT.extend(obj, { fX1: 0, fX2: 1, fY1: 0, fY2: 1 });
972  break;
973  case 'TPave':
974  JSROOT.Create("TBox", obj);
975  JSROOT.extend(obj, { fX1NDC : 0., fY1NDC: 0, fX2NDC: 1, fY2NDC: 1,
976  fBorderSize: 0, fInit: 1, fShadowColor: 1,
977  fCornerRadius: 0, fOption: "blNDC", fName: "title" });
978  break;
979  case 'TAttText':
980  JSROOT.extend(obj, { fTextAngle: 0, fTextSize: 0, fTextAlign: 22, fTextColor: 1, fTextFont: 42});
981  break;
982  case 'TPaveText':
983  JSROOT.Create("TPave", obj);
984  JSROOT.Create("TAttText", obj);
985  JSROOT.extend(obj, { fLabel: "", fLongest: 27, fMargin: 0.05, fLines: JSROOT.Create("TList") });
986  break;
987  case 'TPaveStats':
988  JSROOT.Create("TPaveText", obj);
989  JSROOT.extend(obj, { fOptFit: 0, fOptStat: 0, fFitFormat: "", fStatFormat: "", fParent: null });
990  break;
991  case 'TObjString':
992  JSROOT.Create("TObject", obj);
993  JSROOT.extend(obj, { fString: "" });
994  break;
995  case 'TH1':
996  JSROOT.Create("TNamed", obj);
997  JSROOT.Create("TAttLine", obj);
998  JSROOT.Create("TAttFill", obj);
999  JSROOT.Create("TAttMarker", obj);
1000 
1001  JSROOT.extend(obj, {
1002  fNcells : 0,
1003  fXaxis: JSROOT.Create("TAxis"),
1004  fYaxis: JSROOT.Create("TAxis"),
1005  fZaxis: JSROOT.Create("TAxis"),
1006  fBarOffset: 0, fBarWidth: 1000, fEntries: 0.,
1007  fTsumw: 0., fTsumw2: 0., fTsumwx: 0., fTsumwx2: 0.,
1008  fMaximum: -1111., fMinimum: -1111, fNormFactor: 0., fContour: [],
1009  fSumw2: [], fOption: "",
1010  fFunctions: JSROOT.Create("TList"),
1011  fBufferSize: 0, fBuffer: [], fBinStatErrOpt: 0 });
1012  break;
1013  case 'TH1I':
1014  case 'TH1F':
1015  case 'TH1D':
1016  case 'TH1S':
1017  case 'TH1C':
1018  JSROOT.Create("TH1", obj);
1019  obj.fArray = [];
1020  break;
1021  case 'TH2':
1022  JSROOT.Create("TH1", obj);
1023  JSROOT.extend(obj, { fScalefactor: 1., fTsumwy: 0., fTsumwy2: 0, fTsumwxy : 0});
1024  break;
1025  case 'TH2I':
1026  case 'TH2F':
1027  case 'TH2D':
1028  case 'TH2S':
1029  case 'TH2C':
1030  JSROOT.Create("TH2", obj);
1031  obj.fArray = [];
1032  break;
1033  case 'TGraph':
1034  JSROOT.Create("TNamed", obj);
1035  JSROOT.Create("TAttLine", obj);
1036  JSROOT.Create("TAttFill", obj);
1037  JSROOT.Create("TAttMarker", obj);
1038  JSROOT.extend(obj, { fFunctions: JSROOT.Create("TList"), fHistogram: null,
1039  fMaxSize: 0, fMaximum:-1111, fMinimum:-1111, fNpoints: 0, fX: [], fY: [] });
1040  break;
1041  case 'TMultiGraph':
1042  JSROOT.Create("TNamed", obj);
1043  JSROOT.extend(obj, { fFunctions: JSROOT.Create("TList"), fGraphs: JSROOT.Create("TList"),
1044  fHistogram: null, fMaximum: -1111, fMinimum: -1111 });
1045  break;
1046  case 'TGaxis':
1047  JSROOT.Create("TLine", obj);
1048  JSROOT.Create("TAttText", obj);
1049  JSROOT.extend(obj, { _fChopt: "", fFunctionName: "", fGridLength: 0,
1050  fLabelColor: 1, fLabelFont: 42, fLabelOffset: 0.005, fLabelSize: 0.035,
1051  fName: "", fNdiv: 12, fTickSize: 0.02, fTimeFormat: "",
1052  fTitle: "", fTitleOffset: 1, fTitleSize: 0.035,
1053  fWmax: 100, fWmin: 0 });
1054  break;
1055 
1056  }
1057 
1058  obj._typename = typename;
1059  this.addMethods(obj);
1060  return obj;
1061  }
1062 
1063  // obsolete functions, can be removed by next JSROOT release
1064  JSROOT.CreateTList = function() { return JSROOT.Create("TList"); }
1065  JSROOT.CreateTAxis = function() { return JSROOT.Create("TAxis"); }
1066 
1067  JSROOT.CreateTH1 = function(nbinsx) {
1068 
1069  var histo = JSROOT.extend(JSROOT.Create("TH1I"),
1070  { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" });
1071 
1072  if (nbinsx!==undefined) {
1073  histo.fNcells = nbinsx+2;
1074  for (var i=0;i<histo.fNcells;++i) histo.fArray.push(0);
1075  JSROOT.extend(histo.fXaxis, { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx });
1076  }
1077  return histo;
1078  }
1079 
1080  JSROOT.CreateTH2 = function(nbinsx, nbinsy) {
1081 
1082  var histo = JSROOT.extend(JSROOT.Create("TH2I"),
1083  { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" });
1084 
1085  if ((nbinsx!==undefined) && (nbinsy!==undefined)) {
1086  histo.fNcells = (nbinsx+2) * (nbinsy+2);
1087  for (var i=0;i<histo.fNcells;++i) histo.fArray.push(0);
1088  JSROOT.extend(histo.fXaxis, { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx });
1089  JSROOT.extend(histo.fYaxis, { fNbins: nbinsy, fXmin: 0, fXmax: nbinsy });
1090  }
1091  return histo;
1092  }
1093 
1094  JSROOT.CreateTGraph = function(npoints, xpts, ypts) {
1095  var graph = JSROOT.extend(JSROOT.Create("TGraph"),
1096  { fBits: 0x3000408, fName: "dummy_graph_" + this.id_counter++, fTitle: "dummytitle" });
1097 
1098  if (npoints>0) {
1099  graph.fMaxSize = graph.fNpoints = npoints;
1100 
1101  var usex = (typeof xpts == 'object') && (xpts.length === npoints);
1102  var usey = (typeof ypts == 'object') && (ypts.length === npoints);
1103 
1104  for (var i=0;i<npoints;++i) {
1105  graph.fX.push(usex ? xpts[i] : i/npoints);
1106  graph.fY.push(usey ? ypts[i] : i/npoints);
1107  }
1108  }
1109 
1110  return graph;
1111  }
1112 
1113  JSROOT.CreateTMultiGraph = function() {
1114  var mgraph = JSROOT.Create("TMultiGraph");
1115  for(var i=0; i<arguments.length; ++i)
1116  mgraph.fGraphs.Add(arguments[i], "");
1117  return mgraph;
1118  }
1119 
1120  JSROOT.methodsCache = {}; // variable used to keep methods for known classes
1121 
1122  JSROOT.getMethods = function(typename, obj) {
1123  var m = JSROOT.methodsCache[typename];
1124 
1125  if (m !== undefined) return m;
1126 
1127  m = {};
1128 
1129  if ((typename=="TObject") || (typename=="TNamed") || ((obj!==undefined) && ('fBits' in obj))) {
1130  m.TestBit = function (f) { return (this.fBits & f) != 0; };
1131  m.InvertBit = function (f) { this.fBits = this.fBits ^ (f & 0xffffff); };
1132  }
1133 
1134  if ((typename === 'TList') || (typename === 'THashList')) {
1135  m.Clear = function() {
1136  this.arr = [];
1137  this.opt = [];
1138  }
1139  m.Add = function(obj,opt) {
1140  this.arr.push(obj);
1141  this.opt.push((opt && typeof opt=='string') ? opt : "");
1142  }
1143  m.AddFirst = function(obj,opt) {
1144  this.arr.unshift(obj);
1145  this.opt.unshift((opt && typeof opt=='string') ? opt : "");
1146  }
1147  m.RemoveAt = function(indx) {
1148  this.arr.splice(indx, 1);
1149  this.opt.splice(indx, 1);
1150  }
1151  }
1152 
1153  if ((typename === "TPaveText") || (typename === "TPaveStats")) {
1154  m.AddText = function(txt) {
1155  this.fLines.Add({ fTitle: txt, fTextColor: 1 });
1156  }
1157  m.Clear = function() {
1158  this.fLines.Clear();
1159  }
1160  }
1161 
1162  if (typename.indexOf("TF1") == 0) {
1163  m.addFormula = function(obj) {
1164  if (obj==null) return;
1165  if (!('formulas' in this)) this.formulas = [];
1166  this.formulas.push(obj);
1167  }
1168 
1169  m.evalPar = function(x) {
1170  if (! ('_func' in this) || (this._title !== this.fTitle)) {
1171 
1172  var _func = this.fTitle;
1173 
1174  if ('formulas' in this)
1175  for (var i=0;i<this.formulas.length;++i)
1176  while (_func.indexOf(this.formulas[i].fName) >= 0)
1177  _func = _func.replace(this.formulas[i].fName, this.formulas[i].fTitle);
1178  _func = _func.replace(/\b(abs)\b/g, 'TMath::Abs');
1179  _func = _func.replace('TMath::Exp(', 'Math.exp(');
1180  _func = _func.replace('TMath::Abs(', 'Math.abs(');
1181  if (typeof JSROOT.Math == 'object') {
1182  this._math = JSROOT.Math;
1183  _func = _func.replace('TMath::Prob(', 'this._math.Prob(');
1184  _func = _func.replace('gaus(', 'this._math.gaus(this, x, ');
1185  _func = _func.replace('gausn(', 'this._math.gausn(this, x, ');
1186  _func = _func.replace('expo(', 'this._math.expo(this, x, ');
1187  _func = _func.replace('landau(', 'this._math.landau(this, x, ');
1188  _func = _func.replace('landaun(', 'this._math.landaun(this, x, ');
1189  }
1190  _func = _func.replace('pi', 'Math.PI');
1191  for (var i=0;i<this.fNpar;++i)
1192  while(_func.indexOf('['+i+']') != -1)
1193  _func = _func.replace('['+i+']', this.GetParValue(i));
1194  _func = _func.replace(/\b(sin)\b/gi, 'Math.sin');
1195  _func = _func.replace(/\b(cos)\b/gi, 'Math.cos');
1196  _func = _func.replace(/\b(tan)\b/gi, 'Math.tan');
1197  _func = _func.replace(/\b(exp)\b/gi, 'Math.exp');
1198 
1199  this._func = new Function("x", "return " + _func).bind(this);
1200  this._title = this.fTitle;
1201  }
1202 
1203  return this._func(x);
1204  }
1205  m.GetParName = function(n) {
1206  if (('fFormula' in this) && ('fParams' in this.fFormula)) return this.fFormula.fParams[n].first;
1207  if ('fNames' in this) return this.fNames[n];
1208  return "Par"+n;
1209  }
1210  m.GetParValue = function(n) {
1211  if (('fFormula' in this) && ('fClingParameters' in this.fFormula)) return this.fFormula.fClingParameters[n];
1212  if (('fParams' in this) && (this.fParams!=null)) return this.fParams[n];
1213  return null;
1214  }
1215  }
1216 
1217  if ((typename.indexOf("TGraph") == 0) || (typename == "TCutG")) {
1218  // check if point inside figure specified by the TGrpah
1219  m.IsInside = function(xp,yp) {
1220  var j = this.fNpoints - 1, x = this.fX, y = this.fY;
1221  var oddNodes = false;
1222 
1223  for (var i=0; i<this.fNpoints; ++i) {
1224  if ((y[i]<yp && y[j]>=yp) || (y[j]<yp && y[i]>=yp)) {
1225  if (x[i]+(yp-y[i])/(y[j]-y[i])*(x[j]-x[i])<xp) {
1226  oddNodes = !oddNodes;
1227  }
1228  }
1229  j=i;
1230  }
1231 
1232  return oddNodes;
1233  };
1234  }
1235 
1236  if (typename.indexOf("TH1") == 0 ||
1237  typename.indexOf("TH2") == 0 ||
1238  typename.indexOf("TH3") == 0) {
1239  m.getBinError = function(bin) {
1240  // -*-*-*-*-*Return value of error associated to bin number bin*-*-*-*-*
1241  // if the sum of squares of weights has been defined (via Sumw2),
1242  // this function returns the sqrt(sum of w2).
1243  // otherwise it returns the sqrt(contents) for this bin.
1244  if (bin >= this.fNcells) bin = this.fNcells - 1;
1245  if (bin < 0) bin = 0;
1246  if (bin < this.fSumw2.length)
1247  return Math.sqrt(this.fSumw2[bin]);
1248  return Math.sqrt(Math.abs(this.fArray[bin]));
1249  };
1250  m.setBinContent = function(bin, content) {
1251  // Set bin content - only trival case, without expansion
1252  this.fEntries++;
1253  this.fTsumw = 0;
1254  if ((bin>=0) && (bin<this.fArray.length))
1255  this.fArray[bin] = content;
1256  };
1257  }
1258 
1259  if (typename.indexOf("TH1") == 0) {
1260  m.getBin = function(x) { return x; }
1261  m.getBinContent = function(bin) { return this.fArray[bin]; }
1262  }
1263 
1264  if (typename.indexOf("TH2") == 0) {
1265  m.getBin = function(x, y) { return (x + (this.fXaxis.fNbins+2) * y); }
1266  m.getBinContent = function(x, y) { return this.fArray[this.getBin(x, y)]; }
1267  }
1268 
1269  if (typename.indexOf("TH3") == 0) {
1270  m.getBin = function(x, y, z) { return (x + (this.fXaxis.fNbins+2) * (y + (this.fYaxis.fNbins+2) * z)); }
1271  m.getBinContent = function(x, y, z) { return this.fArray[this.getBin(x, y, z)]; };
1272  }
1273 
1274  if (typename.indexOf("TProfile") == 0) {
1275  m.getBin = function(x) { return x; }
1276  m.getBinContent = function(bin) {
1277  if (bin < 0 || bin >= this.fNcells) return 0;
1278  if (this.fBinEntries[bin] < 1e-300) return 0;
1279  if (!this.fArray) return 0;
1280  return this.fArray[bin]/this.fBinEntries[bin];
1281  };
1282  m.getBinEffectiveEntries = function(bin) {
1283  if (bin < 0 || bin >= this.fNcells) return 0;
1284  var sumOfWeights = this.fBinEntries[bin];
1285  if ( this.fBinSumw2 == null || this.fBinSumw2.length != this.fNcells) {
1286  // this can happen when reading an old file
1287  return sumOfWeights;
1288  }
1289  var sumOfWeightsSquare = this.fSumw2[bin];
1290  return ( sumOfWeightsSquare > 0 ? sumOfWeights * sumOfWeights / sumOfWeightsSquare : 0 );
1291  };
1292  m.getBinError = function(bin) {
1293  if (bin < 0 || bin >= this.fNcells) return 0;
1294  var cont = this.fArray[bin], // sum of bin w *y
1295  sum = this.fBinEntries[bin], // sum of bin weights
1296  err2 = this.fSumw2[bin], // sum of bin w * y^2
1297  neff = this.getBinEffectiveEntries(bin); // (sum of w)^2 / (sum of w^2)
1298  if (sum < 1e-300) return 0; // for empty bins
1299  var EErrorType = { kERRORMEAN : 0, kERRORSPREAD : 1, kERRORSPREADI : 2, kERRORSPREADG : 3 };
1300  // case the values y are gaussian distributed y +/- sigma and w = 1/sigma^2
1301  if (this.fErrorMode === EErrorType.kERRORSPREADG)
1302  return 1.0/Math.sqrt(sum);
1303  // compute variance in y (eprim2) and standard deviation in y (eprim)
1304  var contsum = cont/sum;
1305  var eprim2 = Math.abs(err2/sum - contsum*contsum);
1306  var eprim = Math.sqrt(eprim2);
1307  if (this.fErrorMode === EErrorType.kERRORSPREADI) {
1308  if (eprim != 0) return eprim/Math.sqrt(neff);
1309  // in case content y is an integer (so each my has an error +/- 1/sqrt(12)
1310  // when the std(y) is zero
1311  return 1.0/Math.sqrt(12*neff);
1312  }
1313  // if approximate compute the sums (of w, wy and wy2) using all the bins
1314  // when the variance in y is zero
1315  // case option "S" return standard deviation in y
1316  if (this.fErrorMode === EErrorType.kERRORSPREAD) return eprim;
1317  // default case : fErrorMode = kERRORMEAN
1318  // return standard error on the mean of y
1319  return (eprim/Math.sqrt(neff));
1320  };
1321  }
1322 
1323  JSROOT.methodsCache[typename] = m;
1324  return m;
1325  };
1326 
1327  JSROOT.addMethods = function(obj) {
1328  this.extend(obj, JSROOT.getMethods(obj._typename, obj));
1329  };
1330 
1331  JSROOT.lastFFormat = "";
1332 
1333  JSROOT.FFormat = function(value, fmt) {
1334  // method used to convert numeric value to string according specified format
1335  // format can be like 5.4g or 4.2e or 6.4f
1336  // function saves actual format in JSROOT.lastFFormat variable
1337  if (!fmt) fmt = "6.4g";
1338 
1339  JSROOT.lastFFormat = "";
1340 
1341  fmt = fmt.trim();
1342  var len = fmt.length;
1343  if (len<2) return value.toFixed(4);
1344  var last = fmt.charAt(len-1);
1345  fmt = fmt.slice(0,len-1);
1346  var isexp = null;
1347  var prec = fmt.indexOf(".");
1348  if (prec<0) prec = 4; else prec = Number(fmt.slice(prec+1));
1349  if (isNaN(prec) || (prec<0) || (prec==null)) prec = 4;
1350 
1351  var significance = false;
1352  if ((last=='e') || (last=='E')) { isexp = true; } else
1353  if (last=='Q') { isexp = true; significance = true; } else
1354  if ((last=='f') || (last=='F')) { isexp = false; } else
1355  if (last=='W') { isexp = false; significance = true; } else
1356  if ((last=='g') || (last=='G')) {
1357  var se = JSROOT.FFormat(value, fmt+'Q');
1358  var _fmt = JSROOT.lastFFormat;
1359  var sg = JSROOT.FFormat(value, fmt+'W');
1360 
1361  if (se.length < sg.length) {
1362  JSROOT.lastFFormat = _fmt;
1363  return se;
1364  }
1365  return sg;
1366  } else {
1367  isexp = false;
1368  prec = 4;
1369  }
1370 
1371  if (isexp) {
1372  // for exponential representation only one significant digit befor point
1373  if (significance) prec--;
1374  if (prec<0) prec = 0;
1375 
1376  JSROOT.lastFFormat = '5.'+prec+'e';
1377 
1378  return value.toExponential(prec);
1379  }
1380 
1381  var sg = value.toFixed(prec);
1382 
1383  if (significance) {
1384 
1385  // when using fixed representation, one could get 0.0
1386  if ((value!=0) && (Number(sg)==0.) && (prec>0)) {
1387  prec = 20; sg = value.toFixed(prec);
1388  }
1389 
1390  var l = 0;
1391  while ((l<sg.length) && (sg.charAt(l) == '0' || sg.charAt(l) == '-' || sg.charAt(l) == '.')) l++;
1392 
1393  var diff = sg.length - l - prec;
1394  if (sg.indexOf(".")>l) diff--;
1395 
1396  if (diff != 0) {
1397  prec-=diff;
1398  if (prec<0) prec = 0; else if (prec>20) prec = 20;
1399  sg = value.toFixed(prec);
1400  }
1401  }
1402 
1403  JSROOT.lastFFormat = '5.'+prec+'f';
1404 
1405  return sg;
1406  }
1407 
1408  JSROOT.log10 = function(n) {
1409  return Math.log(n) / Math.log(10);
1410  }
1411 
1412  // dummy function, will be redefined when JSRootPainter is loaded
1413  JSROOT.progress = function(msg) {
1414  if ((msg !== undefined) && (typeof msg=="string")) JSROOT.console(msg);
1415  }
1416 
1417  JSROOT.Initialize = function() {
1418 
1419  if (JSROOT.source_fullpath.length === 0) return this;
1420 
1421  function window_on_load(func) {
1422  if (func!=null) {
1423  if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading')
1424  func();
1425  else
1426  window.onload = func;
1427  }
1428  return JSROOT;
1429  }
1430 
1431  var src = JSROOT.source_fullpath;
1432 
1433  if (JSROOT.GetUrlOption('gui', src) !== null)
1434  return window_on_load( function() { JSROOT.BuildSimpleGUI(); } );
1435 
1436  if ( typeof define === "function" && define.amd )
1437  return window_on_load( function() { JSROOT.BuildSimpleGUI('check_existing_elements'); } );
1438 
1439  var prereq = "";
1440  if (JSROOT.GetUrlOption('io', src)!=null) prereq += "io;";
1441  if (JSROOT.GetUrlOption('2d', src)!=null) prereq += "2d;";
1442  if (JSROOT.GetUrlOption('jq2d', src)!=null) prereq += "jq2d;";
1443  if (JSROOT.GetUrlOption('more2d', src)!=null) prereq += "more2d;";
1444  if (JSROOT.GetUrlOption('geo', src)!=null) prereq += "geo;";
1445  if (JSROOT.GetUrlOption('3d', src)!=null) prereq += "3d;";
1446  if (JSROOT.GetUrlOption('math', src)!=null) prereq += "math;";
1447  if (JSROOT.GetUrlOption('mathjax', src)!=null) prereq += "mathjax;";
1448  var user = JSROOT.GetUrlOption('load', src);
1449  if ((user!=null) && (user.length>0)) prereq += "load:" + user;
1450  var onload = JSROOT.GetUrlOption('onload', src);
1451  var bower = JSROOT.GetUrlOption('bower', src);
1452  if (bower!==null) {
1453  if (bower.length>0) JSROOT.bower_dir = bower; else
1454  if (JSROOT.source_dir.indexOf("jsroot/") == JSROOT.source_dir.length - 7)
1455  JSROOT.bower_dir = JSROOT.source_dir.substr(0, JSROOT.source_dir.length - 7);
1456  if (JSROOT.bower_dir.length > 0) console.log("Set JSROOT.bower_dir to " + JSROOT.bower_dir);
1457  }
1458 
1459  if ((prereq.length>0) || (onload!=null))
1460  window_on_load(function() {
1461  if (prereq.length>0) JSROOT.AssertPrerequisites(prereq, onload); else
1462  if (onload!=null) {
1463  onload = JSROOT.findFunction(onload);
1464  if (typeof onload == 'function') onload();
1465  }
1466  });
1467 
1468  return this;
1469  }
1470 
1471  return JSROOT.Initialize();
1472 
1473 }));
1474 
1476